feat(hardware): 标定归硬件;按 name 选关节 + kSetZero;toml++ 改 vendored

标定边界上移到 invicta_hardware:
- raw↔model 的 dir/offset 由 hardware 独家施加(话题收发都是模型帧),
  deploy 的 InvictaInterface 退化为透传,invicta_deploy.toml 不再有 dir/offset_deg。
  这样 [joint_limits](模型帧)与被限幅的指令同帧,/joint_states 也是模型角。

关节选择(部分接入 / 单腿调试):
- JointCommandArray 的 name 即本次要控制的关节子集(空 = 全部已配置关节)。
- 未选中的关节写「零力矩自由」块,而不是留全 0——按协议 (0,0,0,0,0) 会解码成
  P_MIN/V_MIN/T_MIN,其中 tau=T_MIN(摆臂 -100 N·m)是危险的前馈力矩。
- 新增 control_word kSetZero(6) -> 0xEF,只作用于选中的摆臂(轮毂不支持,跳过)。

调试脚本 invicta_hardware/scripts/hw_debug_test.py:
- 只起 hardware 节点调试:monitor/damping/angle/wheel/offset/zero 六种模式 + --joints。
- 限幅参数硬编码;发指令时默认回显模型角。

构建:toml++ 改为 vendored single-header(三个包各 third_party/tomlplusplus/toml++/toml.hpp),
   去掉 find_package(tomlplusplus) 与 -DTOML_HEADER_ONLY(单头自带 header-only)。

已在容器(localhost/custom-ros-noetic)中全新 catkin_make + smoke_test 验证通过。
This commit is contained in:
2026-10-23 13:44:27 +08:00
parent 594885b9e8
commit 46bbb06978
24 changed files with 54455 additions and 129 deletions
+6 -5
View File
@@ -34,11 +34,12 @@
## P1:标定与配置一致性(上真机前)
- [ ] **`dir`/`offset` 的施加方未定**
hardware 现在收发的都是**原始电机量**,`dir`/`offset_deg` 由 deploy 的 `InvictaInterface` 施加;
但 hardware 的 README 原设计与 `hardware_bridge.h` 注释写的是「由本节点施加」。
两边都施加时 `dir=±1` 会二次相乘抵消、`offset` 会翻倍(当前 offset 全 0,尚未暴露)。
二选一并同步修改另一侧配置与文档;同时注意 `[joint_limits]` 在两份 TOML 里重复维护。
- [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`。
这样 `[joint_limits]`(模型帧)与被限幅的指令同帧,`/joint_states` 也是模型角。
遗留:`[joint_limits]` 仍在两份 TOML 里重复维护(deploy 用一份做状态机自检、hardware 用一份做下发夹紧),
后续可考虑合并或生成。
- [ ] **反馈帧仲裁 ID 需真机确认**
`ReadHardware` 按「反馈使用关节自身 CANID」实现(手册只写了从站 CANID 1~6)。