Files
yiliao2026/CLAUDE.md
2026-06-06 20:35:53 +08:00

166 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CLAUDE.md
## 项目概述
这是一个 ROS 2 Humble 工作空间,用于 Ackermann 转向小车的 Gazebo 仿真、SLAM 建图和 Nav2 导航。同时支持实车部署(无 Gazebo
## 工作空间结构
```
test_ws/
├── src/
│ ├── gc_navigation2_slamtoolbox/ # 仿真版:导航+SLAM 启动文件和配置
│ │ ├── launch/ # Python launch 文件
│ │ ├── config/ # slam_toolbox 参数
│ │ ├── params/ # Nav2 参数
│ │ ├── maps/ # 地图文件 (.pgm, .yaml, .posegraph)
│ │ └── world/ # Gazebo 模型 (zhihui/)
│ ├── gc_navigation2_real/ # 实车版:导航+SLAM 启动文件和配置(无 Gazebo
│ │ ├── launch/ # Python launch 文件
│ │ ├── config/ # slam_toolbox 参数(实车调优)
│ │ ├── params/ # Nav2 参数use_sim_time=false
│ │ ├── maps/ # 实车地图存放目录
│ │ └── behavior_tree/ # 阿克曼自定义行为树
│ ├── origincar_description/ # 机器人 URDF 和 Gazebo world
│ │ ├── urdf/ # origincar.urdf
│ │ ├── world/ # .world 文件
│ │ ├── meshes/ # 3D 模型
│ │ ├── launch/ # display.launch.py
│ │ └── rviz/ # RViz 配置
│ ├── origincar_base/ # 实车底盘驱动(串口通信+EKF+IMU融合
│ │ ├── src/ # C++ 源码origincar_base.cpp
│ │ ├── scripts/ # cmd_vel_to_ackermann_drive.py
│ │ ├── launch/ # origincar_bringup / base_serial / ekf
│ │ └── config/ # ekf.yaml / imu.yaml
│ ├── origincar_msg/ # 自定义 ROS 2 消息
│ │ └── msg/ # Data.msg / Sign.msg
│ └── LSLIDAR_X_ROS2-20240228/ # 镭神激光雷达 ROS 2 驱动
│ └── src/
│ ├── lslidar_driver/ # 雷达驱动核心
│ └── lslidar_msgs/ # 雷达消息定义
├── build/ # colcon build 输出
├── install/ # colcon install 输出 (含符号链接)
└── log/ # 构建日志
```
## 构建命令
```bash
cd /home/guoch/test_ws
source /opt/ros/humble/setup.bash
colcon build --symlink-install
source install/setup.bash
```
## 常用 Launch 文件
### 仿真版 (gc_navigation2_slamtoolbox)
| 文件 | 功能 |
|------|------|
| `gc_slam_mapping.launch.py` | Gazebo + SLAM 建图模式 |
| `gc_nav2_with_slam_online.launch.py` | 已知地图 + SLAM 在线更新 + Nav2 导航 |
| `gc_nav2_with_slam.launch.py` | 已知地图 + SLAM 定位 + Nav2 导航 |
| `gc_nav2_with_amcl.launch.py` | AMCL 定位 + Nav2 导航 |
### 实车版 (gc_navigation2_real)
| 文件 | 功能 |
|------|------|
| `real_bringup.launch.py` | 基础 bringup底盘驱动+雷达+TF无导航 |
| `real_slam_mapping.launch.py` | 实车 SLAM 建图模式 |
| `real_nav2_slam.launch.py` | 已知地图 + SLAM 定位 + Nav2 导航 |
| `real_nav2_slam_online.launch.py` | 已知地图 + SLAM 在线更新 + Nav2 导航 |
## 机器人参数 (origincar)
- **类型**: Ackermann 转向小车
- **尺寸**: 0.276 × 0.214 × 0.211 m (长×宽×高)
- **轴距**: 0.143 mURDF 中前轮 x=0.0715,后轮 x=-0.0715**轮距**: 0.189 m
- **轮子**: 半径 0.03 m厚 0.025 m
- **激光雷达**: 360°, 0.12~3.5 m, 5 Hz仿真; 镭神 N10 0.15~12m实车
- **IMU**: 100 Hz, 含高斯噪声
- **Gazebo 插件**: `gazebo_ros_ackermann_drive`, `gazebo_ros_ray_sensor`, `gazebo_ros_imu_sensor`
## 实车 TF 树
```
map ──→ odom_combined ──→ base_footprint ──→ base_link ──→ laser
↑ ↑ ↑ ↑
slam_toolbox EKF static TF URDF/static
(定位) (融合odom+IMU) (origincar_bringup)
```
- slam_toolbox 发布 `map → odom_combined`
- EKF 发布 `odom_combined → base_footprint`
- origincar_bringup 发布 `base_footprint → base_link`z=0`base_link → laser`
- robot_state_publisher 发布 URDF 各连杆 TF
### 仿真 vs 实车关键差异
| 方面 | 仿真版 | 实车版 |
|------|--------|--------|
| use_sim_time | `true` | `false` |
| odom_frame | `odom` | `odom_combined`EKF 融合后) |
| 底盘驱动 | Gazebo plugin | origincar_base 串口驱动 |
| 激光雷达 | Gazebo ray plugin | lslidar_driver镭神 N10 |
| robot_state_publisher | launch 文件内启动 | origincar_bringup 已包含,勿重复启动 |
| joint_state_publisher | launch 文件内启动 | origincar_bringup 已包含,勿重复启动 |
## 阿克曼底盘模式
通过 `akmcar` 参数控制,链路如下:
```
origincar_bringup.launch.py
└─ akmcar=LaunchConfiguration('akmcar', default='true')
└─ 传入 base_serial.launch.py
├─ IfCondition(true) → origincar_base_node (akm_cmd_vel='ackermann_cmd')
│ + cmd_vel_to_ackermann_drive.py (Twist→Ackermann)
└─ UnlessCondition(false) → 差速模式(跳过)
```
数据流:`MPPI cmd_vel(Twist) → cmd_vel_to_ackermann_drive.py → ackermann_cmd(AckermannDriveStamped) → STM32`
关键参数:
- `cmd_vel_to_ackermann_drive.py`: `wheelbase = 0.143`(与 URDF 一致)
- `akmcar=true` 时 STM32 接收 `speed + steering_angle`
- `akmcar=false` 时 STM32 接收 `vx + vy + wz`(固件自行转换)
## 关键设计
1. **map_server** 提供全量静态底图(`/map`
2. **slam_toolbox** 负责定位和增量建图,重映射 `/map``/slam_map` 避免冲突
3. **Nav2** 使用 `global_costmap/static_layer ← /map` + `local_costmap/obstacle_layer ← /scan`
4. 保存地图: `ros2 service call /slam_toolbox/serialize_map ...`
5. 实车版 launch 文件**不应**自行启动 `robot_state_publisher``joint_state_publisher``origincar_bringup` 已包含
## 地图文件
地图放在 `src/gc_navigation2_slamtoolbox/maps/`(仿真)和 `src/gc_navigation2_real/maps/`(实车),包含:
- `xxx.pgm` — 地图图像
- `xxx.yaml` — 地图元数据 (resolution, origin, thresholds)
- `xxx.posegraph` — 序列化的位姿图
## Gazebo World
World 文件在 `src/origincar_description/world/`:
- `zhihui.world` — 智慧楼墙体环境(内联模型)
- `test.world` — 测试环境
- `fishbot.world` / `gc_world.world` — 其他场景
## 实车底盘驱动包 (origincar_base)
- `origincar_base_node`C++: 串口读写(/dev/ttyACM0, 115200bps、航迹推算、四元数姿态解算Mahony AHRS
- `cmd_vel_to_ackermann_drive.py`Python: Twist → AckermannDriveStamped 转换wheelbase=0.143
- 帧协议: 24 字节收帧头0x7B/帧尾0x7D/ 11 字节发
- EKF 融合: `/odom` + IMU → `/odom_combined``two_d_mode=true`
## 注意事项
- 使用 `--symlink-install` 构建Python launch 文件修改后无需重新编译
- `.world` 文件不应使用 `model://` 外部引用,应将模型内联定义
- `robot_base_frame` 在 ackermann plugin 中应设为 `base_footprint`
- 实车 `gc_navigation2_real` 的 launch 文件调用 `origincar_bringup.launch.py` 时,不再重复启动 `robot_state_publisher``joint_state_publisher`
- 轴距参数在三处需保持一致URDF0.143m)、`cmd_vel_to_ackermann_drive.py`0.143m、Nav2 planner `minimum_turning_radius`0.40m