《视觉SLAM进阶:从零开始手写VIO》 第7讲作业 超详细运行步骤

《视觉SLAM进阶:从零开始手写VIO》 第7讲作业 超详细运行步骤

前言:VINS-Course代码解析

参考:
[从零写VIO|第七节]——VINS-Mono代码精简版代码详解——run_euroc前端的数据处理(内容|代码),写得特别详细,不管是前端,后端以及初始化部分都有详细的解析(后端及初始化部分可以根据这篇文章的链接顺序看下去)!!

关于第七节VINS的初始化,其内容和代码均整理在下面列出的博客中。视频的主要讲解内容在初始化1,初始化3。

run_euroc前端的数据处理(内容|代码)
初始化1外参标定(内容|代码)
初始化2视觉初始化(内容|代码)
初始化3视觉IMU对齐(内容|代码)
初始化4visualInitialAlign()(内容|代码)
VINS_Mono知识点解析

1.使用EuRoC MAV Dataset跑本VINS工程

1.1 下载数据集: EuRoC MAV Dataset

在这里插入图片描述

1.2 修改数据集路径

将文件test/run_euroc.cpp的如下

string sData_path = "/home/dataset/EuRoC/MH-05/mav0/";

改为自己的路径,我的数据集路径如下:

string sData_path = "/home/cgm/MH_05/mav0/";

在这里插入图片描述

1.3 编译

cd build
cmake ..
make

1.4 报错及解决

因我当前环境opencv版本过高问题,需要针对每个报错点进行相应版本的匹配修改

  • 报错1error: ‘CV_BGR2GRAY’ was not declared in this scope

    解决方法:将 CV_BGR2GRAY 全部替换为 cv::COLOR_BGR2GRAY

    在这里插入图片描述

  • 报错2 error: ‘CV_GRAY2BGR’ was not declared in this scope

    error: ‘CV_GRAY2RGB’ was not declared in this scope

    解决方法:

    ​ 将 CV_GRAY2BGR 全部替换为 cv::COLOR_GRAY2BGR

    ​ 将 CV_GRAY2RGB 全部替换为 cv::COLOR_GRAY2RGB在这里插入图片描述

报错3error: ‘CV_CALIB_CB_ADAPTIVE_THRESH’ was not declared in this scope

error: ‘CV_CALIB_CB_NORMALIZE_IMAGE’ was not declared in this scope

error: ‘CV_CALIB_CB_FILTER_QUADS’ was not declared in this scope

error: ‘CV_CALIB_CB_FAST_CHECK’ was not declared in this scope

**解决方法:**将CV_CALIB_CB_ADAPTIVE_THRESH、CV_CALIB_CB_NORMALIZE_IMAGE、CV_CALIB_CB_FILTER_QUADS和CV_CALIB_CB_FAST_CHECK

修改为 cv::CALIB_CB_ADAPTIVE_THRESH 、 cv::CALIB_CB_NORMALIZE_IMAGE 、cv::CALIB_CB_FILTER_QUADS 和cv::CALIB_CB_FAST_CHECK

在这里插入图片描述

其他3个替换同理

报错4error: ‘CV_ADAPTIVE_THRESH_MEAN_C’ was not declared in this scope

解决办法

  • 在报错文件上添加头文件 #include <opencv2/imgproc/imgproc_c.h>

  • 单独遇到CV_AA的报错时,也可以将 CV_AA 改为 cv::LINE_AA

报错5/home/cgm/VINS-Course/test/run_euroc.cpp:10:10: fatal error: cv.h: 没有那个文件或目录 10 | #include <cv.h>

解决办法:

#include <cv.h>

#include <highgui.h>

改为

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>

报错6:

error: ‘QuitAll’ is not a member of ‘pangolin’; did you mean ‘Quit’? 34 | pangolin::QuitAll();

解决办法:

pangolin::QuitAll();改为 pangolin::Quit();

报错7:

error: ‘CV_WINDOW_AUTOSIZE’ was not declared in this scope 164 | cv::namedWindow("IMAGE", CV_WINDOW_AUTOSIZE);

解决办法:

CV_WINDOW_AUTOSIZE 改为 cv::WINDOW_AUTOSIZE

可以参考一下链接的报错解决办法:

源码安装vins-mono算法问题整理(ROS Melodic + opencv 4.1.1)

1.5 运行 run_euroc

cd bin
./run_euroc /home/cgm/MH_05/mav0/ ../config/

可以在VINS-Course目录下创建build.sh脚本文件,以后测试只需要运行 ./build.sh 就可以了。

build.sh

#!/bin/bash
echo "Configuring and building ..."
if [ ! -d "build" ]; then
    mkdir build
fi
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j4
cd ../bin
./run_euroc /home/cgm/MH_05/mav0/ ../config/

1.6 结果

