← reports index
工具 · 2026-09-08

servo_load_probe.py:判一颗舵机是不是真的坏了

起因是我判错过一次。左臂 shoulder_lift 过热之后一动就让总线丢包,我从三个插值点得出"劣化,该换",连找主办方要备件的话都写好了。操作者只说了一句 「而且你应该做一个梯度测试才行呀」——扫完整条曲线,结论整个反了。这个脚本就是那次教训的固化。

它判的不是"热不热",是"同总线上更累的邻居有没有事"

单看一颗舵机永远说不清:温度高可能是它在使劲,通信失败可能是总线、供电、线缆,甚至是别人在占串口。

所以判据是对照:拿同一条总线、同一路供电、同一束线缆上的健康关节做参照,比的是同样负载下谁先崩。当晚热态的数据是这样——

ID 2 负载 184-218  ->  通信失败 15 / 23 / 33
ID 3 负载 215-223  ->  失败 0
ID 4 负载 199-224  ->  失败 0

健康的扛得住 220+,它过约 150 就让总线崩。同总线、同供电、同线缆——只能是那一颗。这一步是对的,被推翻的是下一步。

被推翻的那一步:三个点不足以定性

上面那三行是三个幅度点。我据此写下"劣化",其实是在两点之间画直线:默认失败率随负载单调上升、而且已经跨过了它的能力边界。

这两个假设都没有被验证过。过热会让舵机暂时降额——表面凉了不等于绕组凉了——所以"现在扛不住 150"完全可能是"此刻扛不住",而不是"永久扛不住"。分不开这两者,靠的不是更小心地解读三个点,而是把整条曲线扫出来,凉透之后再扫一遍。

--sweep:凉透之后的完整梯度

0801602403205101520253040 ID2 291(过热那颗) ID3/ID4 223 / 220(健康对照) 动作幅度(counts) 负载读数
横轴是命令幅度,纵轴是舵机报的负载。三条曲线在同一条总线上同时测得。过热那颗(粗线)全程高于两个健康对照,峰值 291 对 223 / 220,而且七个幅度全部零失败——包括热态时失败 15–33 次的 2.6°。
幅度角度ID2 失败/负载ID3 失败/负载ID4 失败/负载
50.4°0 / 320 / 360 / 37
100.9°0 / 780 / 770 / 81
151.3°0 / 1490 / 1200 / 116
201.8°0 / 1950 / 1480 / 143
252.2°0 / 2390 / 1710 / 164
302.6°0 / 2550 / 2070 / 188
403.5°0 / 2910 / 2230 / 220

结论:过热降额,已完全恢复。舵机是好的。

注意它翻的方向——不是"没那么糟",是反过来了:那颗被我判死刑的舵机,凉透后的带载能力高于两个健康参照。三个点给出的结论和七个点给出的结论是相反的,不是程度不同。

怎么跑

# 默认:左臂 ID2 为怀疑对象,ID3/ID4 为对照
python servo_load_probe.py

# 完整梯度扫描(推翻误判用的就是这条)
python servo_load_probe.py --sweep

# 换一条总线 / 换怀疑对象
python servo_load_probe.py --bus /dev/ttyACM0 --suspect 2 --refs 3 4
参数默认作用
--bus/dev/ttyACM1串口。左臂 ACM1,右臂 ACM0
--suspect2怀疑的舵机 ID(2 = shoulder_lift)
--refs3 4对照组。必须同总线,否则比的是两条总线不是两颗舵机
--delta30单步幅度,counts。30 ≈ 2.6°
--sweep关扫整条梯度,而不是只测一个幅度
--temp-stop45.0超过这个温度立刻卸力矩中止

安全边界

下次怎么用这些数字

上面那张表就是基线。以后同一颗关节再出问题,凉透之后跑 --sweep 直接对比:

有基线和没基线的差别,就是这一页和那次误判的差别。

这个工具答不了什么

源码 03-software/scripts/servo_load_probe.py(230 行)。数据为 2026-09-08 凌晨实测。

相关:过热事件全过程 · 给主办方的通报 · 当晚修掉的三个遥操作 bug