在开始ORB_SLAM3的集成之前,我们需要先搭建一个稳定的ROS2开发环境。我推荐使用Ubuntu 20.04 LTS作为基础系统,这个版本与ROS2 Foxy的兼容性最好。记得在安装前更新系统:
bash复制sudo apt update && sudo apt upgrade -y
ROS2 Foxy的安装其实比ROS1简单很多,官方提供了完整的安装脚本。不过在实际操作中,我发现有几个依赖项需要特别注意:
bash复制sudo apt install -y \
build-essential \
python3-colcon-common-extensions \
python3-rosdep \
python3-vcstool
安装完基础依赖后,建议设置一个专门的工作空间。我习惯在home目录下创建ros2_ws文件夹,这样便于管理:
bash复制mkdir -p ~/ros2_ws/src
cd ~/ros2_ws
在安装过程中最容易出问题的是网络连接导致的包下载失败。如果遇到这种情况,可以尝试更换软件源或者使用代理(注意:这里不讨论具体网络配置)。安装完成后,记得测试基础功能是否正常:
bash复制source /opt/ros/foxy/setup.bash
ros2 run demo_nodes_cpp talker
在另一个终端运行listener,如果能正常收发消息,说明ROS2环境已经准备就绪。
ORB_SLAM3的2D格栅地图功能依赖于PCL点云库,而PCL又需要VTK支持。这里我踩过不少坑,总结出一套可靠的安装流程。
首先安装VTK 8.2.0,这个版本与Ubuntu 20.04的兼容性最好。安装依赖项时,有几个包特别容易漏掉:
bash复制sudo apt install -y \
libx11-dev libxext-dev libxtst-dev \
libxrender-dev libxmu-dev libxmuu-dev \
libgl1-mesa-dev libglu1-mesa-dev \
libxt-dev cmake-qt-gui
编译VTK时,建议使用CMake GUI进行配置,这样能直观地看到所有选项。关键是要勾选"VTK_Group_Qt"选项,否则后续PCL的可视化功能会出问题。编译过程可能需要较长时间,可以使用make -j$(nproc)加速。
PCL 1.10.1的编译相对简单,但要注意以下几点:
我遇到过最常见的问题是动态库链接错误,解决方法是在.bashrc中添加:
bash复制export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
现在进入核心环节——将ORB_SLAM3的ROS1版本移植到ROS2。这个过程需要修改不少代码,但别担心,我会带你一步步完成。
首先获取必要的代码仓库:
bash复制git clone https://github.com/electech6/ORB_SLAM3_detailed_comments.git ORB_SLAM3
git clone https://github.com/MrPicklesGG/ORB_SLAM3_Grid_Mapping.git
关键的移植工作集中在以下几个方面:
具体到2D格栅地图功能,需要特别注意ros_mono_pub.cc和ros_mono_sub.cc这两个文件的移植。我建议先创建一个新的ROS2包专门处理地图相关功能:
bash复制cd ~/ros2_ws/src
ros2 pkg create orbslam3_grid_mapping --build-type ament_cmake
在移植过程中,最棘手的是坐标变换的处理。ROS2的tf2库使用方式与ROS1有所不同,需要特别注意时间戳的处理。建议参考以下代码结构:
cpp复制// 创建静态坐标变换
geometry_msgs::msg::TransformStamped transformStamped;
transformStamped.header.stamp = this->now();
transformStamped.header.frame_id = "map";
transformStamped.child_frame_id = "odom";
// 设置变换参数...
tf_broadcaster_->sendTransform(transformStamped);
系统搭建完成后,最关键的就是参数调试了。ORB_SLAM3的2D格栅地图有几个核心参数直接影响地图质量:
经过多次测试,我总结出一套适用于室内环境的参数组合:
bash复制ros2 run orbslam3 Monosub 5 3 29 -25 48 -12 0.55 0.50 1 5
这些参数的具体含义如下:
| 参数名 | 推荐值 | 作用 |
|---|---|---|
| scale_factor | 5 | 尺度转换因子 |
| resize_factor | 3 | 最终地图的缩放系数 |
| cloud_max | 29,48 | 点云最大边界 |
| cloud_min | -25,-12 | 点云最小边界 |
| free_thresh | 0.55 | 空闲区域阈值 |
| occupied_thresh | 0.5 | 占据区域阈值 |
| use_local_counters | 1 | 使用局部计数器 |
| visit_thresh | 5 | 最小访问次数阈值 |
在实际调试中,我发现地图边缘经常会出现锯齿状噪声。这个问题可以通过调整visit_thresh参数来解决,适当提高这个值可以过滤掉大部分噪点,但设置太高又会导致地图细节丢失。
另一个常见问题是地图尺度不准确。由于单目SLAM的特性,我们需要通过实地测量来校准scale_factor。我的做法是在环境中放置一个已知长度的物体(比如1米长的标尺),然后调整参数直到地图上的对应距离显示正确。
地图更新频率也是一个需要权衡的因素。在Tracking.cc中,可以修改关键帧选择策略来平衡地图更新频率和计算开销。我通常会把关键帧间隔设置为0.5米或者15度旋转,这样既能保证地图实时性,又不会给系统带来太大负担。