摘要
通过前面的基础学习, 本章进入最为激动的机器人自主导航的学习. 在前面的学习铺垫后, 终于迎来了最大乐趣的时刻, 就是赋予我们的 miiboo 机器人能自由行走的生命. 本章将围绕机器人 SLAM 建图, 导航避障, 巡航, 监控等内容展开. 本章内容:
1. 在机器人上使用传感器
2.google-cartographer 机器人 SLAM 建图
3.ros-navigation 机器人自主避障导航
4. 多目标点导航及任务调度
5. 机器人巡航与现场监控
1. 在机器人上使用传感器
SLAM 建图需要用到底盘, 激光雷达和 IMU, 所以这里详细介绍如何在机器人上使用这些传感器. 要使用这些传感器也很简单, 就是在机器人上开启相应传感器的 ROS 驱动节点, 在设置合适的可配参数就行了.
需要注意的是, 底盘, 激光雷达, IMU 这三个传感器都使用串口与树莓派通信, 为了防止每次开机这三个设备的串口号发生变动, 需要将串口号进行绑定与重映射, 操作方法在前面已经介绍过了, 如果还没有绑定直接前往前面相关内容参考.
这里将建立一个叫 catkin_ws 的 ROS 工作空间, 专门用于存放机器人传感器相关的 ROS 驱动功能包. 关于创建 ROS 工作空间的操作, 请参考前面相应部分内容, 这里就不做讲解.
1.1. 使用底盘
在机器人上只需要使用 miiboo 这个驱动包就可以驱动底盘了. 将 miiboo 这个驱动包拷贝到~/catkin_ws/src / 中, 编译后就可以使用了. miiboo 驱动包文件结构, 如图 1.miiboo 驱动包中含有两个 ROS 功能包 miiboo_bringup 和 miiboo_description, 驱动 miiboo 底盘, 底盘 PID 整定, 里程计标定这些功能包含在 miiboo_bringup 中, miiboo 底盘 urdf 模型包含在 miiboo_description 中.
(图 1)miiboo 驱动包文件结构
底盘控制可配参数:
关于底盘控制可配参数都放在 miiboo_bringup/launch/minimal.launch 中, 如图 2.
参数 com_port 是底盘控制的串口号, 由于前面已经做了绑定, 所以直接填入绑定好的名称 / dev/miiboo 就行了;
参数 speed_ratio 是里程计走直线标定值, 这个值通过标定得到.
参数 wheel_distance 是里程计转角标定值, 这个值通过标定得到.
其余参数一般不需要修改, 如有需要可以结合阅读源码来了解参数含有和做相应修改.
(图 2)底盘控制可配参数
驱动 miiboo 底盘:
其实很简单, 一条命令启动 miiboo 底盘控制.
roslaunch miiboo_bringup minimal.launch
底盘 PID 整定:
我们的 miiboo 机器人底盘的 stm32 控制板中已经内置了整定好的 PID 参数, 如果选用我们提供的控制板和电机, 一般情况下是不需要整定 PID 的.
对于想体验一下 PID 参数整定过程或将我们的 miiboo 机器人底盘的 stm32 控制板应用到其他地方的朋友, 这里给出了整定 PID 的整个操作过程和思路, 方便大家学习和更深层次的研究. 这里主要讲解 PID 整定的操作, 关于原理性的东西可以参考前面相关内容进行了解.
由于底盘 PID 整定是非必须的功能, 所以没有对底盘 PID 整定的串口 (DEBUG-uart1) 做绑定, 需要先手动插入该串口到树莓派 3, 然后手动查看该串口的设备号, 并修改该设备号的可读写权限. 然后将该设备号填入 miiboo_bringup/launch/pid_set.launch 中的 com_port 参数中. 然后, 需要启动底盘控制节点, 底盘调试节点, 键盘控制节点. 键盘控制节点 teleop_twist_keyboard 需要通过 apt-get 命令来安装, rqt_plot 是 ROS 提供的绘图工具.
- # 打开终端, 启动底盘控制节点
- roslaunch miiboo_bringup minimal.launch
- # 再打开一个终端, 启动底盘调试节点, 按提示输入命令
- roslaunch miiboo_bringup pid_set.launch
- # 安装键盘控制工具
- sudo apt-get install ros-kinetic-teleop-twist-keyboard
- # 再打开一个终端, 启动键盘控制节点,
- source ~/.bashrc
rosrun teleop_twist_keyboard teleop_twist_keyboard.py
- # 再打开一个终端, 用 rqt_plot 对底盘速度曲线进行绘制, 指定曲线数据来源的 topic
- rosrun rqt_plot rqt_plot
ROS 提供的绘图工具 rqt_plot 用法很简单, 在 rqt_plot 界面中, 在 Topic 栏输入曲线数据来源, 我们这里为左, 右轮速度, 然后点击旁边的 "+" 将曲线加入绘制界面, 人如图 3.
(图 3)用 rqt_plot 显示速度曲线
然后, 通过在启动 teleop_twist_keyboard 节点的终端通过 I/</J/L 四个按键来控制底盘前进 / 后退 / 左转 / 右转控制, 并观察速度曲线的变化, 根据 PID 整定规则对 PID 参数进行整定, 在启动 pid_set.launch 的终端下按相应提示输入 PID 参数实现对整定参数的编辑. 直到得到一个比较好的速度曲线, 就可以结束整定过程了. 实时速度曲线显示, 如图 4.
(图 4)实时速度曲线显示
里程计标定:
机器人底盘运行的精度是衡量底盘的重要指标. 底盘精度受里程计的走直线误差和转角误差影响. 因此, 需要对里程计的走直线和转角进行标定, 尽量减小误差. miiboo 机器人底盘的 ROS 驱动中已经写好了相应的标定程序, 跟里程计标定有关的文件主要有:
.../miiboo_bringup/launch/check_linear.launch 为里程计走直线标定启动文件
.../miiboo_bringup/launch/check_angular.launch 为里程计转角标定启动文件
.../miiboo_bringup/launch/minimal.launch 为设置标定参数及底盘控制启动文件
下面是标定步骤过程.
由于标定过程在前面已经讲解过了, 请直接前往相应内容参考.
miiboo 底盘 urdf 模型:
urdf 模型描述了机器人底盘的形状, 传感器之间的安装关系, 各个传感器在 tf tree 中的关系. 其实, miiboo 底盘 urdf 模型的主要作用是提供各个传感器在 tf tree 中的关系, 这些关系将在 SLAM 和导航算法中被使用.
(图 5)miiboo 机器人底盘中各个传感器 tf 关系
图 5 是 miiboo 机器人底盘中各个传感器 tf 关系, base_footprint 是底盘的运动中心, base_laser_link 是激光雷达的中心, imu_link 为 IMU 模块的中心. 以 base_footprint 为原点, 建立机器人底盘的坐标系, 坐标系为标准右手系, 即底盘正前方为 x 轴, 正左方为 y 轴, 正上方为 z 轴, 以 x 轴起始逆时针方向为 theta 轴. 以 base_footprint 为父坐标系, 建立 base_footprint->base_laser_link 关系, 建立 base_footprint->imu_link 关系, 就实现了各个传感器 tf 关系的构建, 构建的具体实现在 miiboo_description/urdf/miiboo.urdf 中完成. 如图 6, 为 miiboo.urdf 的具体内容.
(图 6)miiboo 底盘 urdf 模型描述文件
要使用这个 urdf 模型就很简单了, 直接一句命令启动.
roslaunch miiboo_description miiboo_description.launch
1.2. 使用激光雷达
在机器人上只需要使用 ydlidar 这个驱动包就可以驱动 ydlidar-x4 雷达了. 将 ydlidar 这个驱动包拷贝到~/catkin_ws/src / 中, 编译后就可以使用了. ydlidar 驱动包文件结构, 如图 7.ydlidar 驱动包中的其他文件我们不需要关心, 这些都是由雷达厂商提供的标准驱动, 只需要设置我们自己建立的 ydlidar/launch/my_x4.launch 文件, 这个用于启动雷达.
(图 7)ydlidar 驱动包文件结构
激光雷达数据可配参数:
关于激光雷达数据可配参数都放在 ydlidar/launch/my_x4.launch 中, 如图 8.
参数 port 是激光雷达的串口号, 由于前面已经做了绑定, 所以直接填入绑定好的名称 / dev/lidar 就行了;
参数 range_min 和 range_max 是设置激光雷达数据的有效值区间.
其余参数一般不需要修改, 如有需要可以结合阅读源码来了解参数含有和做相应修改.
(图 8)激光雷达数据可配参数
驱动 ydlidar-x4 激光雷达:
其实很简单, 一条命令启动 ydlidar-x4 激光雷达.
roslaunch ydlidar my_x4.launch
激光雷达数据格式:
激光雷达采用右手坐标系, 雷达正前方为 x 轴, 正左方为 y 轴, 正上方为 z 轴, 以 x 轴起始逆时针方向为 theta 轴. 激光雷达的扫描数据以极坐标的形式表示, 雷达正前方是极坐标 0 度方向, 雷达正左方是极坐标 90 度方向, 红色点为扫描到的数据点, 如图 9 所示.
(图 9)激光雷达数据格式
激光雷达的数据在 ROS 中是以 sensor_msgs/LaserScan 消息类型进行表示, 如图 10,angle_increment 表示激光数据点的极坐标递增角度, ranges 数组存放实际的极坐标点距离值.
(图 10)激光雷达数据 sensor_msgs/LaserScan 消息类型
1.3. 使用 IMU
在机器人上只需要使用 miiboo_imu 这个驱动包就可以驱动 mpu9250 模块了. 将 miiboo_imu 这个驱动包拷贝到~/catkin_ws/src / 中, 编译后就可以使用了. miiboo_imu 驱动包文件结构, 如图 11.ydlidar 驱动包中的其他文件我们不需要关心, 只需要设置 ydlidar/launch/my_x4.launch 文件, 这个用于启动 IMU.
(图 11)miiboo_imu 驱动包文件结构
IMU 数据可配参数:
关于 IMU 数据可配参数都放在 miiboo_imu/launch/imu.launch 中, 如图 12.
参数 come_port 是 IMU 的串口号, 由于前面已经做了绑定, 所以直接填入绑定好的名称 / dev/imu 就行了;
其余参数一般不需要修改, 如有需要可以结合阅读源码来了解参数含有和做相应修改.
(图 12)IMU 数据可配参数
驱动 IMU 模块:
其实很简单, 一条命令启动 IMU 模块.
roslaunch miiboo_imu imu.launch
IMU 数据格式:
IMU 模块采用右手坐标系, IMU 模块正前方为 x 轴, 正左方为 y 轴, 正上方为 z 轴. IMU 模块提供 3 轴加速度, 3 轴角速度, 3 轴磁力计, 经数据融合后用欧拉角表示的姿态.
IMU 数据在 ROS 中是以 sensor_msgs/Imu 消息类型进行表示, 如图 13.
(图 13)IMU 数据 sensor_msgs/Imu 消息类型
1.4. 使用摄像头
miiboo 机器人上使用的是 USB 摄像头, 用 ROS 驱动 USB 摄像头可以采用以下 3 中方法.
方法 1:
使用 usb_cam 这个 ROS 包直接驱动
方法 2:
使用 gscam 这个 ROS 包直接驱动
方法 3:
自制 OpenCV,cv_bridge,image_transport 驱动 ROS 包
为了方便起见, 我采用的是方法 1, 直接安装 usb_cam 这个 ROS 包直接驱动.
usb_cam 摄像头驱动安装:
将 usb_cam 下载到~/catkin_ws/src / 中, 直接编译就行了.
- cd ~/catkin_ws/src/
- Git clone https://github.com/ros-drivers/usb_cam.git
- rosdep install usb_cam
- cd ~/catkin_ws/
- catkin_make
摄像头数据可配参数:
关于摄像头数据可配参数都放在 usb_cam/launch/usb_cam.launch 中, 如图 14.
参数 video_device 是摄像头的设备号, 由于直插了一个 USB 摄像头, 所以直接填入名称 / dev/video0 就行了;
其余参数一般不需要修改, 如有需要可以结合阅读源码来了解参数含有和做相应修改.
(图 14)摄像头数据可配参数
驱动 USB 摄像头:
其实很简单, 一条命令启动 USB 摄像头.
roslaunch usb_cam usb_cam.launch
摄像头远程显示:
摄像头数据远程显示的方法有两种, 方法一是在 PC 端 rviz 中订阅摄像头发布的图像 topic, 方法二是用 Android 手机上 miiboo 机器人 App 直接显示.
先说方法一, 在 PC 端打开 rviz, 在 rviz 中添加需要显示的 Topic, 这样就可以看到图像了. 如图 15 和 16.
(图 15)在 rviz 中添加需要显示的图像 Topic
(图 16)在 rviz 中显示图像 Topic
方法二, 就很简单了, 只要 Android 手机上 miiboo 机器人 App 连接到机器人端成功后, 就能自动显示图像了. 如图 17.
(图 17)在 Android 手机的 miiboo 机器人 App 中显示图像 Topic
1.5. 局域网内广播机器人自己的 IP
这个很简单, 由 broadcast_ip 这个功能包实现, 我已经写好放入~/catkin_ws/src / 并编译了. 只需要一句命令启动就行了.
roslaunch broadcast_ip broadcast_udp.launch
后记
来源: https://www.cnblogs.com/hiram-zhang/p/10412509.html