100 lines
5.1 KiB
Markdown
100 lines
5.1 KiB
Markdown
# Python Sim2Real v2
|
||
|
||
本目录归档 Python Sim2Real v2,对应 `v0.9.0`。该阶段从第一代闭环继续演进,保持 `53D -> 16D` 策略契约,重点完善电机反馈判断、IMU/Odin 可观测性、Web 调试和运行时诊断;后续 ROS 2/C++ 版本另行归档。下文“当前”均指该版本快照。
|
||
|
||
## 当前控制链路
|
||
|
||
- 策略模型:默认优先使用 `policies/model_rough.onnx`,`.pt` 仅作为导出源和 fallback
|
||
- 策略输入:单帧 `53D`
|
||
- 策略输出:`16D`
|
||
- 控制频率:默认 `50Hz`
|
||
- 电机数量:16 个 RS02/RobStride 电机
|
||
- 电机映射、方向、零位:以 `interface/motor_mapping.py` 为准,当前视为真机验证过,不在本轮改造中修改
|
||
- Web 入口:`python web/server.py --host 0.0.0.0 --port 8080`
|
||
|
||
策略观测顺序保持不变:
|
||
|
||
1. `base_ang_vel * 0.25`
|
||
2. `projected_gravity`
|
||
3. `command`
|
||
4. `joint_pos[:12] - default_dof_pos[:12]`
|
||
5. `joint_vel[:12] * 0.05`
|
||
6. `wheel_vel[12:] * 0.05`
|
||
7. `last_actions`
|
||
|
||
Odin odom 现在只作为诊断和全局状态显示接入,不进入策略观测,避免破坏已训练模型的输入契约。
|
||
|
||
## 本轮改造内容
|
||
|
||
- 日志写入改为后台线程,降低 `state.csv` 高频写入对 50Hz 控制循环的阻塞。
|
||
- 电机 fresh/stale 判断优先使用驱动层 `update_count`,避免静止电机反馈正常但位置速度不变时被误判为丢电机。
|
||
- `wait_feedback_ready()` 同步识别 `update_count`,降低使能后零位静止电机被误判 missing 的概率。
|
||
- `IMUClient` 增加 `get_latest_odom()`,读取 Odin odom 的位置、姿态、线速度、角速度、类型和 age。
|
||
- `RealIO.read_state()` 增加只读 `odom` 字段,但不改变策略观测。
|
||
- 增加 `OdomTracker`,把 Odin raw odom 转成启动点局部坐标 `local x/y/yaw`,并做跳变检测。
|
||
- 增加 `LatestTarget` 诊断,记录当前下发目标来源、age、目标变化量,为后续双 loop 解耦铺路。
|
||
- Web runtime 状态增加 `loop_profile`、odom、电机 fresh 计数、每电机 update_count。
|
||
- Web Diagnostics 面板增加 loop overrun、最慢阶段、电机 fresh 来源、Odin odom 状态。
|
||
- 增加 `command_filter`,对 Web/遥控命令统一做限加速度平滑,降低起停冲击;Web 同时显示 raw cmd 和 filtered cmd。
|
||
- 策略推理入口改为 ONNXRuntime 优先,默认查找 `policies/model_rough.onnx`;不存在时兼容回退到 `policies/model_rough.pt`。
|
||
- ONNXRuntime 使用 CPU 单线程顺序执行,减少推理线程池和 motor/status/logger 线程抢占。
|
||
|
||
## 重点诊断字段
|
||
|
||
Web 中重点看这些项:
|
||
|
||
- `loop_dt`:控制循环总耗时,50Hz 下目标约 `20ms`。
|
||
- `Loop Overruns`:runtime 超时累计次数和最大超时。
|
||
- `Loop Profile`:显示本轮最慢阶段,例如 `read_state_ms`、`policy_ms`、`send_actions_ms`。
|
||
- `Latest Target`:显示目标来源、age 和本次目标最大变化量;age 异常增大说明目标更新链路卡住。
|
||
- `Obs / Action`:显示观测绝对值最大值、raw action 最大值和 scaled action 最大值,用来发现输入爆炸或动作饱和。
|
||
- `Motor Fresh`:格式为 `fresh/16 (cnt x, val y)`;`cnt` 表示通过 `update_count` 确认的新反馈数量。
|
||
- `Odin Odom`:显示 odom 类型、age、local x/y/yaw;没有 odom 时不影响控制。
|
||
- `cmd/raw cmd`:`cmd` 是进入策略的滤波后命令,`raw cmd` 是 Web/遥控原始命令。
|
||
- 电机列表状态点:绿色代表 stale count 为 0,黄色代表短时未刷新,红色代表连续 stale。
|
||
|
||
## 当前仍需实机重点确认
|
||
|
||
- 如果继续出现 `LOOP_OVERRUN`,先看 Web 的 `Loop Profile`,不要直接调低控制频率。
|
||
- 如果 `read_state_ms` 慢,重点排查 SocketCAN/CAN 队列、Odin bridge 或电机反馈处理。
|
||
- 如果 `policy_ms` 慢,重点排查 ONNXRuntime 推理耗时、CPU 占用和是否有后台进程抢占。
|
||
- 如果 `send_actions_ms` 慢,重点排查 CAN 发送阻塞或 USB-CAN 适配器。
|
||
- 如果 `Obs / Action` 中 obs 接近 `100` 或 raw action 接近 `10`,说明策略输入/输出可能在饱和边界,需要优先检查观测缩放、IMU、关节速度和命令。
|
||
- 如果 `Motor Fresh` 不是 16/16,但 `update_counts` 在增长,需要检查 Web stale 阈值而不是电机丢失。
|
||
- 如果 odom age 长时间不更新,只影响全局坐标/诊断,不应影响当前策略控制。
|
||
|
||
## 启动命令
|
||
|
||
在 Orin / Linux 真机上:
|
||
|
||
```bash
|
||
python -m pip install -r requirements-orin.txt
|
||
python tools/export_onnx.py --pt policies/model_rough.pt --onnx policies/model_rough.onnx
|
||
python tools/alignment_check.py --policy policies/model_rough.onnx --manifest deployment_manifest.yaml
|
||
python tools/standalone_check.py
|
||
python web/server.py --host 0.0.0.0 --port 8080
|
||
```
|
||
|
||
Web 流程:
|
||
|
||
1. Connect
|
||
2. Enable Motors
|
||
3. Startup
|
||
4. Start Runtime
|
||
5. 策略 release 后,如需要,点击遥控接管
|
||
6. 实时观察 Diagnostics、Motors、Plots
|
||
|
||
## 安全边界
|
||
|
||
当前保留原有保护链路:
|
||
|
||
- Web 急停
|
||
- 遥控软急停
|
||
- runtime guard
|
||
- safety monitor
|
||
- NaN/Inf 检查
|
||
- 电机 stale holdover
|
||
- damping brake
|
||
|
||
这轮没有放宽安全边界,也没有调整电机限位、零位、方向、默认增益和策略动作缩放。
|