VINS-Mono 代码详细解读——基础储备:在线Cam到IMU的外参标定 InitialEXRotation类

本文深入解析VINS-Mono中InitialEXRotation类的相机到IMU外参在线标定过程。通过CalibrationExRotation函数,利用多帧旋转矩阵约束,结合SVD分解与旋转约束估计,实现外参的迭代优化。成功条件为至少迭代WINDOW_SIZE次且旋转矩阵奇异值大于0.25。

本讲还是为了estimator类中最主要的函数processImage()做知识储备。

前面两讲知识储备主要讲了IMU预积分相关的integrationBase类以及图像特征点管理器feature_manager.cpp,本节将对processImage()的相机到IMU的外参矩阵的代码讲解。

当外参完全不知道的时候,VINS也可以在线对其进行估计(rotation),先在processImage内进行初步估计,然后在后续优化时,会在optimize函数中再次优化。

目录

InitialEXRotation类

1、CalibrationExRotation()函数

1.初始化获取几个旋转矩阵,放入到vector中

2、SVD分解,Ax=0,对A填充。多帧组成A,一对点组成的A是4*4的。

3.至少迭代计算了WINDOW_SIZE次,且R的奇异值大于0.25才认为标定成功

2、solveRelativeR()

3、decomposeE()

4、testTriangulation()


我们首先来回顾以下整体的processImage()函数流程 

processImage()中:

第一步为检测当前输入的image是否为关键帧,f_manager.addFeatureCheckParallax()

第二步为更新临时预积分初始值  tmp_pre_integration = new IntegrationBase() 

第三步为:本文的贡献中相机和IMU外参的在线标定作为创新点。initial_ex_rotation.CalibrationExRotation()代码如下:

// 3. 如果没有外参则标定IMU到相机的外参
// 0表示外参优化完成;1表示粗略估计,后面作为初始值放进非线性优化;2表示需要进行标定。
    if(ESTIMATE_EXTRINSIC == 2)
    {
        ROS_INFO("calibrating extrinsic param, rotation movement is needed");
        if (frame_count != 0)
        {
            //得到corres传入的是当前帧和其之前一帧的对应特征点对的归一化坐标。
            vector<pair<Vector3d, Vector3d>> corres = f_manager.getCorresponding(frame_count - 1, frame_count);
            Matrix3d calib_ric;
            //标定从camera到IMU之间的外参数
            if (initial_ex_rotation.CalibrationExRotation(corres, pre_integrations[frame_count]->delta_q, calib_ric))
            {
                ROS_WARN("initial extrinsic rotation calib success");
                ROS_WARN_STREAM("initial extrinsic rotation: " << endl << calib_ric);
                //有几个相机,就有几个ric,目前单目情况下,ric内只有一个值
                ric[0] = calib_ric;
                RIC[0] = calib_ric;
                ESTIMATE_EXTRINSIC = 1;// 完成外参标定
            }
        }
    }

InitialEXRotation类

位于vins_estimator/src/initial/initial_ex_rotation.cpp,首先介绍一个这个类的成员变量以及成员函数:

/* 标定IMU和相机的外参数 */
class InitialEXRotation
{
public:
	InitialEXRotation();
    // !!!重要,主函数标定外参旋转矩阵
    bool CalibrationExRotation(vector<pair<Vector3d, Vector3d>> corres, Quaterniond delta_q_imu, Matrix3d &calib_ric_result);
private:
    // 两帧之间相机系旋转矩阵 
	Matrix3d solveRelativeR(const vector<pair<Vector3d, Vector3d>> &corres);

    double testTriangulation(const vector<cv::Point2f> &l,
                             const vector<cv::Point2f> &r,
                             cv::Mat_<double> R, cv::Mat_<double> t);
    // 本质矩阵SVD分解求得4组RT                         
    void decomposeE(cv::Mat E,
                    cv::Mat_<double> &R1, cv::Mat_<double> &R2,
                    cv::Mat_<double> &t1, cv::Mat_<double> &t2);
    int frame_count;

    vector< Matrix3d > Rc;// 相机之间旋转矩阵,对极几何得到
    vector< Matrix3d > Rimu;// 两个IMU之间旋转矩阵,由IMU预积分得到
    vector< Matrix3d > Rc_g;  // 每个IMU相对于起始IMU的旋转矩阵
    Matrix3d ric;// 相机到IMU的外参
};

1、CalibrationExRotation()函数

标定相机和IMU的外参数。

bool InitialEXRotation::CalibrationExRotation(vector<pair<Vector3d, Vector3d>> corres, Quaterniond delta_q_imu, Matrix3d &calib_ric_result)

输入参数为:vector<pair<Vector3d, Vector3d>> corres, Quaterniond delta_q_imu, 匹配的特征点 和 IMU预积分得的旋转矩阵Q

输出参数:Matrix3d &calib_ric_result    标定的外参数

