主要参考链接:
一. 代码框架
cartographer开源代码主要包含两个部分:casrtographer、cartographer_ros。cartographer主要负责处理来自激光雷达、IMU、里程计的数据,并基于这些数据进行地图的构建,是cartographer理论的底层实现。cartographer_ros则是基于ros的通信机制获取传感器的数据并将它们转换成cartographer中定义的格式传递给cartographer处理,与此同时也将cartographer的处理结果发布用于显示或保存,是基于cartographer的上层应用。cartographer_ros相当于对cartographer的ROS封装。
算法流程如下:
cartographer可以分为两部分:
- 前端,Local SLAM部分;该部分主要任务是建立维护Submaps,但是会随时间产生累计误差。该部分相关参数定义在
src/cartographer/configuration_files/trajectory_builder_2d.lua
和src/cartographer/configuration_files/trajectory_builder_2d.lua
中。 - 后端,Global SLAM部分;该部分主要进行回环检测以及后端优化。回环检测本质上也是一个优化问题,文中将其表达成
pixel-accurate match
形式,采用Branch-and-Bound Approach(BBA)方法来解决。
cartographer运行是两个比较重要的节点:
- cartographer_node 订阅传感器数据,生成submap_list
|==@订阅的topic |----------scan (sensors_msgs/LaserScan) 激光传感器数据 |----------echoes (sensors_msgs/MultiEchoLaserScan) 超声波数据 |----------points2 (sensors_msgs/PointCloud2) 点云数据 |----------imu (sensors_msgs/Imu) IMU数据 |----------odom (nav_msgs/Odometry) 里程计数据 |==@发布的topic |----------scan_matched_points2 (sensors_msgs/PointCloud2) 匹配好的点云数据,用来scan-to-submap matching |----------submap_list (cartographer_ros_msgs/SubmapList) 发布构建好的submap |==@提供的Service |----------submap_query (cartographer_ros_msgs/SubmapQuery) 可以提供查询submap的服务,获取到查询的submap |----------start_trajectory (cartographer_ros_msgs/StartTrajectory) 维护一条轨迹 |----------finish_trajectory (cartographer_ros_msgs/FinishTrajectory) 结束一条给定ID的轨迹 |----------write_state (cartographer_ros_msgs/WriteState) 将当前状态写入磁盘文件中 |----------get_trajectory_states (cartographer_ros_msgs/GetTrajectoryStates) 获取指定trajectory的状态 |----------read_metrics (cartographer_ros_msgs/ReadMetrics)
- cartographer_occupancy_grid 订阅submap_list,生成栅格地图
cartographer_node节点的入口函数 /cartographer_ros/cartographer_ros/node_main.cc