当前位置: 代码迷 >> 综合 >> rosserial移植到STM32(CUBEMX+HAL库)
  详细解决方案

rosserial移植到STM32(CUBEMX+HAL库)

热度:48   发布时间:2023-11-13 16:40:21.0

使用cubemx+HAL库将rosserial移植到STM32

    • rosserial的作用
    • 需要实现的功能
    • 移植步骤
    • 我创建的工程
    • 没有积分的可以到github下载

rosserial的作用

使用过ros的话都会了解过ros特殊的通信机制,通过话题的发布和订阅来进行通信。
有时候我们需要从PC端的串口与单片机进行通信,我曾试着直接调用串口与STM32进行数据传输,但是数据非常不好处理,自己定协议也是一个非常麻烦的事情,还经常出现一些奇怪的乱码,如果能在STM32上模仿ros直接发布或订阅话题并能够使用ros的数据类型就好了。
我曾在ros的官网上看到有将rosserial移植到arduino的教程,当移植成功后可以将arduino当成一个节点直接订阅ros通信网络上的话题,也可以直接往ros的通信网络发布话题,但是坑爹的是ros官网没给STM32的移植教程。
网上也有一些大佬用标准库移植过,但写的不明不白,我花了大量精力将大佬的代码看懂并强行移植到HAL库,最后确实能用,但代码看起来非常恶心。直到今天我发现了一种非常简单的移植方法,可以将代码搞得非常漂亮,为了让大家少踩坑,我将移植过程写出来供大家参考。

需要实现的功能

我们从PC端发布一个话题为pc_to_stm32的std_msgs::String类型数据,单片机订阅该话题,并将该数据通过话题stm32_to_pc发布出来。

移植步骤

  1. 首先我们建一个CUBEMX工程
    在这里插入图片描述
  2. 选好你的芯片的型号,我的单片机是F103ZET6
    在这里插入图片描述
  3. 分别配RCC ,SYS,TIM2,USART
    在这里插入图片描述
    在这里插入图片描述
  4. 配时钟树,这里我配64MHZ
    在这里插入图片描述
  5. 配USART波特率,这里我配57600,因为这是serial_node的默认参数,方便,你要是改别的也行,但是serial_node也要改对应了
    在这里插入图片描述
    在这里插入图片描述
  6. 配串口DMA
    在这里插入图片描述
    在这里插入图片描述
  7. 串口中断开启
    在这里插入图片描述
    在这里插入图片描述
  8. 配置工程路径与参数
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  9. 点击OK后CUBEMX将生成32的工程,但先别急着打开,先关掉
    在这里插入图片描述
  10. 我们将RosLibs文件夹复制粘贴到我们的工程文件夹下,这个文件夹是arduino移植过程生成的,里面储存的是ROS的各种消息类型,方便我们以后调用的,我们这次移植的目的就是为了能直接调用这些数据类型。这个文件夹可以从我分享的文件获得,或者参考官网的arduino教程获取。
    在这里插入图片描述
  11. 我们在MDK-ARM目录建立三个文件
    在这里插入图片描述
  12. 将刚才加进来的文件添加进32的工程
    在这里插入图片描述
    在这里插入图片描述
  13. 如果成功添加那我们就能从工程看到所添加的文件
    在这里插入图片描述
  14. 由于ros数据类型是以类的方式写好的,属于C++的特性,所以我们的32工程需要进行C与C++的混编,同时我们添加数据类型文件的路径
    在这里插入图片描述
    在这里插入图片描述
  15. 在mainpp.cpp文件创建订阅节点和发布节点,与ros在PC的方式完全一样,mainpp.h文件需要注意添加使用C编译规则编译
    在这里插入图片描述
    在这里插入图片描述
  16. 然后我们在main.c文件调用mainpp.cpp的函数,记住要添加mainpp.cpp的头文件
    在这里插入图片描述
    在这里插入图片描述
  17. 编译后我们可以看到编译是通过的,但是有15个警告,不要慌,这是由于keil对C++的支持不太好,但是不影响我们使用。我们需要将警告屏蔽掉,因为不能让别人以为是由于我们代码写的不好而出现的警告
    在这里插入图片描述
    在这里插入图片描述
  18. 忽略警告后重新编译,又是一段 0 Error(s), 0 Warning(s)的完美代码
    在这里插入图片描述
  19. 我们将代码烧录到单片机并将串口怼到PC测试,看能不能出现我们想要的效果,首先不要忘了提高串口权限,然后运行rosserial节点
    在这里插入图片描述
sudo chmod 777 /dev/ttyUSB0
rosrun rosserial_python serial_node.py
  1. 监听话题 /stm32_to_pc(此时/stm32_to_pc没有任何数据)
    在这里插入图片描述
rostopic echo /stm32_to_pc 
  1. 发布话题 /pc_to_stm32 ,同时我们可以看到STM32通过话题/stm32_to_pc将数据转反回来,到这里就说明我们移植成功了。
    在这里插入图片描述
rostopic pub -r 1 pc_to_stm32 std_msgs/String hello
  1. 通过rqt查看节点我们可以这样理解,节点serial_node作为STM32与ros的桥梁,主要负责数据的转化。
    在这里插入图片描述
  2. 如果移植到STM32别的系列主要改动下面几个地方(以F407ZGT6为例)
    在这里插入图片描述
    24.BUG解决
    由于我用来讲解的单片机是F103ZET6,受限于硬件问题,就是tim2用于计数那个寄存器是16位的,最大值只能到65535,我们用了它的数据作为rosserial协议的时间戳的数据源,当计数超出65535时候就会溢出,这导致了我们的时间戳匹配不上,从而会重新连接,并报出Unable to sync with device; possible link problem or link software version mismatch such as hydro rosserial_python with groovy Arduino这个错误,你们会发现没10秒左右就出重新连接一次就是这个原因,但是这并不影响实际的通信效果,只是非常恶心罢了,如果你用了别的型号的单片机,你可以检查一下这个寄存器的容量,有的是32位的,比如F407ZGT6就是32位的,根据下图修改就可以修复这个小bug了
    在这里插入图片描述

我创建的工程

rosserial

没有积分的可以到github下载

github下载地址