- 内容总结:
- 内容:
IMU原理与模型
后端优化与VIO BA
滑动窗口算法与FEJ
后端求解系统与代码
前端介绍
VIO初始化
VIO系统回顾
- 预备知识:
数学:线性代数、微积分、概率论
编程:Linux、C++、OpenCV
英语:文献阅读
专业知识:2D/3D 计算机视觉、图像处理
- VIO 概述
- VIO:
以视觉与IMU融合实现的里程计
IMU:惯性测量单元
组成:陀螺仪和加速度计,共6轴。
较高频率(>100Hz),易受自身温度、零偏、振动等因素干扰,积分得到的平移与旋转容易漂移。
视觉:
较低频率(15-60Hz居多),通过相机特整点进行匹配,推断相机运动。
- 2种传感器比较:

- 两种融合方案
- 紧耦合:直接将图像的特征匹配点与IMU定位,进行融合。典型方案为MSCKF和非线性优化。
- 松耦合:将IMU定位与视觉定位,直接进行融合。后处理方式输出。典型方案为卡尔曼滤波器。
- 紧耦合优势:视觉BA中含有IMU信息,整体层面最优。而且,可以对所有运动、测量信息进行建模,达到最优。
- 主要总结:
- IMU数据的状态信息,及噪声
- 对含有IMU测量信息和视觉特征点信息的非线性优化
- 随时间将如何变化
- 预备知识
- 三维刚体运动(2种):
- 李代数与李群
- 四元数
- 两种导数(具体推导请自行查看《SLAM十四讲》):

以上2种导数更新方式,误差相差不大。证明代码如下:
1 #include <iostream>
2 #include <cmath>
3 using namespace std;
4
5 #include <Eigen/Core>
6 #include <Eigen/Geometry>
7
8 #include "sophus/so3.h"
9 #include "sophus/se3.h"
10
11 int main( int argc, char** argv )
12 {
13 // 沿Z轴转90度的旋转矩阵
14 Eigen::Matrix3d R = Eigen::AngleAxisd(M_PI/2, Eigen::Vector3d(0,0,1)).toRotationMatrix();
15
16
17 // 四元数乘法饶动微元
18 Eigen::Matrix<double,4,1> w_q ;
19
20 w_q << 0.005,0.01,0.015,1;
21
22
23 // 李树饶动微元
24 Eigen::Vector3d w;
25
26 w << 0.01,0.02,0.03;
27
28
29 // 生成李树与四元数
30 Sophus::SO3 SO3_R(R); // Sophus::SO(3)可以直接
31 Eigen::Quaterniond q(R); // 或者四元数
32
33 cout<<"\n***********准备开始*******************\n"<<endl;
34
35 cout<<endl;
36 cout<<"R : \n"<<R<<endl;
37
38 cout<<"******************************"<<endl;
39
40 cout<<endl;
41 cout<<"SO(3) from matrix: \n"<<SO3_R<<endl;
42
43 cout<<endl;
44 cout<<"q : \n"<<q.coeffs()<<endl;
45
46 cout<<"************我是分割线*****************\n\n\n"<<endl;
47
48 // 计算饶动后的数值
49 Sophus::SO3 SO3_updated_R_left = Sophus::SO3::exp(w)*SO3_R;
50 Sophus::SO3 SO3_updated_R_right = SO3_R*Sophus::SO3::exp(w);
51
52
53 cout<<"***********R饶动的值(李树)**********"<<endl;
54 cout<<"**********R饶动的值(左)*********"<<endl;
55
56 cout<<"SO3 updated = \n"<<SO3_updated_R_left<<endl;
57
58 cout<<"**********R饶动的值(右)*********"<<endl;
59
60 cout<<"SO3 updated = \n"<<SO3_updated_R_right<<endl;
61
62 cout<<"***************************************\n\n\n"<<endl;
63
64 /********************萌萌的分割线*****************************/
65 cout<<"************我是分割线*****************"<<endl;
66
67 //计算四元数的值
68 Eigen::Quaterniond w_q_0(w_q);
69 Eigen::Quaterniond q_updated_left;
70 Eigen::Quaterniond q_updated_right;
71
72 q_updated_left = w_q_0 * q;
73 q_updated_right = q * w_q_0;
74
75 q_updated_left.normalize();
76 q_updated_right.normalize();
77
78 cout<<"***********四元数饶动的值*********\n"<<endl;
79 cout<<"***四元数饶动的值(微变量)*******"<<endl;
80
81 cout<<"w_q = \n"<<w_q_0.coeffs()<<endl;
82
83 cout<<"\n***四元数饶动的值(结果zuo)******"<<endl;
84
85 cout<<"q_updated = \n"<<q_updated_left.coeffs() <<endl;
86
87 cout<<"***四元数饶动的值(结果you)*********"<<endl;
88
89 cout<<"q_updated = \n"<<q_updated_right.coeffs()<<endl;
90
91 cout<<"***************************************\n\n\n"<<endl;
92
93 //传结果
94 cout<<"************我是分割线*****************"<<endl;
95
96 cout<<"***********jie guo*********\n"<<endl;
97
98 cout<<"***************************************"<<endl;
99
100 cout<<"李树上(左) = \n"<<SO3_updated_R_left<<endl;
101
102 cout<<"***************************************"<<endl;
103
104 cout<<"李树上(右) = \n"<<SO3_updated_R_right<<endl;
105
106
107 Sophus::SO3 SO3_q_l(q_updated_left );
108 Sophus::SO3 SO3_q_r(q_updated_right);
109
110
111 cout<<"\n***四元数饶动的值(结果zuo)******"<<endl;
112
113 cout<<"q_左 = \n"<<SO3_q_l<<endl;
114
115 cout<<"***四元数饶动的值(结果you)*********"<<endl;
116
117 cout<<"q_右 = \n"<<SO3_q_r<<endl;
118
119 cout<<"***************************************\n\n\n"<<endl;
120
121
122 return 0;
123 }
并请在CMakeList.txt添加,下面代码:
cmake_minimum_required( VERSION 2.8 )
project( useSophus )
# 为使用 sophus,您需要使用find_package命令找到它
find_package( Sophus REQUIRED )
include_directories( ${Sophus_INCLUDE_DIRS} )
add_executable( useSophus useSophus.cpp )
target_link_libraries( useSophus ${Sophus_LIBRARIES} )
以上是在cmake下,进行运行。具体自行查看cmake操作,后续会上传至,GitHub上。或,自行学习。
运行结果:

以上仅是学习之用。GitHub 地址:https://github.com/icra205
