先读到,再看懂,再安全动。

把 GO-M8010-6 的通信、状态读取、参数发送与失败排查收束到一个可观察、可停止的网页工具里。

宇树 GO-M8010-6 电机 Web 调试助手的信息图,展示 Mac 网页、树莓派、USB-485、电源与急停

这篇在系列中的位置

上一篇我们做了一个 IMU 姿态调试器,目标是先把传感器数据“看见”。这一篇继续沿用同一个思路,但对象换成了更危险、也更关键的东西: 电机。

电机和 IMU 不一样。IMU 读错了,最多是画面姿态不对;电机命令发错了,它会真的转起来。所以这篇的重点不是“如何最快让电机转”,而是如何一步一步搭一个安全、可观察、可回退的调试工具。

最终我们做成了一个运行在树莓派上的 Flask Web 服务。Mac 不直接插电机,只需要打开浏览器访问树莓派网页,就可以读取电机 ID、观察回包数据、设置调试参数、开始或停止发送命令。

先用一句话讲清楚

我们做的不是一个花哨网页,而是一个“电机翻译台”: Mac 负责显示和操作,树莓派负责和电机说话,网页把每一步通信过程都展示出来,让新手也能知道问题卡在网络、串口、电机模式、协议解析,还是控制参数上。

先把几个词讲成人话

树莓派是什么

树莓派可以理解成一台很小的 Linux 电脑。它没有普通笔记本那么强,但很适合放在机器人身上,负责连接各种传感器、电机和通信模块。

在这个项目里,树莓派承担两件事:

  • 插 USB 转 485 设备,和电机通信。
  • 开一个 Web 服务,让 Mac 浏览器可以远程访问。

Mac 在这里做什么

Mac 不直接控制电机。Mac 只是打开网页,相当于一个遥控器和显示屏。

这样做的好处是:

  • 树莓派可以固定接在线路上。
  • Mac 不需要安装一堆电机 SDK。
  • 调试界面可以做得更直观。
  • 后续换电脑也方便,只要能打开网页就行。

RS-485 是什么

RS-485 可以先理解为一种“抗干扰的有线对讲方式”。电机不会通过普通网页或 Wi-Fi 直接说话,它通过 RS-485 这种工业通信方式和外部设备交流。

我们用的是 USB 转 4 路 485 设备。它插在树莓派 USB 口上,树莓派看到的是几个串口。我们最后使用的是 Uart4,对应稳定路径:

/dev/serial/by-id/usb-FTDI_USB__-__Serial_Converter_FTAIPADN-if03-port0

这个路径比 /dev/ttyUSB3、/dev/ttyUSB4 更可靠,因为 USB 设备重新插拔后,临时编号可能变化。

Flask 是什么

Flask 是 Python 里的一个轻量 Web 框架。你可以把它理解成“用 Python 写一个网页服务器”的工具。

在这个项目里,Flask 做了三件事:

  • 给浏览器返回调试页面。
  • 接收页面按钮和参数。
  • 调用树莓派上的宇树 SDK 或官方工具,真正和电机通信。

GO-M8010-6 是什么

GO-M8010-6 是宇树的一款机器人关节电机。更准确地说,它不是普通“转起来就行”的电机,而是一个集成了电机、减速器、驱动控制、位置传感器和通信接口的伺服关节。

你可以把它想象成机器人腿上的“肌肉 + 关节感知器 + 小脑控制器”的组合。它不只是能转,还要知道自己转到了哪里、转得多快、正在输出多少力,并能按照上位机给的目标去控制位置、速度或扭矩。

我们这次不是把整台机器人一次性跑起来,而是先只调一个电机。只调一个电机的好处是问题更少、更容易定位,也更安全。

资料来源主要是宇树 GO-M8010-6 官方规格页和 GO-M8010-6 Motor User Manual。下面这些数字不是为了让新手背参数,而是帮助你建立直觉: 这个小电机到底有多有力、多快、为什么需要谨慎对待。

左右滑动查看完整表格

