vins-fusion发出位姿话题时延相对较大原因分析(如在NX板卡上)

vins里发布位姿话题是在pubOdometry这个函数里(VINS-Fusion/vins_estimator/src/utility/visualization.cpp),这个函数在void Estimator::processMeasurements()函数(VINS-Fusion/vins_estimator/src/estimator/estimator.cpp)里被调用,pubOdometry运行前会运行一个processImage(feature.second, feature.first)函数,这个函数里有pnp/IMU预积分得到初始位姿,三角化,滑窗优化,怪不得发出位姿延迟大。不像ORBSLAM前端就发出位姿话题了,vins虽然也有前端tracking,但是前端tracking输出的是比如特征点匹配结果,并没有相机帧初始位姿估计,相机帧初始位姿估计放在了后端estimator.cpp里。

Estimator::processMeasurements()函数
https://blog.csdn.net/shikaiaixuexi/article/details/139609769

//这个函数是用来处理测量数据的主要循环。它从 featureBuf 中获取特征数据,同时等待IMU数据(如果启用了IMU),然后对图像和IMU数据进行处理
void Estimator::processMeasurements()
{
    //这里开始一个无限循环,一直等待处理测量数据。
    while (1)
    {
        //printf("process measurments\n");
        //定义了一个 feature 变量,其中包含时间戳和特征点数据的映射。
        pair<double, map<int, vector<pair<int, Eigen::Matrix<double, 7, 1> > > > > feature;
        //定义了用于存储IMU数据的向量。
        vector<pair<double, Eigen::Vector3d>> accVector, gyrVector;
        if(!featureBuf.empty())
        {
            //如果特征点缓冲区不为空,就从中获取下一个特征数据。
            feature = featureBuf.front();
            // 计算当前时间(特征数据的时间戳加上时间偏移)
            curTime = feature.first + td;
            // 等待IMU数据,直到IMU数据在当前时间戳可用
            while(1)
            {
                // 如果不使用IMU或者IMU数据在当前时间戳处可用,则退出循环
                if ((!USE_IMU  || IMUAvailable(feature.first + td)))
                    break;
                // 否则,等待IMU数据
                else
                {
                    printf("wait for imu ... \n");
                    // 如果没有启用多线程,直接返回
                    if (! MULTIPLE_THREAD)
                        return;
                    // 等待5毫秒
                    std::chrono::milliseconds dura(5);
                    std::this_thread::sleep_for(dura);
                }
            }
            // 加锁,获取IMU数据并存储到accVector和gyrVector中
            mBuf.lock();
            if(USE_IMU)
                getIMUInterval(prevTime, curTime, accVector, gyrVector);
 
            // 从特征数据缓冲区中移除已处理的特征数据
            featureBuf.pop();
            mBuf.unlock();
 
            // 如果使用IMU数据
            if(USE_IMU)
            {
                // 如果尚未初始化第一个姿态,先初始化第一个IMU姿态
                if(!initFirstPoseFlag)
                    initFirstIMUPose(accVector);
                // 对每个时间间隔的IMU数据进行处理
                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处理IMU数据
                    processIMU(accVector[i].first, dt, accVector[i].second, gyrVector[i].second);
                }
            }
            // 加锁,调用processImage函数处理图像数据
            mProcess.lock();
            processImage(feature.second, feature.first);
            prevTime = curTime;
 
            // 打印统计信息
            printStatistics(*this, 0);
 
            // 设置ROS消息头部,并发布相关数据
            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);
    }
}

processImage函数部分内容
VINS-Fusion/vins_estimator/src/estimator/estimator.cpp

    if(!USE_IMU)
            f_manager.initFramePoseByPnP(frame_count, Ps, Rs, tic, ric);
        f_manager.triangulate(frame_count, Ps, Rs, tic, ric);
        optimization();
        set<int> removeIndex;
        outliersRejection(removeIndex);
        f_manager.removeOutlier(removeIndex);
        if (! MULTIPLE_THREAD)
        {
            featureTracker.removeOutliers(removeIndex);
            predictPtsInNextFrame();
        }
            
        ROS_DEBUG("solver costs: %fms", t_solve.toc());

        if (failureDetection())
        {
            ROS_WARN("failure detection!");
            failure_occur = 1;
            clearState();
            setParameter();
            ROS_WARN("system reboot!");
            return;
        }

        slideWindow();
        f_manager.removeFailures();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值