本文档用于VINS-Mono的代码学习与记录,主要参考博客VINS-Mono代码解读——启动文件launch与参数配置文件yaml介绍
一、启动文件launch
位置:VINS-Mono/vins_estimator/launch
//launch文件中的根元素采用标签定义
<launch>
//<arg>是launch文件中的局部变量,仅限于launch使用
//设置局部变量"config_path",表示euroc_config.yaml具体地址
//设置局部变量"vins_path",在parameters.cpp中使用鱼眼相机mask中会用到
//.yaml一般用于编写配置文件
<arg name="config_path" default = "$(find feature_tracker)/../config/euroc/euroc_config.yaml" />
<arg name="vins_path" default = "$(find feature_tracker)/../config/../" />
//<node>是启动节点,pkg是文件所在的包名,type是可执行文件名,output是输出
//启动feature_tracker节点,该节点中需要读取参数文件,地址为config_file,即config_path
<node name="feature_tracker" pkg="feature_tracker" type="feature_tracker" output="log">
//<param>是设置ROS系统运行的参数,存储在参数服务器中
//name是输出框架,type是输出形式,value是??????
<param name="config_file" type="string" value="$(arg config_path)" />
<param name="vins_folder" type="string" value="$(arg vins_path)" />
</node>
//启动vins_estimator节点
<node name="vins_estimator" pkg="vins_estimator" type="vins_estimator" output="screen">
<param name="config_file" type="string" value="$(arg config_path)" />
<param name="vins_folder" type="string" value="$(arg vins_path)" />
</node>
//启动posr_graph节点,除了参数配置文件的地址外还设置了4个参数
<node name="pose_graph" pkg="pose_graph" type="pose_graph" output="screen">
<param name="config_file" type="string" value="$(arg config_path)" />
//visualization_shift_x和visualization_shift_y表示在进行位姿图优化后,对得到的位姿在x坐标和y坐标的偏移量(一般都设为0)
<param name="visualization_shift_x" type="int" value="0" />
<param name="visualization_shift_y" type="int" value="0" />
//skip_cnt在pose_graph_node的process()中,表示每隔skip_cnt个图像帧才进行一次处理;
<param name="skip_cnt" type="int" value="0" />
//skip_dis也在pose_graph_node的process()中,目的是将距上一帧的时间间隔超过SKIP_DIS的图像创建为位姿图中的关键帧
<param name="skip_dis" type="double" value="0" />
</node>
</launch>
二、参数配置文件yaml
位置:VINS-Mono-master\config\euroc
%YAML:1.0
//通用参数
#common parameters
//在节点/vins_estimator中被订阅,进行IMU预积分
imu_topic: "/imu0"
//在节点/fature_tracker中被订阅,进行角点的光流跟踪
image_topic: "/cam0/image_raw"
//输出文件的地址,输出内容为VINS的运行轨迹"/vins_result_no_loop.csv"与"/vins_result_loop.csv",
//相机与IMU的外参估计 “/extrinsic_parameter.csv”(如果estimate_extrinsic不为0即需要对外参进行估计的话)
//如果文件夹不存在则不输出
output_path: "/home/shaozu/output/"
//相机基础信息
//相机内参数应当根据建议进行标定获得较准确结果,降低调参难度
#camera calibration
//相机模型:PINHOLE(针孔相机)、KANNALA_BRANDT(一种常用的鱼眼相机模型)等
model_type: PINHOLE
camera_name: camera
//图像的高和宽
image_width: 752
image_height: 480
//相机的畸变系数(如果是鱼眼相机还要求mu、mv、u0、v0)
distortion_parameters:
k1: -2.917e-01
k2: 8.228e-02
p1: 5.333e-05
p2: -1.578e-04
//相机的内参
projection_parameters:
fx: 4.616e+02
fy: 4.603e+02
cx: 3.630e+02
cy: 2.481e+02
//IMU和相机之间的外参
//注意旋转矩阵ric和平移向量tic都是表示从camera坐标系到IMU坐标系变换
//外参对于VINS输出的精度和鲁棒性影响很大,尤其是初始化阶段,如果外参不准确,会有很大偏差,所以最好进行手眼标定,即直接用工具尺测量。
# Extrinsic parameter between IMU and Camera.
//为0表示外参准确,后续不需要再优化
//为1表示外参是估计值,后续需要将其作为初始值放入非线性优化中
//为2表示不知道外参,需要进行标定,在estimator.cpp的函数processImage()中调用了CalibrationExRotation()进行外参标定
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.0148655429818, -0.999880929698, 0.00414029679422,
0.999557249008, 0.0149672133247, 0.025715529948,
-0.0257744366974, 0.00375618835797, 0.999660727178]
//#Translation from camera frame to imu frame, imu^T_cam
extrinsicTranslation: !!opencv-matrix
rows: 3
cols: 1
dt: d
data: [-0.0216401454975,-0.064676986768, 0.00981073058949]
//在节点/feature_traker中需要用到的参数
#feature traker paprameters
//进行特征光流跟踪时保持特征点的数量,具体在FeatureTracker::readImage(),通过当前帧成功跟踪的特征点数,
//计算是否需要提取新的特征点,如果需要则通过goodFeaturesToTrack()提取。
//max_cnt值增大在一定条件下会提高跟踪的鲁棒性(但在环境特征本来就不丰富的地方反而会提取不够鲁棒的特征点),但是会增加之后所有算法的运算时间
max_cnt: 150 # max feature number in feature tracking
//min_dist为两个相邻特征之间像素的最小间隔,目的是保证图像中均匀的特征分布。
//在FeatureTracker::setMask()中应用,该函数的作用是对跟踪点进行排序并去除密集点。
//min_dist的实现原理是在mask中将当前特征点周围半径为MIN_DIST的区域设置为0,后面便不再选取该区域内的点。
//这个参数取大一些,比如30,可以保证图像的特征点分布非常均匀,有利于图像全局的光流跟踪;如果在特征明显的场合下可以适当取小一些,保证跟踪的特征都聚集在特征明显的地方
min_dist: 30 # min distance between two features
//freq控制图像跟踪的发布频率。在回调函数img_callback()中应用,通过判断间隔时间内的发布次数控制发布频率。一般根据相机的运行速度以及其他参数调完后的实时运行情况进行调整。
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为ransac算法的门限值,在FeatureTracker::rejectWithF()通过计算基本矩阵去除图像特征跟踪的外点时使用,一般不修改
F_threshold: 1.0 # ransac threshold (pixel)
//show_track:将经过特征跟踪的图像进行发布,需要。
show_track: 1 # publish tracking image as topic
//equalize: 如果图像整体太暗或者太亮则需要进行直方图均衡化,
//在FeatureTracker::readImage()中进行自适应直方图均衡化,需要
equalize: 1 # if image is too dark or light, trun on equalize to find enough features
//fisheye:鱼眼相机一般需要圆形的mask,以去除外部噪声点。mask图在config文件夹中。
fisheye: 0 # if using fisheye, trun on it. A circle mask will be loaded to remove edge noisy points
//在节点/vins_estimator中需要用到的参数
#optimization parameters
//max_solver_time和max_num_iterations分别定义了ceres优化器的最大迭代时间和最大迭代次数,以保证实时性。
//在Estimator::optimization()中使用,并根据不同的边缘化方案而有改变。
//ceres是一个非线性优化问题的数值求解器
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定义了关键帧的选择阈值。
//在FeatureManager::addFeatureCheckParallax()中通过计算每一个点跟踪次数和它在次新帧和次次新帧间的视差确定是否是关键帧。这个参数影响着算法中关键帧的个数。
//其中keyframe_parallax为像素坐标系,MIN_PARALLAX为归一化相机坐标系。
keyframe_parallax: 10.0 # keyframe selection threshold (pixel)
//IMU参数
//因为在进行IMU预积分时我们假设传感器的噪声noise服从高斯分布,偏置bias的导数服从高斯分布。
//这部分的参数对结果的精度有一定影响,建议读取IMU的datasheet中具体参数或者进行IMU标定直接确定,以降低之后调参的难度。
#imu parameters The more accurate parameters you provide, the better performance
//加速度计噪声标准差
acc_n: 0.08 # accelerometer measurement noise standard deviation. #0.2 0.04
//陀螺仪噪声标准差
gyr_n: 0.004 # gyroscope measurement noise standard deviation. #0.05 0.004
//加速度计随机偏差噪声标准差
acc_w: 0.00004 # accelerometer bias random work noise standard deviation. #0.02
//陀螺仪随即偏差噪声标准差
gyr_w: 2.0e-6 # gyroscope bias random work noise standard deviation. #4.0e-5
//重力加速度大小
g_norm: 9.81007 # gravity magnitude
//闭环的参数
#loop closure parameters
//开启或关闭闭环
loop_closure: 1 # start loop closure
//load_previous_pose_graph 为新功能:地图重用,通过载入先前的位姿图文件实现。
load_previous_pose_graph: 0 # load and reuse previous pose graph; load from 'pose_graph_save_path'
//fast_relocalization常用于高实时性或者地图非常大、持续时间长的地方,得到的结果精度会降低。一般实验时先不打开。
fast_relocalization: 0 # useful in real-time and large project
pose_graph_save_path: "/home/shaozu/output/pose_graph/" # save and load path
//在线时差较准
//这是VINS的新功能:因为大多数相机和IMU不是时间同步的,所以将estimate_td设置为1可以在线估计相机和IMU之间的时间差。
//参数td在Estimator::optimization()里放在视觉残差函数中进行非线性优化
#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)
//卷帘相机的支持
//是VINS的新功能:将rolling_shutter设置为0表示全局曝光相机;设置为1表示卷帘曝光相机,此时需要从传感器的datasheet中得到rolling_shutter_tr的值。
//不要使用网络摄像头webcam,不适合用。
#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).
//RVIZ可视化参数
//其中visualize_imu_forward在pose_graph_node中的imu_forward_callback()即imu前向递推的回调函数中用到,如果为1则接收IMU前向递推的角度预测值,经回环的偏移矫正并转换为世界坐标系下的相机姿态,发布;为0则什么都不做,不发布。
#visualization parameters
//保存在位姿图中的图像,为0则关闭
save_image: 1 # save image in pose graph for visualization prupose; you can close this function by setting 0
//输出IMU前向递推的角度预测值,一般用于低延迟和高频率的应用要求下
visualize_imu_forward: 0 # output imu forward propogation to achieve low latency and high frequence results
//在RVIZ显示中相机模型的大小
visualize_camera_size: 0.4 # size of camera marker in RVIZ
三、总注意点:
拿到一个新的相机-IMU组件,在安装对应的驱动和ROS包后,首先需要对yaml文件的传感器信息部分进行以下修改(这部分信息尽可能准确):
1、确定相机和IMU各自发布的topic;
2、标定相机、IMU的内参,从相机到IMU的外参;
3、是否是硬件时间同步,如果不是的话需要进行在线同步时差估计;
4、相机是卷帘曝光还是全局曝光。
之后根据应用场景的要求,确定是否需要进行回环检测、快速重定位或是读取之前位姿图等功能,以及用于RVIZ可视化的参数。根据在实际场景运行后的情况再对/feature_traker和/vins_estimator中的参数进行调整,以获得较好的结果。当然这只是在实验阶段,要使其能真正落地应用,还需要进行不断的测试和优化。