内容
# 游侠小车 2.0 CAN + ROS 2 控制
该项目使用 Ubuntu 22.04 和 ROS 2 Humble 在 CAN 总线上控制 AgileX 游侠小车 2.0。
软件栈:
```text
command/ranger_move.py
↓ /cmd_vel, /odom, /system_state
官方 ranger_ros2
↓
官方 ugv_sdk
↓ SocketCAN can0
游侠小车 2.0
```
## 日常使用
### 1. 检查 CAN 总线
USB-CAN 接口为 `can0`,波特率为 500 kbit/s:
```bash
ip -details -statistics link show can0
```
预期状态为:
```text
状态 UP
CAN 状态 ERROR-ACTIVE
比特率 500000
```
在不发送命令的情况下检查 CAN 帧:
```bash
candump can0
```
按 `Ctrl+C` 停止。
如果 `can0` 未运行:
```bash
cd /home/sqz/projects/ranger_interface
./scripts/setup_can.sh can0
```
推荐的一键启动命令为:
```bash
start-ranger
```
`start-ranger` 首先检查 `can0` 是否已经 `UP`、`ERROR-ACTIVE` 并配置为 500 kbit/s。如果是,则跳过冗余的 CAN 设置。否则,它会配置 CAN,然后始终启动 ROS 2 命令模式。该命令占用当前终端;启动后请保持该终端打开。
如果当前 shell 还未加载快捷键:
```bash
source ~/.bash_aliases
```
底层脚本仍然可用于诊断或手动启动:
```bash
cd /home/sqz/projects/ranger_interface
./scripts/setup_can.sh can0
./scripts/start_command_mode.sh can0
```
### 2. 清除启动错误
在底盘重新上电后,可能会显示错误代码 `0x03000000`,对应 SDK 中的 `0x0300`。
按照以下步骤清除错误:
1. 打开遥控器。
2. 将 `SWB` 移至上部位置。
3. 将 `SWA` 移至下部位置。
4. 将左轮移到最低位置。
5. 按 `KEY1` 并等待转向自动校准完成。
6. 将 `SWB` 移至中间位置,进入 RC 模式。
7. 按住 `KEY1` 并稍微移动底盘。
8. 停止底盘并将 `SWB` 移回上部位置。
错误清除后可以关闭遥控器。正常的系统状态帧应类似:
```text
can0 211 [8] 00 00 ... 00 00 00 00
```
### 3. 启动 ROS 驱动
推荐命令为:
```bash
start-ranger
```
手动启动可以使用:
```bash
source /home/sqz/projects/ranger_interface/scripts/setup_workspace.sh
ros2 launch ranger_bringup ranger_mini_v2.launch.py port_name:=can0
```
等效的简化命令为:
```bash
cd /home/sqz/projects/ranger_interface
./scripts/start_command_mode.sh can0
```
等待:
```text
Ranger accepted CAN control mode; motion commands enabled
```
如果底盘已经清除错误并处于正常状态,通常无需再次按 `KEY1`。
### 4. 发送运动命令
打开第二个终端。推荐的前进快捷键为:
```bash
move_forward 0.2
```
这会自动加载 ROS 环境并运行里程计闭环控制器,以驱动 0.2 米。也可以进行旋转:
```bash
rotate 1.570796
```
这意味着逆时针旋转 90 度。`rotate -0.174533` 意味着顺时针旋转 10 度。这些快捷键需要加载 `~/.bash_aliases` 的 Bash 终端,并且运行 `start-ranger` 的终端必须保持打开。
如果当前终端不可用快捷键:
```bash
source ~/.bash_aliases
```
底层 Python 命令也可以在加载工作区后直接调用:
```bash
source /home/sqz/projects/ranger_interface/scripts/setup_workspace.sh
```
如果没有此 `source` 命令,Python 无法找到 `ranger_msgs` 并会报错缺少 ROS 模块。快捷键会自动加载环境。
前进 0.2 米:
```bash
python3 /home/sqz/projects/ranger_interface/command/ranger_move.py drive 0.2
```
后退 0.2 米:
```bash
python3 /home/sqz/projects/ranger_interface/command/ranger_move.py drive -0.2
```
逆时针旋转 10 度:
```bash
python3 /home/sqz/projects/ranger_interface/command/ranger_move.py rotate 0.174533
```
顺时针旋转 10 度:
```bash
python3 /home/sqz/projects/ranger_interface/command/ranger_move.py rotate -0.174533
```
快捷键到 Python 的映射:
```text
move_forward 0.2 -> ranger_move.py drive 0.2
rotate -0.174533 -> ranger_move.py rotate -0.174533
```
`move_forward` 接受有符号距离:正值前进,负值后退。例如:
```bash
move_forward -0.1
```
参数范围:
```text
drive: [-1.0, 1.0] 米
rotate: [-π, π] 弧度
```
正角度为逆时针,负角度为顺时针。
### 5. 安全关闭
在运行 ROS 启动的终端中按:
```text
Ctrl+C
```
节点将:
1. 反复发送零速度。
2. 请求底盘退出 CAN 命令模式。
3. 等待底盘进入 `STANDBY`。
4. 关闭 ROS 节点。
正常输出为:
```text
安全关闭:发送零速度并请求 STANDBY
安全关闭完成:Ranger 已退出 CAN 控制模式
```
请勿突然关闭终端、强制终止进程或拔掉 USB-CAN 接口。这些操作可能会导致通信错误 `0x02000000`。
## 控制程序
运动程序为:
```text
command/ranger_move.py
```
它提供了两个里程计闭环函数:
```python
rotate(angle_rad)
drive(distance_m)
```
两个函数都使用 `/odom` 反馈:
- `rotate()` 控制累计偏航变化;
- `drive()` 将位置变化投影到初始航向上以控制行驶距离。
安全机制包括:
- 仅在 `NORMAL + CAN + error_code=0` 下允许运动;
- 当 `/odom` 或 `/system_state` 变得陈旧时停止;
- 参数范围限制;
- 总体运动超时;
- 在正常完成、错误或 `Ctrl+C` 时重复发送零速度命令。
目前没有障碍物检测、触觉感知或卡顿检测。请仅在清空区域并由人员监督底盘的情况下运行运动命令。
## 构建
安装依赖:
```bash
cd /home/sqz/projects/ranger_interface
./scripts/install_dependencies.sh
```
构建工作区:
```bash
cd /home/sqz/projects/ranger_interface
./scripts/build.sh
```
工作区包含两个官方上游项目:
- `src/ugv_sdk`:CAN 通信和协议编码/解码;
- `src/ranger_ros2`:ROS 2 节点和主题接口。
该项目为上游代码添加了 Ranger Mini 2.0 参数修复、CAN 命令模式握手重试、零速度心跳、运动状态门控和安全关闭行为。
`staged_packages/` 是一个存档原型,被 `COLCON_IGNORE` 排除,不属于当前构建或运行时工作流。请勿使用其控制节点。
## ranger-robot MCP 服务器
MCP 包装器位于:
```text
mcp/ranger_robot/
```
它通过 ROS 2 访问已经运行的 `ranger_base_node`。它不直接访问 CAN,也不启动或停止 `start_command_mode`。默认 Streamable HTTP 端点为:
```text
http://10.100.6.232:8000/mcp
```
有关 MCP 工具、Bearer Token 配置、systemd 部署和只读测试,请参见:
```text
mcp/ranger_robot/README.md
```