参数 官方规格 新手可以怎么理解
工作电压 24 V DC 常见机器人低压直流系统,不是手机充电器那种小电流场景。
最大允许电压 30 V DC 电压不能随便加高,超过上限可能损坏驱动。
峰值电流 40 A 这是非常大的电流,线材、接头、供电都要认真对待。
最大扭矩 23.7 N·m 这代表它能在短力臂上产生很大的“拧劲”,不是玩具级别。
最大转速 30 rad/s 约 286 rpm,也就是空载时每秒接近 4.8 圈。
减速比 1:6.33 电机内部高速转动,经过减速器后输出更大的力、更低的速度。
编码器 15 bit 绝对编码器 可以把一圈分成 32768 份,用来知道转子位置。
通信方式 RS-485 用一对差分信号线和上位机通信,适合机器人内部抗干扰通信。
重量 约 530 g 接近一瓶 500 ml 矿泉水的重量。
尺寸 约 96.5 × 92.5 × 42 mm 大概是手掌级别的紧凑关节执行器。

最大扭矩到底有多大

扭矩的单位是 N·m,读作牛米。它不是“能直接提起多少公斤”,而是“在某个力臂长度上能产生多大的旋转力”。

可以用一个近似公式建立直觉:

能托住的重量 kg ≈ 扭矩 N·m / (9.8 × 力臂长度 m)

如果按峰值扭矩 23.7 N·m 做理想估算:

左右滑动查看完整表格

力臂长度 理想静态等效重量
5 cm 约 48 kg
10 cm 约 24 kg
20 cm 约 12 kg

这不是说你应该拿它去吊这些重量。真实系统里还要考虑连续扭矩、散热、冲击、结构强度、安全系数和控制稳定性。这个表只是为了说明一件事: 这种电机的力非常大,手指、线缆、3D 打印件、桌面夹具都可能被它轻易伤到或打坏。

所以我们在调试软件里一直坚持:

  • 不自动启动电机运动。
  • 每个运动功能都要有停止按钮。
  • 页面要显示真实发送数据。
  • 启动前先能读取 ID 和安全读取。
  • 参数从很小值开始慢慢试。

最大转速为什么也危险

30 rad/s 听起来不直观。换算一下:

30 rad/s ≈ 286 rpm ≈ 每秒 4.8 圈

这里有两个常见单位:

  • rad/s: 每秒多少弧度,中文可以叫“弧度每秒”。弧度是角度的另一种表示方式,一整圈是 2π rad,大约等于 6.28 rad。
  • rpm: revolutions per minute,中文常说“每分钟转数”。286 rpm 的意思是每分钟约转 286 圈。

所以把 30 rad/s 换成人更容易感知的说法,就是:

30 rad/s ÷ 6.28 ≈ 每秒 4.8 圈
每秒 4.8 圈 × 60 ≈ 每分钟 286 圈

这也是为什么工程师喜欢用 rad/s 做计算,但普通人更容易用 rpm 或“每秒几圈”建立感觉。

如果输出端接了一个 10 cm 长的小连杆,末端线速度理想情况下可能接近:

30 × 0.1 = 3 m/s

3 m/s 已经是很快的一甩。机器人腿、连杆、螺丝、测试夹具如果没有固定好,就可能突然扫到人或桌面。所以调试时哪怕只是“慢速旋转”,也要把电机固定好,让输出端远离手和易碎物。

峰值电流 40A 意味着什么

很多新手看到 24V 会觉得“电压不高,应该安全”。但电机系统不能只看电压,还要看电流。

40A 是很大的电流。它意味着:

  • 供电电源要能承受瞬时大电流。
  • 线材太细会发热。
  • 接头接触不良会发热、打火或掉电。
  • 电机突然加速时,系统可能出现电压下陷。

所以不要在通电状态下随意插拔电机电源线,也不要用来路不明、规格不足的线材和电源做运动测试。

编码器是干什么的

编码器可以理解成电机里的“量角器”。

普通电机只要通电就会转,但它自己不一定知道转到了哪里。机器人关节不能这样,因为机器人需要知道:

  • 腿现在抬到多少度。
  • 关节有没有到目标位置。
  • 当前是不是被外力推偏了。
  • 速度有没有超出预期。

GO-M8010-6 里有 15 bit 绝对编码器。15 bit 的意思是理论上一圈可以分成:

2^15 = 32768 份

也就是说,转子一圈里每一份大约是:

360° / 32768 ≈ 0.011°

