VINS-Mono LoopClosure
Last updated on November 26, 2023 pm
[TOC]
Overview
- 忽略掉了 shift to base frame:
w_t_vio,w_r_vio
loop closure 初始化
- PoseGraph 设置
- 设置参数
- 启动线程
PoseGraph::optimize4DoF或PoseGraph::optimize6DoF - 加载 词典文件
- 启动线程
SystemROS::loop_closing
线程 loop_closing
- 获取同步的图像、位姿、2D与3D点信息
- img
- pose
point_id,point_3d,point_2d_uv,point_2d_normal
- 构建 KeyFrame
- KeyFrame 成员变量初始化
computeWindowBRIEFPoint: 根据point_2d_uv生成window_keypoints, 计算其对应的描述子window_brief_descriptorscomputeBRIEFPoint: 提取FAST特征点,一起和point_2d_uv放到keypoints,计算其描述子brief_descriptors和keypoints_norm
- addKeyFrame
- cur_kf->index = global_index++;
- loop_index = detectLoop(cur_kf, cur_kf->index)
db.query(keyframe->brief_descriptors, ret, 3, max_frame_id_allowed)db.add(keyframe->brief_descriptors);
- KeyFrame* old_kf = getKeyFrame(loop_index)
- cur_kf->findConnection(old_kf)
point_2d_uv-->point_2d_normold_kf->keypoints-->old_kf->keypoints_norm- searchByBRIEFDes:
window_brief_descriptors<-->old_kf->brief_descriptors-->matched_2d_old_norm - PnP RANSAC (利用PnP得到回环帧位姿):
matched_3d<-->matched_2d_old_norm-->PnP_T_old, PnP_R_old - get loop_info
(计算PnP得到的回环帧的位姿与当前帧位姿的相对变换):
relative_t,relative_q,relative_yaw
- earliest_loop_index = loop_index;
- optimize_buf:
optimize_buf.push(cur_kf->index); - updatePose
1
2
3
4cur_kf->getVioPose(P, R);
P = r_drift * P + t_drift;
R = r_drift * R;
cur_kf->updatePose(P, R); - keyframelist:
keyframelist.push_back(cur_kf);
线程 optimize4DoF
get
first_looped_indexandcur_index1
2
3
4
5while (!optimize_buf.empty()) {
cur_index = optimize_buf.front();
first_looped_index = earliest_loop_index;
optimize_buf.pop();
}ceres solver 优化
- 遍历
keyframelist, 忽略first_looped_index之前的 keyframe,直到cur_index - getVioPose -->
t_array,q_array,euler_array - problem.AddParameterBlock:
euler_array,t_array - problem.SetParameterBlockConstant:
first_looped_index - problem.AddResidualBlock
- 相邻帧约束关系
- 回环边和顶点
- ceres::Solve(options, &problem, &summary);
- 遍历
updatePose
- 遍历
keyframelist, 忽略first_looped_index之前的 keyframe,直到cur_index - updatePose:
euler_array,t_array
- 遍历
get drift:
yaw_drift,r_drift,t_drift\[ T_{drift} = T_{opt} * T_{vio}^{-1} \]updatePose
- 遍历
cur_index之后的keyframelist - updatePose
1
2
3
4(it)->getVioPose(P, R);
P = r_drift * P + t_drift;
R = r_drift * R;
(it)->updatePose(P, R);
- 遍历
updatePath
- 遍历
keyframelist,获取位姿getPose给Path
- 遍历
线程 optimize6DoF
FAST_RELOCALIZATION
- cur_kf->findConnection(old_kf)
- publish: 回环帧的
matched_2d_old_norm,matched_id,T_wi
- publish: 回环帧的
- relocalization_callback
- subscribe: get
relo_buf
- subscribe: get
- process loop
- get latest
relo_msgfromrelo_buf estimator.setReloFrame(frame_stamp, frame_index, match_points, relo_t, relo_r);relo_frame_indexmatch_pointsprev_relo_tprev_relo_rrelo_Pose<--para_Poserelo_frame_local_index<-- irelocalization_info = 1
- get latest
- optimization
problem.AddParameterBlock:relo_Poseproblem.AddResidualBlock
- double2vector(?????)
drift_correct_r,drift_correct_trelo_relative_q,relo_relative_t,relo_relative_yaw
- publish
- pub_relo_path
drift_correct_r,drift_correct_t+estimator.Ps[WINDOW_SIZE]-->correct_t,correct_q
- pub_relo_relative_pose (
relo_relative_pose)relo_relative_q,relo_relative_t,relo_relative_yaw
- pub_relo_path
- relo_relative_pose_callback
- loop_info <--
relo_relative_pose posegraph.updateKeyFrameLoop(index, loop_info);- get drift:
yaw_drift,r_drift,t_drift
- get drift:
- loop_info <--
VINS-Mono LoopClosure
https://cgabc.xyz/posts/d02c141a/