Rosserial & STM32

в 18:46, , рубрики: robotics, ROS, rosserial, SET_LAB, stm32, программирование микроконтроллеров, робототехника

Робототехническая операционная система ROS является довольно мощной платформой для создания робототехнических систем, которая включает все необходимое для разработки своих проектов от простейших программных компонентов, называемых “узлами”, и протокола обмена данными до среды симулирования реальной робототехнической платформы Gazebo. В основном ROS используется в связке с такими микроконтроллерами на платформе Arduino. Интернет переполнен всевозможными туториалами о связке ROS и Arduino.

В данный момент не существует информации об использовании робототехнической операционной системы ROS в связке с микроконтроллером STM32. Интернет переполнен только вопросами.

Rosserial & STM32 - 1

Начнем работу

Для работы с STM32 нам понадобится STM32CubeMX и SystemworkbenchforSTM32. Информации об их установке в сети предостаточно, не будем на этом останавливаться.

Для конфигурации контроллера зайдем в STM32CubeMX

Создадим новый проект.

Rosserial & STM32 - 2

Выберем микроконтроллер, у меня STM32f103c8t6.

Rosserial & STM32 - 3

В периферии указываем, что у на подключен внешний кварцевый резонатор, у нас их 2

Rosserial & STM32 - 4

Настраиваем выводы, через которые можно включать отладку контроллера, (забегая вперед, если проект будет на С++, отладка может не работать)

Rosserial & STM32 - 5

Настроим 13 вывод порта С, к нему подключен встроенный светодиод.

Rosserial & STM32 - 6

Настроим выводы UART.

Rosserial & STM32 - 7

Перейдем в Сlock_configuration и выполним настройки как на картинке.

Rosserial & STM32 - 8

Перейдем к более детальной настройке периферии

UART

Настройка скорости обмена данных.

Rosserial & STM32 - 9

Настройка DMA.

Rosserial & STM32 - 10

Rosserial & STM32 - 11

Настройка прерывания, нужно указать глобальное прерывание по UART

Rosserial & STM32 - 12

Настройка GPIO

Rosserial & STM32 - 13

Настройка сборки проекта

Rosserial & STM32 - 14

Ждем пока соберется

Rosserial & STM32 - 15

Открываем проект,

Rosserial & STM32 - 16

Создание проекта под System Workbench For STM32

Открыв данный проект в SW4STM32, дописав некоторое управление периферией, собрав его, и прошив контроллер, я не получил никакого результата.

Поэтому создаем новый проект по следующей инструкции, и переносим конфигурацию полученную STM32CubeMX.

Создание проекта под System Workbench For STM32

1) Нажмите File > New > C Project

2) C Project
1) Введите название проекта
2) Выберите тип проекта: Executable > Ac6 STM32 MCU Project
3) Выберите Toolchains: Ac6 STM32 MCU GCC
4) Нажмите «Далее»

Rosserial & STM32 - 17

3) Выбираем микроконтроллер
1) Нажмите «Create a new custom board»
1) Сохранить Определение новой платы
2) Введите имя новой платы: STM32F103
3) Выберите чип платы: STM32F1
4) Выберите МСU: STM32F103RCTx
5) Нажмите «ОК».
2) Выберите плату, которое вы только что создали!
1) Выбрать серию: STM32F1
2) Выберите плату: STM32F103
3) Нажмите «Далее»

Rosserial & STM32 - 18

4) Подключаем библиотеки HAL

Rosserial & STM32 - 19

5) Нажмите «Finish»

Добавление файлов

Копируем содержимое файлов src и inc, созданных кубом в наши файлы, также копируем STM32F103C8Tx_FLASH.ld

Rosserial & STM32 - 20

Для проверки работоспособности самой STM32 и кода в цикл while прописываем следующие строки

      HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
      HAL_Delay(100);

Тут мы просто моргаем светодиодом.

При сборке могут возникнуть проблемы в файле stm32f1xx_hal_msp.c

Ошибку связанную с функцией void HAL_MspInit(void) исправляем следующим образом.
Открываем папку с библиотекой HAL_Driver, идем /src открываем файл stm32f1xx_hal_msp_template.c и закомментируем эту же функцию:

Rosserial & STM32 - 21

Собираем заново (должно собраться без ошибок)

Забыл упомянуть для прошивки контроллера понадобится утилита st-flash.

$ sudo apt-get install cmake 
$ sudo apt-get install libusb-1.0.0 
$ git clone github.com/texane/stlink.git 
$ cd stlink 
$ make release 
$ cd build/Release; sudo make install 
$ sudo ldconfig 

