image

基于ROS无人小车搭建


writerlIcht                      emaillIcht.gzl@gmail.com                 date:  2019.12.1

 

 

15

        一、用仿真的思想解决没有实际里程计的问题以及最重要的基础:tf树的建立。编写假odom欺骗上层导航包,还能达到让小车动的目的,但是误差十分大,但是能在硬件情况不理想的情况下配置上层导航包。

假里程计代码:

 

launch里面发布小车的静态tf:

 

测试验证:odom tf树的成功与否,用teleop发出odom里程计的进口(速度),看tf树时候成功实时变换以及在rviz里面的效果。

tf树成功建立建立与相关节点:

image

查询odom主题数据:

 

 

RVIZ里面的运动效果:

image

image

 

 

 

 

 

 

 

 

        二、gmapping 的实现,以及现场跑图的测试。要实现gmapping进行SLAM需要的传感器信息(topic)有:/laser、/odom。需要的tf转换有:laser—>base_link、base_link—>odom。启动rp雷达后便可获得雷达laser信息,这样就满足了gmapping的全部要求。

gmapping参数设置:

 

测试方式:teleop发送伪odom进口数据,建立简单的地图,重点是里程计和雷达数据的成功取用,利用gmapping成功建立地图。

tf树的建立,map坐标成功发布:

image

teleop控制小车建立地图:

image

 

 

 

        三、在gmapping可以成功运作后,对move_base及其导航框架的搭建,对move_base里出现的问题:goal off global map,DWA cann't get path等报错的处理

move_base node原理图:

image

手动整理版:

image

        move_base的搭建是导航的关键,这个框架牵扯到很多的功能包,可以变得非常的复杂。简单来说move_base功能包的作用就是接受一个目标姿态,根据这个姿态给小车点发出速度指令,直到到达目标点。整个导航以及避障的过程都在这个框架中实现。

直接需要提供的信息:

odometry data(里程计信息):

        由驱动方法的不同里程计的计算方法也不同,轮、履带、甚至船,都有其不同的计算方法,但是其计算原理都相同,目的是获得小车的里程信息。除了以上机遇电机编码器等里程计计算方法,还有更加复杂更加精确的视觉里程计计算方法,这是计算机视觉通过连续帧的图像信息来得到里程信息的。

TF(坐标变换):

        坐标转换关系的建立是分析系统运动学的基础,导航系统的每个传感器以及小车与世界地图左边远点的关系的确定统统可以通过左边转换来实现,因此这是必要的信息,是定位信息以及发送速度指令的基础。这里tf树是由ros操作系统实时维护的,这种tf维护机制是通过广播与监听实现的:两节点发生了位姿关系发生了变化就即时广播出去,ros系统会及时计算并更新所有关联坐标之间的关系,如果要得到某两个坐标之间的位姿信息,就创建监听者实时监听这两个坐标之间的位姿信息。

sensor massege(传感器信息):

        在建立地图以及定位的时候,则会依赖传感器的信息,如雷达,imu,gps,camera等。雷达是建立地图必要的传感器信息,也能同时提供定位信息,例如Hector这种算法就只需雷达便可实现SLAM。然而没有里程计的参考,其建图的误差也是非常大的,单靠里程计也不是很理想,所以需要传感器的定位与里程计的定位相配合,减小误差实现更精确的定位与避障,最低的要求也得需要一个雷达。

 

需要间接提供的信息(功能包提供):

map(地图信息):

        这里的地图至世界坐标系和地图信息,世界地图充当基准坐标系的作用,地图信息则用来构建地图,为导航提供定位与障碍以及路径信息。导航时能使用已经建立好的静态地图,也能实时建立地图进行导航。可通过gmapping或map_server实现。

 

localization(定位信息):

        有了地图,小车必须知道自己在什么位置是什么姿态才能进行导航。这里的定位由传感器以及里程计计算得出,主要用的是amcl算法进行定位。可通过gmapping、hector、cartographer等SLAM算法包实现。

 

测试方案:tf树以及话题的连接是否合理,rviz里有没有成功发布出相应的全局/局部map以及path主题。

RVIZ:

image

 

 

 

 

        四、对cost_common_params、global_planner、local_planner、base_local_planner……各项参数的配置,各种配置方案实际对小车的计算效果。

move_base内部结构:

image

整理版:

image

        前面介绍了要启动move_base所需要的信息与功能包,这里就是具体对move_base功能包里面的参数做配置了。简单来讲在move_base中对目标的导航路线的规划分为了全局规划和局部规划。这两个不同的规划算法相组合,利用所需的信息实现导航和避障的功能。

        参照上面的流程图,global_costmap是基于已有的地图(静态地图或者实时地图),由map这个topic得到。然后global planner在此地图信息的基础上计算出小车到目标点的路径,如果是有实时地图的到,那么局部规划器规划出来的路径随着扫描出地图的不断扩大而改变更新。局部地图则不一样,它的地图得使用实时的地图,局部规划器也得参照全局规划器的路径和局部地图进行局部路径的规划,然后下发相应的速度指令,使底盘控制电机运动。对这两个规划器的参数配置则决定了导航效果的好坏。

        在move_base节点运行前需要四个配置文件,这些文件定义了一系列相关参数,包括越过障碍物的代价、机器人的半径、路径规划时需要考虑未来多长的路、我们想让机器人以多块的速度移动等等。这四个配置文件分别是:

base_local_planner_params.yaml

costmap_common_params.yaml

global_costmap_params.yaml

local_costmap_params.yaml

base_local_planner_params.yaml:

 

costmap_common_params.yaml:

 

global_costmap_params.yaml:

 

local_costmap_params.yaml:

 

落实配置

base_local_planner_params.yaml:

 

costmap_common_params.yaml:

 

global_costmap_params.yaml:

 

local_costmap_params.yaml:

 

        测试方案:move_base没有发出实时变化的速度指令(/cmd_vel),全局/局部规划的膨胀地图以及相应的路径线条是否能够显示,小车坐标在规划处路径之后能够正常移动,同时局部规划路径出现。发送简单的直线目标点能够到达,move_base节点显示goal reached!,简单避障效果的测试。

路径规划:

image

goal reached:

image