ROS学习笔记--移植rosserial到stm32(HAL库、MDK)和ROS通信
前言
ROS通过话题的发布和订阅来进行节点的通信,底层控制器使用rosserial也可以当作一个ROS中的节点,常用的控制器都是基于arduino的,官方也推出了rosserial_stm32。不过官方的是在linux环境下使用sw4stm32,现在使用MDK创建一个工程在博客中记录一下注意事项。
移植
创建CUBEMX工程
使用cubemx创建一个工程,需要使用一个串口和一个定时器。具体创建cubemx工程的步骤这里不再重复,相信大家都会,这里只说明一下注意事项。
串口部分
- 开启接收和发送的DMA通道,注意接DMA模式为Circular,而发送DMA模式为Normal
- 打开串口和DMA中断
- 串口波特率根据需求而定,rosserial_python中默认波特率为57600,可以设置为此波特率。
定时器部分
- 最好是高级定时器和部分通用定时器,要求
ARR
寄存器是32位 ,如果没有之后会介绍解决办法 - 设置时钟分频
Prescaler
,使定时器计数频率为1K,即CNT
加1用时1ms,由于32定时器的PSC
寄存器为16位,所以需要调整系统时钟使定时器的时钟为65MHz以下,通常设置64MHz,例如使用TIM2,则调整时钟树使APB1 Timer Clocks
为64MHz,然后设置Prescaler
为64000-1。若不想降频,后面会介绍方法。
Counter Period
设为FFFFFFFF,越大越好。- 不用开启中断
RosLib的获取
roslib包含了ros相关消息的头文件,获取的方式有很多,可以使用arduino的也可以按rosserial_stm32官方给的方法再linux下直接生成。直接生成的话需要安装sw4stm32,并在其workspace中运行python教本,rosrun rosserial_stm32 make_libraries.py
,过程很简单。
使MDK支持C++
Misc Control 中填写 --cpp11,既可。
阅读部分源码避免进坑
使用rosserial需要注意的地方使时间同步,对32定时器设置有一定的要求,需要看一下roslib内的部分代码来决定定时器的设置。
STM32Hardware.h
STM32Hardware():
htim(&htim2), huart(&huart1), rind(0), twind(0), tfind(0){
}
这里指定了需要rosserial用到的定时器和串口,可以根据需求改变
unsigned long time(){
return __HAL_TIM_GET_COUNTER(htim);}
这一函数获取定时器计数,即获取时间
node_handle.h
STM32Hardware.h中的函数都会在node_handle.h文件中被调用,我们主要看time()
的调用情况。大概如下所示:
void syncTime(uint8_t * data)
{
std_msgs::Time t;
uint32_t offset = hardware_.time() - rt_time;
t.deserialize(data);
t.data.sec += offset / 1000;
t.data.nsec += (offset