再考虑 1:6.33 的减速比,输出端角度变化会更细。我们的 Web 页面后来把 SDK 原始 q 保留下来,同时增加“输出端绝对位置 °”,就是因为原始编码器数据和人想看的关节角度不是一回事。

它和两轮电动车上的电机有什么区别

很多人第一次看到机器人电机会问: 电动车电机也能转,也很有力,为什么不能拿来做机器人关节?

核心区别是: 电动车电机主要是为了“持续高效地让轮子转”,机器人伺服电机是为了“精确、快速、可反馈地控制关节”。

可以这样对比:

左右滑动查看完整表格

对比项 两轮电动车电机 机器人伺服关节电机
主要目标 让车轮持续转动 控制关节位置、速度和扭矩
常见工作方式 一直往前转,追求效率和续航 经常启停、换向、保持角度
位置感知 通常只需要粗略换相或速度反馈 需要高精度编码器反馈
控制要求 人拧油门,车轮转起来 程序给目标角度/速度/力矩
体积和重量 为车轮和车架设计 为机器人关节紧凑集成
低速控制 很多场景不追求极低速精确控制 需要低速、静止、抗外力都可控
安装方式 装在车轮或传动系统里 直接作为髋、膝、踝等关节

机器人关节经常要做这些事:

  • 转到 30° 后停住。
  • 以很慢速度转动。
  • 被外力推时能感知偏差。
  • 在不转动时仍然保持姿态。
  • 多个关节同步配合。

这就需要伺服控制。

所谓“伺服”,可以先理解为闭环控制:

设定目标 -> 传感器测量当前位置 -> 控制器比较误差 -> 电机修正动作 -> 再测量

也就是说,伺服电机不是“我给电它就转”,而是“我告诉它目标,它边测量边修正”。编码器就是这个闭环里的眼睛。

两轮电动车电机当然也有控制器,也可能有霍尔传感器,但它的系统目标通常不是高精度关节控制。它更大、更重、惯量更高,低速精密控制和静止保持也不是它的强项。把它硬塞进机器人关节里,会遇到重量、安装、控制精度、响应速度、通信接口和安全性等一连串问题。

所以在 Qmini 这种机器人里,我们需要的是像 GO-M8010-6 这样的关节伺服电机,而不是普通交通工具轮毂电机。

我们要做什么

目标很朴素:

  1. 树莓派接上电机。
  2. 树莓派运行一个 Web 服务。
  3. Mac 打开网页。
  4. 网页能选择串口。
  5. 网页能读取电机 ID。
  6. 网页能安全读取电机实时数据。
  7. 网页能发送真实调试参数,让电机按我们配置运动。
  8. 任何危险动作都要可停止、可观察、可记录。

最终页面大致分成四块:

  • 顶部通信区: 电机类型、串口、发送频率、接收频率、急停。
  • 数据解析区: 电机 ID、模式、扭矩、速度、位置、温度、错误状态、接收原始数据。
  • 调试数据输入区: 目标 ID、模式、速度、位置、Kp、Kd、扭矩、发送频率、发送数据预览。
  • 配置工具区: 查询 ID、恢复电机模式、安全读取、修改 ID 等工具入口。

系统结构

流程概览
  1. 宇树 Python SDK / 官方 motor_tools
  2. USB 转 4 路 RS-485

↻ 反馈进入下一轮

这张图里最重要的是方向感:

  • 人在 Mac 上点按钮。
  • 按钮请求发到树莓派。
  • 树莓派通过 USB-485 对电机说话。
  • 220V 转 24V 电源给电机提供动力,中间串接急停开关;出现紧急情况时,可以用急停快速切断电机电源。
  • 通信线不能替代电源线,网页里的停止按钮也不能替代硬件急停。
  • 电机把数据回给树莓派。
  • 树莓派把结果显示回网页。

如果网页打不开,问题可能在 Mac 到树莓派这段。

如果网页能打开但读不到 ID,问题可能在树莓派到电机这段。

如果能读 ID 但电机不动,问题可能在电机模式或控制参数。

第一阶段: 先让网页能打开

一开始我们要解决的不是电机控制,而是更基础的问题: Mac 能不能访问树莓派上的网页。

我们把 Flask 服务放在树莓派上,监听端口 5010。Mac 浏览器访问:

http://raspberrypi.local:5010/

这里踩过一个非常新手但常见的坑: Mac 连错了路由器。