在这里插入图片描述

2.使用第二章仿真数据跑该VINS工程

2.1 第二章的仿真数据

在这里插入图片描述

数据在vio_data_simulation/bin 文件下

第二章的运动轨迹是一个xy平面椭圆运动,z正弦运动。
house_model

​ 保存了原始设置的3d房屋关键点(一行两个点连成线,保存点前判断一下是否之前获取过)
运行后生成如下数据:
keyframe文件夹

	每一帧相机观测到的特征点,代码中设定相机帧率为30Hz,仿真20s,对应一共产生600帧观测

all_points

​ 保存了所有特征点(对比房屋关键点可以有所增加)文件存储的是house模型的线特征,每行4个数,对应 该线两端点 在归一化平面的坐标,一共23行对应23条线段

cam_pose

​ 所有相机位姿, cam_pose_tum只是存储顺序和变量个数有所不同
imu_pose

​ 所有imu位姿, imu_pose_noise 带噪声
mu_int_pose

​ 积分后得到的imu轨迹, imu_int_pose_noise 带噪声

在这里插入图片描述

2.2 新建run_simulate.cpp

在VINS-Course下的test文件下:复制 run_euroc.cpp 并重命名为 run_simulate.cpp

修改部分:imu位姿的路径;cam位姿的路径;void PubImuData()函数;void PubImageData()函数;

我的imu位姿和cam位姿还是在第二章的代码 vio_data_simulation/bin 文件下

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <thread>
#include <iomanip>

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <eigen3/Eigen/Dense>
#include "System.h"

using namespace std;
using namespace cv;
using namespace Eigen;

const int nDelayTimes = 2;

string sData_path = "/home/cgm/vio_data_simulation/bin";//修改imu位姿文件的路径
string sConfig_path = "/home/cgm/vio_data_simulation/bin";//修改cam位姿文件的路径

std::shared_ptr<System> pSystem;

void PubImuData()
{
	string sImu_data_file = sConfig_path + "imu_pose.txt";//修改要测试的imu位姿文件  //不带噪声的IMU数据的路径
	cout << "1 PubImuData start sImu_data_filea: " << sImu_data_file << endl;
    ifstream fsImu;//文件流对象
    fsImu.open(sImu_data_file.c_str());
    if (!fsImu.is_open())
    {
        cerr << "Failed to open imu file! " << sImu_data_file << endl;
        return;
    }

    std::string sImu_line;
    double dStampNSec = 0.0;//时间戳
    double tmp;
    Vector3d vAcc;//加速度
    Vector3d vGyr;
    while (std::getline(fsImu, sImu_line) && !sImu_line.empty()) // read imu data sImu_line获得每行的文件流 
    {
        // timestamp (1),imu quaternion(4),imu position(3),imu gyro(3),imu acc(3)
        std::istringstream ssImuData(sImu_line);//ssImuData得到每行文件的内容
        ssImuData >> dStampNSec;//时间戳
        //利用循环跳过imu quaternion(4),imu position(3)
        for(int i=0;i<7;i++)
            ssImuData>>tmp;
        ssImuData>>vGyr.x() >> vGyr.y() >> vGyr.z() >> vAcc.x() >> vAcc.y() >> vAcc.z();
        // 时间单位为 s
        pSystem->PubImuData(dStampNSec, vGyr, vAcc);//PubImuData不需要改变 用来将不同时刻下的IMU数据放进VINS系统
        usleep(5000*nDelayTimes);
    }
    fsImu.close();
}

