开发机器人时,如何通过Python控制RobStride电机
与其它类型的软件工程相比,机器人领域的一个显著区别在于硬件和物理世界是开发的核心问题。尽管理解机器人运行所涉及的物理原理和机械结构极为复杂,值得撰写多部专著,但本文的重点将放在RobStride系列电机上,简要介绍如何使用它们,以便在AI热潮推动下开始涉足硬件领域的众多软件工程师,能够借助这些出色的执行器有一个坚实的学习起点。我撰写本文的核心原因在于,我发现目前关于这些电机脚本的文档存在不足(或在某些情况下完全缺失,链接已失效),因此希望本文能为他人节省时间和麻烦。
那么首先,什么是RobStride电机?这些是现代机器人中使用的一种特定电机系列,例如Seeed Studio ReBot或开源的HuggingFace LeRobot Humanoid。虽然其他小型机器人项目中常见的电机,如SO-ARM101中的Feetech电机,通常为齿轮伺服电机或步进电机,
但RobStride系列电机采用的是准直驱(QDD)执行器,其核心结构为高扭矩无刷直流(BLDC)外转子,搭配行星减速齿轮和双高分辨率磁编码器。换言之,电机内部完全静止不动,而核心机械机构通过电信号控制外部外壳围绕中心平稳旋转,利用磁场力的平滑切换产生旋转效果。
设置
本文中,我将使用RobStride O0电机,因为这是其中一款体积较小、价格较便宜的型号。这类电机需要48伏电压才能正常工作,因此我的示例接线使用了一块小型电动自行车电池,以及从LeRobot Humanoid项目中提取的SavvyCAN USB转CAN FD转换器来为电机供电,并通过Linux笔记本电脑与之通信(其他操作系统可能也能运行,但在我Mac上使用时出现了一些问题,而Linux系统则一切顺利)。
关于接线,电池会提供一根火线和一根地线,分别连接到电机。地线还需要分出两路,分别连接至CAN转换器。转换器本身也有高低电平数据线,需连接到电机。最终,你的接线配置应如下所示:
关于CAN总线终端电阻的硬件说明:CAN总线网络在两端都需要安装120欧姆的终端电阻,以防止信号反射。大多数USB转CAN适配器(例如我所使用的SavvyCAN适配器)默认已启用内置的终端电阻。但是,如果您使用的是不同的CAN接口,并且遇到数据包丢失或帧错误,请检查您的适配器或电机是否需要开启终端电阻。
RobStride 模式
当您首次从包装中取出RobStride电机时,它将默认设置为RobStride私有模式,但同时也支持MIT和CANopen模式。这些模式在数据包的帧结构、反馈触发方式以及电机驱动器上执行的底层循环方面各有不同。
私有模式是一种专有协议,可在初始台架测试时使用,当需要重新配置为默认系统,或计划采用原生的位置/速度曲线命令而非纯扭矩前馈控制时使用。该模式采用29位扩展帧ID。MIT模式则使用11位标准CAN帧格式,专为快速、轻量化的数据包传输而优化。它不采用独立的位置或速度环路,而是提供一种低延迟控制方式,通过一个紧凑的循环同时接收五个参数:目标位置、目标速度、位置刚度、速度阻尼和前馈扭矩。这是LeRobot人形机器人项目及其他机器人项目所使用的默认模式。最后还有CANopen模式,该模式适用于多种现有的工业设备架构,有助于实现多厂商间的互操作性。本文将重点介绍MIT模式。
初步测试
在介绍了RobStride电机系列的一些基本概念之后,现在让我们进入更有趣的部分:实际使用执行器。
在您的 Linux 电脑上,您需要确保已安装 can-utils 软件包,以便与电机进行通信。
安装该工具包后,您应设置 can0 接口使用 1 Mbps 的波特率,并处于“开启”(on)模式。需要注意的是,除非在系统网络配置中保存,否则 Linux 每次重启时都会重置此接口。
接下来,我们开启对实时 CAN 总线的嗅探功能。
由于默认的电机配置为私有模式,ID 为 127,因此我假设您拥有相同的值。如果您已经更改了模式或 ID,则您已具备基础条件,可以跳过本部分直接查看是否有新内容需要了解。
在第二个终端窗口中,尝试向电机发送 ping 命令,查看是否能在嗅探器终端窗口中收到响应。
您应该会收到一个 29 位的响应,其中仲裁 ID(ArbID)为 0x00007FFD,包含一个 64 位的 MCU UID。
如果上述操作成功,说明所有设置均已正确完成,现在可以继续进行后续操作。
发现扫描器
在测试 LeRobot 人形机器人时,我遇到的第一个问题是:用于定位电机并检查其 ID 的脚本仅在私有模式下有效。因此,一旦我切换到 MIT 模式,该电机就会对默认提供的脚本不可见(不过最近我已经重写并发布了这个脚本到代码仓库中,所以如果你正在尝试运行这个项目,现在应该不会再有问题了 :))。此脚本可以帮助你识别连接到设备的任何模式/ID 配置下的电机,以验证其通信是否正常。同时,你也需要确保安装 Python 包 'can'。
更改协议
现在你已经可以找到电机的模式和 ID 信息,接下来就是切换这些模式。假设你当前处于私有模式,可以使用以下脚本来将电机切换为 MIT 模式。需要注意的是,在更改模式以及更改所有 ID 以确保正确存储到电机闪存中时,都需要重新上电(拔掉电源后重新插上)。
结果:
如果你想从 MIT 模式切换回私有模式,可以使用更简单的脚本完成:
结果:
MIT 电机控制(摆动测试)
使用传统伺服电机时,通过高机械阻抗(高刚度)来控制它。你指令设备移动到角度θ,如果前方有障碍物,控制器会增加功率以强行推动其通过。
而采用准直接驱动电机时,低速比齿轮使轴易于反向驱动,这意味着除非被高主动扭矩所抵消,否则外部力可以物理地推压并旋转电机。我们不再强制设定固定位置,而是通过阻抗控制,让电机表现出如同连接在减震器上的虚拟机械弹簧一般的行为。与直接命令硬性位置不同,我们只需告诉电机目标弹簧锚点的位置(p_target)、弹簧的刚度(Kp)以及需要施加的减震量(Kd)。
这可以用以下方程表示:
其中,Kp * (p_target - p_actual) 表示一种虚拟刚度(弹簧),其作用是根据物理学中的胡克定律向目标方向拉伸;Kd * (v_target - v_actual) 表示一种虚拟阻尼/减震器,用于抵抗速度的快速变化并抑制振荡;而 torque_ff(前馈扭矩)则代表为抵消外部载荷(如重力)所需的基本力,且无需依赖位置误差来建立扭矩。
我们可以利用这些信息,为电机设置自定义的摆动测试,通过设定 p_target(time) = amplitude × sin(angular_frequency × time) 和 v_target(time) = angular_frequency × amplitude × cos(angular_frequency × time),从而定义运动的形状、幅度和速度。
运行此脚本时,请确保电机处于安全位置或被固定。如果电机尚未归零,它将迅速移动到零位以开始摆动测试。
运行后,您应看到电机先返回零位,然后在-90度至90度之间摆动,最后再次回到零位。
将 MIT 模式电机设置为机械零点(校准)
在之前的代码片段中,你可能已经注意到电机快速跳转到零位。为了避免这种情况,或在新组装的机器人上设置默认的零点,你可以手动将电机的当前位置设为新的零值。这通常是校准机器人时的第一步之一,以便更好地控制设备在运行过程中最大和最小值的设定。
一旦设置了零点位置,你可以根据需要移动电机以记录其上下限,然后运行此脚本返回已校准的零点位置。
读取更多数据
在掌握了运动和配置的核心概念之后,我想重点介绍的最后一项功能是:你可以从电机读取多个数值,用于做出决策,例如当电机开始过热时降低施加的力,以避免烧毁电机;或者了解电机的运动速度,确保其处于安全范围内。
在这个示例中,你可以看到如何在电机运行过程中读取角度、速度、扭矩和温度,并获取其整体健康状态。你可以在ROS2节点中执行这些操作,以触发各种动作。
这应该会输出连续的状态值流,就像我开启状态脚本并手动移动电机中心,在测试期间改变速度和角度值时的这个例子一样。
本文编译自hackster.io





