В данный момент не существует информации об использовании робототехнической операционной системы ROS в связке с микроконтроллером STM32. Интернет переполнен только вопросами.
![](https://habrastorage.org/webt/r3/xo/-i/r3xo-ix7liahiwhpqfbrcqncg9c.png)
Начнем работу
Для работы с STM32 нам понадобится STM32CubeMX и SystemworkbenchforSTM32. Информации об их установке в сети предостаточно, не будем на этом останавливаться.
Для конфигурации контроллера зайдем в STM32CubeMX
Создадим новый проект.
![](https://habrastorage.org/webt/vz/j9/ps/vzj9psilnxbv70jt76mfjd2sqf4.png)
Выберем микроконтроллер, у меня STM32f103c8t6.
![](https://habrastorage.org/webt/er/1e/da/er1edan5rp-bs93zy8pilw-od-y.png)
В периферии указываем, что у на подключен внешний кварцевый резонатор, у нас их 2
![](https://habrastorage.org/webt/sy/db/ac/sydbacocbufrmk9l22wle_hvpuy.png)
Настраиваем выводы, через которые можно включать отладку контроллера, (забегая вперед, если проект будет на С++, отладка может не работать)
![](https://habrastorage.org/webt/tc/3s/_a/tc3s_aixqy6w1nkdkozxvwclwii.png)
Настроим 13 вывод порта С, к нему подключен встроенный светодиод.
![](https://habrastorage.org/webt/ow/ne/4_/owne4_udwfi9iih_vdu1bp0iarg.png)
Настроим выводы UART.
![](https://habrastorage.org/webt/nm/yv/js/nmyvjsjhwx6dgrzfe-xjdwkzpq4.png)
Перейдем в Сlock_configuration и выполним настройки как на картинке.
![](https://habrastorage.org/webt/gm/rm/c_/gmrmc_agfm2tyflepfoa0y0g56o.png)
Перейдем к более детальной настройке периферии
UART
Настройка скорости обмена данных.
![](https://habrastorage.org/webt/dr/40/xg/dr40xgaz113_lo3rtadkfrkwnmg.png)
Настройка DMA.
![](https://habrastorage.org/webt/sp/k2/ev/spk2ev7ycm_vl_479vnmiauxhqc.png)
![](https://habrastorage.org/webt/5p/bj/pe/5pbjperakd3brrhxunktphz7ehu.png)
Настройка прерывания, нужно указать глобальное прерывание по UART
![](https://habrastorage.org/webt/yg/rv/gc/ygrvgcoshvrwetba3nfgeo76rca.png)
Настройка GPIO
![](https://habrastorage.org/webt/i2/ch/ey/i2cheyaelog_qpsrtwoclx5ig9k.png)
Настройка сборки проекта
![](https://habrastorage.org/webt/zw/lj/_i/zwlj_i4e7f0phoetsvdfbezigys.png)
Ждем пока соберется
![](https://habrastorage.org/webt/hy/wr/z0/hywrz0g0d9hu0rqokae4lpihrhi.png)
Открываем проект,
![](https://habrastorage.org/webt/x8/jl/ie/x8jliev2ccwcuf0wj9-tqvgkdmi.png)
Создание проекта под 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) Нажмите «Далее»
![](https://habrastorage.org/webt/pl/ll/ed/pllledbfjtuwsaqwlj2vb2ndun8.png)
3) Выбираем микроконтроллер
1) Нажмите «Create a new custom board»
1) Сохранить Определение новой платы
2) Введите имя новой платы: STM32F103
3) Выберите чип платы: STM32F1
4) Выберите МСU: STM32F103RCTx
5) Нажмите «ОК».
2) Выберите плату, которое вы только что создали!
1) Выбрать серию: STM32F1
2) Выберите плату: STM32F103
3) Нажмите «Далее»
![](https://habrastorage.org/webt/6j/m-/gc/6jm-gc_rykla5chzbymmfw-vxem.png)
4) Подключаем библиотеки HAL
![](https://habrastorage.org/webt/ky/-z/bo/ky-zboy5nsakqwym1wgggs9mbqk.png)
5) Нажмите «Finish»
Добавление файлов
Копируем содержимое файлов src и inc, созданных кубом в наши файлы, также копируем STM32F103C8Tx_FLASH.ld
![](https://habrastorage.org/webt/yu/iw/ky/yuiwkyljb6jmjbrgywjc4axj8v0.png)
Для проверки работоспособности самой 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 и закомментируем эту же функцию:
![](https://habrastorage.org/webt/jb/rq/5w/jbrq5wpklb-ztmqzuklqepwgh5g.png)
Собираем заново (должно собраться без ошибок)
Забыл упомянуть для прошивки контроллера понадобится утилита 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: "\x56\x3f\x72\x06\x51\x3f\x52\x50\x48\x32\x15\x3f"
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
Вставляем склонированную папку в проект
![](https://habrastorage.org/webt/c5/a9/yx/c5a9yx2j6uf7wevljunc0bks0og.png)
![](https://habrastorage.org/webt/3_/4h/jh/3_4hjhqbl-psljdqsrlikkqvsmy.png)
Перейдем в настройки проект (Properties), первым делом подключаем библиотеку, переходим…
![](https://habrastorage.org/webt/us/dp/6l/usdp6l8xeq7qk5qvxu2fnbcqhdu.png)
![](https://habrastorage.org/webt/zx/n7/u_/zxn7u_v5m9yvc2oupzjmy0a93we.png)
![](https://habrastorage.org/webt/cd/uv/cf/cduvcfrjdw-xxniumtmlzbrxpdm.png)
Изменяем компоновщик
![](https://habrastorage.org/webt/pp/ux/e_/ppuxe_icwxsytenafdelbhzewzq.png)
![](https://habrastorage.org/webt/a4/aw/t9/a4awt9_8ztkfqqjrusjrvcq0mfy.png)
Выполняем оптимизацию
![](https://habrastorage.org/webt/52/dk/vk/52dkvkhaq9_ql7fqbqxodty5mrw.png)
![](https://habrastorage.org/webt/od/ji/_-/odji_-8zr16qykp3cafrpy4a304.png)
Ну теперь внесем некие изменения в 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();
Собираем проект.
Могут появится следующие ошибки:
![](https://habrastorage.org/webt/_e/im/mx/_eimmxwleimawe2wtzilcvhgwe4.png)
![](https://habrastorage.org/webt/yy/wn/fp/yywnfpvkeqjycws0cvtiqo6lulo.png)
![](https://habrastorage.org/webt/k0/tj/mm/k0tjmm6aap31tbezwmuqoddtkq4.png)
Собираем заново и прошиваем.
Теперь непосредственно само взаимодействие с 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
![](https://habrastorage.org/webt/go/ov/fr/goovfriahknpo0ep99v9h7ycqn4.png)
Теперь отправим данные в топик led.
rostopic pub /led std_msgs/UInt16 "data: 0"
И у нас должно изменится состояние светодиода.
Комментарии (17)
SET_LAB Автор
08.03.2019 23:20Переписывать все на Си нецелесообразно, использовать Arduino в качестве посредника налаживает дополнительные задержки по времени.
ZEN_LS
09.03.2019 13:45wiki.ros.org/rosserial
пункт 1.1.
Даже не так -> сразу гит.
github.com/yoneken/rosserial_stm32SET_LAB Автор
09.03.2019 14:15-1github.com/yoneken/rosserial_stm32 не имеет никаких подробностей по настройке периферии, проект полностью урезан, к тому же еще и на костылях(main.c, main.cpp)
AVI-crak
09.03.2019 02:03Кхм, очень похоже на фотографию в полный рост на коне в окопе. Если система слишком сложна и непонятно как работает — ко какой смысл её использовать?
Как ROS управляет движками — можно вдоволь насмотреться на ютюбе. Некоторым даже нравится смотреть на конвульсии железа.
besitzeruf
09.03.2019 02:491) Прочитал статью, но так и не понял… Каким образом проект в C++ мешает отладке???
2)Так как библиотеки ROS написаны на C++, переводим наш проект в проект С++, и изменяем формат файлов main.c, stm32f1xx_hal_msp.c, stm32f1xx_it.c в .cpp
Вы пробовали создавать комбинированный проект C/C++?
Dead_Angel
09.03.2019 11:07В данный момент не существует информации об использовании робототехнической операционной системы ROS в связке с микроконтроллером STM32. Интернет переполнен только вопросами.
А чем это не подошло?
А если у вас nucleo и есть доступ к mbed то есть это
olartamonov
09.03.2019 13:11-1А если убрать из этого поста стопятьсот скриншотов куба и воркшопа, и оставить только про подключение и использование библиотеки, то он станет раз в десять короче и раз в пять полезнее.
Серьёзно, это на кого рассчитано? На человека, который STM32 видит впервые в жизни?AmigoRRR
10.03.2019 00:03+1И правильно он сделал, без этих скриншотов не разберешься что жать и куда перетаскивать в cubmx и systemworkbench.
olartamonov
10.03.2019 11:22Вы не поверите, но я, например, ни разу в жизни не пользовался ни CubeMX, ни SystemWorkbench — и не планирую.
А те люди, которые пользовались, очевидно, должны быть уже в курсе, куда там нажимать.
Отсюда и вопрос — статья-то на кого рассчитана? На людей, которые, открыв её, впервые в жизни CubeMX запустят?
augorelov
10.03.2019 00:08Автор, пора перелезть с убого воркбенча с его глюками и багами на новую среду от ST-ников.
SadAngel
10.03.2019 01:59Работал с Rosserial на F407, F429, F767, в Atollic True Studio:
Так как библиотеки ROS написаны на C++, переводим наш проект в проект С++, и изменяем формат файлов main.c, stm32f1xx_hal_msp.c, stm32f1xx_it.c в .cpp
Не нужно, достаточно только изменить main.c на main.cpp
В Atollic True Studio есть возможность «конвертировать C проект в С++»
забегая вперед, если проект будет на С++, отладка может не работать
неправда, работает без проблем.
Мой проект под STM32F767 с Rosserial и FreeRTOS и LL библиотекой (не люблю HAL), пока сироват и работает без UART прериваний и DMA:
github.com/ros-ukraine/leobot/tree/F%23111_STM32F767_Firmware/leobot_firmware/STM32F767_Firmware
В данный момент не существует информации об использовании робототехнической операционной системы ROS в связке с микроконтроллером STM32. Интернет переполнен только вопросами.
полно, например Adding Support for New Hardware:
wiki.ros.org/rosserial_client/Tutorials/Adding%20Support%20for%20New%20Hardware
wiki.ros.org/rosserial_client/Tutorials/Using%20rosserial%20with%20AVR%20and%20UART
Не знаю почему, но если после nh.spinOnce(); поставить задержку (даже osDelay(1)) Rosserial работать не будет.
ZEN_LS
Возникает серия вопросов:
* Почему не использовать кусок либы из реализации rosserial под ардуино, переписав ее на си.
* Почему нельзя написать ноду которая парсит любые сообщения с стм32, I2C, SPI, хоть кан. Инит либы rosserial в уне занимает половину памяти (на сколько я помню), что делает эту либу не очень полезной.
* Почему-бы скриншоты не обрезать.
* Зачем танцы с бубном и консолью, почти в любой IDE есть кнопка прошить.
BiosUefi
?Зачем танцы с бубном и консолью, почти в любой IDE есть кнопка прошить.
Может по тому что ЛЮБАЯ IDE пишет не больше 64кб, а для большего, увы, надо покупать лицензию за 5К евро?
SadAngel
Atollic TrueSTUDIO: atollic.com/truestudio — 100% free, работает и под Windows и Linux, ограничений нет, и работает с STM32CubeMX.
www.youtube.com/watch?v=q9Ssi9ry1eg
www.youtube.com/watch?v=6RqUkFIeN6w
www.youtube.com/watch?v=JnmjmP2Xchg
Atollic is now part of STMicroelectronics: atollic.com