摘要
运动底盘是移动机器人的重要组成部分, 不像激光雷达, IMU, 麦克风, 音响, 摄像头这些通用部件可以直接买到, 很难买到通用的底盘. 一方面是因为底盘的尺寸结构和参数是要与具体机器人匹配的; 另一方面是因为底盘包含软硬件整套解决方案, 是很多机器人公司的核心技术, 一般不会随便公开. 出于强烈的求知欲与学习热情, 我想自己 DIY 一整套两轮差分底盘, 并且将完整的设计过程公开出去供大家学习. 说干就干, 本章节主要内容:
1.stm32 主控硬件设计
2.stm32 主控软件设计
3. 底盘通信协议
4. 底盘 ROS 驱动开发
5. 底盘 PID 控制参数整定
6. 底盘里程计标
4. 底盘 ROS 驱动开发
对于做纯 SLAM 算法, 机器人导航避障, 或者别的需要用到移动底盘的应用, 根据底盘的通信协议, 直接使用底盘 ROS 驱动实现跟底盘的交互. miiboo 机器人底盘的 ROS 驱动代码组织如图 36.
(图 36)miiboo 机器人底盘的 ROS 驱动代码组织
整个代码组织是一个完整的 ROS 功能包, 功能包名为 miiboo_bringup, 功能包中包含两个 ROS 节点源码 (base_controller.cpp 和 pid_set.cpp), 不难看出这两个节点正是对底盘通信协议中的 DATA-uart2 与 DEBUG-uart1 的具体实现. base_controller.cpp 负责对底盘控制驱动的具体实现, pid_set.cpp 负责对底盘调试驱动的具体实现. 本节重点对这两个节点进行讲解, 至于功能包名下的其他内容将放在后面的 miiboo 机器人 SLAM 导航实战中具体展开.
4.1. 底盘控制节点
接口:
底盘控制节点对下与底盘 DATA-uart2 串口通信, 对上开放 ROS 接口为应用层提功能数据发布与订阅, 便于 SLAM 导航等功能的开发.
(图 37) 底盘控制节点接口
节点实现源码解析:
底盘控制节点由 base_controller.cpp 实现. 程序主要分为两个过程: 订阅 topic 数据并下发给底盘, 从底盘接收数据并发布到 topic.
首先, 程序订阅 / cmd_vel 作为用户的控制输入, 将控制输入的速度信息转换为通信协议中 DATA-uart2 规定的格式, 然后通过串口下发给底盘, 实现对底盘的运动控制. 订阅 / cmd_vel 的回调函数和串口下发函数分别如图 38 和图 39 所示.
(图 38) 订阅 / cmd_vel 的回调函数
(图 39) 串口下发函数
然后, 程序从串口获取底盘的速度反馈, 并将速度反馈数据放入航迹推演算法中进行解算, 得到里程计, 将反馈回来的左轮速度, 右轮速度值分别发布到 / wheel_left_speed 和 / wheel_right_speed 主题, 将解算出来的里程计分别发布到 / odom 和 / tf 主题. 由于不同的算法对里程计的格式要求不一样, 所以将里程计同时发布到 / odom 和 / tf 主题, 便于不同的算法使用. 从串口获取速度反馈并求解里程计和发布反馈速度与里程计到 topic
分别如图 40 和图 41 所示.
(图 40) 从串口获取速度反馈并求解里程计
(图 41) 发布反馈速度与里程计到 topic
基于航迹推演算法的里程计解算:
首先, 我们需要了解一下 ROS 下的机器人坐标系为右手坐标系, 如图 42, 机器人底盘的正前方为 x 轴正方向, 机器人底盘的正上方为 z 轴正方向, 机器人底盘的正左方向为 y 轴正方向, 机器人航向角 theta 坐标轴以 x 轴为 0 度角并逆时针方向增大. 一般以机器人底盘上电时刻, 机器人底盘的位置建立里程计坐标系, 也就是说机器人底盘的起始位姿为原点 O, 机器人底盘在运动过程中, 通过前一时刻的位置和左, 右轮位移可以推算出机器人底盘的下一时刻位姿, 这就是航迹推演算法.
(图 42) 机器人右手坐标系与航迹推演
我们这里值讨论两轮差分底盘的情况, 分析如图 41, 通过前一时刻的位置和左, 右轮位移可以推算出机器人底盘的下一时刻位姿. 航迹推演的数学模型如图 43.
(图 43) 航迹推演的数学模型
在很短的时间间隔里, 前后两个机器人位姿满足一定的关系, 具体看图 44 的推导.
(图 44) 短时间内两个机器人位姿的约束关系
这样, 经过进一步的化简, 可以得到我们解算里程计的核心公式, 如图 45.
(图 45) 解算里程计核心公式
不难发现, 上面程序中解算里程计部分的代码就是这个核心公式的具体编程实现. 关于航迹推演算法更详细的推导, 请参考:
4.2. 底盘调试节点
接口:
底盘调试节点对下与底盘 DEBUG-uart1 串口通信, 对上通过命令行终端指令交互方式.
(图 46) 底盘调试节点接口
节点实现源码解析:
底盘调试节点由 pid_set.cpp 实现. 程序主要分为两个过程: 从终端获取调试命令并下发给底盘, 从底盘接收应答数据并显示在终端.
首先, 程序从终端获取调试命令, 用户可输入数字 1,2,3, 如果用户输入 3 会再要求输入 kp,ki,kd 这三个数, 将调试命令转换为通信协议中 DEBUG-uart1 规定的格式, 然后通过串口下发给底盘, 实现对底盘的调试. 调试命令获取与下发如图 47.
(图 47) 调试命令获取与下发
然后, 程序从串口获取底盘的应答信息, 这里就比较简单了, 直接将获取的应答数据原样打印到终端就行了, 如图 48.
(图 48) 应答数据原样打印
来源: http://www.bubuko.com/infodetail-2961181.html