Rosserial & STM32
The ROS robotic operating system is a fairly powerful platform for creating robotic systems, which includes everything necessary for developing your projects from the simplest software components called “nodes” and the data exchange protocol to the simulation environment of a real Gazebo robotic platform. Mostly ROS is used in conjunction with such microcontrollers on the Arduino platform. The Internet is full of all sorts of tutorials on a bunch of ROS and Arduino.
There is currently no information on the use of the ROS robotic operating system in conjunction with the STM32 microcontroller. The Internet is only full of questions.
![](https://habrastorage.org/webt/r3/xo/-i/r3xo-ix7liahiwhpqfbrcqncg9c.png)
To work with STM32 we need STM32CubeMX and SystemworkbenchforSTM32. There is plenty of information about their installation on the network, we will not dwell on this.
To configure the controller, go to STM32CubeMX.
Create a new project.
![](https://habrastorage.org/webt/vz/j9/ps/vzj9psilnxbv70jt76mfjd2sqf4.png)
We’ll select a microcontroller, I have STM32f103c8t6.
![](https://habrastorage.org/webt/er/1e/da/er1edan5rp-bs93zy8pilw-od-y.png)
In the periphery, we indicate that an external quartz resonator is connected, we have 2 of them. We
![](https://habrastorage.org/webt/sy/db/ac/sydbacocbufrmk9l22wle_hvpuy.png)
configure the outputs through which you can enable debugging of the controller (looking ahead, if the project is in C ++, debugging may not work)
![](https://habrastorage.org/webt/tc/3s/_a/tc3s_aixqy6w1nkdkozxvwclwii.png)
Let's configure port 13 of port C, to it has a built-in LED.
![](https://habrastorage.org/webt/ow/ne/4_/owne4_udwfi9iih_vdu1bp0iarg.png)
Set up the UART pins.
![](https://habrastorage.org/webt/nm/yv/js/nmyvjsjhwx6dgrzfe-xjdwkzpq4.png)
Go to Lock_configuration and make the settings as in the picture.
![](https://habrastorage.org/webt/gm/rm/c_/gmrmc_agfm2tyflepfoa0y0g56o.png)
UART
Setting the data rate.
![](https://habrastorage.org/webt/dr/40/xg/dr40xgaz113_lo3rtadkfrkwnmg.png)
DMA setup.
![](https://habrastorage.org/webt/sp/k2/ev/spk2ev7ycm_vl_479vnmiauxhqc.png)
![](https://habrastorage.org/webt/5p/bj/pe/5pbjperakd3brrhxunktphz7ehu.png)
Configure interrupt, you need to specify a global interrupt on UART
![](https://habrastorage.org/webt/yg/rv/gc/ygrvgcoshvrwetba3nfgeo76rca.png)
![](https://habrastorage.org/webt/i2/ch/ey/i2cheyaelog_qpsrtwoclx5ig9k.png)
![](https://habrastorage.org/webt/zw/lj/_i/zwlj_i4e7f0phoetsvdfbezigys.png)
We are waiting for it to gather.
![](https://habrastorage.org/webt/hy/wr/z0/hywrz0g0d9hu0rqokae4lpihrhi.png)
We open the project,
![](https://habrastorage.org/webt/x8/jl/ie/x8jliev2ccwcuf0wj9-tqvgkdmi.png)
By opening this project in SW4STM32, adding some peripheral control, assembling it, and flashing the controller, I did not get any result.
Therefore, we create a new project according to the following instructions, and transfer the configuration obtained by STM32CubeMX.
1) Click File> New> C Project
2) C Project
1) Enter the name of the project
2) Choose the type of project: Executable> Ac6 STM32 MCU Project
3) Select Toolchains: Ac6 STM32 MCU GCC
4) Click "Next"
![](https://habrastorage.org/webt/pl/ll/ed/pllledbfjtuwsaqwlj2vb2ndun8.png)
3) Select the microcontroller
1 ) Click “Create a new custom board”
1) Save Definition of a new board
2) Enter the name of the new board: STM32F103
3) Select the chip of the board: STM32F1
4) Select the MCU: STM32F103RCTx
5) Click “OK”.
2) Select the board you just created!
1) Select a series: STM32F1
2) Select a board: STM32F103
3) Click "Next"
![](https://habrastorage.org/webt/6j/m-/gc/6jm-gc_rykla5chzbymmfw-vxem.png)
4) Connect the HAL libraries
![](https://habrastorage.org/webt/ky/-z/bo/ky-zboy5nsakqwym1wgggs9mbqk.png)
5) Click "Finish"
We copy the contents of the src and inc files created by the cube into our files, we also copy STM32F103C8Tx_FLASH.ld.
![](https://habrastorage.org/webt/yu/iw/ky/yuiwkyljb6jmjbrgywjc4axj8v0.png)
To check the operability of STM32 itself and the code in the while loop, write the following lines
Here we just blink the LED.
During assembly, problems may occur in the stm32f1xx_hal_msp.c file. The
error associated with the void function HAL_MspInit (void) is fixed as follows.
We open the folder with the HAL_Driver library, go to / src, open the stm32f1xx_hal_msp_template.c file and comment out the same function:
![](https://habrastorage.org/webt/jb/rq/5w/jbrq5wpklb-ztmqzuklqepwgh5g.png)
We reassemble (it should assemble without errors) I
forgot to mention the st-flash utility for the controller firmware.
Using ST link
Verifying ST link detection:
In response, we should see something like:
To flush the controller, go to the folder of our project and flash the controller through the following command:
Checked. Everything works. We move on.
Since the ROS libraries are written in C ++, we translate our project into a C ++ project, and change the file format main.c, stm32f1xx_hal_msp.c, stm32f1xx_it.c to .cpp We
clone my repository with the libraries and the necessary files for rosserial to work on STM32.
We insert the cloned folder into the project
![](https://habrastorage.org/webt/c5/a9/yx/c5a9yx2j6uf7wevljunc0bks0og.png)
![](https://habrastorage.org/webt/3_/4h/jh/3_4hjhqbl-psljdqsrlikkqvsmy.png)
Let's go to the project settings (Properties), first of all, connect the library, go ...
![](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)
Change the linker
![](https://habrastorage.org/webt/pp/ux/e_/ppuxe_icwxsytenafdelbhzewzq.png)
![](https://habrastorage.org/webt/a4/aw/t9/a4awt9_8ztkfqqjrusjrvcq0mfy.png)
Perform the optimization
![](https://habrastorage.org/webt/52/dk/vk/52dkvkhaq9_ql7fqbqxodty5mrw.png)
![](https://habrastorage.org/webt/od/ji/_-/odji_-8zr16qykp3cafrpy4a304.png)
Well, now we will make some changes to main.cpp, since it is almost empty, the first thing we do is connect the ROS library, and libraries for interactions with ROS topics, or rather with the data types of these topics.
Create a node that publishes this topic and accepts
Initialize the node and topics in main.
We also add variables to work with time and what we will publish.
In the while loop, we will have the following. We will publish our phrase after a certain time.
Putting together a project.
The following errors may appear:
![](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)
Reassemble and flash.
Now directly interacting with ROS.
In one terminal, run ROS.
In the next run the node.
We get the following
Next, in a new terminal window, look at the topics
We get the following topics:
In the topic of the chatter, the controller publishes the phrase.
We can listen to it through the team
![](https://habrastorage.org/webt/go/ov/fr/goovfriahknpo0ep99v9h7ycqn4.png)
Now send the data to the topic led.
And we have to change the state of the LED.
There is currently no information on the use of the ROS robotic operating system in conjunction with the STM32 microcontroller. The Internet is only full of questions.
![](https://habrastorage.org/webt/r3/xo/-i/r3xo-ix7liahiwhpqfbrcqncg9c.png)
Get started
To work with STM32 we need STM32CubeMX and SystemworkbenchforSTM32. There is plenty of information about their installation on the network, we will not dwell on this.
To configure the controller, go to STM32CubeMX.
Create a new project.
![](https://habrastorage.org/webt/vz/j9/ps/vzj9psilnxbv70jt76mfjd2sqf4.png)
We’ll select a microcontroller, I have STM32f103c8t6.
![](https://habrastorage.org/webt/er/1e/da/er1edan5rp-bs93zy8pilw-od-y.png)
In the periphery, we indicate that an external quartz resonator is connected, we have 2 of them. We
![](https://habrastorage.org/webt/sy/db/ac/sydbacocbufrmk9l22wle_hvpuy.png)
configure the outputs through which you can enable debugging of the controller (looking ahead, if the project is in C ++, debugging may not work)
![](https://habrastorage.org/webt/tc/3s/_a/tc3s_aixqy6w1nkdkozxvwclwii.png)
Let's configure port 13 of port C, to it has a built-in LED.
![](https://habrastorage.org/webt/ow/ne/4_/owne4_udwfi9iih_vdu1bp0iarg.png)
Set up the UART pins.
![](https://habrastorage.org/webt/nm/yv/js/nmyvjsjhwx6dgrzfe-xjdwkzpq4.png)
Go to Lock_configuration and make the settings as in the picture.
![](https://habrastorage.org/webt/gm/rm/c_/gmrmc_agfm2tyflepfoa0y0g56o.png)
Let's move on to more detailed configuration of the periphery
UART
Setting the data rate.
![](https://habrastorage.org/webt/dr/40/xg/dr40xgaz113_lo3rtadkfrkwnmg.png)
DMA setup.
![](https://habrastorage.org/webt/sp/k2/ev/spk2ev7ycm_vl_479vnmiauxhqc.png)
![](https://habrastorage.org/webt/5p/bj/pe/5pbjperakd3brrhxunktphz7ehu.png)
Configure interrupt, you need to specify a global interrupt on UART
![](https://habrastorage.org/webt/yg/rv/gc/ygrvgcoshvrwetba3nfgeo76rca.png)
GPIO setup
![](https://habrastorage.org/webt/i2/ch/ey/i2cheyaelog_qpsrtwoclx5ig9k.png)
Project build setup
![](https://habrastorage.org/webt/zw/lj/_i/zwlj_i4e7f0phoetsvdfbezigys.png)
We are waiting for it to gather.
![](https://habrastorage.org/webt/hy/wr/z0/hywrz0g0d9hu0rqokae4lpihrhi.png)
We open the project,
![](https://habrastorage.org/webt/x8/jl/ie/x8jliev2ccwcuf0wj9-tqvgkdmi.png)
Creating a project for System Workbench For STM32
By opening this project in SW4STM32, adding some peripheral control, assembling it, and flashing the controller, I did not get any result.
Therefore, we create a new project according to the following instructions, and transfer the configuration obtained by STM32CubeMX.
Creating a project for System Workbench For STM32
1) Click File> New> C Project
2) C Project
1) Enter the name of the project
2) Choose the type of project: Executable> Ac6 STM32 MCU Project
3) Select Toolchains: Ac6 STM32 MCU GCC
4) Click "Next"
![](https://habrastorage.org/webt/pl/ll/ed/pllledbfjtuwsaqwlj2vb2ndun8.png)
3) Select the microcontroller
1 ) Click “Create a new custom board”
1) Save Definition of a new board
2) Enter the name of the new board: STM32F103
3) Select the chip of the board: STM32F1
4) Select the MCU: STM32F103RCTx
5) Click “OK”.
2) Select the board you just created!
1) Select a series: STM32F1
2) Select a board: STM32F103
3) Click "Next"
![](https://habrastorage.org/webt/6j/m-/gc/6jm-gc_rykla5chzbymmfw-vxem.png)
4) Connect the HAL libraries
![](https://habrastorage.org/webt/ky/-z/bo/ky-zboy5nsakqwym1wgggs9mbqk.png)
5) Click "Finish"
Adding Files
We copy the contents of the src and inc files created by the cube into our files, we also copy STM32F103C8Tx_FLASH.ld.
![](https://habrastorage.org/webt/yu/iw/ky/yuiwkyljb6jmjbrgywjc4axj8v0.png)
To check the operability of STM32 itself and the code in the while loop, write the following lines
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
HAL_Delay(100);
Here we just blink the LED.
During assembly, problems may occur in the stm32f1xx_hal_msp.c file. The
error associated with the void function HAL_MspInit (void) is fixed as follows.
We open the folder with the HAL_Driver library, go to / src, open the stm32f1xx_hal_msp_template.c file and comment out the same function:
![](https://habrastorage.org/webt/jb/rq/5w/jbrq5wpklb-ztmqzuklqepwgh5g.png)
We reassemble (it should assemble without errors) I
forgot to mention the st-flash utility for the controller firmware.
$ 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
Using ST link
Verifying ST link detection:
$ st-info —probe
In response, we should see something like:
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
To flush the controller, go to the folder of our project and flash the controller through the following command:
cd workspace/ros_stm32_2/
st-flash write Debug/ros_stm32_2.bin 0x8000000
Checked. Everything works. We move on.
Since the ROS libraries are written in C ++, we translate our project into a C ++ project, and change the file format main.c, stm32f1xx_hal_msp.c, stm32f1xx_it.c to .cpp We
clone my repository with the libraries and the necessary files for rosserial to work on STM32.
git clone https://gitlab.com/ivliev123/ros_lib
We insert the cloned folder into the project
![](https://habrastorage.org/webt/c5/a9/yx/c5a9yx2j6uf7wevljunc0bks0og.png)
![](https://habrastorage.org/webt/3_/4h/jh/3_4hjhqbl-psljdqsrlikkqvsmy.png)
Let's go to the project settings (Properties), first of all, connect the library, go ...
![](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)
Change the linker
![](https://habrastorage.org/webt/pp/ux/e_/ppuxe_icwxsytenafdelbhzewzq.png)
![](https://habrastorage.org/webt/a4/aw/t9/a4awt9_8ztkfqqjrusjrvcq0mfy.png)
Perform the optimization
![](https://habrastorage.org/webt/52/dk/vk/52dkvkhaq9_ql7fqbqxodty5mrw.png)
![](https://habrastorage.org/webt/od/ji/_-/odji_-8zr16qykp3cafrpy4a304.png)
Well, now we will make some changes to main.cpp, since it is almost empty, the first thing we do is connect the ROS library, and libraries for interactions with ROS topics, or rather with the data types of these topics.
#include
#include
#include
Create a node that publishes this topic and accepts
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 sub("led", led_cb);
Initialize the node and topics in main.
nh.initNode();
nh.advertise(chatter);
nh.subscribe(sub);
We also add variables to work with time and what we will publish.
const char * hello = "Hello World!!";
int chatter_interval = 1000.0 / 2;
int chatter_last = HAL_GetTick();
In the while loop, we will have the following. We will publish our phrase after a certain time.
if (nh.connected())
{
if(HAL_GetTick() - chatter_last > chatter_interval)
{
str_msg.data = hello;
chatter.publish(&str_msg);
chatter_last = HAL_GetTick();
}
}
nh.spinOnce();
Putting together a project.
The following errors may appear:
![](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)
Reassemble and flash.
Now directly interacting with ROS.
In one terminal, run ROS.
roscore
In the next run the node.
rosrun rosserial_python serial_node.py /dev/ttyUSB0
We get the following
[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]
Next, in a new terminal window, look at the topics
rostopic list
We get the following topics:
/chatter
/diagnostics
/led
/rosout
/rosout_agg
In the topic of the chatter, the controller publishes the phrase.
We can listen to it through the team
rostopic echo /chatter
![](https://habrastorage.org/webt/go/ov/fr/goovfriahknpo0ep99v9h7ycqn4.png)
Now send the data to the topic led.
rostopic pub /led std_msgs/UInt16 "data: 0"
And we have to change the state of the LED.