完整教程:机器人控制器开发(定位——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 = 10
TRAJECTORY_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 -- 子图分辨率 2cm
return 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.
然后我改为 绝对路径后,报错便修复了。

浙公网安备 33010602011771号