VINS-Fusion代码按执行顺序阅读(二)

2023-05-16

main()函数的最后一句,std::thread sync_thread{sync_process};
可以看出,只有time0time1前后0.03s内的两幅图片,才会被发布estimator.inputImage(time, image0, image1);

// extract images with same timestamp from two topics
void sync_process()
{
    while(1)
    {
        if(STEREO)  // STEREO 取值为1 表示双目,为0 表示单目
        {
            cv::Mat image0, image1;
            std_msgs::Header header;
            double time = 0;
            m_buf.lock();
            if (!img0_buf.empty() && !img1_buf.empty())
            {
                double time0 = img0_buf.front()->header.stamp.toSec();
                double time1 = img1_buf.front()->header.stamp.toSec();
                // 0.003s sync tolerance
                if(time0 < time1 - 0.003)
                {
                    img0_buf.pop();
                    printf("throw img0\n");
                }
                else if(time0 > time1 + 0.003)
                {
                    img1_buf.pop();
                    printf("throw img1\n");
                }
                else
                {
                    time = img0_buf.front()->header.stamp.toSec();
                    header = img0_buf.front()->header;
                    image0 = getImageFromMsg(img0_buf.front());
                    img0_buf.pop();
                    image1 = getImageFromMsg(img1_buf.front());
                    img1_buf.pop();
                    //printf("find img0 and img1\n");
                }
            }
            m_buf.unlock();
            if(!image0.empty())
                estimator.inputImage(time, image0, image1);
        }
        
        std::chrono::milliseconds dura(2);  // 2ms
        std::this_thread::sleep_for(dura);
    }
}

进入estimator类中查看inputImage()类成员函数:
int inputImageCnt;是一个类数据成员
对于双目调用featureFrame = featureTracker.trackImage(t, _img, _img1);,前面阅读的代码派上用场了!这一句话完成了解析上13页(四、前端视觉处理)的部分。

SHOW_TRACK变量的含义?如果为真,则发布消息pubTrackImage(imgTrack, t);
imgTrackFeatureTracker类的数据成员。

queue<pair<double, map<int, vector<pair<int, Eigen::Matrix<double, 7, 1> > > > > > featureBuf;Estimator类的一个数据成员,是一个队列。

进入到Estimator类的一个函数成员void processMeasurements();

void Estimator::inputImage(double t, const cv::Mat &_img, const cv::Mat &_img1)
{
    inputImageCnt++;
    map<int, vector<pair<int, Eigen::Matrix<double, 7, 1>>>> featureFrame;
    TicToc featureTrackerTime;

    if(_img1.empty())
        featureFrame = featureTracker.trackImage(t, _img);
    else
        featureFrame = featureTracker.trackImage(t, _img, _img1);
    //printf("featureTracker time: %f\n", featureTrackerTime.toc());

    if (SHOW_TRACK)
    {
        cv::Mat imgTrack = featureTracker.getTrackImage();
        pubTrackImage(imgTrack, t);
    }
    
    if(MULTIPLE_THREAD)  
    {     
        if(inputImageCnt % 2 == 0)
        {
            mBuf.lock();
            featureBuf.push(make_pair(t, featureFrame));
            mBuf.unlock();
        }
    }
    else
    {
        mBuf.lock();
        featureBuf.push(make_pair(t, featureFrame));
        mBuf.unlock();
        TicToc processTime;
        processMeasurements();
        printf("process time: %f\n", processTime.toc());
    }
    
}

进入该函数会一直在此处循环,通过break方式退出的条件是
USE_IMU的含义?推测此处的取值为true

下面进入Estimator类的另一个成员函数,getIMUInterval()bool Estimator::getIMUInterval(double t0, double t1, vector<pair<double, Eigen::Vector3d>> &accVector, vector<pair<double, Eigen::Vector3d>> &gyrVector)
该函数的目的很明确,将时间区间[t0,t1]之间的陀螺仪、加速度计输出的数据从accBufgyrBu取出存放在accVectorgyrVector两个vector中。

如果还未初始化,即initFirstPoseFlagfalse,则首先进行初始化。
感觉这个地方使用了双矢量定姿(一个是加速度计输出的平均值,一个是重力矢量)。还有些细节的地方没有理解(例如yaw用来干什么?),暂时略过。
最后,初始姿态保存为了Rs[0],是Estimator的一个类数据成员Matrix3d Rs[(WINDOW_SIZE + 1)];