Использование ST link

Проверка обнаружения ST link:

$ st-info —probe 

В ответ мы должны увидеть что-то вроде:

Found 1 stlink programmers 
serial: 563f7206513f52504832153f 
openocd: "x56x3fx72x06x51x3fx52x50x48x32x15x3f" 
flash: 262144 (pagesize: 2048) 
sram: 65536 
chipid: 0x0414 
descr: F1 High-density device 

Для прошивки контроллера переходим в папку нашего проекта и и прошиваем контроллер через следующий команду:

cd workspace/ros_stm32_2/
st-flash write Debug/ros_stm32_2.bin 0x8000000

Проверили. Все работает. Двигаемся дальше.

Так как библиотеки ROS написаны на C++, переводим наш проект в проект С++, и изменяем формат файлов main.c, stm32f1xx_hal_msp.c, stm32f1xx_it.c в .cpp

Клонируем мой репозиторий с библиотеками рос и нужными файлами для работы rosserial на STM32.

git clone https://gitlab.com/ivliev123/ros_lib

Вставляем склонированную папку в проект

Rosserial & STM32 - 22

Rosserial & STM32 - 23

Перейдем в настройки проект (Properties), первым делом подключаем библиотеку, переходим…

Rosserial & STM32 - 24

Rosserial & STM32 - 25

Rosserial & STM32 - 26

Изменяем компоновщик

Rosserial & STM32 - 27

Rosserial & STM32 - 28

Выполняем оптимизацию

Rosserial & STM32 - 29

Rosserial & STM32 - 30

Ну теперь внесем некие изменения в main.cpp, так как он почти пустой, первое что делаем подключаем библиотеку ROS, и библиотеки для взаимодействия с топиками ROS, а точней с типами данных этих топиков.

#include <ros.h>
#include <std_msgs/String.h>
#include <std_msgs/UInt16.h>

Создадим узел, топик публикующий данный и принимающий

void led_cb( const std_msgs::UInt16& cmd_msg){
          HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
}

ros::NodeHandle nh;
std_msgs::String str_msg;
ros::Publisher chatter("chatter", &str_msg);

ros::Subscriber<std_msgs::UInt16> sub("led", led_cb);

Инициализируем узел и топики в main.

        nh.initNode();
        nh.advertise(chatter);
        nh.subscribe(sub);

Также добавим переменные для работы со временем и то что будем публиковать.

const char * hello = "Hello World!!";

int chatter_interval = 1000.0 / 2;
int chatter_last = HAL_GetTick();

В цикле while у нас будет следующее. Будем публиковать нашу фразу через определенное время.

        if (nh.connected())
        {
            if(HAL_GetTick() - chatter_last > chatter_interval)
            {
                str_msg.data = hello;
                chatter.publish(&str_msg);
                chatter_last = HAL_GetTick();
            }
        }

        nh.spinOnce();

Собираем проект.

Могут появится следующие ошибки:

Rosserial & STM32 - 31

Rosserial & STM32 - 32

Rosserial & STM32 - 33

Собираем заново и прошиваем.

Теперь непосредственно само взаимодействие с ROS.
В одном терминале запускаем ROS.

roscore

В следующем запускаем узел.

rosrun rosserial_python serial_node.py /dev/ttyUSB0

Получаем следующее

[INFO] [1551788593.109252]: ROS Serial Python Node
[INFO] [1551788593.124198]: Connecting to /dev/ttyUSB0 at 57600 baud
[INFO] [1551788595.233498]: Requesting topics...
[INFO] [1551788595.258554]: Note: publish buffer size is 2048 bytes
[INFO] [1551788595.259532]: Setup publisher on chatter [std_msgs/String]
[INFO] [1551788595.275572]: Note: subscribe buffer size is 2048 bytes
[INFO] [1551788595.276682]: Setup subscriber on led [std_msgs/UInt16]

Далее в новом окне терминала, смотрим, топики

rostopic list 

Получаем следующие топики:

/chatter
/diagnostics
/led
/rosout
/rosout_agg

В топик chatter контроллер публикует фразу.

Можем его послушать через команду

rostopic echo /chatter 

Rosserial & STM32 - 34

Теперь отправим данные в топик led.

rostopic pub /led std_msgs/UInt16 "data: 0" 

И у нас должно изменится состояние светодиода.

Автор: Евгений Ивлиев

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js