当时表现是:

ping raspberrypi.local: 100% 丢包
SSH 22: 超时
Web 5010: 超时

后来发现 Mac 当前 IP 在另一个网段。换回正确路由器后,网页就能打开。

这件事给我们的第一个经验是: 调硬件前先确认网络。网页打不开时,不要急着怀疑程序,先问:

  • 树莓派开机了吗?
  • Mac 和树莓派在同一个网络吗?
  • 树莓派 IP 还是不是原来的地址?
  • 5010 端口的服务有没有启动?

第二阶段: 不要急着自研协议

最开始我们尝试自己做协议监听和解析,希望能直接看到电机持续发出的数据。但很快出现了不正常的回包:

correct=False
q=1.83149e+25
dq=5.3522e-11
tau=1.74693e+19
temp=0
err=1635087459

对新手来说,这串数字看起来像天书。其实可以先记住一个判断: 数值特别离谱时,先不要相信自己解析对了。

那一刻我们决定暂停自研协议,改用官方工具和官方示例。这是整件事里很重要的一次收敛。

原因很简单:

  • 如果官方工具也读不到,说明电气、模式、串口或设备状态有问题。
  • 如果官方工具能读到,而自研代码读不到,才说明自研代码有问题。

调硬件时,不要一开始就站在最难的位置。先找一条官方验证路径。

第三阶段: 官方例程也失败了

我们把宇树官方 GO-M8010-6 Python 示例封装成网页按钮。页面可以选择串口,点击启动就运行官方例程,点击停止就杀掉例程进程,并把例程日志显示在网页上。

但官方例程运行后,电机没有动作,日志仍然显示:

motor id=0 does not reply

这说明问题还没到“我们写错控制算法”的层面。官方例程都收不到正常回复,优先怀疑的是:

  • 电机 ID 不对。
  • 电机不在 Motor Mode。
  • 串口通道选错。
  • USB-485 接线、供电或共地有问题。

用户后来在 Windows 官方软件里确认,当前电机 ID 是 0。这时任务进一步简化: 先别管旋转,先在树莓派上成功读取电机 ID。

第四阶段: 先读到电机 ID

我们使用宇树官方 motor_tools 里的 swboot 工具,在树莓派 Uart4 上读取 ID,成功得到:

1.Motor ID 0
---------------
Total 1 motors

这一步非常关键。

它证明:

  • 树莓派串口权限基本没问题。
  • USB 转 485 通道能工作。
  • 线缆和电机供电大概率没问题。
  • 电机 ID 是 0。
  • 树莓派到电机的通信链路是通的。

这个阶段我们把 Web 页面收窄成一个最小功能: 查询 ID。

这听起来很小,但它是整个调试助手的第一块地基。因为只有先证明“能说上话”,后面才谈得上读数据和控制运动。

第五阶段: 页面开始像一个调试助手

读 ID 成功后,我们开始参考宇树官方 Motor Debugging Assistant 的界面,把页面整理成更像真正上位机的结构。

我们没有一口气接入所有按钮。相反,我们采用了一个原则:

已经实测成功的功能,才接真实硬件动作。
还没验证的危险功能,先做界面占位。

于是页面里最早真实接入的是:

  • 查询 ID。
  • 恢复电机模式。
  • 安全读取。

像修改 ID、上传固件这类动作,虽然页面上可以先出现,但不急着发真实命令。因为这些动作一旦做错,排查成本会高很多。

第六阶段: 恢复电机模式和安全读取

电机不仅有 ID,还有工作模式。用户观察到电机指示灯状态变化,我们结合宇树工具说明判断: 绿灯慢闪通常代表已经处于 Motor Mode,也就是正常工作态。

但判断灯只是一个参考。更可靠的方法是: 用零输出命令安全读取实时数据。

所谓零输出命令,就是每一帧都发送:

cmd.q = 0.0
cmd.dq = 0.0
cmd.kp = 0.0
cmd.kd = 0.0
cmd.tau = 0.0

这些字段先不用完全理解,可以简单看成:

不要位置控制
不要速度控制
不要刚度
不要阻尼
不要扭矩
只要回包数据

我们把这个功能做成“开始安全读取”和“停止读取”按钮。启动后页面能看到电机返回的:

  • 位置 q
  • 速度 dq
  • 扭矩 tau
  • 温度 temp
  • 错误状态 merror

