这篇在系列中的位置
上一篇我们做了一个 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 这样的关节伺服电机,而不是普通交通工具轮毂电机。
我们要做什么
目标很朴素:
- 树莓派接上电机。
- 树莓派运行一个 Web 服务。
- Mac 打开网页。
- 网页能选择串口。
- 网页能读取电机 ID。
- 网页能安全读取电机实时数据。
- 网页能发送真实调试参数,让电机按我们配置运动。
- 任何危险动作都要可停止、可观察、可记录。
最终页面大致分成四块:
- 顶部通信区: 电机类型、串口、发送频率、接收频率、急停。
- 数据解析区: 电机 ID、模式、扭矩、速度、位置、温度、错误状态、接收原始数据。
- 调试数据输入区: 目标 ID、模式、速度、位置、Kp、Kd、扭矩、发送频率、发送数据预览。
- 配置工具区: 查询 ID、恢复电机模式、安全读取、修改 ID 等工具入口。
系统结构
- 宇树 Python SDK / 官方 motor_tools
- 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 / 原始转子位置 radAbsolute 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 整机电机调试流程中。
