Vins-Mono 论文 && Coding 一 1. 系统流程

一、System Pipeline

二、视觉数据处理流程

1. API

// image: feature_id<-->视觉特征(有可能多摄像头)
// 视觉特征:  camera_id <--> x, y, z, p_u, p_v, velocity_x, velocity_y
// header: img_msg->header 
void processImage(const map<int, vector<pair<int, Eigen::Matrix<double, 7, 1>>>> &image, const std_msgs::Header &header)

2. 流程图

 

3. 流程详解

1. 特征点跟踪

更新 FeaturesPerId

class FeaturePerFrame
{
  public:
    FeaturePerFrame(const Eigen::Matrix<double, 7, 1> &_point, double td) {......}
    double cur_td;  // imu, image timestamp offset
    Vector3d point;  // camera 下三维坐标 (深度未知, z=1)
    Vector2d uv;  // 图像观测
    Vector2d velocity;  // 速度
    double z;
    bool is_used;
    double parallax;
    MatrixXd A;
    VectorXd b;
    double dep_gradient;
};
class FeaturePerId
{
  public:
    const int feature_id;
    int start_frame;  // 第一次被观测的帧在窗口中的索引
    vector<FeaturePerFrame> feature_per_frame;  // 所有的观测
    int used_num;
    bool is_outlier;
    bool is_margin;
    double estimated_depth;
    int solve_flag; // 0 haven't solve yet; 1 solve succ; 2 solve fail;
    Vector3d gt_p;
    int endFrame();
};
// frame_count: 当前帧在滑窗中的索引
// image: feature_id<-->视觉特征(有可能多摄像头)
// 视觉特征:  camera_id <--> x, y, z(=1), p_u, p_v, velocity_x, velocity_y
// td: imu, img timestamp offset
// return: whether the seconde last frame is keyframe
bool FeatureManager::addFeatureCheckParallax(int frame_count, const map<int, vector<pair<int, Eigen::Matrix<double, 7, 1>>>> &image, double td)
{
    double parallax_sum = 0;
    int parallax_num = 0;
    last_track_num = 0;
    for (auto &id_pts : image) {
        // 构造 feature per-frame
        FeaturePerFrame f_per_fra(id_pts.second[0].second, td);
        // 查找该 feature 是否之前被观测过
        if (it == feature.end())   {  // 第一次被观测
            feature.push_back(FeaturePerId(feature_id, frame_count));
            feature.back().feature_per_frame.push_back(f_per_fra);   
        } else if (it->feature_id == feature_id)  {   // 之前被观测过
            it->feature_per_frame.push_back(f_per_fra);
            last_track_num++;
        }
    }

    //check the second last frame is keyframe or not
    //parallax betwwen seconde last frame and third last frame
    // 通过对比次新帧和次次新帧的视差量
    if (frame_count < 2 || last_track_num < 20)  // 不计算 parallax
        return true;
    for (auto &it_per_id : feature) {
        // 选择从 third last frame 到 second last frame 均被观测到的 feature
        if (it_per_id.start_frame <= frame_count - 2 &&
            it_per_id.start_frame + int(it_per_id.feature_per_frame.size()) - 1 >= frame_count - 1) {
            parallax_sum += compensatedParallax2(it_per_id, frame_count);
            parallax_num++;
        }
    }
    if (parallax_num == 0) {
        return true;
    }
    else  {
        return parallax_sum / parallax_num >= MIN_PARALLAX;  // parallax 超过阈值, seconde last frame 视作关键帧
    }
}

2. 更新边缘化策略

判断次新帧是否是关键帧

if (f_manager.addFeatureCheckParallax(frame_count, image, td))
    marginalization_flag = MARGIN_OLD;
else
    marginalization_flag = MARGIN_SECOND_NEW;

(1). 当次新帧为关键帧时,marginalization_flag 是 MARGIN_OLD,将 marg 掉最老帧

(2). 当次新帧不是关键帧时,marginalization_flag 是 MARGIN_SECOND_NEW, 我们将直接扔掉次新帧及它的视觉约束,而不对次新帧进行 marg

三、System Pipeline 详解

1. Measurement Preprocess

(1). 功能

视觉特征提取和跟踪

imu 数据预积分

(2). 详解

Vins-Mono 论文 && Coding 一 2. feature_tracker

Vins-Mono 论文 && Coding 一 3. visual-imu 数据同步

Vins-Mono 论文 && Coding 一 4(1). imu 预积分

Vins-Mono 论文 && Coding 一 4(2). imu factor

2. Initialization

(1). 功能

纯视觉 SFM

视觉惯导数据对齐

外参标定

(2). 详解

Vins-Mono 论文 && Coding 一 5(1). 初始化: SFM 初始化

Vins-Mono 论文 && Coding 一 5(2). 初始化: visual-inertial 对齐

3. visual-inertial odometry

(1). 功能

滑动窗口优化系统状态变量

(2). 详解

Vins-Mono 论文 && Coding 一 6(1). VIO: solveOdometry

Vins-Mono 论文 && Coding 一 6(1). VIO: slideWindow

4. loop closure && pose-graph

(1). 功能

回环检测,位姿图优化

(2). 详解

Vins-Mono 论文 && Coding 一 7(1). pose_graph: pose_graph 流程

Vins-Mono 论文 && Coding 一 7(2). pose_graph: 回环检测 && 重定位

Vins-Mono 论文 && Coding 一 7(3). pose_graph: 4DOF pose_graph

四、运行示例

1. launch 文件

euroc.launch 文件如下

<launch>
    ......
    <node name="feature_tracker" pkg="feature_tracker" type="feature_tracker" output="log">
        ......
    </node>

    <node name="vins_estimator" pkg="vins_estimator" type="vins_estimator" output="screen">
       ......
    </node>

    <node name="pose_graph" pkg="pose_graph" type="pose_graph" output="screen">
        ......
    </node>
</launch>

可以看到 vins-mono 运行了三个节点:feature_tracker, vins_estimator, pose_graph

feature_tracker 负责相邻帧角点跟踪

vins_estimator 是 vins 算法的核心,实现 visual-inertial odometry

pose_graph 是 负责回环检测以及 pose_graph 优化

2. topic 相互订阅关系图

五、参考

1. 博客

VINS-Mono论文学习与代码解读——目录与参考

2. 论文

Tong, Qin, Peiliang, et al. VINS-Mono: A Robust and Versatile Monocular Visual-Inertial State Estimator[J]. IEEE Transactions on Robotics, 2018.

J Solà. Quaternion kinematics for the error-state Kalman filter[J].  2017.

3. github

https://github.com/HKUST-Aerial-Robotics/VINS-Mono

GitHub - StevenCui/VIO-Doc: 主流VIO论文推导及代码解析

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值