<think>我们正在讨论VINS-Mono中的loop closure模块。用户的问题很明确:loop closure模块是否完全属于回环检测部分?是否与相机和IMU标定无关?分析:1.回环检测(LoopClosure)模块的主要作用是识别机器人是否回到了之前访问过的位置,从而进行位姿图的优化,减少累积误差,实现全局一致性。2.相机和IMU标定(T_ic,R_ic)是指相机与IMU之间的相对位姿变换(旋转和平移),这是多传感器融合的基础。根据VINS-Mono的架构(考引用[3]中的msckf_vio系统,虽然不完全相同,但原理似): -VINS-Mono中,标定通常是在初始化阶段完成的(例如在静止初始化时估计重力方向,同时也会估计)。在后续的非线性优化中,可以作为优化变量进行优化(如果设置为优化的话)。-回环检测模块主要处理的是关键帧之间的位姿约束,通过检测视觉相似性建立回环约束,然后进行位姿图优化。这个过程中,相机和IMU(如果已经标定好)是作为已知量使用的,因为回环检测主要依靠视觉特征,而位姿图优化中使用的位姿是由VIO系统提供的(该系统中已经包含了)。因此,我们可以得出结论: -Loopclosure模块的核心功能是回环检测和位姿图优化,它不负责标定-标定是在VIO前端(如特征跟踪)和状态估计中完成的,通常在系统初始化阶段就已经确定(并可能在后端优化中继续优化,但这属于VIO部分,而非回环模块)。但需要注意:在回环检测后的位姿图优化中,可能会优化关键帧的位姿(这些位姿是全局位姿,即世界坐标系下的位姿),而(相机到IMU的变换)是固定的。因此,回环模块本身并不改变。引用[2]中提到了的设置:tic[i] =TIC[i];ric[i]= RIC[i];这是在设置相机到IMU的平移和旋转,这个操作发生在Estimator::setParameter()函数中,也就是在系统开始运行之前就设定好了(或者从配置文件中读取)。在回环模块中,我们使用这些将相机位姿转换到IMU坐标系下(因为VIO系统主要是在IMU坐标系下进行状态估计)。所以,回答用户的问题:1.loop closure模块完全属于回环检测部分,它的作用是识别回环并进行全局优化。2.该模块与相机和IMU标定无关。标定是在VIO部分完成的,并且在回环模块中作为已知常量使用。补充说明:在VINS-Mono中,标定可以在线进行(如设置estimate_extrinsic=1或2),但这部分工作是在VIO线程中完成的,而不是在回环检测线程中。回环检测线程独立运行,它使用已经标定好的(如果在线标定,则使用当前估计的)来将相机位姿转换到IMU坐标系,然后进行回环检测和优化。因此,loopclosure模块不涉及标定,它只负责回环检测和全局优化。</think>在 VINS-Mono/VINS-Fusion 系统中,**loop closure 模块完全属于回环检测部分,与相机-IMU标定($T_{ic}$)无直接关联**。以下是关键分析: ### 1. loop closure 模块的作用范围 - **核心功能**:识别场景回环,优化全局轨迹一致性 - **数据处理流程**: ```mermaid graph LR A[关键帧图像] --> B[特征描述子提取] B --> C[回环候选帧检索] C --> D[几何验证] D --> E[位姿图优化] ``` - **输出**:闭环约束($T_{loop}$),用于校正累积漂移[^3] ### 2. 与相机-IMU标定的关系 - **标定独立进行**: ```cpp // 代码示例(引用[2]) void Estimator::setParameter() { for (int i = 0; i < NUM_OF_CAM; i++) { tic[i] = TIC[i]; // 相机-IMU平移 ric[i] = RIC[i]; // 相机-IMU旋转 } f_manager.setRic(ric); } ``` - 在系统初始化阶段固定加载(`TIC[i]`, `RIC[i]`) -与回环检测计算过程[^2] - **数据流隔离**: - 回环模块输入:**纯视觉特征** - 标定输入:**IMU预积分+视觉重投影** - 两者在VINS架构中并行运行: ``` VINS主线程: IMU积分 + 视觉BA + 优化 └── 回环检测线程: 词袋检索 + 位姿图优化 ``` ### 3. 系统级验证 在 MSCKF-VIO 的实现中(引用[3]): - IMU 静止初始化仅处理重力方向估计 - 特征回调函数分离视觉和IMU处理 - 回环检测完全不依赖 IMU 数据流 ### 结论 1. **功能隔离**:loop closure 是纯视觉回环模块 2. **数独立**:相机-IMU ($R_{ic}, t_{ic}$) 在初始化后即固定 3. **架构设计**:VINS 系统将传感器标定与回环检测解耦,确保实时性 > 工程建议:若需在线优化,应修改 VIO 线程的 BA 部分(`ProjectionFactor::sqrt_info`),而非回环模块[^2]。
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值