Files
huoyi_deploy/docs/TODO.md
T
caowangrenbo 7ba2bba450 feat(safety): 错误位上报 1002/3;IMU 断流判定;移除硬件假 IMU
- MotionState 增加 error_code,新增 invicta_msgs/error_code.h 共用位定义;SafeController 写入、remote 展开成协议 ErrorList(component 暂为 0)
- InvictaInterface 增加 IMU 断流/恢复判定(imu_timeout_s / imu_recover_s),covariance=-1 视为不可用;RL 丢失 IMU 走正常趴下
- invicta_hardware 不再发布硬编码单位四元数 IMU(含错误的 covariance[0]=0)
- 更新 README 与 docs/TODO.md:记录已完成项、反馈帧 CANID 1~4 已确认、[joint_limits] 重复维护入待办
2026-10-23 23:32:57 +08:00

83 lines
6.2 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.
# TODO
本文件记录**当前会话中确认但本期不做**的事项。按优先级分组,每项尽量写清「为什么」和「验收方式」,
避免下次重新推导。已完成的部分见各包 README 与文末清单。
## P0:安全链路(真机跑 RL 前必须处理)
- [ ] **异常数据接入 deploy 的保护链路**
硬件已在 `/joint_diagnostics` 提供温度/状态字/电压(10 Hz),但 deploy 侧仍未接:
`InvictaInterface` 没有订阅该话题,`GetMotorTemperture()` 走基类常量 30 ℃;
`GetDriverStatusWord()` 虽已重写为返回成员 `driver_status_`,但该成员只被初始化成全 1、无人更新,
所以 `SafeController` 的过温检查与驱动报错检查依然恒不触发。
做法:`InvictaInterface` 订阅 `/joint_diagnostics`,按关节名填 `driver_status_`、覆盖 `GetMotorTemperture()`。
注意:协议 Byte9 的 bit0 是「使能中」,而 `IsDriverStatusNormal()` 判断 `status_word != 1` 报错,
失能但健康的电机回 `0x00` 会误判;建议在接口层归一化成「无故障位就填 1」。
验收:人为把某个关节温度改成 101 ℃,deploy 进入 `safe_control_mode=2` 并切 `kJointDamping`。
- [ ] **诊断超时判断**
诊断话题 10 Hz,`SafeController` 读缓存值。若 hardware 进程死掉,温度会停在最后一帧的「正常」。
需要在接口层记录诊断时间戳,超时(如 1 s)按异常处理。
验收:杀掉 hardware 节点后 deploy 进入安全状态。
(对照:IMU 的同类问题已解,走 `IsImuHealthy()` 的断流判定——本条可照抄那套「时间戳 + 超时 + 恢复去抖」。)
## P1:标定与配置一致性(上真机前)
- [ ] **`[joint_limits]` 在两份 TOML 里重复维护**
`invicta_deploy.toml` 用一份做状态机自检,`invicta_hardware.toml` 用一份做下发夹紧。
两份手改容易漂移,且改限位时要同步改两处。可考虑合并成单一来源(hardware 读 deploy 的,或从一处生成另一处)。
- [ ] **`lie_height = 0` 与位置限位矛盾**
`invicta_deploy.toml` 里 `lie_height = 0.00` 反解 `θ = acos(0) = 90° = 1.571 rad`,
超过同文件 `[joint_limits].upper = 1.40`。确认是笔误还是限位需要放宽。
- [ ] **轮的位置限位占位值**
`[joint_limits]` 中轮的 `lower/upper = ±100` 既不在归一化边界内,也不表示限幅
(轮不支持位置控制,手册 §4.4)。加载校验时已跳过,但语义上应改成 ±12.5 或显式标注「仅占位」。
- [ ] **摆臂速度限幅复核**
`vel_limit = 22.40 rad/s` 是额定 15.5 的 1.45 倍,比轮的 100/81.2(1.23 倍)更激进。
如果当初是估的,建议按实测重新定。
- [ ] **位置指令越界目前静默夹紧**
`invicta_hardware_node.cpp` 的 `PackRunBlocks` 里力矩和 kp/kd 越界会告警,位置不会。
策略动作顶到限位时可能值得提示一次(`ROS_WARN_THROTTLE`,注意别刷屏)。
## P2:协议状态上报的剩余占位
- [ ] `MotionStatus` 的 `LinearX / LinearY / Height / RemainMile`:需要里程计、运动学估计与电池数据。
- [ ] `1002/5` 的电池(电压/电量/温度/serial)、CPU、GPS:无数据源。
- [ ] `Charge / HES / Sleep`:没有充电状态、硬急停信号与休眠管理。
- [ ] `HipY` 的正负号未与真实 App/M20 对照:如果 App 只是显示数值没问题,若渲染姿态需要核对。
- [ ] 未实现指令:照明灯、休眠设置/查询、自主充电、速度指令(导航模式)、导航任务(Pro)。
- [ ] 错误上报的 `component` 恒为 0(见文末遗留):要定位到具体关节,需在 deploy 侧把错误位与关节号关联。
## P3:工程与清理
- [ ] **启动时序的 `kEnable` 可能被采样合并**
deploy 已改为「等订阅者再发」且 hardware 在 `kMotorControl` 未使能时会补发使能,功能上已安全;
但 hardware 循环线程处理 `kErrorReset` 的使能连发会阻塞约 80 ms,期间可能观察不到 `kEnable`。
若要严格逐帧落地,可把连发改成分段非阻塞发送。
- [ ] `[motor.gains].bench_*` 已被指令里的 kp/kd 取代(现仅被加载、无消费方),确认是否删除。
- [ ] 真机联调清单:`ip link set canX ... fd on` 权限、`roslaunch` 启动顺序、双路差分驱动方向。
## 已完成
- [x] **SocketCAN FD 收发 + 智身模组协议编解码**(使能/失能/运行、12 字节反馈解码)
- [x] **温度读回 → `/joint_diagnostics`**(默认 10 Hz,可配置)→ remote 填 1002/5
- [x] **1002/4 的 8 → 16 槽映射**(swing→HipY、wheel→Wheel,HipX/Knee 占位 0)
- [x] **力矩/速度/位置限幅,kp/kd 越界夹紧并告警**;限幅与归一化边界分离 + 加载期校验
- [x] **指令看门狗**(100 ms 无指令转阻尼)
- [x] **`dir`/`offset` 的施加方已定:hardware**(2026-10-22)
raw↔model 换算由 `invicta_hardware` 独家承担(`[[legs]].swing/wheel` 的 `dir`/`offset_deg`),话题上收发都是模型帧;
deploy 的 `InvictaInterface` 退化为纯透传,`invicta_deploy.toml` 不再有 `dir`/`offset_deg`。
- [x] **反馈帧仲裁 ID 已确认为 1~4**(2026-10-23):`ReadHardware` 按关节自身 CANID 匹配,与实测一致,无需改动。
- [x] **toml++ 改为 vendored**(`third_party/tomlplusplus`),不再依赖镜像或 `CMAKE_PREFIX_PATH`。
- [x] **容器内构建 + 冒烟测试**(`scripts/smoke_test.sh`);修复启动时序丢失与订阅回调阻塞。
- [x] **异常上报 1002/3 的数据源**:`MotionState.error_code` + 共用位定义 `invicta_msgs/error_code.h`;
`SafeController` 每周期写 `UserCommand::robot_error_code`,remote 经 `RobotErrorList()` 展开成协议 `ErrorList`。
遗留:`component` 恒填 0(未按关节定位),已单列在 P2。
- [x] **IMU 数据源缺失**:`invicta_hardware` 不再发假 IMU(删掉单位四元数 + `covariance[0]=0`);
deploy 把 `orientation_covariance[0]==-1` 视为不可用,并做断流/恢复判定(`imu_timeout_s`/`imu_recover_s`),
RL 丢失 IMU 走「正常趴下」而非就地垮下。实际数据源 `odin_imu_bridge` 不在本仓库,契约见 `invicta_deploy/README.md`。