Cartographer中对激光雷达运动畸变的处理方法分析

任务动机:梳理cartographer处理激光雷达运动畸变的原理,并针对特殊数据特性的雷达数据作相应适配,进而提高建图效果。算法

任务描述:查阅cartographer源码中激光雷达运动畸变的处理流程,对比分析实际使用中特定激光雷达数据处理时可能产生的问题。针对于不一样的实际问题做相应修改后,进行对比建图实验验证。后端

1. 激光雷达运动畸变的缘由

        一帧激光点云由多个激光点组成,而这些激光点不是同一时刻产生的,因此在雷达运动过程当中,一帧内的各个激光点基准不一样,就会产生运动畸变。例如:当机器人旋转速度为1.57rad/s,此时雷达若频率为10hz,那么一帧激光点内的首尾两点基准会相差1.57 * 0.1 =0.157rad,即约为9°,在点云帧间匹配时该偏差不能忽视。优化

2. Cartographer中对雷达运动畸变的处理

        Cartographer中对于激光雷达的运动补偿大体为如下流程,具体细节可从代码(pose_extrapolator)中查看。spa

  1. 对于一帧激光数据中的每一点都赋予对应的时间戳;
  2. 假设匀速运动模型,经过前面帧间匹配的位移除以时间间隔求出速度;
  3. 根据每个激光点对应的时间戳进行运动补偿。

3. Cartographer处理运动畸变中可能出现的问题

        Cartographer中处理雷达点云运动畸变时已经默认拿到的雷达数据已经足够准确,使用雷达驱动中发出的time_increament直接对单帧内的没一点赋值时间戳。而现实中激光雷达因为硬件设备问题,会出现两种异常状况:调试

3.1 问题一

        雷达点云打包发出的顺序与真实电机旋转扫描时的数据正好相反,对于cartographer计算过程当中每一个点对应时间戳刚好相反。即处理运动畸变时第一个激光点被假设成了最后一个激光点,结果拔苗助长。code

3.2 问题二

        激光雷达的频率不稳定,例如官方标定为10HZ,可是实际运行中数据间隔可能徘徊与0.08-0.12s之间,只能保证平均间隔为0.1s,但在cartographer中收到的time_increament多数状况下是固定的,导致处理运动畸变时,单帧激光数据中的每一个点没法对应其准确的时间戳,例以下面几个雷达数据(rostopic记录)连续七帧时间戳的对比。blog

  雷达一 雷达二 雷达三
扫描频率 15hz 13hz 28hz
理论帧间间隔(s) 0.066667 0.076923 0.03571
时间戳1(stamp.nsecs) 138875719 217470838 574852851
时间戳2(stamp.nsecs) 205275613 297503257 611164101
时间戳3(stamp.nsecs) 271705863 369562690 646372642
时间戳4(stamp.nsecs) 338044979 449569886 681654101
时间戳5(stamp.nsecs) 404755814 529576631 717150226
时间戳6(stamp.nsecs) 471542889 601488252 752839434
时间戳7(stamp.nsecs) 538550579 681515123 788386892

        能够看出,雷达一数据间隔为0.066四、0.0664三、0.0663四、0.0667一、0.0667九、0.06701,雷达二时间帧间间隔为0.08003s、0.07206s、0.08s、0.07192s、0.08003s,雷达三数据间隔为0.03631s、0.03521s、0.0352s、0.0355s、0.0356九、0.03555s,相对于雷达一和雷达三,雷达二数据波动更为明显。对于这种波动,从数据源上影响cartographer建图效果。索引

4. 问题解决方法与实验对比

