slam_toolbox 编译与测试

10 编译与测试

对应源码:../slam_toolboxros2 分支,包版本 2.10.0)。
本机环境:Ubuntu 22.04 · ROS 2 Humble · CMake 3.22 · Ceres 2.0.0。

官方 ros2 分支默认对着 Jazzy / Ubuntu 24.04 / Ceres ≥ 2.1。在 Humble 上能编过,是本仓库加过兼容层,不是上游原样。系统 apt 仍是 2.6.10(launch 还不是 Lifecycle),编完必须 overlay,不要和 apt 包混用。

10.1 工作空间

colcon 在仓库根目录,不在 third_party/slam_toolbox 里直接 cmake:

1
2
3
4
5
6
slamDev/
├── src/slam_toolbox → ../third_party/slam_toolbox
├── build/ gitignore
├── install/ gitignore
├── log/ gitignore
└── third_party/slam_toolbox/ 源码(含本机 Humble 补丁)

建软链(已做过可跳过):

1
2
3
cd /home/cp/work2/slamDev
mkdir -p src
ln -sfn ../third_party/slam_toolbox src/slam_toolbox

build/ install/ log/ 已在仓库 .gitignore

10.2 依赖

ros-humble-desktop + 本机已装的求解库即可。缺包时:

1
2
3
4
5
6
7
8
9
source /opt/ros/humble/setup.bash
sudo apt update
sudo apt install -y \
libceres-dev libsuitesparse-dev liblapack-dev libomp-dev libtbb-dev \
libboost-serialization-dev libboost-filesystem-dev libboost-thread-dev \
qtbase5-dev libqt5-core5a \
ros-humble-nav2-map-server ros-humble-interactive-markers \
ros-humble-rviz-common ros-humble-rviz-default-plugins \
python3-colcon-common-extensions

或:

1
2
3
cd /home/cp/work2/slamDev
source /opt/ros/humble/setup.bash
rosdep install --from-paths src --ignore-src -r -y

核对:

本机当时
ROS Humble(/opt/ros/humble
CMake 3.22.1(不认识 CMP0167
Ceres 2.0.0(没有 autodiff_manifold.h
apt slam_toolbox 2.6.10

10.3 Humble 兼容(本树已改)

2.10 原样在 Humble 上会失败。本仓库改动如下,再编不用手改:

失败点 文件 处理
Policy CMP0167 is not known lib/karto_sdk/CMakeLists.txt if(POLICY CMP0167)SET
tf2_sensor_msgs::tf2_sensor_msgs 不存在 CMakeLists.txt Humble 头文件包,补 INTERFACE target
ceres/autodiff_manifold.h 找不到 solvers/ceres_utils.h Ceres < 2.1 走 LocalParameterization
message_filters::Subscriber 不接 LifecycleNode + SensorDataQoS slam_toolbox_common.* SLAM_TOOLBOX_HUMBLE_COMPATrmw_qos_profile_sensor_data

CMake 在 ROS_DISTRO=humble 时定义 SLAM_TOOLBOX_HUMBLE_COMPAT。换 Jazzy 编同一棵树时不要带这个宏,走上游 API。

10.4 编译

1
2
3
4
5
6
cd /home/cp/work2/slamDev
source /opt/ros/humble/setup.bash
colcon build --packages-select slam_toolbox \
--allow-overriding slam_toolbox \
--symlink-install \
--cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=ON

--allow-overriding 必须加:underlay 里已有 apt 的同名包。
C++17,CMakeLists.txt 默认 Release。首次大约 5 分钟。

只改过某个 .cpp 时同样命令即可,--symlink-install 下 launch / yaml 改完不用重编。

成功时:

1
2
Finished <<< slam_toolbox
Summary: 1 package finished

产物:

1
2
3
4
5
6
7
8
install/slam_toolbox/lib/slam_toolbox/
async_slam_toolbox_node
sync_slam_toolbox_node
localization_slam_toolbox_node
lifelong_slam_toolbox_node
map_and_localization_slam_toolbox_node
decentralized_multirobot_slam_toolbox_node
merge_maps_kinematic

库:install/slam_toolbox/lib/libtoolbox_common.solibkartoSlamToolbox.solibceres_solver_plugin.solibSlamToolboxPlugin.so

跳转定义:把 build/slam_toolbox/compile_commands.json 链到源码根(已链过可跳过):

1
2
ln -sfn /home/cp/work2/slamDev/build/slam_toolbox/compile_commands.json \
/home/cp/work2/slamDev/third_party/slam_toolbox/compile_commands.json

IDE / clangd Reload Window。

10.5 环境(overlay)

每个新终端:

1
2
source /opt/ros/humble/setup.bash
source /home/cp/work2/slamDev/install/setup.bash

确认吃到的是 2.10,不是 apt 2.6:

1
2
3
4
5
ros2 pkg prefix slam_toolbox
# 应为 /home/cp/work2/slamDev/install/slam_toolbox
# 若是 /opt/ros/humble,说明没 source overlay

ros2 pkg executables slam_toolbox

10.6 仓库自带测试

CMakeLists.txt 里 gtest 整段注释掉了colcon test --packages-select slam_toolbox 现在几乎无用例。

1
2
3
4
#if(BUILD_TESTING)
# ament_add_gtest(lifelong_metrics_test test/lifelong_metrics_test.cpp)
# ...
#endif()

test/lifelong_metrics_test.cpp 测 lifelong 的包围盒 / IoU,不是建图正确性。要跑:先取消这段注释,再:

1
2
3
4
5
6
cd /home/cp/work2/slamDev
source /opt/ros/humble/setup.bash
colcon build --packages-select slam_toolbox --allow-overriding slam_toolbox \
--cmake-args -DBUILD_TESTING=ON
colcon test --packages-select slam_toolbox
colcon test-result --verbose

test/process_constraints.py 是画「节点约束数」的离线脚本,要先在 publishGraph 里加它注释里的打印,不是 CI。

10.7 冒烟:包与节点

不接雷达,只确认 overlay 和可执行文件:

1
2
3
4
5
6
7
source /opt/ros/humble/setup.bash
source /home/cp/work2/slamDev/install/setup.bash

test "$(ros2 pkg prefix slam_toolbox)" = "/home/cp/work2/slamDev/install/slam_toolbox" && echo "overlay OK"

ros2 run slam_toolbox async_slam_toolbox_node --ros-args --params-file \
$(ros2 pkg prefix slam_toolbox)/share/slam_toolbox/config/mapper_params_online_async.yaml

Lifecycle 节点起来后停在 unconfigured(没有 launch 的 configure/activate)。另开终端:

1
2
3
4
5
source /opt/ros/humble/setup.bash
source /home/cp/work2/slamDev/install/setup.bash
ros2 lifecycle list /slam_toolbox # 或节点实际名
ros2 lifecycle set /slam_toolbox configure
# 无雷达时 activate 可能卡住等 scan/TF,Ctrl+C 结束即可

看到 CeresSolver: Using ...SlamToolbox: ... 日志,说明插件和公共层加载成功。

10.8 冒烟:launch(需要 scan + TF)

2.10 的 launch 是 Lifecycleautostart:=true 时自动 configure → activate。

最低输入:

  • /scansensor_msgs/LaserScan
  • TF odom → base_frame(默认 base_footprint,按 YAML 改)
  • 雷达相对 base 的 tf_static

仿真 / bag 记得 use_sim_time:=true,并先播 /clock

1
2
3
4
5
6
7
8
9
source /opt/ros/humble/setup.bash
source /home/cp/work2/slamDev/install/setup.bash

# 另开:ros2 bag play <bag> --clock
# 或:机器人驱动 + 雷达

ros2 launch slam_toolbox online_async_launch.py \
use_sim_time:=true \
autostart:=true

其它入口:

launch 节点 场景
online_async_launch.py async_slam_toolbox_node 在线建图(先跑这个)
online_sync_launch.py sync_slam_toolbox_node bag 回放不丢帧
localization_launch.py localization_slam_toolbox_node 已有 .posegraph
offline_launch.py sync + 离线 YAML 离线建图
merge_maps_kinematic_launch.py merge_maps_kinematic 刚体拼图,不是匹配

通过标准(async 建图):

  1. ros2 topic hz /map 有输出(有订阅者时才更新,RViz 订 /map
  2. ros2 topic echo /tf --once 里有 map → odom
  3. ros2 topic echo /pose --once 有位姿
  4. 转一圈墙角大致对齐,没有整图拧成麻花(回环阈值另见 08

存图:

1
2
3
4
5
6
7
ros2 service call /slam_toolbox/serialize_map slam_toolbox/srv/SerializePoseGraph \
"{filename: '/tmp/test_map'}"
# 生成 /tmp/test_map.posegraph 和 /tmp/test_map.data

ros2 service call /slam_toolbox/save_map slam_toolbox/srv/SaveMap \
"{name: {data: '/tmp/test_map'}}"
# 栅格,给 Nav2;和上面的位姿图不是一回事

定位模式:YAML 里填 map_file_name,或启动后再 deserialize_map。RViz 2D Pose Estimate/initialpose

10.9 对照实验(建议新手做)

改一个量,看图怎么变;比空跑 gtest 有用:

动作 预期
use_scan_matching: false 图跟着里程计漂
do_loop_closing: false 绕回起点对不齐
async 换 sync + bag 不丢帧,CPU 可能更高
不播 odom→base MessageFilter 一直等,不加节点
不 overlay,直接用 apt launch 2.6 行为,和这份源码对不上

10.10 编译失败对照

现象 原因 处理
提示加 --allow-overriding slam_toolbox apt 已占包名 加上该参数
CMP0167 is not known CMake < 3.30 确认 karto 的 if(POLICY CMP0167) 还在
tf2_sensor_msgs::... was not found Humble 无该 target 确认 CMakeLists.txt 里 INTERFACE 补丁
autodiff_manifold.h Ceres 2.0 确认 ceres_utils.h 的版本分支
Subscriber / SensorDataQoS 编译错 没带 Humble 宏 echo $ROS_DISTRO 为 humble 后再 colcon
ros2 pkg prefix 仍是 /opt/ros/humble 没 source install 先 humble 再 overlay
和系统节点抢 /mapmap→odom 同时开了 apt 节点 只留 overlay 这一份
SSH 不能跳转到定义 compile_commands.json 见 10.4,Reload Window

清掉重编:

1
2
cd /home/cp/work2/slamDev
rm -rf build/slam_toolbox install/slam_toolbox log

不要 rm -rf build 整个目录,除非没有其它包。

10.11 和二次开发的关系

  • 改 YAML / launch:--symlink-install 后直接 relaunch。
  • src/solvers/karto_sdk:按 10.4 重编,再 overlay。
  • 上实车若只用 apt 2.6.10:不要用 2.10 的 Lifecycle launch 去喂系统包。
  • 读码顺序仍见 09。编译只保证「能跑」,不代替沿 Process() 走一帧。

文章互动

阅读 --

留言

0 条留言

正在加载留言…