void PubImageData()
{
	string sImage_file = sConfig_path + "cam_pose.txt";//修改要测试的cam位姿文件

	cout << "1 PubImageData start sImage_file: " << sImage_file << endl;

    ifstream fsImage;//文件流对象
    fsImage.open(sImage_file.c_str());
    if (!fsImage.is_open())
    {
        cerr << "Failed to open image file! " << sImage_file << endl;
        return;
    }

    std::string sImage_line;
    double dStampNSec;
    string sImgFileName;
    int n=0;

    // cv::namedWindow("SOURCE IMAGE", CV_WINDOW_AUTOSIZE);
    //这个循环是遍历所有的相机
    while (std::getline(fsImage, sImage_line) && !sImage_line.empty())//sImage_line是cam_pose每行的数据流
    {
        std::istringstream ssImgData(sImage_line);//是cam_pose每行的内容
        ssImgData >> dStampNSec;   //读入时间戳
        cout<<"cam time: "<<fixed<<dStampNSec<<endl;
        // all_points_ 文件存储的是house模型的线特征,每行4个数,对应该线两端点在归一化平面的坐标
        //all_points_  文件每行的内容是 x, y, z, 1, u, v  这里的u v是归一化下的x ,y 不是像素坐标
        //在函数PubSimImageData中会算出具体特征点的像素坐标
        string all_points_file_name = "/home/cgm/vio_data_simulation/bin/keyframe/all_points_" + to_string(n)+ ".txt";  //第n个相机对应的观测数据的文件名
        cout<<"points_file: "<<all_points_file_name<<endl;
        vector<cv::Point2f> FeaturePoints;//容器FeaturePoints存放一个相机的特征点(归一化坐标)
        std::ifstream f;
        f.open(all_points_file_name);

        //这个循环是遍历每个相机的特征点信息
        // file content in each line: x, y, z, 1, u, v
        //经过这个循环把all_points_的特征点都放在FeaturePoints了
        while(!f.eof())
        {
            std::string s;
            std::getline(f,s);//得到all_points_的文件流s
            // 一行两个点连成线,获取每行点判断一下是否之前获取过
            if(!s.empty())
            {
                std::stringstream ss;//
                ss << s;//ss得到每行的内容

                double tmp;//跳过  x y z 1
                for(int i=0;i<4;i++)
                    ss>>tmp;

                float px,py;
                ss >> px;
                ss >> py;
                cv::Point2f pt( px, py);//归一化坐标

                FeaturePoints.push_back(pt);
            }
        }

//        cout << "All points:" << endl;
//        for(auto point : FeaturePoints){
//            cout << point << " ";
//        }
//        cout << endl;


        pSystem->PubSimImageData(dStampNSec, FeaturePoints);//把每一个图片的特征点 放进VINS系统里

        usleep(50000*nDelayTimes);
        n++;
    }
    fsImage.close();
}
//后面代码没变化,就不复制了。
//后面代码没变化,就不复制了。
//后面代码没变化,就不复制了。

2.3 修改CMakeLists.txt

CMakeLists.txt 末尾增加代码

add_executable(run_simulate test/run_simulate.cpp)
target_link_libraries(run_simulate 
  MyVio  
  -lpthread) 

2.4 修改System.h

增加 第14行 代码

class System
{
public:
    System(std::string sConfig_files);

    ~System();

