前言
定位的方法有很多,包括gps、imu等。但是gps易受攻击,imu具有累积误差,这些缺点都是不可避免的。
因此就诞生了智能定位导航。包括LOAM、ORB-SLAM等。
所有LOAM存在的本质之一就是为了根据单纯的点云输入得到将点云转化到全局坐标系的/tf消息(定位)。
LEGO-LAOM
下图反映了lego-loam的tf树:
其中camera_init->map和base_link->camera都是在launch文件中直接发布的静态tf消息。所以其中最重要的部分是camera->camera_init,也就是从小车的当前时刻位置到最初始位置的坐标转换。
然而我们录制的velodyne_points消息的坐标系一般都是velodyne,如果只使用上面这个tf树是得不到全局位置的。因此我们需要加入一个velodyne->base_link的tf消息。
这个也可以在launch文件中直接写入:
<node pkg="tf" type="static_transform_publisher" name="velodyne_to_base_link" args="0 0 0 0 0 0 /base_link /velodyne 10" />
这样我们便可以通过LEGO-LOAM得到velodyne->map的转换。然后便可以在全局坐标系map下查看点云。
现在的tf树是这个样子:
在运行LEGO-LOAM的同时播放包含velodyne_points消息的的rosbag包(注意:一定要使用–clock),然后再开一个终端重新录制velodyne_points消息和tf消息。这样我们便可以使用点云消息和/tf消息同步接收转化到全局坐标系来得到全局坐标系下的点云了。(或者直接可以使用录制的包在rviz中map坐标系下查看)
A-LOAM
ALOAM的tf树还是和lego-loam有很大区别的:
很简单粗暴的,得到现在坐标系到最开始坐标系的转化。
但是ALOAM存在很严重的问题:点云时间戳和tf时间戳不一致,因此需要进行修改。
修改aloam_velodyne_VLP_16.launch文件,除了增加同样的静态tf发布之外,还要增加一个使用仿真时间的设定。
即,加入这样两句:
<param name="use_sim_time" value="true"/>
<node pkg="tf" type="static_transform_publisher" name="velodyne_to_aft_mapped" args="0 0 0 0 0 0 /aft_mapped /velodyne 10" />
这样变完成了修改,此时的tf树为
在运行A-LOAM的同时播放包含velodyne_points消息的的rosbag包(注意:一定要使用–clock),在自动打开的rviz中可以查看/scan/raw_data,这就是全局坐标系下的点云。
问题
我使用在gazebo中录制的包来这样运行,但是存在问题:
在转弯处,总是有几帧点云的tf消息不准确,导致无法使用。
我怀疑的原因有两个:
- gazebo中小车的转弯并不丝滑
- loam算法发布的tf其实并不准确,之后它会使用点云到地图的配准进一步优化
如果有哪位前辈大佬知道如何解决,请一定告诉我,万分感谢!!