4.1 问题一解决方法

        能够从硬件驱动层面上来处理,经过雷达厂家上位机软件或者驱动程序使雷达输出反序。 若是不便于进行上述处理,对于问题1从算法层面修改,能够从rostopic读到的原始数据调整。cartographer中的对于每个激光点point都带有一个时间戳,其计算方式为每一帧从0开始,计算方式为i * msg.time_increment,其中i为一帧激光点中的点索引,msg.time_increment为相邻两激光点间时间增量。详细代码可在cartographer_ros_extended-master/cartographer_ros/cartographer_ros/msg_conversion.cc中对于laserscan数据处理中可查到。从rostopic中读到的msg.time_increment多为固定值,不能适应于频率波动状况。能够修改msg_conversion.cc中的代码以下:rem

angle += msg.angle_increment;
}
/********************** Adjust timestamp for point reverse ********************/
std::vector<float>time_tempx;
std::vector<float>time_tempy;
for (auto& point :point_cloud.points) {
    time_tempx.push_back(point.position.x());
    time_tempy.push_back(point.position.y());
}
int i_time = 0;
for (auto& point :point_cloud.points) {
    point.position.x() =  time_tempx[point_cloud.points.size()-1-i_time];
    point.position.y() =  time_tempy[point_cloud.points.size()-1-i_time];
    i_time++;
}
/********************** end *********************/ 
::cartographer::common::Time timestamp = FromRos(msg.header.stamp);

        对应修改如上代码,可解决数据反序问题。 以下两图为未调整反序的建图效果(后端优化关闭)源码

 

        点云反序调整后建图效果(其他参数同样)

 

 

        第一幅对比图为雷达原地旋转情形,能够看出为调序的激光旋转一圈后地图出现明显重影,调整点云反序后原地旋转一圈激光与地图基本可以对齐。 第二幅地图为使用雷达创建的一个办公室场景(无回环),能够看出在调整点云反序后建图效果有明显提高。

4.2 问题二解决方法

        因为雷达在实际运行中频率不稳定致使建图受到影响,主要缘由是多数雷达驱动发过来的topic中的time_increament是一个固定的值,而真实值却实时变化。解决方法为使用连续两帧之间的时间戳差值求出的实时time_increament代替原topic收到的固定值。修改msg_conversion.cc代码以下。

PointCloudWithIntensities point_cloud;
float angle = msg.angle_min;
/************Adjust timestamp for point frequency *********/
static double timestamp_current = 0 ;
static double timestamp_last = 0 ;
double time_increment_vary;
timestamp_last = timestamp_current;
timestamp_current = msg.header.stamp.toSec();
if(timestamp_last != 0) {
    time_increment_vary = (timestamp_current - timestamp_last)/(6.2831852/msg.angle_increment);
}
else time_increment_vary = msg.time_increment;
/************ end *********/
for (size_t i = 0; i < msg.ranges.size(); ++i) {
    const auto& echoes = msg.ranges[i];

        使用求解出的time_increment_vary代替源码中的msg.time_increment 以下

const cartographer::sensor::TimedRangefinderPoint point {
    rotation * (first_echo * Eigen::Vector3f::UnitX()), i * time_increment_vary
};//i * msg.time_increment
point_cloud.points.push_back(point);
if (msg.intensities.size() > 0)

        以下图为使用某雷达未调整实时频率建图效果

        调整实时频率建图效果

        能够看出长方形边有细微差异,调整实时频率后的建图边缘较为光滑,无明显重影。对于不一样的雷达建图可能表现不一样,某些雷达自身输出的频率较为稳定,波动不明显,则无需实时校准帧间时间间隔。对于帧间频率波动较大的激光雷达,建图效果会有提高。

5. 总结

        因为雷达自身硬件与数据输出问题致使建图受到影响,尤为是时间戳间隔的问题,每每会疏于考虑。博主也是在调试时偶然发现,这里进行梳理与总结,抛砖引玉,针对于问题二也须要更多款型的雷达进行试验,文中若有不妥之处,还望指正。若是以前没注意到这一点,调参很久也没有获得理想的地图,那么,快去查看本身使用的雷达的频率吧!

相关文章
相关标签/搜索