    void PubImageData(double dStampSec, cv::Mat &img);

    
    void PubImuData(double dStampSec, const Eigen::Vector3d &vGyr, 
        const Eigen::Vector3d &vAcc);
    //添加声明
    void PubSimImageData(double dStampSec, const vector<cv::Point2f> &FeaturePoints);

2.5 修改System.cpp

System.cpp末尾增加如下代码

这个函数是根据 System.cppvoid System::PubImageData(double dStampSec, Mat &img)进行修改得到的。

void System::PubSimImageData(double dStampSec, const vector<cv::Point2f> &FeaturePoints)
{
    if (!init_feature)
    {
        cout << "1 PubImageData skip the first detected feature, which doesn't contain optical flow speed" << endl;
        init_feature = 1;
        return;
    }

    if (first_image_flag)
    {
        cout << "2 PubImageData first_image_flag" << endl;
        first_image_flag = false;
        first_image_time = dStampSec;
        last_image_time = dStampSec;
        return;
    }
    // detect unstable camera stream 发现时间戳不连续甚至倒退,提示重新输入
    if (dStampSec - last_image_time > 1.0 || dStampSec < last_image_time)
    {
        cerr << "3 PubImageData image discontinue! reset the feature tracker!" << endl;
        first_image_flag = true;
        last_image_time = 0;
        pub_count = 1;
        return;
    }
    last_image_time = dStampSec;
    // frequency control 控制频率设定小于某一阈值
//    if (round(1.0 * pub_count / (dStampSec - first_image_time)) <= FREQ)
//    {
//        PUB_THIS_FRAME = true;
//        // reset the frequency control TODO question:若当前连续图像序列的频率与 FREQ=10 误差在一定范围内重置?
//        if (abs(1.0 * pub_count / (dStampSec - first_image_time) - FREQ) < 0.01 * FREQ)
//        {
//            first_image_time = dStampSec;
//            pub_count = 0;
//        }
//    }
//    else
//    {
//        PUB_THIS_FRAME = false;
//    }
    PUB_THIS_FRAME = true;

    TicToc t_r;
    // cout << "3 PubImageData t : " << dStampSec << endl;
    // TODO Bookmark:获取图像特征点
//    trackerData[0].readImage(img, dStampSec);
//    trackerData[0].readPoints(FeaturePoints, dStampSec);

//    for (unsigned int i = 0;; i++)
//    {
//        bool completed = false;
//        completed |= trackerData[0].updateID(i);
//
//        if (!completed)
//            break;
//    }
    if (PUB_THIS_FRAME)
    {
        pub_count++;
        shared_ptr<IMG_MSG> feature_points(new IMG_MSG());
        feature_points->header = dStampSec;
        vector<set<int>> hash_ids(NUM_OF_CAM);
        for (int i = 0; i < NUM_OF_CAM; i++)
        {
//            auto &un_pts = trackerData[i].cur_un_pts;// 去畸变的归一化图像坐标
//            auto &cur_pts = trackerData[i].cur_pts;// 当前追踪到的特征点
//            auto &ids = trackerData[i].ids;
//            auto &pts_velocity = trackerData[i].pts_velocity;
            for (unsigned int j = 0; j < FeaturePoints.size(); j++)
            {
//                if (trackerData[i].track_cnt[j] > 1)
//                {
//                    int p_id = ids[j];
                int p_id = j;
                hash_ids[i].insert(p_id);
                double x = FeaturePoints[j].x;
                double y = FeaturePoints[j].y;
                double z = 1;
                feature_points->points.push_back(Vector3d(x, y, z));
                feature_points->id_of_point.push_back(p_id * NUM_OF_CAM + i);
//                    feature_points->u_of_point.push_back(cur_pts[j].x); // 像素坐标
//                    feature_points->v_of_point.push_back(cur_pts[j].y);
//                    // TODO Bookmark:速度项用于对齐imu时间戳 作业不考虑可以设为0
//                    feature_points->velocity_x_of_point.push_back(pts_velocity[j].x);
//                    feature_points->velocity_y_of_point.push_back(pts_velocity[j].y);

                cv::Point2f pixel_point;
                pixel_point.x = 460 * x + 255;
                pixel_point.y = 460 * y + 255;

                feature_points->u_of_point.push_back(pixel_point.x); // 像素坐标
                feature_points->v_of_point.push_back(pixel_point.y);
                feature_points->velocity_x_of_point.push_back(0);
                feature_points->velocity_y_of_point.push_back(0);
//                }
            }

            // skip the first image; since no optical speed on frist image
            if (!init_pub)
            {
                cout << "4 PubImage init_pub skip the first image!" << endl;
                init_pub = 1;
            }
            else
            {
                m_buf.lock();
                feature_buf.push(feature_points);
                // cout << "5 PubImage t : " << fixed << feature_points->header
                //     << " feature_buf size: " << feature_buf.size() << endl;
                m_buf.unlock();
                con.notify_one();
            }
        }
    }
}


2.6 修改配置文件

复制VINS-Course/config下的euroc_config_sim.yaml 并重命名为 euroc_config_sim.yaml

euroc_config_sim.yaml

%YAML:1.0

#common parameters
imu_topic: "/imu0"
image_topic: "/cam0/image_raw"
output_path: "/home/hyj/slam_course_vins/"

#camera calibration 
model_type: PINHOLE
camera_name: camera
image_width: 640
image_height: 640
distortion_parameters:
   k1: 0
   k2: 0
   p1: 0
   p2: 0
projection_parameters:
   fx: 460
   fy: 460
   cx: 255
   cy: 255

# Extrinsic parameter between IMU and Camera.
estimate_extrinsic: 0   # 0  Have an accurate extrinsic parameters. We will trust the following imu^R_cam, imu^T_cam, don't change it.
                        # 1  Have an initial guess about extrinsic parameters. We will optimize around your initial guess.
                        # 2  Don't know anything about extrinsic parameters. You don't need to give R,T. We will try to calibrate it. Do some rotation movement at beginning.                        
#If you choose 0 or 1, you should write down the following matrix.
#Rotation from camera frame to imu frame, imu^R_cam
extrinsicRotation: !!opencv-matrix
   rows: 3
   cols: 3
   dt: d
   data: [0, 0, -1,
          -1, 0, 0,
          0, 1, 0]
#Translation from camera frame to imu frame, imu^T_cam
extrinsicTranslation: !!opencv-matrix
   rows: 3
   cols: 1
   dt: d
   data: [0.05,0.04,0.03]

#feature traker paprameters
max_cnt: 150            # max feature number in feature tracking
min_dist: 30            # min distance between two features 
freq: 10                # frequence (Hz) of publish tracking result. At least 10Hz for good estimation. If set 0, the frequence will be same as raw image 
F_threshold: 1.0        # ransac threshold (pixel)
show_track: 1           # publish tracking image as topic
equalize: 1             # if image is too dark or light, trun on equalize to find enough features
fisheye: 0              # if using fisheye, trun on it. A circle mask will be loaded to remove edge noisy points

#optimization parameters
max_solver_time: 0.04  # max solver itration time (ms), to guarantee real time
max_num_iterations: 8   # max solver itrations, to guarantee real time
keyframe_parallax: 10.0 # keyframe selection threshold (pixel)

#imu parameters       The more accurate parameters you provide, the better performance
acc_n: 0.019          # accelerometer measurement noise standard deviation. #0.2   0.04
gyr_n: 0.015          # gyroscope measurement noise standard deviation.     #0.05  0.004
acc_w: 0.0001         # accelerometer bias random work noise standard deviation.  #0.02
gyr_w: 1.0e-5       # gyroscope bias random work noise standard deviation.     #4.0e-5
g_norm: 9.81007     # gravity magnitude

#loop closure parameters
loop_closure: 0                    # start loop closure
load_previous_pose_graph: 0        # load and reuse previous pose graph; load from 'pose_graph_save_path'
fast_relocalization: 0             # useful in real-time and large project
pose_graph_save_path: "/home/cgm/VINS-Course/" # save and load path

#unsynchronization parameters
estimate_td: 0                      # online estimate time offset between camera and imu
td: 0.0                             # initial value of time offset. unit: s. readed image clock + td = real image clock (IMU clock)

#rolling shutter parameters
rolling_shutter: 0                  # 0: global shutter camera, 1: rolling shutter camera
rolling_shutter_tr: 0               # unit: s. rolling shutter read out time per frame (from data sheet). 

#visualization parameters
save_image: 0                   # save image in pose graph for visualization prupose; you can close this function by setting 0 
visualize_imu_forward: 0        # output imu forward propogation to achieve low latency and high frequence results
visualize_camera_size: 0.4      # size of camera marker in RVIZ

修改**System.cpp**配置文件的路径,下面代码的第12行改为刚刚的euroc_config_sim.yaml文件

#include "System.h"

#include <pangolin/pangolin.h>

using namespace std;
using namespace cv;
using namespace pangolin;

System::System(string sConfig_file_)
    :bStart_backend(true)
{
    string sConfig_file = "../config/euroc_config_sim.yaml";

2.6 使用脚本运行run_simulate

复制VINS-Course目录下创建的build.sh脚本文件,并修改最后一行。

#!/bin/bash
echo "Configuring and building ..."
if [ ! -d "build" ]; then
    mkdir build
fi
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j4
cd ../bin
./run_simulate /home/cgm/vio_data_simulation/bin/ /home/cgm/vio_data_simulation/bin/

注意自己的 imu位姿 和 cam位姿 的数据位置

结果:

生成的 pose_output.txtVINS-Course/bin 目录下

在这里插入图片描述

3.使用evo评估工具

3.1 evo评估pose_output.txt

代码生成的 pose_output.txtVINS-Course/bin 目录下。

但是我们使用evo工具

evo_traj tum pose_output.txt --plot

却报错:

[ERROR] TUM trajectory files must have 8 entries per row and no trailing delimiter at the end of the rows (space)

**原因:**pose_output.txt有的数据中间有两个空格,使用evo工具,不符合tum格式

在这里插入图片描述

在这里插入图片描述

3.2 pose_output.txt存储为TUM数据集格式

使用evo工具可视化和评测SLAM算法性能

解决办法:

方法1:把pose_output.txt里面的 2个空格 全部替换成 1个空格。

方法2:修改保存数据的代码-------void System::ProcessBackEnd()函数。

​ 将 void System::ProcessBackEnd() 函数的如下2行

cout << "1 BackEnd processImage dt: " << fixed << t_processImage.toc() << " stamp: " <<  dStamp << " p_wi: " << p_wi.transpose() << endl;
ofs_pose << fixed << dStamp << " " << p_wi.transpose() << " " << q_wi.coeffs().transpose() << endl;

修改为下面的代码

//修改保存数据的代码如下:
ofs_pose.setf(std::ios::fixed, std::ios::floatfield);
ofs_pose.precision(9);
ofs_pose <<dStamp<<" ";//时间戳保存为9位数精度
ofs_pose.precision(5);//位姿保存位5位数的精度
ofs_pose <<p_wi(0)<<" "
 <<p_wi(1)<<" "
 <<p_wi(2)<<" "
 <<q_wi.coeffs().x()<<" "
 <<q_wi.coeffs().y()<<" "
 <<q_wi.coeffs().z()<<" "
 <<q_wi.coeffs().w()<<std::endl;
cout << "1 BackEnd processImage dt: "  << " stamp: " <<  dStamp << " p_wi: " << p_wi.transpose() << endl;

把之前的 pose_output.txt文件 和 可执行文件run_simulate 删除

再次运行 ./build_sim.sh 查看一下 pose_output.txt 为 TUM数据集格式:

timestamp tx ty tz qx qy qz qw

(每行有8个元素,元素之间只有1个空格,结尾没有空格, 时间以秒为单位
在这里插入图片描述

3.3 画出轨迹

evo_traj tum pose_output.txt --plot

在这里插入图片描述

4.对无噪声和默认噪声的IMU数据和相机数据仿真

4.1生成无噪声的 pose_output_without_noise.txt

因为我们的run_simulate.cpp用的是没有噪声的数据:

	string sImu_data_file = sConfig_path + "imu_pose.txt";

	string sImage_file = sConfig_path + "cam_pose.txt";

所以为了测试,我们修改System.cpp

	ofs_pose.open("./pose_output.txt",fstream::app | fstream::out);

修改导出文件的名字
    
	ofs_pose.open("./pose_output_without_noise.txt",fstream::app | fstream::out);

运行./build_sim.sh 生成 pose_output_without_noise.txt

4.2生成有噪声(默认)的 pose_output_with_noise.txt

这里的 imu_pose_noise.txt 是第二讲默认的噪声生成的

    // 第二讲默认的噪声  default noise
    double gyro_bias_sigma = 1.0e-5;     //陀螺仪的 bias 随机游走噪声
    double acc_bias_sigma = 0.0001;      //加速度 bias 的随机游走噪声

    double gyro_noise_sigma = 0.015;    // rad/s * 1/sqrt(hz)  陀螺仪的高斯白噪声
    double acc_noise_sigma = 0.019;      // m/(s^2) * 1/sqrt(hz)  加速度的高斯白噪声

修改

	string sImu_data_file = sConfig_path + "imu_pose.txt";
改为
    string sImu_data_file = sConfig_path + "imu_pose_noise.txt";

修改

    ofs_pose.open("./pose_output_without_noise.txt",fstream::app | fstream::out);
改为
    ofs_pose.open("./pose_output_with_noise.txt",fstream::app | fstream::out);

运行./build_sim.sh 生成 pose_output_with_noise.txt

在这里插入图片描述

4.3 对比无噪声

我们把 vio_data_simulation/bin 里的 cam_pose_tum.txt 复制到

命令:

evo_ape tum cam_pose_tum.txt pose_output_without_noise.txt -va --plot --plot_mode xyz --save_results without_noise.zip
这里我们使用evo_ape(cam_pose_tum.txt是参考) 计算来自 pose_output_without_noise.txt 的轨迹的绝对位姿误差,并将各个结果绘制并保存到 without_nois.zip 文件中

在这里插入图片描述

cgm@ubuntu:~/VINS-Course/bin$ evo_ape tum cam_pose_tum.txt pose_output_without_noise.txt -va --plot --plot_mode xyz --save_results without_noise.zip
--------------------------------------------------------------------------------
Loaded 600 stamps and poses from: cam_pose_tum.txt
Loaded 1761 stamps and poses from: pose_output_without_noise.txt
--------------------------------------------------------------------------------
Synchronizing trajectories...
Found 587 of max. 600 possible matching timestamps between...
	cam_pose_tum.txt
and:	pose_output_without_noise.txt
..with max. time diff.: 0.01 (s) and time offset: 0.0 (s).
--------------------------------------------------------------------------------
Aligning using Umeyama's method...
Rotation of alignment:
[[ 9.99434516e-01 -3.36250974e-02  1.78172351e-05]
 [ 3.36250971e-02  9.99434516e-01  1.59104301e-05]
 [-1.83421495e-05 -1.53023267e-05  1.00000000e+00]]
Translation of alignment:
[19.9895646   5.66108537  5.33820265]
Scale correction: 1.0
--------------------------------------------------------------------------------
Compared 587 absolute pose pairs.
Calculating APE for translation part pose relation...
--------------------------------------------------------------------------------
APE w.r.t. translation part (m)
(with SE(3) Umeyama alignment)

       max	0.062322
      mean	0.051179
    median	0.050118
       min	0.039944
      rmse	0.051528
       sse	1.558558
       std	0.005985

--------------------------------------------------------------------------------
Plotting results... 

APE w.r.t. translation part (m)( with SE(3) Umeyama alignment) raw

在这里插入图片描述

APE w.r.t. translation part (m )(with SE(3) Umeyama alignment) map

在这里插入图片描述

4.4 对比有噪声(第二讲默认的噪声)

命令

evo_ape tum cam_pose_tum.txt pose_output_with_noise.txt -va --plot --plot_mode xyz --save_results with_noise.zip
cgm@ubuntu:~/VINS-Course/bin$ evo_ape tum cam_pose_tum.txt pose_output_with_noise.txt -va --plot --plot_mode xyz --save_results with_noise.zip
--------------------------------------------------------------------------------
Loaded 600 stamps and poses from: cam_pose_tum.txt
Loaded 1312 stamps and poses from: pose_output_with_noise.txt
--------------------------------------------------------------------------------
Synchronizing trajectories...
Found 587 of max. 600 possible matching timestamps between...
	cam_pose_tum.txt
and:	pose_output_with_noise.txt
..with max. time diff.: 0.01 (s) and time offset: 0.0 (s).
--------------------------------------------------------------------------------
Aligning using Umeyama's method...
Rotation of alignment:
[[ 0.998435   -0.05419753 -0.0137906 ]
 [ 0.05373543  0.9980448  -0.03192294]
 [ 0.01549378  0.03113193  0.99939519]]
Translation of alignment:
[21.15684026  4.41788869  4.27253012]
Scale correction: 1.0
--------------------------------------------------------------------------------
Compared 587 absolute pose pairs.
Calculating APE for translation part pose relation...
--------------------------------------------------------------------------------
APE w.r.t. translation part (m)
(with SE(3) Umeyama alignment)

       max	3.300167
      mean	1.750798
    median	1.577023
       min	0.954810
      rmse	1.856596
       sse	2023.358491
       std	0.617783

--------------------------------------------------------------------------------
Plotting results... 

APE w.r.t. translation part (m)( with SE(3) Umeyama alignment) raw

在这里插入图片描述

APE w.r.t. translation part (m )(with SE(3) Umeyama alignment) map

在这里插入图片描述

5.不同大小噪声的imu数据仿真结果

5.1 改为更小的噪声

  • 步骤1:修改第二讲的代码(vio_data_simulation/src/param.h里的噪声部分),并运行。

    我第一次将噪声改小:

    	double gyro_bias_sigma = 1.0e-5;//陀螺仪的 bias 随机游走噪声
    	double acc_bias_sigma = 0.0001;//加速度 bias 的随机游走噪声
        double gyro_noise_sigma = 0.015;    // rad/s * 1/sqrt(hz)  陀螺仪的高斯白噪声
        double acc_noise_sigma = 0.019;      // m/(s^2) * 1/sqrt(hz)  加速度的高斯白噪声
    改为
        //smaller nosie
    	double gyro_bias_sigma = 1.0e-6;    //陀螺仪的 bias 随机游走噪声
    	double acc_bias_sigma = 0.00001;     //加速度 bias 的随机游走噪声
        double gyro_noise_sigma = 0.0015;    // rad/s * 1/sqrt(hz)  陀螺仪的高斯白噪声
        double acc_noise_sigma = 0.0019;      // m/(s^2) * 1/sqrt(hz)  加速度的高斯白噪声
    
  • 步骤2:使用脚本运行run_simulate

    ./build._sim.sh
    
  • 步骤3:在目录VINS-Course/bin 下打开终端进行对比。

​ 命令

evo_ape tum cam_pose_tum.txt pose_output_with_noise.txt -va --plot --plot_mode xyz --save_results with_noise_smaller.zip

结果:

cgm@ubuntu:~/VINS-Course/bin$ evo_ape tum cam_pose_tum.txt pose_output_with_noise.txt -va --plot --plot_mode xyz --save_results with_noise_smaller.zip
--------------------------------------------------------------------------------
Loaded 600 stamps and poses from: cam_pose_tum.txt
Loaded 587 stamps and poses from: pose_output_with_noise.txt
--------------------------------------------------------------------------------
Synchronizing trajectories...
Found 587 of max. 587 possible matching timestamps between...
	cam_pose_tum.txt
and:	pose_output_with_noise.txt
..with max. time diff.: 0.01 (s) and time offset: 0.0 (s).
--------------------------------------------------------------------------------
Aligning using Umeyama's method...
Rotation of alignment:
[[ 9.99528250e-01 -3.07127532e-02  6.32727881e-05]
 [ 3.07127431e-02  9.99528240e-01  1.55148469e-04]
 [-6.80079752e-05 -1.53131997e-04  9.99999986e-01]]
Translation of alignment:
[19.94065242  5.7381364   5.37494616]
Scale correction: 1.0
--------------------------------------------------------------------------------
Compared 587 absolute pose pairs.
Calculating APE for translation part pose relation...
--------------------------------------------------------------------------------
APE w.r.t. translation part (m)
(with SE(3) Umeyama alignment)

       max	0.143044
      mean	0.082941
    median	0.076755
       min	0.051445
      rmse	0.085677
       sse	4.308874
       std	0.021479

--------------------------------------------------------------------------------
Plotting results... 

在这里插入图片描述

在这里插入图片描述

==提示:==如果画的轨迹不对,关闭终端重新打开再输入。或者把之前的数据删除,比如 imu_pose_noise.txt 和 pose_output_with_noise.txt

5.2 改为中等的噪声

建议把之前的数据 imu_pose_noise.txt 和 pose_output_with_noise.txt 删除,重新生成。

(1)修改vio_data_simulation/src/param.h里的噪声部分

    // medium  noise
    double gyro_bias_sigma = 5.0e-6;    //陀螺仪的 bias 随机游走噪声
    double acc_bias_sigma = 0.00005;    //加速度 bias 的随机游走噪声

    double gyro_noise_sigma = 0.0075;    // rad/s * 1/sqrt(hz)  陀螺仪的高斯白噪声
    double acc_noise_sigma = 0.0095;      // m/(s^2) * 1/sqrt(hz)  加速度的高斯白噪声

(2)运行vio_data_simulation工程

(3)运行VINS-Course工程

(4)在目录VINS-Course/bin 下打开终端进行对比

(5)在终端输入命令

evo_ape tum cam_pose_tum.txt pose_output_with_noise.txt -va --plot --plot_mode xyz --save_results with_noise_medium.zip

(6)结果:

cgm@ubuntu:~/VINS-Course/bin$ evo_ape tum cam_pose_tum.txt pose_output_with_noise.txt -va --plot --plot_mode xyz --save_results with_noise_medium.zip
--------------------------------------------------------------------------------
Loaded 600 stamps and poses from: cam_pose_tum.txt
Loaded 587 stamps and poses from: pose_output_with_noise.txt
--------------------------------------------------------------------------------
Synchronizing trajectories...
Found 587 of max. 587 possible matching timestamps between...
	cam_pose_tum.txt
and:	pose_output_with_noise.txt
..with max. time diff.: 0.01 (s) and time offset: 0.0 (s).
--------------------------------------------------------------------------------
Aligning using Umeyama's method...
Rotation of alignment:
[[ 9.99477227e-01 -3.23186345e-02 -8.82261297e-04]
 [ 3.23234921e-02  9.99458238e-01  6.19858381e-03]
 [ 6.81453557e-04 -6.22386113e-03  9.99980399e-01]]
Translation of alignment:
[19.69164372  6.83792945  5.06506652]
Scale correction: 1.0
--------------------------------------------------------------------------------
Compared 587 absolute pose pairs.
Calculating APE for translation part pose relation...
--------------------------------------------------------------------------------
APE w.r.t. translation part (m)
(with SE(3) Umeyama alignment)

       max	1.257529
      mean	0.634277
    median	0.652913
       min	0.217522
      rmse	0.663024
       sse	258.045365
       std	0.193115

--------------------------------------------------------------------------------
Plotting results... 

在这里插入图片描述
在这里插入图片描述

5.3 改为更大的噪声

建议把之前的数据 imu_pose_noise.txt 和 pose_output_with_noise.txt 删除,重新生成。

(1)修改vio_data_simulation/src/param.h里的噪声部分

    // larger  noise
    double gyro_bias_sigma = 1.0e-5;    //陀螺仪的 bias 随机游走噪声
    double acc_bias_sigma = 0.0001;     //加速度 bias 的随机游走噪声

    double gyro_noise_sigma = 0.015;    // rad/s * 1/sqrt(hz)  陀螺仪的高斯白噪声
    double acc_noise_sigma = 0.019;      // m/(s^2) * 1/sqrt(hz)  加速度的高斯白噪声

(2)运行vio_data_simulation工程

(3)运行VINS-Course工程

(4)在目录VINS-Course/bin 下打开终端进行对比

(5)在终端输入命令

evo_ape tum cam_pose_tum.txt pose_output_with_noise.txt -va --plot --plot_mode xyz --save_results with_noise_larger.zip

(6)结果:

cgm@ubuntu:~/VINS-Course/bin$ evo_ape tum cam_pose_tum.txt pose_output_with_noise.txt -va --plot --plot_mode xyz --save_results with_noise_larger.zip
--------------------------------------------------------------------------------
Loaded 600 stamps and poses from: cam_pose_tum.txt
Loaded 587 stamps and poses from: pose_output_with_noise.txt
--------------------------------------------------------------------------------
Synchronizing trajectories...
Found 587 of max. 587 possible matching timestamps between...
	cam_pose_tum.txt
and:	pose_output_with_noise.txt
..with max. time diff.: 0.01 (s) and time offset: 0.0 (s).
--------------------------------------------------------------------------------
Aligning using Umeyama's method...
Rotation of alignment:
[[ 0.99155227 -0.10602052  0.07472451]
 [ 0.09982098  0.99159396  0.08232364]
 [-0.08282437 -0.07416912  0.99380031]]
Translation of alignment:
[17.64534845 13.25170598  7.44484511]
Scale correction: 1.0
--------------------------------------------------------------------------------
Compared 587 absolute pose pairs.
Calculating APE for translation part pose relation...
--------------------------------------------------------------------------------
APE w.r.t. translation part (m)
(with SE(3) Umeyama alignment)

       max	10.887888
      mean	6.548863
    median	5.900705
       min	4.079211
      rmse	6.794114
       sse	27095.909198
       std	1.808969

--------------------------------------------------------------------------------
Plotting results... 

在这里插入图片描述

在这里插入图片描述

6.可视化总结

在这里插入图片描述

结论:可以看到设置的imu噪声越大通过vins估计出来的轨迹结果越差

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

楚歌again

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值