VINS-Fusion开源代码之loop_fusion_node数据流分析
1. 源由
之前对VINS-Fusion做了简单了解,详见:《Linux 35.5 + JetPack v5.1.3@VINS-Fusion编译安装》。
为了更好的从模块化视角了解该模块功能,我们需要通过类似灰盒的角度去分析模块的数据流,以便进一步深入模块设计。
在《VINS-Fusion开源代码之vins_node数据流分析》已经对其中一个模块进行了分析,接下来研究loop_fusion_node
。
2. 方法
分析方法,请参考:《VINS-Fusion开源代码之vins_node数据流分析》。
3. 仿真分析
借助脚本和ROS系统的强大DEBUG功能,在实际执行以下模拟命令时:
- terminal 1 仿真环境
$ source ./devel/setup.sh
$ roslaunch vins vins_rviz.launch
- terminal 2 逻辑算法1 - vins_node
$ source ./devel/setup.sh
$ rosrun vins vins_node src/VINS-Fusion/config/euroc/euroc_stereo_imu_config.yaml
- terminal 3 逻辑算法2 - loop_fusion_node
$ source ./devel/setup.sh
$ rosrun loop_fusion loop_fusion_node src/VINS-Fusion/config/euroc/euroc_stereo_imu_config.yaml
- terminal 4 仿真回放
$ source ./devel/setup.sh
$ rosbag play MH/MH_04_difficult.bag
VINS-Fusion | loop_fusion_node
3.1 rostopic 清单
根据启动脚本vins_rviz.launch
,具体内容详见附录。
以及rostopic list
指令,可以清晰的看到整个环境目前所有的话题。
$ rostopic list
/cam0/image_raw
/cam1/image_raw
/clicked_point
/clock
/feature_tracker/feature
/globalEstimator/car_model
/globalEstimator/global_path
/imu0
/initialpose
/leica/position
/loop_fusion/base_path
/loop_fusion/camera_pose_visual
/loop_fusion/margin_cloud_loop_rect
/loop_fusion/match_image
/loop_fusion/match_image/mouse_click
/loop_fusion/odometry_rect
/loop_fusion/path_1
/loop_fusion/path_2
/loop_fusion/path_3
/loop_fusion/path_4
/loop_fusion/path_5
/loop_fusion/path_6
/loop_fusion/path_7
/loop_fusion/path_8
/loop_fusion/path_9
/loop_fusion/point_cloud_loop_rect
/loop_fusion/pose_graph
/loop_fusion/pose_graph_path
/move_base_simple/goal
/rosout
/rosout_agg
/tf
/tf_static
/vins_cam_switch
/vins_estimator/camera_pose
/vins_estimator/camera_pose_visual
/vins_estimator/extrinsic
/vins_estimator/image_track
/vins_estimator/image_track/mouse_click
/vins_estimator/imu_propagate
/vins_estimator/key_poses
/vins_estimator/keyframe_point
/vins_estimator/keyframe_pose
/vins_estimator/margin_cloud
/vins_estimator/odometry
/vins_estimator/path
/vins_estimator/point_cloud
/vins_imu_switch
/vins_restart
3.2 rosbag 输入
仿真数据在回放过程,将会向系统注入以下topic:
- /imu0
- /cam0/image_raw
- /cam1/image_raw
- /leica/position
$ rosbag info MH/MH_04_difficult.bag
path: MH/MH_04_difficult.bag
version: 2.0
duration: 1:42s (102s)
start: Jun 25 2014 03:28:47.33 (1403638127.33)
end: Jun 25 2014 03:30:29.91 (1403638229.91)
size: 1.4 GB
messages: 25855
compression: none [1356/1356 chunks]
types: geometry_msgs/PointStamped [c63aecb41bfdfd6b7e1fac37c7cbe7bf]
sensor_msgs/Image [060021388200f6f0f447d0fcd9c64743]
sensor_msgs/Imu [6a62c6daae103f4ff57a132d6f95cec2]
topics: /cam0/image_raw 2033 msgs : sensor_msgs/Image
/cam1/image_raw 2032 msgs : sensor_msgs/Image
/imu0 20320 msgs : sensor_msgs/Imu
/leica/position 1470 msgs : geometry_msgs/PointStamped
数据格式详见:
$ rosmsg show geometry_msgs/PointStamped
std_msgs/Header header
uint32 seq
time stamp
string frame_id
geometry_msgs/Point point
float64 x
float64 y
float64 z
daniel@daniel-nvidia:~/ego-planner$ rosmsg show sensor_msgs/Imu
std_msgs/Header header
uint32 seq
time stamp
string frame_id
geometry_msgs/Quaternion orientation
float64 x
float64 y
float64 z
float64 w
float64[9] orientation_covariance
geometry_msgs/Vector3 angular_velocity
float64 x
float64 y
float64 z
float64[9] angular_velocity_covariance
geometry_msgs/Vector3 linear_acceleration
float64 x
float64 y
float64 z
float64[9] linear_acceleration_covariance
$ rosmsg show geometry_msgs/PointStamped
std_msgs/Header header
uint32 seq
time stamp
string frame_id
geometry_msgs/Point point
float64 x
float64 y
float64 z
$ rosmsg show sensor_msgs/Image
std_msgs/Header header
uint32 seq
time stamp
string frame_id
uint32 height
uint32 width
string encoding
uint8 is_bigendian
uint32 step
uint8[] data
4. 代码分析
4.1 启动入口
算法逻辑代码启动过程如下:
rosrun loop_fusion loop_fusion_node src/VINS-Fusion/config/euroc/euroc_stereo_imu_config.yaml
└──> loop_fusion/loop_fusion_node/loop_fusion
└──> VINS-Fusion\loop_fusion\src\pose_graph_node.cpp (main)
4.2 配置文件
配置文件中含有各类数据,包括输入的topic路径:
VINS-Fusion/config/euroc/euroc_stereo_imu_config.yaml
├──> "/imu0"
├──> "/cam0/image_raw"
├──> "/cam1/image_raw"
├──> "cam0_mei.yaml"
├──> "cam1_mei.yaml"
└──> "~/output/pose_graph/"
../support_files/brief_k10L6.bin
../support_files/brief_pattern.yml
4.3 业务数据流
loop_fusion/loop_fusion_node/loop_fusion
+---------------------------+
INT.1 "/vins_estimator/odometry" ---> | vio_callback --|---+
INT.2 "/cam0/image_raw" ---> | image_callback --|---|---+
INT.3 "/vins_estimator/keyframe_pose" ---> | pose_callback | | |
INT.4 "/vins_estimator/extrinsic" ---> | extrinsic_callback | | |
INT.5 "/vins_estimator/keyframe_point" ---> | point_callback --|---|---|---+
INT.6 "/vins_estimator/margin_cloud" ---> | margin_point_callback--|---|---|---|---+
| process --|---|---|---|---|---+
+---------------------------+ | | | | |
| | | | |
| | | | |
| | | | |
OUT <------------+ | | | |
├──> OUT.6 visualization_msgs::MarkerArray "camera_pose_visual" | | | |
└──> OUT.9 nav_msgs::Odometry "odometry_rect" | | | |
| | | |
OUT <------------------------------------------+ | | |
├──> OUT.1 nav_msgs::Path "pose_graph_path" | | |
├──> OUT.2 nav_msgs::Path "base_path" | | |
├──> OUT.3 visualization_msgs::MarkerArray "pose_graph" | | |
└──> OUT.4 nav_msgs::Path "path_1..9" | | |
| | |
OUT.7 sensor_msgs::PointCloud "point_cloud_loop_rect" <-------------------------+ | |
| |
OUT.8 sensor_msgs::PointCloud "margin_cloud_loop_rect" <-----------------------------+ |
|
OUT.5 sensor_msgs::Image "match_image" <---------------------------------+
5. vins_node + loop_fusion_node 总流程图
vins_node loop_fusion_node
+-------------------------------------+
| +---------------------------+ | +--------------------------+
IN.1 "/imu0" ----|--> | imu_callback | +----------------------------------------------> | image_callback |
IN.2 "/feature_tracker/feature" ----|--> | feature_callback -------|---+-- nav_msgs::Odometry "odometry" -------------> | vio_callback |
IN.3 "/cam0/image_raw" ----+--> | img0_callback ----+ | +-- nav_msgs::Odometry "keyframe_pose" --------> | pose_callback | ===> rviz
IN.4 "/cam1/image_raw" -------> | img1_callback ----+ | +-- sensor_msgs::PointCloud "margin_cloud" ---> | margin_point_callback | ^
IN.5 "/vins_restart" -------> | restart_callback | | +-- nav_msgs::Odometry "extrinsic" -----------> | extrinsic_callback | |
IN.6 "/vins_imu_switch" -------> | imu_switch_callback | | +-- sensor_msgs::PointCloud "keyframe_point" --> | point_callback | |
IN.7 "/vins_cam_switch" -------> | cam_switch_callback | | | +--------------------------+ |
| sync_process <-----+ | +-------------------------------------------------------------------------------->+
| | | |
| +-------------------|------ sensor_msgs::Image "image_track" ---------------------------------------------+
+---------------------------+
6. 附录
6.1 loop_fusion_node 本地文件
"~/output/vio_loop.csv"
"~/output/pose_graph/i_briefdes.dat"
"~/output/pose_graph/i_keypoints.txt"
"~/output/pose_graph/pose_graph.txt"
6.2 vins_node 数据流
vins/vins_node/vins_estimator
+---------------------------+
IN.1 "/imu0" ---> | imu_callback -------|--+
IN.2 "/feature_tracker/feature" ---> | feature_callback -------|--|--+
IN.3 "/cam0/image_raw" ---> | img0_callback ----+ | | |
IN.4 "/cam1/image_raw" ---> | img1_callback ----+ | | |
IN.5 "/vins_restart" ---> | restart_callback | | | |
IN.6 "/vins_imu_switch" ---> | imu_switch_callback | | | |
IN.7 "/vins_cam_switch" ---> | cam_switch_callback | | | |
| sync_process <-----+ | | |
| | | | |
| +-------------------|--|--|--+
+---------------------------+ | | |
| | |
OUT.1 nav_msgs::Odometry "imu_propagate" <-----------------------------+ | |
| |
OUT <--------------------------------------------------------------------+ |
├──> pubOdometry |
│ ├──> OUT.2 nav_msgs::Path> "path" |
│ ├──> OUT.3 nav_msgs::Odometry "odometry" |
│ └──> "~/output/pose_graph/vio.csv" |
├──> pubKeyPoses |
│ └──> OUT.6 visualization_msgs::Marker "key_poses" |
├──> pubCameraPose |
│ ├──> OUT.7 nav_msgs::Odometry "camera_pose" |
│ └──> OUT.8 visualization_msgs::MarkerArray "camera_pose_visual" |
├──> pubPointCloud |
│ ├──> OUT.4 sensor_msgs::PointCloud "point_cloud" |
│ └──> OUT.5 sensor_msgs::PointCloud "margin_cloud" |
├──> pubKeyframe |
│ ├──> OUT.9 nav_msgs::Odometry "keyframe_pose" |
│ └──> OUT.10 sensor_msgs::PointCloud "keyframe_point" |
└──> pubTF |
└──> OUT.11 nav_msgs::Odometry "extrinsic" |
|
OUT.12 sensor_msgs::Image "image_track" <-----------------------------------+