一次无人看管的远程遥操作把左臂开到伸展姿势后一直撑着,那一颗关节升到 61°C,温度守卫在极限处停机。之后它一动就让总线丢包,我据此判定「舵机劣化,该换」,并且已经写好了向主办方要备件的话。操作者一句「你应该做一个梯度测试才行呀」把这个结论推翻了——凉透之后它扛得住的负载比两个健康邻居还高。这一页记录数据、误判、和推翻它的那条曲线。
那次会话 6889 拍里 6821 拍(99%)是 "holding position":手臂被开到一个伸展姿势之后就一直扛在那儿,没有任何东西让它退出来。承重最大的 shoulder_lift 一路升到 61°C。
[thermal] STOP: left shoulder_lift at 61C (limit 60C, confirmed twice)
left shoulder_lift reached 61C — stopping before the servo drops torque
on its own and the arm falls.
最后那句是守卫存在的意义:抢在舵机自己过热卸力矩之前停机。等舵机自保护,力矩会突然消失,手臂直接掉下去。
| 本次会话峰值 | shoulder_lift | 同臂其余五颗 |
|---|---|---|
| 左臂 | 61°C | 34–43°C |
| 右臂 | 36°C | 34–42°C |
只有那一颗。这排除了环境温度和整臂负载。
把两条臂都停在 home、静置对照(负载和电压是当晚新加进温度守卫的记录,总线流量一点没增加):
left shoulder_lift 37°C / load 224 / 12.1V
right shoulder_lift 36°C / load 216 / 12.0V
同姿势下差 1°C。 所以 61°C 是姿势 + 无人看管造成的,不是左臂天生更热。
61°C 之后约半小时,驱动它 2.6° 会产生 15/23/33 次总线通信失败,而同一条总线上负载更高的邻居一次都没有。我当时有三个点:
| 动作 | 峰值负载 | 通信失败 |
|---|---|---|
| 只上力矩、不动 | 0 | 0 |
| 动 1.3° | 117 | 0 |
| 动 2.6°(热态) | 184–218 | 15 / 23 / 33 |
据此我给出「阈值约 150,超过就崩,判定劣化」。那个 150 是在两个点之间插出来的,不是测出来的。
servo_load_probe.py --sweep| 幅度 | 角度 | ID2 失败/负载 | ID3 失败/负载 | ID4 失败/负载 |
|---|---|---|---|---|
| 5 | 0.4° | 0 / 32 | 0 / 36 | 0 / 37 |
| 10 | 0.9° | 0 / 78 | 0 / 77 | 0 / 81 |
| 15 | 1.3° | 0 / 149 | 0 / 120 | 0 / 116 |
| 20 | 1.8° | 0 / 195 | 0 / 148 | 0 / 143 |
| 25 | 2.2° | 0 / 239 | 0 / 171 | 0 / 164 |
| 30 | 2.6° | 0 / 255 | 0 / 207 | 0 / 188 |
| 40 | 3.5° | 0 / 291 | 0 / 223 | 0 / 220 |
为什么之前会误判:热态那批测试的起始温度也是 34°C —— 但外壳凉不代表绕组凉。 61°C 之后又过了约一小时、全程力矩 off,才恢复到上表。表面温度传感器骗了我。
无操作 3 分钟 → 缓慢缩回 home → 保持力矩停在那儿
任何按键 → 立刻中止,控制权交还
三条边界,测试逐条守住:保留夹爪状态(直接用 home 位姿会张开爪、把杯子扔了)、不卸力矩(卸了手臂会掉,而 home 姿势保持力矩实测只有 37°C)、按键立刻中止(归位分支有 continue,不中止的话按键会被无视好几秒)。
判据是「没有真实操作」而不是「没有数据」—— XLeVR 的网页即使不戴头显也在持续推位姿,按「有没有数据」判的话只要页面开着就永远不会触发,而那正是烧电机的场景。
原来只记温度,「这颗在使劲」和「这颗坏了」分不开。现在三个寄存器轮换,每拍仍只读一次,每颗舵机 1.2 秒拿到温度/负载/电压各一次。停机判据一个字没动。
left: shoulder_lift=61C/load108/11.6V elbow_flex=36C/load22/12.4V ...
当晚就是靠这个新增的负载数据,才把「姿势问题」和「硬件问题」分开的。
① XLeVR 网页即使不戴头显也推逐位相同的位姿,于是键盘增量每拍被 VR 分支覆盖 —— 按一次 W,y 跳 +5 mm,下一拍回原位,手臂原地抖。判据:真实追踪永远有抖动,连续 15 拍逐位相同 = 合成流。
② (是①的修复暴露的)filt 只在归位分支和 VR 分支里绑定,「goal 是 None 且归位完成」那条路用的是上一轮循环的残留 —— 按左臂的键改右臂的目标位姿,再把结果发给左臂。
修好后实机验证:操作者连点 S 四十秒,左臂 y 0.12863 → 0.09563 单调后退净走 33 mm,右臂 0.14848 全程一个数字没变。
03-software/scripts/servo_load_probe.py --sweep ·
交接 HANDOFF-2026-09-08-LEFT-SHOULDER.md