当安全读取成功时,我们终于确认: 电机已经不只是能读 ID,而是能通过 SDK 正常回包。

第七阶段: 第一次让电机转起来

接下来我们尝试让电机慢速旋转。

第一版思路是速度控制,用 dq 和 kd。但用户反馈电机没有转。后来用户用官方软件试出一个有效条件:

扭矩: 0.03 Nm
通信频率: 1000 Hz

于是我们先复刻这个有效参数,把控制改成力矩慢转:

cmd.dq = 0.0
cmd.kp = 0.0
cmd.kd = 0.0
cmd.tau = direction * torque_nm

这里的 tau 可以先理解为“给电机多大劲”。direction 是方向,torque_nm 是力矩大小。所以:

正向: tau = +0.03
反向: tau = -0.03

电机终于能动起来。

但这也带来一个重要发现: 用力矩控制,不等于控制速度。

如果电机空载,稍微加大一点力矩,它就会越转越顺,因为你是在持续给它施加“推力”。这就像你一直推一个转盘,它会越来越快,直到摩擦或负载把它平衡住。

所以我们后来明确区分:

  • tau: 给多大劲。
  • dq: 希望转多快。
  • q: 希望到哪个位置。

第八阶段: 页面填什么,就真的发什么

中间出现过一个容易误导人的问题: 页面上有很多输入框,比如速度、位置、Kp、Kd,但后端真实发送时只用了其中几个字段。

用户指出这一点后,我们做了一个重要修正:

开始发送时,必须发送页面中配置的真实调试数据。
发送过程中,用户改任何参数,后台也要切换到新参数。

这个要求让工具从“几个按钮的封装”变成了真正的调试助手。

实现方式是:

  • 页面把所有调试参数组成一个 JSON。
  • 点击“开始发送”时,把 JSON 发给后端。
  • 后端启动一个持续发送进程。
  • 运行中页面参数变化时,调用 /api/spin/update。
  • 发送进程不重启,但会读取最新命令继续发送。

对使用者来说,这意味着:

我看到什么参数,就知道电机正在按什么参数发送。

这对调试非常重要。

第九阶段: 做定速旋转

当真实参数都能发送后,我们开始做定速旋转。

理论上,如果想 60 秒转一圈,输出端角速度应该是:

2π / 60 = 0.1047 rad/s

但实际测试发现,直接填 0.1047 不一定能稳定转动。原因是这里还牵涉到电机内部齿比、静摩擦和 SDK 原始量纲。

用户后来测试:

Output Speed rad/s = 1
Kd = 0.2

电机开始缓慢旋转。

再进一步,用户配置:

Output Speed rad/s = 0.8

实测一圈大约用了 52 秒。我们用比例校准:

新速度 = 当前速度 * 实际时间 / 目标时间
新速度 = 0.8 * 52 / 60
新速度 = 0.6933

所以下一次可以试:

Output Speed rad/s = 0.69

这个过程给新手一个很好的经验: 控制参数不是只靠公式一次算完。现实里要测、要标定、要修正。

第十阶段: 位置显示也会骗人

页面里一开始显示 Rotor Position,也就是转子位置。用户发现它看起来像累计圈数,不像自己想要的绝对位置。

我们先把原始 q 做了单圈取模,但后来进一步发现: SDK 原始 q 更接近电机转子侧角度,不是输出端角度。

树莓派上查询 GO-M8010-6 齿比:

queryGearRatio(GO_M8010_6) = 6.33

所以输出端位置应该这样换算:

输出端位置 rad = data.q / 6.33

如果要显示成度:

输出端角度 ° = (data.q / 6.33) * 180 / π

我们最后在页面上同时保留两套数据:

  • Raw Rotor Position rad / 原始转子位置 rad
  • Absolute Position ° / 绝对位置 °

并增加了“设置零点位置”按钮。点击后,当前角度会被当成 0 度,后续显示范围归一化到:

0-360°

这一步很重要,因为它体现了一个调试工具应该有的态度:

不要丢掉原始数据。
在原始数据旁边增加人更容易理解的换算数据。

最终做成了什么

