资讯详情

资讯详情

ROS1与ROS2双平台洞穴建图方案:传感器选型与多包融合实战

洞穴建图属于“看起来不复杂落地全是坑”的典型场景。洞穴内没有 GPS 信号光照条件差地面碎石多、坡度起伏大轮式底盘打滑之后里程计马上漂移单靠编码器根本撑不住长距离定位。更麻烦的是洞穴环境往往无法提前做高精地图机器人的实时定位和建图必须同时进行。所以洞穴建图不是选一个 SLAM 算法就行而是要解决传感器选型、硬件固定、时间同步、ROS 版本适配、数据回放、多包融合建图这一整条链路。这次我们来看一套基于 ROS1 与 ROS2 双平台的洞穴建图方案。它会先说明洞穴环境下传感器该如何搭配再分别给出 ROS1 Noetic 和 ROS2 Humble 两套环境的搭建与启动方式然后重点演示数据采集、bag 回放建图、多包批量建图和地图导出。文章后面还会给出常见的漂移、时间不同步、坐标系错误、内存不足等问题的排查清单。读完这篇文章你可以直接对照自己的机器人平台做环境配置不需要先把整个 SLAM 原理啃完。文章核心是解决“能不能跑起来”和“建出来的图能不能用”两个问题。1. 核心能力速览能力项说明项目类型洞穴环境机器人建图技术方案覆盖 ROS1 与 ROS2 双版本主要功能多传感器融合实时建图、bag 离线建图、多包批量建图、地图导出与导航适配推荐传感器3D 激光雷达如 Livox、Velodyne 系列、IMU、轮式或履带底盘里程计ROS 版本ROS1 Noetic、ROS2 Humble其它版本可按驱动适配可选 SLAM 方案Cartographer、LIO-SAM、FAST-LIO2、loam_livox运行平台Ubuntu 20.04、Ubuntu 22.04启动方式roslaunch 启动、launch 文件批处理、节点配置启动对外通信不提供 HTTP API以 ROS topic / service / action 方式对外交互批量任务支持多 bag 顺序建图、批量地图导出可脚本化处理适合场景洞穴巡检、矿井测绘、隧道检测、地下空间扫描、考古测绘这里有一个非常重要的事实洞穴建图不是“某一个算法”单独完成的而是“传感器驱动 前端里程计 后端优化 回环检测 地图输出”的组合。ROS1 和 ROS2 在这个链路里承担的任务也不只是跑一个 SLAM 节点还要负责传感器数据同步、TF 树维护、bag 录制回放和节点生命周期管理。所以下文在讲环境准备时会把 ROS 系统本身算作一个关键依赖项。2. 适用场景与使用边界洞穴建图方案的典型使用场景可以分成四类。第一类是洞穴巡检与安全检测。机器人搭载激光雷达进入洞穴生成二维或三维地图为后续路径规划和人员定位提供底图。这种场景要求建图过程尽量实时同时地图质量要稳定不能出现明显的分层和错位。第二类是矿井与隧道测绘。矿井巷道结构相对规则但粉尘大、GPS 信号完全失效、地面湿滑。这种环境需要激光雷达与 IMU 强融合轮式里程计的权重通常要调低。第三类是考古与地质调查。这类洞穴通常空间复杂、障碍物多可能需要进入狭窄通道对机器人的尺寸和传感器的安装位置有较高要求。第四类是地下空间数字化存档。目标不是机器人导航而是把洞穴扫描成带颜色或带反射强度信息的点云地图后续在 PC 上做三维重建。这种场景更看重地图精度和点云完整性。使用边界也需要明确。洞穴建图目前不能完全依赖纯视觉方案因为洞穴光照条件不稳定双目和深度相机在黑暗区域会退化。如果必须使用视觉传感器需要额外补光并接受更大的计算开销。另外洞穴内如果存在大量悬空岩石和细小突出物2D SLAM 的平面激光扫描会丢失很多有效信息建出来的图看起来“扁平”不能直接用于三维测量。对于湿滑、多尘的洞穴环境传感器防护等级和下视防撞措施也要在算法之前考虑否则硬件问题会先于软件问题暴露。合规方面洞穴和矿井往往属于受控区域。进入现场测试前需要确认测绘权限和作业许可不要在有安全风险或未授权的地下空间直接进行设备部署。建图过程中采集的点云数据如果涉及设施位置、工程结构等内容应当按照实际要求进行存储和脱敏处理。3. 环境准备与前置条件洞穴建图对硬件环境的要求比较集中主要包括计算平台、激光雷达、IMU、底盘和存储介质。计算平台建议使用 x86 架构的迷你主机或工业电脑。如果机器人空间有限也可以使用 Jetson Orin 系列但需要注意部分 3D SLAM 算法在 ARM 平台上的编译依赖比如 LIO-SAM 的 gtsam、Ceres版本兼容问题。CPU 建议 8 核以上内存 16GB 以上。现场建图如果使用 32GB 内存会更稳因为多包融合建图时后端优化节点会占用较多内存。激光雷达建议选择机械式 3D 雷达或固态雷达。固态雷达在抗震动方面有优势洞穴环境中更稳妥机械式雷达扫描覆盖范围大但在地下空间容易因粉尘和震动出现故障。2D 雷达可以用于简单洞穴通道建图但复杂空间不推荐。IMU 的选型要关注陀螺仪零偏稳定性和加速度计量程。洞穴中没有 GPSIMU 是激光里程计之外最重要的定位信息源。IMU 与激光雷达的安装位置要固定牢避免弹性连接导致的高频抖动。存储介质建议使用大容量 SSD同时准备一块移动硬盘用于备份 bag。洞穴建图的数据量比普通室内建图大得多一段 20 分钟的 3D 激光点云 bag 通常能到几 GB 到几十 GB。如果使用 64 线雷达且未做降频这个数据量还会翻倍。软件环境的版本建议如下表组件ROS1 推荐版本ROS2 推荐版本操作系统Ubuntu 20.04Ubuntu 22.04ROS 版本ROS NoeticROS2 Humble激光雷达驱动按雷达型号安装官方 ROS 驱动按雷达型号安装官方 ROS2 驱动SLAM 框架Cartographer、LIO-SAMCartographer、FAST-LIO2依赖库Ceres、GTSAM、PCL、EigenCeres、GTSAM、PCL、Eigen国内环境安装 ROS 时如果直接使用官方源经常卡在rosdep update和apt update阶段可以使用社区维护的鱼香 ROS 一键安装脚本来简化。这种方式适合快速搭建开发环境但生产环境建议核对脚本内容后手动执行核心安装步骤避免引入不必要的源。4. 安装部署与启动方式4.1 安装 ROS1 NoeticUbuntu 20.04 下安装 ROS1 Noetic核心步骤如下。# 设置软件源 sudo sh -c echo deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main /etc/apt/sources.list.d/ros-latest.list # 设置密钥 sudo apt install curl curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.key | sudo apt-key add - # 更新软件包列表 sudo apt update # 安装桌面完整版 sudo apt install ros-noetic-desktop-full安装完成后需要初始化 rosdep。sudo rosdep init rosdep update如果rosdep update因为网络问题失败可以检查当前rosdep数据源配置替换为国内源后再执行。不要直接跳过这一步否则后续编译工作空间时依赖解析会报错。4.2 安装 ROS2 HumbleUbuntu 22.04 下安装 ROS2 Humble核心步骤如下。# 添加 ROS2 软件源 sudo apt update sudo apt install curl gnupg lsb-release sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg # 写入源 echo deb [arch$(dpkg --print-architecture) signed-by/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(source /etc/os-release echo $UBUNTU_CODENAME) main | sudo tee /etc/apt/sources.list.d/ros2.list /dev/null # 安装 sudo apt update sudo apt install ros-humble-desktop安装后需要配置环境变量。echo source /opt/ros/humble/setup.bash ~/.bashrc source ~/.bashrc如果开发中需要 ROS1 和 ROS2 共存建议通过 Docker 分别隔离两套环境不要在同一个 shell 里反复 source 两个版本否则rclpy和rospy的 Python 依赖会冲突。4.3 安装激光雷达驱动不同激光雷达的驱动差异很大以下是通用流程。到雷达厂商官网下载对应 ROS1 或 ROS2 驱动源码。将源码放入catkin_ws/srcROS1或ros2_ws/srcROS2。执行catkin_make或colcon build。配置雷达 IP 地址和固定 IP 子网。运行驱动节点检查/scan或/livox/lidar话题是否正常输出。以 Livox 雷达在 ROS1 环境下为例cd ~/catkin_ws/src git clone https://github.com/Livox-SDK/livox_ros_driver.git cd ~/catkin_ws catkin_make source devel/setup.bash roslaunch livox_ros_driver livox_lidar.launch启动后用rostopic hz /livox/lidar查看点云频率。如果频率显示为 0 或远低于雷达规格说明网络连接或驱动参数没有配对。4.4 编译 Cartographer 并启动建图Cartographer 是洞穴建图方案中用得比较多的激光 SLAM 框架同时支持 2D 和 3D也同时支持 ROS1 和 ROS2。它的优点是回环检测能力较强适合需要后期优化的洞穴场景。ROS1 环境下编译sudo apt install -y python3-wstool python3-rosdep ninja-build stow mkdir -p ~/cartographer_ws/src cd ~/cartographer_ws wstool init src wstool merge -t src https://raw.githubusercontent.com/cartographer-project/cartographer_ros/master/cartographer_ros.rosinstall wstool update -t src rosdep install --from-paths src --ignore-src --rosdistronoetic -y catkin_make_isolated --install --use-ninja启动 3D 建图节点source ~/cartographer_ws/install_isolated/setup.bash roslaunch cartographer_ros demo_revo_lds.launch实际洞穴建图时需要把demo_revo_lds.launch替换为自己写的 launch 文件。核心配置项包括use_online_correlative_scan_matching是否开启实时相关性扫描匹配。num_accumulated_range_data每次累积多少帧点云。tracking_frame跟踪坐标系通常设为雷达的 frame id。map_frame地图坐标系通常设为map。imu_topicIMU 数据话题。ROS2 环境下Cartographer 的安装方式不同。可以直接使用官方cartographer_ros的 ROS2 分支或通过 vcs 工具导入依赖后编译。启动方式与 ROS1 类似只是命令中的roslaunch改为ros2 launch。4.5 使用 Docker 启动 ROS 环境如果不想在宿主机上污染系统环境可以使用 Docker 运行 ROS1 和 ROS2。插件rocker可以把 ROS 的 master 环境和设备节点如 USB、网络挂载进容器适合在开发机上切换多个 ROS 版本。# 启动 ROS1 Noetic 容器 docker run -it --network host osrf/ros:noetic-desktop-full bash # 启动 ROS2 Humble 容器 docker run -it --network host osrf/ros:humble-desktop bash需要注意docker 容器内访问激光雷达时要确认雷达是通过 USB 还是以太网连接。以太网雷达直接使用 host 网络即可访问USB 雷达需要把设备挂载进容器docker run -it --network host --device/dev/ttyUSB0 osrf/ros:noetic-desktop-full bash5. 功能测试与效果验证5.1 仿真环境测试现场测试之前先在 Gazebo 里搭建一个模拟洞穴环境验证整套建图流程是否跑得通。第一步准备一个模拟洞穴模型。可以手动搭一个简单的“隧道”模型由多个长方形墙体组成也可以使用开源地下车库模型。第二步启动仿真环境。roslaunch turtlebot3_gazebo turtlebot3_world.launch第三步启动 Cartographer 建图。roslaunch cartographer_ros demo_revo_lds.launch第四步通过键盘控制机器人前进。roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch观察建图界面中地图是否随机器人移动逐步扩展。这一步判断成功的标准是地图边缘清晰没有大片错位和重影机器人回到起点附近时地图能通过回环检测基本闭合。仿真测试能发现很多问题TF 树缺失、传感器话题名不匹配、数据帧率过低、建图参数不合理。这些问题如果直接拿到洞穴现场去排查成本会高得多。5.2 现场数据采集现场采集数据时机器人先不要追求建图效果优先保证 bag 质量。启动雷达驱动和 IMU 驱动后先检查数据频率。rostopic hz /livox/lidar rostopic hz /imu/data再用rosbag record录制数据。mkdir -p ~/bag_files/cave01 rosbag record -O ~/bag_files/cave01/cave01.bag \ /livox/lidar \ /imu/data \ /odom \ /tf \ /tf_static录制过程中注意几点机器人启动前先静止 10 秒给 IMU 提供一个初始化参考。行进速度不要过快洞穴环境建议控制在 0.5m/s 以内。通过狭窄通道后尽量回头走一小段给回环检测创造机会。每段 bag 录制时长控制在 10 到 30 分钟避免单文件过大。5.3 离线 bag 建图现场录制完 bag 后回到实验室离线建图通常更稳。离线建图的好处是参数可以反复调整跑一次 bag 只需要几分钟甚至几秒效率远高于现场反复调试。启动离线建图的基本流程如下。第一个终端启动建图节点roslaunch cartographer_ros offline_cave.launch第二个终端回放 bagrosbag play ~/bag_files/cave01/cave01.bag --clock需要注意bag 回放时要使用--clock参数否则 SLAM 后端的时间戳会异常。观察建图终端的输出重点关注pose和time是否连续更新。constraint数量和回环检测错误率是否正常。是否出现“Frame didnt have a timestamp”或“TF repeated data”错误。5.4 多包融合建图洞穴测绘经常需要把多次采集的数据合到一张地图里。比如第一次采集主洞道第二次采集支洞两次数据在同一个坐标系下拼接。Cartographer 的纯定位模式适合多包拼图。流程是先加载第一次 bag 建好的地图作为固定地图然后把第二次 bag 以localization模式播放让 SLAM 后端在地图里重新定位并扩展地图。roslaunch cartographer_ros localization_cave.launch rosbag play --clock cave02.bag如果第二条 bag 的初始位置与固定地图偏差太大需要先预估初始位姿写入 launch 文件否则定位容易失败。多包融合的核心不是算法而是数据采集时保证重叠区域足够多。两条 bag 之间的重叠区域至少要有 20% 以上拼接效果才可靠。5.5 地图导出与导航适配Cartographer 输出的地图默认是 protobuf 格式。要用于导航需要导出为 PGM YAML 的标准 ROS 地图格式。ROS1 下使用rosrun map_server map_saver -f ~/maps/cave01执行后会生成cave01.pgm和cave01.yaml。这个地图可以直接用于 ROS Navigation Stack 或 Nav2。如果是 3D 点云地图需要导出为 PCD / PLY 格式。rosrun pcl_ros pointcloud_to_pcd input:/map_3d或使用 pcl_ros 工具自行转换。导出后可以用 CloudCompare 打开点云检查是否存在明显漂移和分层。判断建图是否成功可以从三个维度验证地图闭合性回到起点附近地图是否闭合有没有出现道路“错开成两条”。测量误差选取洞穴中已知尺寸的通道宽度对比地图测量值与实际值。点云厚度在 3D 点云地图中观察墙面点的厚度厚度小于 10cm 说明建图质量较好如果点云厚度超过几十厘米说明定位漂移明显。6. 数据采集与批量任务工程化6.1 数据采集节点设计对于长时间洞穴采集建议单独写一个采集 launch 文件统一管理驱动节点、话题屏蔽和自动录制。一个简单的做法是写一个 Python 节点监听启动信号然后在节点内调用 rosbag record。更推荐的做法是使用rosbag record的-e正则表达式参数只录制需要的传感器话题rosbag record -O cave_session.bag \ -e (livox|lidar|imu|odom|tf.*) \ --duration1800这样可以避免把导航、点云预处理等不必要话题全部录进 bag减少磁盘占用。6.2 批量建图脚本当有多个 bag 文件需要处理时写一个简单的 bash 脚本批量执行。#!/bin/bash BAG_DIR~/bag_files/cave01 MAP_DIR~/maps/cave01 mkdir -p $MAP_DIR for bag in $BAG_DIR/*.bag; do echo Processing $bag roslaunch cartographer_ros offline_cave.launch sleep 5 rosbag play $bag --clock sleep 3 # 保存地图 rosrun map_server map_saver -f $MAP_DIR/$(basename $bag .bag) # 停止建图节点 rosnode kill -a sleep 2 done这个脚本的缺点是串行执行耗时较长。如果机器性能足够可以把多个 bag 分配到多个 Docker 容器里并行建图每个容器使用不同的输出目录。6.3 地图后处理流程批量建图完成后还需要做后处理去除点云中的离群点和悬浮噪点。对多段地图做拼接和全局优化。将点云地图降采样生成导航需要的 2D 占据栅格地图。标注关键点和危险区域供人工复核。后处理工具推荐使用 CloudCompare、PCL、Open3D。如果地图质量差优先回源检查采集数据而不是指望后处理能修复所有漂移。7. 资源占用与性能观察洞穴建图的资源占用主要集中在三个位置激光雷达驱动节点、SLAM 前端节点、SLAM 后端优化节点。激光雷达驱动节点对 CPU 消耗取决于雷达型号和点云密度。例如 64 线机械雷达原始点云数据量很大驱动节点通常需要 2 到 4 个 CPU 核心。SLAM 前端的实时扫描匹配也吃 CPU尤其是开启实时相关性扫描匹配后计算量会明显上升。SLAM 后端优化在 robot 回环检测成功时会触发一次全局优化此时 CPU 会出现明显峰值如果机器性能不足会表现为建图界面卡顿。内存方面Cartographer 3D 建图时地图数据的存储和子图的维护都很占内存。内存占用与建图范围和点云密度直接相关。一个 500 米长的洞穴3D 地图在内存中可能占用 3GB 到 8GB如果使用高分辨率体素化占用会进一步上升。建议现场机器至少 16GB 内存离线批量建图机器建议 32GB。如果发现 CPU 占用过高可以通过以下方式降低负载降低点云话题发布频率例如从 20Hz 降到 10Hz。增大体素滤波器分辨率例如把voxel_size从 0.05m 调整到 0.1m。关闭不必要的可视化节点建图时不要同时开 Rviz 多个插件。对于 3D 点云只保留雷达前方一定范围内的数据减少无效点云。rostopic hz和nvidia-smi如果使用 GPU是观察系统资源的常用工具。# 查看话题频率 rostopic hz /livox/lidar rostopic hz /map # 查看 CPU 和内存占用 htop建图过程中如果rostopic hz /map频率低于 0.5Hz说明后端优化压力很大需要检查参数配置或降低地图分辨率。8. 常见问题与排查方法问题现象可能原因排查方式解决方案激光雷达启动后无点云话题雷达 IP 配置错误或网线不通用ifconfig查看网卡地址ping雷达 IP修改雷达固定 IP 为同一子网换网线点云话题有数据但建图界面空白TF 树缺失或 frame_id 不一致运行rosrun rqt_tf_tree rqt_tf_tree查看 TF 树检查 launch 文件中 frame_id 配置建图过程中机器人明显漂移轮式里程计权重过高或 IMU 外参不对录制一段直线行进 bag回放观察订阅话题降低里程计权重重新标定 IMU 外参回环检测时地图突然大幅错位回环约束构建错误或地图精度不足观察 Rviz 中 constraint 箭头调整回环检测阈值提高扫描匹配精度bag 回放时提示时间戳异常使用--clock参数后仍有时间冲突检查 bag 中/clock话题使用rosbag play --clock并确认建图节点使用仿真时间建图节点内存持续增长直至卡死地图范围过大或参数体素分辨率过细观察htop内存占用增大体素降低点云频率分批建图地图导出后 PGM 文件全黑或全白map_saver 使用错误的 map 话题用rostopic list检查 /map 话题是否存在调整 map_saver 输入话题多包融合时定位失败两段 bag 重叠区域太少检查两段 bag 轨迹是否在同一区域重新采集重叠区域数据修改初始位姿2D 地图中上下楼梯或坡道变形2D SLAM 无法感知三维坡度使用 3D SLAM 方案换 LIO-SAM 或 FAST-LIO2ROS1 与 ROS2 共存时依赖冲突两个环境变量互相覆盖检查.bashrc中 source 顺序使用 Docker 隔离或通过脚本切换环境在洞穴现场最容易忽略的一个问题是时间同步。激光雷达、IMU 和相机如果使用不同的时钟源或者没有做好硬件同步会导致 SLAM 前端的数据关联出现毫秒级偏差最终体现为建图漂移。现场条件允许时尽量给传感器做硬件时间同步条件不足时也要在录制 bag 前用rostopic delay检查话题时间戳的一致性。9. 最佳实践与使用建议洞穴建图的工程化比调参更重要的事情其实是流程管理。以下几条建议来自实际项目中的常见经验。9.1 先从仿真和数据回放开始不要直接把机器人搬进洞穴现场调试。先做一轮仿真测试验证 launch 文件没有逻辑错误再录制一段 10 分钟左右的 bag 回办公室离线调参。离线调参的速度远快于现场调参而且不会消耗机器人电量。9.2 保持一套最小可运行配置把配置拆成“最小可用”和“完整功能”两套。最小可用配置只包括雷达、IMU、建图节点和 TF用于现场快速验证完整功能配置再加入地图服务器、导航节点、可视化插件和任务调度脚本。这样在出现问题时可以先回到最小配置验证传感器链路是否正常避免一次排查多个变量。9.3 处理好传感器时间同步时间同步是整个系统中的隐性故障源。雷达和 IMU 的帧率如果不同步里程计输出的轨迹会出现抖动。建议在采集 bag 之前固定执行一次时间同步检查rostopic delay /livox/lidar rostopic delay /imu/data差值应该在几十毫秒以内。如果偏差过大优先检查传感器驱动的时钟源设置。9.4 把 bag 视为原始资产bag 文件是建图项目的原始数据必须分目录管理。推荐目录结构cave_project/ ├── bags/ │ ├── cave001/ │ │ ├── cave001.bag │ │ ├── config.yaml │ │ └── notes.txt │ └── cave002/ ├── maps/ │ ├── 2d/ │ └── 3d/ ├── config/ │ ├── cartographer/ │ └── nav2/ └── scripts/每次采集完 bag把对应的雷达配置、IMU 外参、建图参数和现场记录一并存到同一个目录方便复现和复盘。9.5 涉及真实场景时的合规与安全洞穴、矿井、隧道等区域属于受控环境。进入现场前需要确认作业许可。机器人硬件需要具备一定的防尘防潮能力必要时在雷达窗口加装保护结构。采集的点云数据如果包含工程设施布局等内容存储和分享应遵守现场管理要求。人脸、车牌等敏感信息如果混入纹理点云应做脱敏处理后再导出。9.6 检查地图精度建完图后不要急着拿去导航先做精度检查。找几个特征明显的点用激光测距仪实际测量一次和地图上的距离、位置做对比。2D 地图的通道宽度误差应控制在 5cm 到 10cm 以内3D 地图的点云厚度应控制在 10cm 左右。误差偏大时先回顾采集速度、回环质量、IMU 标定三项。10. 总结与下一步洞穴建图最值得尝试的点是它在“无 GPS、无光照、弱纹理”环境下对多传感器融合能力的完整考验。方案本身不复杂核心是传感器可靠、时间同步稳定、数据链路清晰、建图参数可复现。如果你第一次做洞穴建图建议先跑通 Cartographer 的 2D/3D 仿真流程再用自己的 bag 做离线建图最后再上现场。最容易踩的坑不是算法参数而是雷达驱动没起来、TF 树报错、bag 时间戳异常这类基础问题。把这些底层问题解决掉SLAM 调参才有意义。后续可以扩展的方向包括接入 LIO-SAM 或 FAST-LIO2 做更强的高精度 3D 建图把建图结果直接导入 Nav2 做自主导航加入多机器人协同采集分区域同时建图再通过全局优化合并或者把点云地图发布到 Web 端做数字孪生预览。建议收藏备用后面做地下空间巡检项目时可以直接按这套流程上手。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →