Cartographer 基于ceres的扫描匹配

时间:2024-02-23 14:31:10

调用路径

global_trajectory_builder.AddSensorData
-->local_trajectory_builder.addRangeData
-->local_trajectory_builder.AddAccumulatedRangeData
-->local_trajectory_builder.ScanMatch-->ceres_scan_matcher

输入参数

 * @param[in] target_translation 预测出来的先验位置, 只有xy
 * @param[in] initial_pose_estimate (校正后的)先验位姿, 有xy与theta
 * @param[in] point_cloud 用于匹配的点云 点云的原点位于local坐标系原点
 * @param[in] grid 用于匹配的栅格地图
 * @param[out] pose_estimate 优化之后的位姿

如果不调用correlative_scan_matching,target_translation和initial_pose_estimate是一样的

correlative_scan_matching 目的是对先验位姿进行校准,先验位姿来自于位姿推测器。

问题:如果不使用correlative_scan_matching,那么ceres里面的残差不就为0了? 那还怎么优化,其实相当于只使用了地图的残差???

使用的残差

地图部分的残差

    地图分为概率地图和TSDF地图  

    理想状态下,点云的每个点都是打在地图的障碍物上,这样每个点的地图概率都很小。通过添加点云在概率地图上的概率值为残差项,

    来优化地图。

平移的残差

    位姿推测器推测出来的值当成是目标值(这里是有一定问题的,carto认为姿推测器推测出的位姿是准确的)

    当前位置,是通过暴力匹配校准得到的

    残差的维度是2,位姿的维度是3,只进行了xy方向的残差计算

    (当前位置-目标值)* 残差因子


    bool operator()(const T* const pose, T* residual) const {
        residual[0] = scaling_factor_ * (pose[0] - x_);
        residual[1] = scaling_factor_ * (pose[1] - y_);
        return true;
    }

旋转的残差

    暴力匹配校准得到的角度为目标值,没有使用暴力匹配,则是位姿推测器的

    当前值也是角度匹配得到的 那么残差不是始终为0???

    这里不是这样理解的,优化的过程是一个多个残差,迭代不断优化的过程,虽然说初值和目标值相同,但是在迭代的过程中,

    也有可能会由于综合优化的影响,导致慢慢偏移目标值,所以初值和目标值相同是没有问题的。

    所以前面的不使用暴力匹配也是一样的情况。

    (当前角度-目标值)* 残差因子

    bool operator()(const T* const pose, T* residual) const {
        residual[0] = scaling_factor_ * (pose[2] - angle_);
        return true;

    }

优化的目的使残差最小,也就是使当前值向目标值逼近

优化完成后得到了一个优化后的位姿