接下来调用了processIMU(accVector[i].first, dt, accVector[i].second, gyrVector[i].second);,完成了之前介绍过的解析4页(二、IMU预积分)的当前时刻及帧间PVQ的求取,还有PVQ增量的误差、协方差及Jacobian。

接下来调用了processImage(feature.second, feature.first);,有一种感觉,这里就是处理的核心了!去功能模块仔细阅读。

void Estimator::processMeasurements()
{
    while (1)
    {
        //printf("process measurments\n");
        pair<double, map<int, vector<pair<int, Eigen::Matrix<double, 7, 1> > > > > feature;
        vector<pair<double, Eigen::Vector3d>> accVector, gyrVector;
        if(!featureBuf.empty())
        {
            feature = featureBuf.front();
            curTime = feature.first + td;
            while(1)
            {
                if ((!USE_IMU  || IMUAvailable(feature.first + td)))
                    break;
                else
                {
                    printf("wait for imu ... \n");
                    if (! MULTIPLE_THREAD)
                        return;
                    std::chrono::milliseconds dura(5);
                    std::this_thread::sleep_for(dura);
                }
            }
            mBuf.lock();
            if(USE_IMU)
                getIMUInterval(prevTime, curTime, accVector, gyrVector);

            featureBuf.pop();
            mBuf.unlock();

            if(USE_IMU)
            {
                if(!initFirstPoseFlag)
                    initFirstIMUPose(accVector);
                for(size_t i = 0; i < accVector.size(); i++)
                {
                    double dt;
                    if(i == 0)
                        dt = accVector[i].first - prevTime;
                    else if (i == accVector.size() - 1)
                        dt = curTime - accVector[i - 1].first;
                    else
                        dt = accVector[i].first - accVector[i - 1].first;
                    processIMU(accVector[i].first, dt, accVector[i].second, gyrVector[i].second);
                }
            }
            mProcess.lock();
            processImage(feature.second, feature.first);
            prevTime = curTime;

            printStatistics(*this, 0);

            std_msgs::Header header;
            header.frame_id = "world";
            header.stamp = ros::Time(feature.first);

            pubOdometry(*this, header);
            pubKeyPoses(*this, header);
            pubCameraPose(*this, header);
            pubPointCloud(*this, header);
            pubKeyframe(*this);
            pubTF(*this, header);
            mProcess.unlock();
        }

        if (! MULTIPLE_THREAD)
            break;

        std::chrono::milliseconds dura(2);
        std::this_thread::sleep_for(dura);
    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

VINS-Fusion代码按执行顺序阅读(二) 的相关文章

随机推荐

  • 【leetcode常见面试题】螺旋矩阵解题思路

    文章目录 螺旋矩阵解题思路先找行进路线找每条路线的结束位置再找每条路线的结束位置模拟行走 螺旋矩阵 II总结 螺旋矩阵 解题思路 本题可以采用模拟的方式 xff0c 设4种行走方向 xff0c 如下图 xff1a 先找行进路线 4个方向的行
  • C++面向对象程序设计学习心得

    C 43 43 面向对象程序设计学习心得 经过几周c 43 43 面向对象程序设计的学习 xff0c 对面向对象程序设计有了一些了解 递归 简单地讲 xff0c 递归就是程序直接或间接调用本身的编程技巧 xff0c 通过把一个不能或不好解决
  • STL学习心得

    STL概述 STL组件 1 容器 xff08 Container xff09 xff0d 管理某类对象的集合 2 迭代器 xff08 Iterator xff09 xff0d 在对象集合上进行遍历 xff08 注意 xff1a 这些集合可能
  • 安装nodejs和vue出现问题

    安装nodejs国内镜像时报错 npm install g cnpm registry 61 https registry npm taobao org不知道这是啥错误 xff0c 怎么改啊 xff1f 安装vue 从官网点击下载 下载后点
  • Jetson nano/nx通过网线连接电脑实现远程控制

    Jetson nano nx通过网线连接电脑实现远程控制 摘要1 nano nx桌面共享设置2 安装dconf editor解除加密3 自启VNC server4 网络共享5 获取IP地址6 安装PuTTy7 安装VNC Viewwer8
  • 一文解决MySQL突击面试,关键知识点总结

    文章目录 MySQL重要知识点回顾一 索引1 为什么需要索引2 索引的结构3 避免索引失效3 1 联合索引不满足最左匹配原则3 2 隐式转换3 3 like查询3 4 索引列存在运算或者使用函数3 5 优化器 4 执行计划4 1 type4
  • 51单片机应用篇-- --数码管60秒计时,独立按键可调

    开篇先说一句废话 本旺名字叫萨摩耶 xff0c xff0c Please 叫我旺财 xff0c xff0c xff0c 哈哈 xff0c 招财进宝嘛 xff01 缘由 本来按照我的学习计划 xff0c 我现在应该是单片机的学习过程 xff0
  • 【ESP32+freeRTOS学习笔记之“ESP32环境下使用freeRTOS的特性分析(3-多核环境下的调度)”】

    目录 1 不同核心上分别调度2 tick中断3 关于抢占4 关于同优级的任务按时间片调度5 空闲任务6 调度程序暂停7 启动和终止8 禁用中断9 总结 Vanilla FreeRTOS调度器是具有时间切片的固定优先级抢占调度器 xff0c
  • C++ STL 总结(持续更新)

    因为机试需要用c 43 43 xff0c 暴风吸入式学习 xff08 套用 xff09 它的模板 xff0c 发现还真的挺好用的 xff0c 总结一下 时间紧急 xff0c 取自各个网上的博客 xff0c 没来得及仔细整理 xff0c 都给
  • STM32F103笔记(二)——GPIO原理

    GPIO的工作原理与两个实验实例 一 STM32F103 GPIO说明1 stm32 GPIO引脚的主要功能2 GPIO相关配置寄存器的简介3 STM32F103 GPIO的8种工作方式4种输入模式4种输出模式 二 点亮LED实例 xff0
  • VINS-Fusion代码阅读(五)

    对应解析13页 xff0c 四 前端视觉处理 主要包括特征点检测和特征点跟踪两部分 xff0c 似乎是基于openCV实现的 openCV2 4官方文档 xff0c xff08 暂时未找到openCV3 4有类似的文档 xff09 这一节在
  • 利用putty在windows上通过脚本在远程Linux机器执行指令

    一 前言 借用百度百科关于putty的描述 xff1a PuTTY是一个Telnet SSH rlogin 纯TCP以及串行接口连接软件 较早的版本仅支持Windows平台 xff0c 在最近的版本中开始支持各类Unix平台 xff0c 并
  • 结构体嵌套对齐以及结构体中含有数组的对齐,也基本总结了各类结构体对齐的问题

    目录 结构体嵌套对齐以及结构体中含有数组的对齐 其余的对齐规则 基本的结构体对齐知识点击这里 结构体嵌套对齐以及结构体中含有数组的对齐 32位系统环境 规则一 xff1a 结构体中含有数组 xff0c 数组元素类型和结构中其余的最大类型取较
  • 【杂记1】PC-Ubuntu18.04.5+ROS-melodic环境下安装cartographer功能包

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 ROS下命令行安装 xff08 简单 xff0c 稍微提一下 xff09 二 源码安装cartographer xff0
  • rosdep init 错误解决方法

    遇到的错误如下 mo 64 mo span class token operator span ThundeRobot span class token operator span span class token operator spa
  • stm32+TB6612驱动直流电机

    因为单片机的不可以直接的驱动电机 xff0c 所以需要在他们之间加上一个电机的驱动模块 xff0c 之前的文章里面用过L298N电机驱动模块 xff0c 现在再给大家推荐一个新的电机驱动模块 xff0c 他比L298N好用许多 xff0c
  • 1-范数、2-范数、∞-范数、F-范数,向量范数与矩阵范数

    目录 向量范数1 范数2 范数 范数 矩阵范数1 范数 xff08 列范数 xff09 范数 xff08 行范数 xff09 2 范数 xff08 谱范数 xff09 F范数Frobenius 向量范数 1 范数 2 范数 范数 矩阵范数
  • MATLAB中删除矩阵的某些列或某些行

    MATLAB中删除矩阵的某一列或某一行 删除某一行例子 删除某一列例子 删除多行例子 删除多列例子 删除某一行 span class token function b span span class token punctuation sp
  • 向量叉乘计算公式

    二维向量叉乘 A 61 a1 a2 B 61 b1 b2 A B 61 a1 a2 b1 b2 61 a1b2 a2b1 三维向量叉乘 A 61 a1 a2 a3 B 61 b1 b2 b3 A B 61 a1 a2 a3 b1 b2 b3
  • VINS-Fusion代码按执行顺序阅读(二)

    main 函数的最后一句 xff0c std thread sync thread sync process 可以看出 xff0c 只有time0在time1前后0 03s内的两幅图片 xff0c 才会被发布estimator inputI