ROS 2 自主仓储 AGV 仿真系统
WarehouseNavSim 是一个基于 ROS 2 Jazzy 的自主仓储移动机器人仿真系统。项目在
Gazebo Harmonic 仓储环境中使用自定义差速 AGV,并通过 ros_gz_bridge 将
2D LiDAR、Gazebo 里程计和 TF 数据接入 ROS 2,用于基于已有地图的定位与 Nav2
自主导航。项目还包含按顺序执行的航点巡检,以及用于测试动态避障的移动障碍物场景。
仓库中的视频展示了移动障碍物场景下完成的一次航点巡检,并以 2.2 倍速播放。 原始录像文件体积较大,仅保留在本地,不纳入 Git 版本管理。
flowchart TD
GZ[Gazebo] --> DATA[LiDAR / 里程计]
DATA --> BRIDGE[ros_gz_bridge]
BRIDGE --> ROS[ROS 2]
ROS --> NAV[定位 / Nav2]
NAV --> CMD["/cmd_vel"]
CMD --> DRIVE[差速驱动]
- 使用 URDF/Xacro 描述的自定义差速 AGV。
- 仿真 360° 2D LiDAR、差速驱动、里程计和 TF。
- Gazebo 仓储环境及配套占据栅格地图。
/clock、/scan、/odom、/tf和/cmd_vel的 ROS-Gazebo 单向桥接。- SLAM Toolbox 建图启动配置和基于已有地图的 AMCL 定位。
- 基于 Navfn 全局规划器、MPPI 控制器、代价地图、恢复行为、速度平滑器及碰撞监控器的 Nav2 目标点导航。
- 通过 YAML 配置航点巡检,并按每段路线记录 CSV 结果。
- 可重复运行的移动障碍物测试场景,用于观察障碍物横穿巡检路线时 Nav2 的响应。
- Ubuntu 24.04
- ROS 2 Jazzy
- Gazebo Harmonic
- Nav2
- RViz2
- Python
- URDF/Xacro
以下结构省略了生成的工作空间目录(build/、install/ 和 log/)、Python
缓存文件以及未纳入版本管理的原始录像。
.
├── .gitignore
├── LICENSE
├── README.md
├── docs
│ ├── demo.gif
│ └── evaluation.md
├── results
│ ├── dynamic_obstacle_20260823.csv
│ └── static_patrol_20260823.csv
├── video
│ ├── README.md
│ └── warehouse-nav-demo.mp4
└── src
├── warehouse_nav_bringup
│ ├── launch
│ │ └── warehouse_nav.launch.py
│ ├── CMakeLists.txt
│ ├── README.md
│ └── package.xml
├── warehouse_nav_description
│ ├── config
│ │ ├── nav2_params.yaml
│ │ ├── ros_gz_bridge.yaml
│ │ └── slam_toolbox.yaml
│ ├── docs
│ │ ├── diff-drive-validation.md
│ │ ├── lidar-validation.md
│ │ ├── nav2-navigation-validation.md
│ │ ├── ros-gz-bridge-validation.md
│ │ ├── sdf-world-design-ledger.md
│ │ ├── slam-mapping-validation.md
│ │ └── urdf-design-ledger.md
│ ├── launch
│ │ ├── display.launch.py
│ │ ├── mapping.launch.py
│ │ ├── navigation.launch.py
│ │ └── simulation.launch.py
│ ├── maps
│ │ ├── README.md
│ │ ├── warehouse_slam_map.pgm
│ │ └── warehouse_slam_map.yaml
│ ├── meshes
│ │ └── README.md
│ ├── rviz
│ │ ├── mapping.rviz
│ │ └── navigation.rviz
│ ├── urdf
│ │ └── warehouse_agv.urdf.xacro
│ ├── worlds
│ │ ├── warehouse_empty.sdf
│ │ ├── warehouse_slam.py
│ │ └── warehouse_slam.sdf
│ ├── CMakeLists.txt
│ └── package.xml
└── warehouse_nav_apps
├── config
│ └── waypoints.yaml
├── docs
│ └── dynamic-obstacle-design-ledger.md
├── launch
│ ├── dynamic_obstacle.launch.py
│ └── waypoint_patrol.launch.py
├── models
│ ├── dynamic_obstacle.py
│ └── dynamic_obstacle.sdf
├── resource
│ └── warehouse_nav_apps
├── test
│ ├── test_dynamic_obstacle.py
│ └── test_waypoint_patrol.py
├── warehouse_nav_apps
│ ├── __init__.py
│ ├── dynamic_obstacle.py
│ └── waypoint_patrol.py
├── package.xml
├── README.md
├── setup.cfg
└── setup.py
在已安装 ROS 2 Jazzy 的 Ubuntu 24.04 环境中,从工作空间根目录执行:
source /opt/ros/jazzy/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build --symlink-install
source install/setup.bash
ros2 launch warehouse_nav_bringup warehouse_nav.launch.py该启动文件会运行仓储仿真、AGV、ROS-Gazebo bridge、已有地图定位、Nav2 和 RViz2。AMCL 的默认初始位姿为仿真原点;可在 RViz2 中使用 Nav2 Goal 下发 目标位姿。
无 RViz2 的无界面运行方式:
ros2 launch warehouse_nav_bringup warehouse_nav.launch.py \
use_rviz:=false gz_args:="-s -r"Gazebo 在 /scan 发布激光扫描数据,在 /odom 发布差速驱动里程计数据。
bridge 同时提供 odom -> base_footprint 变换,其余机器人本体和传感器变换由
机器人描述发布。AMCL 结合已有地图、激光扫描、里程计和 TF 估计机器人位姿,
并发布 map -> odom。
2D LiDAR
↓
/scan ───────────────┐
│
Gazebo 里程计 │
↓ ├──→ 定位(AMCL + TF)
/odom ──────────────┤
│
TF 树 ────────────────┘
↓
地图 + 当前位姿 + 传感器数据
↓
Nav2
↓
Navfn 全局规划器
↓
MPPI 控制器
↓
速度平滑器 / 碰撞监控器
↓
/cmd_vel
↓
Gazebo 差速驱动
默认路线配置位于
src/warehouse_nav_apps/config/waypoints.yaml。
每个航点必须包含 name、x、y 和 yaw;位置使用 map 坐标系,偏航角单位为
弧度。第一个航点用于设置初始位姿,其余航点按顺序发送给 Nav2。最后一个航点必须
完整重复第一个航点的位姿,确保每轮巡检返回起点。
frame_id: map
waypoints:
- name: Home
x: 0.0
y: 0.0
yaw: 0.0
- name: Station A
x: 1.0
y: 1.0
yaw: 0.0
- name: Home
x: 0.0
y: 0.0
yaw: 0.0启动完整系统并执行一轮巡检:
ros2 launch warehouse_nav_bringup warehouse_nav.launch.py \
use_patrol:=true patrol_loops:=1使用其他路线文件且不修改仓库默认配置:
ros2 launch warehouse_nav_bringup warehouse_nav.launch.py \
use_patrol:=true patrol_loops:=2 \
waypoints_file:=/absolute/path/to/waypoints.yaml运行移动障碍物场景:
ros2 launch warehouse_nav_apps dynamic_obstacle.launch.py随后在另一个已加载 ROS 和工作空间环境的终端中启动巡检:
ros2 launch warehouse_nav_apps waypoint_patrol.launch.py loops:=1仓库提交了与录制演示对应的两次真实巡检结果。成功率按完成路线段数计算,耗时、 距离和恢复次数为单次巡检内各路线段的总和。
| 场景 | 样本数 | 完成路线段 | 成功率 | 总耗时 | 估算路程 | 恢复次数 |
|---|---|---|---|---|---|---|
| 普通航点巡检 | 1 | 4/4 | 100% | 82.462 s | 14.813 m | 0 |
| 移动障碍物 | 1 | 4/4 | 100% | 169.691 s | 15.416 m | 5 |
原始 CSV 位于 results/,实验环境、计算方法和结果边界见
docs/evaluation.md。当前每个场景只有一个样本,这些结果只用于
确认系统行为,不构成控制器性能的统计比较。行驶距离来自 Gazebo 里程计估算,而非
独立的地面真值测量。
- 当前系统仅在仿真环境中运行。
- 感知主要基于 2D LiDAR。
- Gazebo 里程计比实体机器人上的里程计更理想化。
- 当前未建模复杂动态人群。
- 尚未部署到实体机器人。
- 当前提交的评估数据每个场景仅包含一次巡检。
- 将导航系统部署到实体机器人。
- 提高传感器噪声条件下的定位鲁棒性。
- 增加多机器人任务分配。
