机器人导航与定位的系统架构:


最底层


机器人本身的电机驱动部分,该部分通过串口接收电脑端输出的左右轮期望速度,对左右轮分别进行PID控速。同时,定时采样电机码盘值,并转化为左右轮速度值通过串口上传给电脑。当然PID控速这一部分也可以放到电脑ROS端,这样的话,电脑串口输出的是直接的PWM值而不是之前的期望速度了。


通信层

电脑端和底层电机的控制通信,以及将传感器信息发布给ROS的通信。这一层主要通过串口(ROS已经集成了pyserial 用python操作这个模块进行串口控制)收集左右轮速度值,用航迹推演法将左右轮速度转化为机器人的x轴方向速度和机器人的旋转速度,然后发布/odom主题,好让ROS的相应package收到这个消息,进行机器人位置的估计。同时,这一部分还要关注ROS相应部分发出的机器人控制指令,转化为左右轮的期望速度,再通过串口传给底层。这一层是自己写程序完成。


决策层

就是与导航有关的了,建立地图和定位,然后用move_base根据你发布的传感器信息做出路径规划以及机器人的速度和转向控制。这一部分为ROS相应的package已经完成,我们只需要调用即可。


move_base package介绍:
ROS提供的move_base包让我们能够在已建立好的地图中指定目标位置和方向后,move_base根据机器人的传感器信息控制机器人到达我们想要的目标位置。
move_base的架构:

由图中我们可以看出move_base包需要的输入和输出。

必要的输入
goal: 期望机器人在地图中的目标位置。
tf: 各个坐标系之间的转换关系(/map_frame -> /odom_frame, /odom_frame -> /base_link_frame)。
odom: 根据机器人左右轮的速度推算出的航向信息(即/odom坐标系中机器人x, y坐标,以及航向角yaw)。
LaserScan: 激光传感器的信息。


输出:
cmd_vel: 在cmd_vel这个主题上发布Twist消息,这个消息就是机器人的期望前进速度和转向速度。
知道了move_base的这些外围消息接口以后,move_base的运行还需要一些内部的配置参数,如机器人的最大最小速度,已经路径规划时的最大转弯半径等等。move_base官网wiki

综上,我们已经熟悉了move_base的各种接口, 它需要订阅什么消息,会发布什么消息。因此,让move_base控制实际的机器人最主要的就是要解决实际机器人如何发布这些消息给move_base,以及如何接受move_base发出的消息。

接收move_base发出的消息
Twist 消息转化为机器人左右轮期望速度。

首先,假设move_base能够正常工作了,它将把控制命令Twist发布到cmd_vel这个主题上。我们现在来解决如何利用这个Twist消息来对机器人进行控制。


机器人自身的坐标系系统:
如下图。注意两个坐标系的建立都是右手坐标系,左图中的右手就是机器人本身,x轴就是前进的方向,垂直于两轮之间的轴连线,Y轴就是两个轮之间的轴连线。右图表示机器人的旋转坐标系,大拇指指向Z轴,逆时针方向为正值。

geometry_msgs/Twist的消息类型

其中linear的x就是代表前进方向的速度,单位为m/s。angular的z就代表机器人的绕中心旋转的角速度,单位为弧度/s (rad/s)。
如果linear.y 不为0,说明小车要沿着y轴运动,这会导致两轮的差速,但是对于两轮控制的移动机器人,twist.linear.y = 0 是在move_base的配置文件base_local_planner_params.yaml中有明确指定,所以不需关注linear.y的转换:

max_vel_y = 0.0 #zero for a differential drive robot
min_vel_y = 0.0

机器人期望的前进速度linear.x和转弯速度angular.z都由move_base输出了,那么如何将他们转化成机器人左右轮的期望速度呢?
可以参考:https://blog.csdn.net/heyijia0327/article/details/41823809

发送消息给move_base节点
主要思路:
首先监听串口,一旦收到左右轮的速度信息,马上将左右轮的速度信息转化为x轴方向的前进速度,和绕z轴的旋转速度,进而由其速度转化机器人的坐标以及航向角yaw,这些信息作为Odom topic发布。

Reference:
https://blog.csdn.net/heyijia0327/article/details/41831529