机器人控制器开发(定位——cartographer ros2 使用1)
文章总览
1 构建编译
安装系统依赖
sudo apt update
sudo apt install -y \cmake \g++ \git \libgoogle-glog-dev \libgflags-dev \libatlas-base-dev \libeigen3-dev \libsuitesparse-dev \libtool \autoconf \automake \zlib1g-dev
下载abseil-cpp, protobuf,ceres-solver,cartographer 链接
下载 cartographer_ros,https://github.com/ros2/cartographer_ros
遇到的问题和处理过程记录:
(1)运行时报错:Cartographer collect_metrics标志重复定义问题分析与解决

(2)编译时如下错误:
--- stderr: cartographer_ros
In file included from /home/cat/cartographer_ws/install/cartographer/include/cartographer/transform/transform.h:26,from /home/cat/cartographer_ws/install/cartographer/include/cartographer/sensor/rangefinder_point.h:24,from /home/cat/cartographer_ws/install/cartographer/include/cartographer/sensor/point_cloud.h:24,from /home/cat/cartographer_ws/install/cartographer/include/cartographer/sensor/compressed_point_cloud.h:25,from /home/cat/cartographer_ws/install/cartographer/include/cartographer/sensor/range_data.h:21,from /home/cat/cartographer_ws/install/cartographer/include/cartographer/mapping/trajectory_node.h:27,from /home/cat/cartographer_ws/install/cartographer/include/cartographer/mapping/submaps.h:30,from /home/cat/cartographer_ws/install/cartographer/include/cartographer/mapping/pose_graph_interface.h:25,from /home/cat/cartographer_ws/install/cartographer/include/cartographer/mapping/map_builder_interface.h:29,from /home/cat/cartographer_ws/src/cartographer_ros/cartographer_ros/include/cartographer_ros/node.h:29,from /home/cat/cartographer_ws/src/cartographer_ros/cartographer_ros/src/node.cpp:17:
/home/cat/cartographer_ws/install/cartographer/include/cartographer/transform/rigid_transform.h: In instantiation of ‘cartographer::transform::Rigid2<FloatType>::Rotation2D cartographer::transform::Rigid2<FloatType>::rotation() const [with FloatType = double; cartographer::transform::Rigid2<FloatType>::Rotation2D =
解决方案:
重新编译 Protobuf 并启用 fPIC
# 进入 protobuf 源码目录(假设你已经下载了源码)
cd /path/to/protobuf-source# 清理之前的编译
make clean
rm -rf build# 创建新的构建目录
mkdir build && cd build# 配置时启用 fPIC
cmake -DCMAKE_POSITION_INDEPENDENT_CODE=ON -Dprotobuf_BUILD_TESTS=OFF ..# 编译和安装
make -j4
sudo make install
2 配置2D SLAM 模式
修改backpack_2d.launch.py
def generate_launch_description():## ***** Launch arguments *****use_sim_time_arg = DeclareLaunchArgument('use_sim_time', default_value = 'False')cartographer_node = Node(package='cartographer_ros',executable='cartographer_node',name='cartographer_node',output='screen',parameters=[{'use_sim_time': LaunchConfiguration('use_sim_time'),'tf_buffer_cache_time': 10.0 # ⬅️ 增加 TF 缓存时间,避免 Rviz 丢帧}],arguments=['-configuration_directory',PathJoinSubstitution([FindPackageShare('cartographer_ros'),'configuration_files']),'-configuration_basename','backpack_2d.lua','--save_state_filename', '/home/cat/map/map.pbstream'],remappings=[('/scan', '/scan') # ⬅️ 激光话题 remap,左边是 cartographer 默认订阅的,右边是实际发布的])cartographer_occupancy_grid_node = Node(package = 'cartographer_ros',executable = 'cartographer_occupancy_grid_node',parameters = [{'use_sim_time': True},{'resolution': 0.05}],)return LaunchDescription([use_sim_time_arg,cartographer_node,cartographer_occupancy_grid_node,])
修改配置文件中的lua脚本
include "map_builder.lua"
include "trajectory_builder.lua"options = {map_builder = MAP_BUILDER,trajectory_builder = TRAJECTORY_BUILDER,map_frame = "map",tracking_frame = "base_link",published_frame = "base_link",odom_frame = "odom",provide_odom_frame = true,publish_frame_projected_to_2d = true,use_pose_extrapolator = true,use_odometry = false,use_nav_sat = false,use_landmarks = false,num_laser_scans = 1,num_multi_echo_laser_scans = 0,num_subdivisions_per_laser_scan = 1,num_point_clouds = 0,lookup_transform_timeout_sec = 0.2,submap_publish_period_sec = 0.3,pose_publish_period_sec = 5e-3,trajectory_publish_period_sec = 30e-3,rangefinder_sampling_ratio = 1.,odometry_sampling_ratio = 1.,fixed_frame_pose_sampling_ratio = 1.,imu_sampling_ratio = 1.,landmarks_sampling_ratio = 1.,
}MAP_BUILDER.use_trajectory_builder_2d = true
TRAJECTORY_BUILDER_2D.num_accumulated_range_data = 10TRAJECTORY_BUILDER_2D.use_imu_data = false -- 纯雷达,关闭 IMU
TRAJECTORY_BUILDER_2D.num_accumulated_range_data = 2 -- 累积 2 帧雷达数据
TRAJECTORY_BUILDER_2D.min_range = 0.3 -- 避免近距离虚假点
TRAJECTORY_BUILDER_2D.max_range = 30.0
TRAJECTORY_BUILDER_2D.missing_data_ray_length = 30.0
TRAJECTORY_BUILDER_2D.use_online_correlative_scan_matching = true -- 提高匹配精度-- motion filter: 插入扫描的阈值(降低阈值让每帧扫描都能被使用)
TRAJECTORY_BUILDER_2D.motion_filter.max_angle_radians = math.rad(0.1)
TRAJECTORY_BUILDER_2D.motion_filter.max_distance_meters = 0.1
TRAJECTORY_BUILDER_2D.motion_filter.max_time_seconds = 0.5-- 子图配置
TRAJECTORY_BUILDER_2D.submaps.num_range_data = 90 -- 每个子图包含 90 帧雷达
TRAJECTORY_BUILDER_2D.submaps.grid_options_2d.resolution = 0.02 -- 子图分辨率 2cmreturn options
3 保存地图
在SLAM模式中,机器人完成建图时,需要保存地图。
在cartographer_node中添加’–save_state_filename’, '/home/cat/map/map.pbstream’配置。当结束建图时,地图会自动保存好。
cartographer_node = Node(package='cartographer_ros',executable='cartographer_node',name='cartographer_node',output='screen',parameters=[{'use_sim_time': LaunchConfiguration('use_sim_time'),'tf_buffer_cache_time': 10.0 # ⬅️ 增加 TF 缓存时间,避免 Rviz 丢帧}],arguments=['-configuration_directory',PathJoinSubstitution([FindPackageShare('cartographer_ros'),'configuration_files']),'-configuration_basename','backpack_2d.lua','--save_state_filename', '/home/cat/map/map.pbstream'],remappings=[('/scan', '/scan') # ⬅️ 激光话题 remap,左边是 cartographer 默认订阅的,右边是实际发布的])
注意事项:开始写的是’~/map/map.pbstream’,会报错:
Check failed: map_builder_bridge_->SerializeState(filename, include_unfinished_submaps) Could not write state.
然后我改为 绝对路径后,报错便修复了。
