SLAM - 同时定位与建图¶
SLAM(Simultaneous Localization and Mapping)是机器人自主导航的核心技术,它使机器人能够在未知环境中同时构建地图并确定自身位置。
什么是 SLAM?¶
┌─────────────────────────────────────────────────────────────┐
│ SLAM 问题定义 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 输入: │
│ - 传感器数据(激光雷达、相机、IMU) │
│ - 里程计数据(轮式编码器、视觉里程计) │
│ │
│ 输出: │
│ - 环境地图(2D/3D) │
│ - 机器人位姿(位置和方向) │
│ │
│ 挑战: │
│ - 传感器噪声 │
│ - 累积误差 │
│ - 动态环境 │
│ - 计算复杂度 │
│ │
└─────────────────────────────────────────────────────────────┘
SLAM 算法分类¶
基于激光雷达的 SLAM¶
| 算法 | 特点 | 适用场景 |
|---|---|---|
| gmapping | 2D 激光 SLAM,基于粒子滤波 | 室内环境,小范围 |
| cartographer | Google 开发,2D/3D SLAM | 室内外,大范围 |
| hector_slam | 无需里程计 | 无人机、手持设备 |
| karto_slam | 基于图优化 | 大规模环境 |
基于视觉的 SLAM¶
| 算法 | 特点 | 适用场景 |
|---|---|---|
| ORB-SLAM | 特征点法 | 室内外通用 |
| LSD-SLAM | 直接法 | 纹理丰富环境 |
| DSO | 直接稀疏里程计 | 高精度定位 |
| RTAB-Map | 视觉+激光融合 | 多传感器融合 |
在 ROS 中使用 SLAM¶
1. gmapping¶
gmapping 是最常用的 2D 激光 SLAM 算法。
安装¶
使用¶
配置参数¶
<launch>
<node name="gmapping" pkg="gmapping" type="slam_gmapping">
<param name="base_frame" value="base_link"/>
<param name="odom_frame" value="odom"/>
<param name="map_frame" value="map"/>
<param name="xmin" value="-25.0"/>
<param name="xmax" value="25.0"/>
<param name="ymin" value="-25.0"/>
<param name="ymax" value="25.0"/>
<param name="delta" value="0.05"/>
<param name="maxUrange" value="12.0"/>
<param name="maxRange" value="12.0"/>
</node>
</launch>
2. cartographer¶
cartographer 是 Google 开发的 SLAM 系统,支持 2D 和 3D SLAM。
安装¶
使用¶
# 2D SLAM
roslaunch cartographer_ros demo_backpack_2d.launch
# 3D SLAM
roslaunch cartographer_ros demo_backpack_3d.launch
# 保存地图
rosrun cartographer_ros cartographer_assets_writer - \
-configuration_directory /path/to/config \
-configuration_basename assets_writer.lua
配置文件¶
-- backpack_2d.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 = "odom",
odom_frame = "odom",
provide_odom_frame = false,
publish_frame_projected_to_2d = true,
use_odometry = true,
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,
}
MAP_BUILDER.use_trajectory_builder_2d = true
TRAJECTORY_BUILDER_2D.min_range = 0.3
TRAJECTORY_BUILDER_2D.max_range = 8.
TRAJECTORY_BUILDER_2D.missing_data_ray_length = 1.
TRAJECTORY_BUILDER_2D.use_imu_data = false
TRAJECTORY_BUILDER_2D.use_online_correlative_scan_matching = true
TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.linear_search_window = 0.1
TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.angular_search_window = math.rad(20.)
return options
3. RTAB-Map¶
RTAB-Map 是一个支持多传感器融合的 SLAM 系统。
安装¶
使用¶
# 使用激光雷达
roslaunch rtabmap_ros rtabmap.launch \
laser_scan:=/scan \
frame_id:=base_link
# 使用 RGB-D 相机
roslaunch rtabmap_ros rtabmap.launch \
rgb_topic:=/camera/rgb/image_raw \
depth_topic:=/camera/depth/image_raw \
camera_info_topic:=/camera/rgb/camera_info
# 保存地图
rosrun map_server map_saver -f my_map
SLAM 实践步骤¶
步骤 1:准备传感器¶
步骤 2:启动 SLAM¶
# 启动机器人
roslaunch my_robot bringup.launch
# 启动 SLAM
roslaunch gmapping slam.launch
# 启动 RViz 可视化
roslaunch my_robot rviz.launch
步骤 3:建图¶
步骤 4:保存地图¶
步骤 5:加载地图¶
SLAM 调优技巧¶
1. 参数调优¶
# gmapping 参数
maxUrange: 激光雷达最大有效范围
particles: 粒子数量(越多越精确,但越慢)
delta: 地图分辨率
xmin/xmax/ymin/ymax: 地图范围
2. 传感器校准¶
3. 里程计校准¶
SLAM 评估¶
1. 视觉评估¶
在 RViz 中观察: - 地图是否一致 - 是否有重影 - 是否有闭环
2. 定量评估¶
使用 slam_eval 工具:
常见问题¶
1. 地图漂移¶
原因:里程计误差累积
解决方案: - 增加闭环检测 - 使用更好的里程计(视觉里程计、IMU) - 减小粒子数量
2. 地图重影¶
原因:机器人移动过快或传感器噪声
解决方案: - 降低机器人移动速度 - 增加扫描匹配参数 - 使用更好的传感器
3. 计算资源不足¶
原因:粒子数量过多或地图范围过大
解决方案: - 减小粒子数量 - 减小地图范围 - 使用更高效的算法(cartographer)
实验¶
Lab 4: SLAM¶
- 启动 SLAM 系统
- 使用键盘控制机器人建图
- 保存地图
- 评估地图质量