调用路径
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;
}
优化的目的使残差最小,也就是使当前值向目标值逼近
优化完成后得到了一个优化后的位姿