截至这篇文章整理时,GO-M8010-6 Web 调试助手已经具备这些能力:

  • Mac 浏览器远程访问树莓派页面。
  • 枚举并选择树莓派串口。
  • 使用官方 swboot 查询电机 ID。
  • 使用官方 swmotor 请求恢复电机模式。
  • 低频安全读取电机数据。
  • 显示接收数据和发送数据。
  • 页面参数变化后实时更新发送命令。
  • 支持力矩、速度、位置、Kp、Kd 等真实字段发送。
  • 支持急停和停止发送。
  • 显示原始转子位置。
  • 按齿比换算输出端绝对角度。
  • 支持设置零点位置。
  • 全页面英文都补充中文说明。

对新手最重要的经验

1. 先确认链路,再谈控制

我们不是一上来就让电机转,而是按这个顺序走:

网页能打开
树莓派能访问
串口能找到
官方工具能读 ID
SDK 能安全读取
再开始发送控制命令

这个顺序看起来慢,但它避免了很多“到底哪里错了”的混乱。

2. 官方工具是最好的第一把尺子

当自研解析失败时,不要硬猜。先用官方工具验证:

  • 官方工具也失败: 先查电气、模式、串口。
  • 官方工具成功,自研失败: 再查自己代码。

这能极大减少排错范围。

3. 电机控制一定要可停止

每一个会让电机动起来的功能,都应该配套:

  • 停止按钮。
  • 急停按钮。
  • 参数限幅。
  • 运行状态显示。
  • 原始日志显示。

如果一个工具只能启动,不能可靠停止,它就还不应该用来调真实硬件。

4. 网页显示值不等于原始值

人想看的往往是“输出端角度是多少度”,但 SDK 可能返回的是“转子侧弧度累计值”。所以调试页面里最好同时显示:

  • 原始值。
  • 换算值。
  • 换算依据。

这样后面发现问题时,不会因为显示层隐藏了原始信息而无从排查。

5. 每一步都写日志

这个项目能够推进,很大程度上靠 项目日志索引.md 及其每日记录。它记录了:

  • 每次尝试。
  • 每个现象。
  • 每个失败原因。
  • 每次参数变化。
  • 每次部署验证。

硬件调试最怕“我记得好像试过”。日志能把“好像”变成“可复盘”。

如果你也想做类似工具,可以这样和 Agent 沟通

可以复制下面这段作为起点:

我想为一个电机做一个树莓派 Web 调试助手。
请不要一开始就写复杂控制。
请先帮我按以下顺序推进:
1. 确认 Mac 能访问树莓派 Web 页面。
2. 枚举串口并选择稳定串口路径。
3. 优先运行官方工具读取电机 ID。
4. 只有 ID 读取成功后,再接入安全读取。
5. 安全读取只发送零输出命令。
6. 任何会让电机运动的功能,都必须有停止按钮和状态显示。
7. 页面要显示原始接收数据,方便排查协议和量纲问题。
8. 每一次尝试、现象和结论都写入项目日志。

如果已经能安全读取,可以继续说:

现在已经能安全读取电机数据。
请把 Web 页面改成真实调试助手:
1. 页面中的调试参数必须和实际发送参数一致。
2. 点击开始发送后,如果我修改任意参数,后台应切换为新的参数继续发送。
3. 保留 Receive Data 原始 JSON。
4. 增加 Send Data 预览。
5. 速度、位置、扭矩、Kp、Kd 都要明确显示单位。

这篇文章背后的方法

这次做电机调试助手,本质不是“写了多少代码”,而是把混乱问题拆成一条可靠路径:

先连上
再读到
再看懂
再安全动
再调参数
再做显示修正

对新手来说,这比掌握某个具体 API 更重要。

因为机器人复刻不是一次写对所有东西。它更像是在黑暗里开灯: 每做一个小工具,就多照亮一块区域。等每一块都能看清,整台机器才有可能稳稳地跑起来。

下一步

这个 Web 调试助手已经可以支持单电机调试,但还不是最终整机控制系统。后续可以继续做:

  • 查询版本号等低风险工具。
  • 修改 ID 前的二次确认和保护流程。
  • 更清晰的速度标定工具。
  • 位置控制的 30 度、60 度小角度测试。
  • 多电机接入前的单电机安全测试清单。
  • 将调试助手的经验沉淀到 Qmini 整机电机调试流程中。