开启辅助访问 切换到窄版

打印 上一主题 下一主题

STM32到底如何与ROS进行通信

[复制链接]
作者:admin 
版块:
MCU单片机技术 stm 发布时间:2018-6-8 14:35:56
18500
楼主
跳转到指定楼层
| 只看该作者 回帖奖励 |倒序浏览 |阅读模式
一直有朋友咨询STM32到底如何与ROS实现信息交互,ROS如何获取移动底座的位置、速度、偏航角等信息,移动底座又是如何实时接收ROS的速度控制命令等。为了更清晰的描述这些问题,最近特意进行了总结归纳,从底层的STM32,到ROS的节点设计都做了详细的论述,放到这里给共同学习ROS的朋友一个方向。当然这里不局限于STM32,可以使用其他的MCU。
设计思路


有的朋友使用全向移动底座,有的使用两轮差动或四轮来驱动;为了保持代码通用性,运动学解析这一部分没有特别的说明,移动底座只接收 x 与 y 两个方向的线速度以及一个绕 z 轴的角速度;针对不同的移动底座,还需要设计不同的运动学解析函数,以便于将线速度与角速度转变成电机运动指令,从而控制电机运动。ROS 部分实现一个节点,该节点订阅 cmd_vel 话题,并将该话题转变成 x y 两个方向的线速度以及一个绕 z 轴的角速度,通过串口发送到移动底座,即给STM32或者其他您选用的移动底座MCU;另外该节点还需要发布导航需要的 odom 消息,这个消息需要移动底座提供,通过STM32的串口发送机器人的位置、速度、偏航角等信息,经过特殊的变换之后再发布。当然也可以通过CAN的通信方式实现,原理都一样。
STM32


STM32使用最多的便是STM32F103,为了便于调试,选择STM32的串口1作为调试串口,打印一些调试信息;使用STM32的串口3作为与 ROS 通信的端口;调试串口波特率设置为9600,8位数据1个停止位,偶校验;串口3设置为115200波特率,8位数据1个停止位无校验模式;当然这个波特率可以自行设置。数据的发送和接收可以是固定长度或不固定长度,为了适应不同的长度字节,建议使用DMA模式,并开启串口的空闲中断,否则很难判断一帧数据包的完全接收。当然也可以开启一个定时器,在一定时间内判断是否超时来间接的判断一帧数据是否完成。最好的方式就是开启串口空闲中断,将数据的发送和接收都由DMA负责,这样不占用CPU资源。
调试端口:
PA9--->USART1_TX---->DMA1_Channel4
PA10--->USART1_RX--->DMA1_Channel5
与ROS通信端口:
PB10--->USART3_TX---->DMA1_Channel2
PB11---->USART3_RX--->DMA1_Channel3
数据接收


使用DMA接收数据,配置如下:
开启串口的空闲中断,并在空闲中断中读取串口数据:
这样才能接收变长的数据帧。
数据发送


数据发送时只要将数据发送的首地址以及数据宽度给 DMA 即可,因为一开始固定了发送缓存地址,所以只需要指定发送缓存长度即可:
调试功能


建议stm32 的 DMA 方式实现 printf 功能,因为底座还有很多任务要处理包括运动学解析以及电机控制等。
ROS


需要设计一个 ROS 节点,该节点订阅 cmd_vel 话题,并发布 odom 消息;解析订阅的 cmd_vel 话题,转变成线速度以及角速度参数通过串口发送至移动底座;并实时监听串口送来的移动底座的位置、速度、偏航角等信息,整合成 odom 消息格式,发布出去。因为串口发送的都是16进制数据,因此涉及到浮点与16进制的转换,可以直接读内存实现:
串口发送的数据格式也就是移动底座接收数据包的格式可以定义为:
velocity_x 表示 x 方向线速度,velocity_y 表示 y 方向线速度,angular_v 表示绕 z 轴的角速度,因为移动底座为贴地面运行,因此只有绕 z 轴的角速度,数据发送的总长度为15字节。
串口接收的数据格式也就是移动底座发送的数据包格式可以定义为:
x-position 表示机器人实时 x 坐标位置,y-position表示机器人实时 y 坐标位置,x-velocity表示机器人实时 x 坐标方向速度,y-velocity表示机器人实时 y 坐标方向速度,angular velocity表示机器人当前角速度,pose angular表示机器人当前偏航角。数据上传的总长度为27字节。校验和从有效数据开始取异或即可,如下示例:
ROS 端串口的数据发送与数据读取可参考 rosserial,需要注意的是在订阅 cmd_vel 话题时的回调函数中,参数类型选择 const geometry_msgs::Twist,另外在从串口获取到里程计信息后需要将偏航角转换成四元数才能进行发布:
测试


为了更直观的观察代码可用性,使用时我直接使用了 ROS 中的 turtlesim turtle_teleop_key 来使用键盘的方向键来键入速度、角速度等。测试时开三个terminal,分别运行:
此时可以通过键盘方向键发送运动命令,可以在终端窗口观察到信息的发布,STM32端可以手动给一些位置、速度等的固定值,可以接另外一台电脑连接STM32的调试串口,因为我就一个电脑,测试时直接使用JTAG观察变量:


该截图为按下向上的方向键时捕捉到的信息,可以清晰的看到 stm32 收到的线速度 x 方向为 2:
对应的也可以看到 ROS 的输出信息 :
在STM32端给定的移动底座的实时位置、速度信息为:


此时我们在ROS端可以非常清晰的查看到该信息已经发布,并被我们捕捉到,开一个终端,输入rostopic echo /odom进行查看:


至此,已经完全实现了STM32的串口与ROS进行数据交互,并且测试成功,实际使用时只要添加对应的移动底座运动学解析部分即可。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表