Skip to content
Published on

机械臂究竟由什么构成:连杆、关节,以及真正驱动关节的东西

分享
Authors

引言 —— 六个舵机搭出来的手臂,在自重下垮掉了

决定要做一条机械臂,于是去买零件。搜索结果里出现频率最高的一套组合是:六个 MG996R 舵机,亚克力或 3D 打印支架,5V 电源。

组装起来,通电。舵机们各自找到自己的位置,动了起来。

命令手臂水平伸出。肩部瑟瑟发抖地慢慢往下垂。舵机一直在响,手臂却抬不起来。命令它去抓点什么,直接整条垮掉。

不是代码问题,也不是电源问题。肩关节所需的扭矩,是那个舵机能输出数值的 1.66 倍。

这个数字后面会亲自算出来。眼下重要的是:这个计算本可以在买零件之前就在纸上算完。只要定下臂长和想举起的物体重量,每个关节所需的扭矩就能算出来,再拿这个值去和数据手册比对就行。

这篇文章要讲的,就是这个计算需要的东西:机械臂由什么构成,自由度到底数的是什么,驱动关节的三种方法各自擅长什么、不擅长什么,减速器给了什么、又拿走了什么。最后,把那个扭矩计算从头到尾走一遍。

连杆、关节、末端执行器 —— 三个词的精确含义

先把术语钉准。这三个词的定义,是后面所有计算的地基。

连杆是不发生形变的刚性构件。在机械臂里,它是连接关节与关节之间的结构件。对应到人的手臂,就是上臂骨和前臂骨。运动学之所以把连杆当成刚体来假设,是为了便于计算,而实物会挠曲的那部分,就变成了误差。

关节是连接两根连杆、同时允许它们之间相对运动的元件。它允许哪种运动,就决定了关节的类型。

末端执行器是装在手臂最末端、真正干活的装置:夹爪、吸盘、焊枪、相机。运动学计算里说的「末端位置」,指的是在末端执行器上定义好的一个基准点,这个点叫做工具中心点。

再加上基座,结构就完整了:一条从基座出发,连杆和关节交替相连,终止于末端执行器的链条。这种不分叉、始终是一条链的结构叫开链,绝大多数工业机械臂都是这种形态。

也存在闭链结构,比如并联机器人(delta robot)那样多个分支在末端重新汇合的结构,在刚性和速度上有优势,代价是工作空间窄、运动学复杂得多。这篇文章只讨论开链。

有一个惯例值得了解:给连杆和关节编号时,从基座开始向外数。 基座是连杆 0,第一个关节是关节 1,接下来是连杆 1。这样一来,关节 i 连接的就是连杆 i-1 和连杆 i正运动学那篇里变换矩阵的下标,遵循的正是这个规则。

自由度到底数的是什么,为什么以 6 为基准

自由度是能够独立指定的运动变量个数。在机械臂里,这通常就等于关节的数量。

为什么以 6 为基准,从目标那一端去数就很清楚了。要在三维空间里完全确定一个刚体的状态,需要多少个数?

位置需要三个:x、y、z。

姿态也需要三个,因为即便把物体固定在原地不动,依然可以绕三个轴独立旋转。

加起来是六个。所以要把末端执行器放到任意位置、任意朝向,至少需要六个关节。

以这个数字为基准,机械臂分成三类。

自由度名称能做到什么例子
少于6欠驱动只能指定位置或姿态的一部分SCARA(4)、并联机器人(3)、业余五轴臂
6全驱动工作空间内任意位置和姿态大多数工业机器人
7以上冗余驱动同一个末端姿态可以由多种臂形实现许多协作机器人、人的手臂

欠驱动并不代表不好。SCARA 是 4 自由度,但对于往电路板上垂直插元件这种任务来说,只要零件能垂直落下就够了,剩下的自由度根本用不上。少了自由度,换来的是快得多、也强壮和便宜得多。只拥有恰好需要的自由度,这本身就是一种设计,6 是一个基准点,不是上限。

冗余驱动带来的,是在保持末端不动的情况下改变手臂形状的能力。把手按在桌上一点不动、上下摆动肘部,立刻就能体会到这一点。这份余量可以用来避障或者规避关节极限,对应的数学工具就是逆运动学那篇里的零空间。

业余爱好者手臂里常见的 5 自由度处在一个尴尬的位置。手腕缺了一个旋转轴,导致在需要以特定朝向抓取物体的任务中,会突然冒出够不到的姿态。位置能对上,姿态却对不上——只要写程序,迟早会撞上这种情况。

转动关节与移动关节

实际机械臂里用到的关节,基本上只有两种。

转动关节绕一根轴旋转,关节变量是角度。人的肘和肩就是这种,工业机械臂里的关节几乎全是转动关节。

移动关节沿一根轴滑动,关节变量是长度。3D 打印机的每根轴、龙门机器人、SCARA 的 z 轴,都是这种。

两者的差异体现在性能曲线的形状上。

标准转动关节移动关节
关节变量角度距离
工作空间对占地面积
刚性连杆越长下降越剧烈大体均匀
精度越靠近连杆末端误差被放大越多与位置无关,均匀
负载引起的扭矩变化随姿态大幅变化大体恒定
运动学三角函数,解有多个大体线性,解唯一
密封与洁净容易导轨暴露,较难

第四行是转动关节在机械臂上带来的独有问题。关节的角度误差,会按连杆长度成比例地放大成末端位置误差。肩关节偏差 0.1 度,在 0.35 米外的末端就是:

0.1度 = 0.001745 rad
0.001745 × 0.35 m = 0.000611 m = 0.61 mm

0.61 毫米。而且这个误差,关节越靠近肩部,放大得越厉害。基座一侧关节的精度,支配着末端的精度。 后面讲减速器时,肩部一侧要用更贵的减速器,原因也在这里。

在国际标准 URDF 里,运动学用关节类型字符串来表达,可用的取值精确地只有六个:revolute(有范围限制的转动)、continuous(无限旋转)、prismatic(移动)、fixed(固定)、floating(6自由度)、planar(平面3自由度)。前三个是实际驱动的关节,fixed 用在只是想在计算上多放一个参考系的时候。

真正驱动关节的东西 —— 舵机、步进电机、BLDC

现在进入正题。知道关节要转动了,但到底是什么在转它?

RC 舵机 —— 下达角度指令,它自己就会到位

在业余爱好者的机械臂里用得最多。内部集成了直流电机、减速齿轮、位置传感器和控制电路。外部只需要给出目标角度,走到那个角度的过程由舵机内部的闭环自己搞定。

指令是靠 PWM 脉冲的宽度来传递的。标准惯例是大约每 20 毫秒发一个脉冲,宽度为 1 毫秒对应一端,1.5 毫秒对应中位,2 毫秒对应另一端。更新频率的容忍度很宽,大致在 40Hz 到 200Hz 之间都能工作。

这里有两点需要提醒。

第一,脉宽范围因厂商和型号而异。 以广泛使用的 SG90 为例,分销商的资料写的是 500 到 2400 微秒,但制造商 TowerPro 自己并没有公布脉宽规格。如果只用 1000 到 2000 微秒,实际上只用到了大约一半的可动范围。真实范围需要一点点转动舵机、亲自摸索出来。

第二,普通 PWM 输出的分辨率完全不够。 Arduino 的 analogWrite() 是 8 位的,把 20 毫秒周期分成 256 份,

20000 μs / 256 = 78.125 μs

一档是 78 微秒。如果 1000 到 2000 微秒对应 180 度,那 1 度就是 5.56 微秒,于是

78.125 μs / 5.56 μs = 14.06度

一档是 14 度。也就是说角度只能以 14 度为单位来指定。这就是为什么舵机要用专用库来驱动,而不是 analogWrite()。Arduino 的 Servo 库直接占用一个定时器,生成微秒级精度的脉宽。

#include <Servo.h>

// 舵机电源务必单独供电,只把GND和板子接在一起。
// 原因会在下面的"电源"一节里用计算来确认。
Servo shoulder;

const int SERVO_PIN = 9;
const int PULSE_MIN = 600;    // 这两个值因型号而异。
const int PULSE_MAX = 2400;   // 请一点点收窄区间,找出实际极限。

void setup() {
  // 给attach同时提供最小/最大脉宽,write(角度)就会被映射到这个范围内。
  shoulder.attach(SERVO_PIN, PULSE_MIN, PULSE_MAX);
  shoulder.writeMicroseconds(1500);   // 从中位开始
  delay(500);
}

void loop() {
  // writeMicroseconds(微秒)比write(角度)分辨率更高。
  // 把每步设为20us,换算成角度大约是2度,已经足够平滑。
  for (int us = 1000; us <= 2000; us += 20) {
    shoulder.writeMicroseconds(us);
    delay(20);                        // 与更新周期对齐
  }
  for (int us = 2000; us >= 1000; us -= 20) {
    shoulder.writeMicroseconds(us);
    delay(20);
  }
}

RC 舵机的局限很明确:读不到当前角度,发不出扭矩指令,也不知道自己正在用多大的力。发出指令、然后相信它已经到位,就是全部内容。要是负载太重根本没到位,也完全没办法知道。

解决这个局限的是智能舵机。ROBOTIS 的 Dynamixel 系列是典型代表,通过串行总线把多个舵机串联起来,可以读取每个舵机当前的位置、速度、负载和温度。按厂商资料,AX-12A 在 12V 下能输出 1.5 N·m 的堵转扭矩,位置分辨率 0.29 度(300 度范围分成 1024 份)。更高端的 X 系列分辨率提升到每转 4096,XM430-W350-R 在 11.1V 下能输出 3.8 N·m。这个型号还有基于电流的位置控制模式,可以下达「不要推得比这个力更大」这样的指令。

步进电机 —— 靠数步数前进,但不知道有没有真的到位

步进电机按顺序给线圈通电,把转子一步一步拽着走。就算没有位置传感器,数一数步数,也就等于知道了角度。

最常见的 NEMA 17 规格步距角是 1.8 度,一圈 200 步。直接用这个值,一个关节的分辨率就是 1.8 度,换算成臂长 0.35 米时的末端误差,

1.8度 = 0.031416 rad
0.031416 × 0.35 = 0.011 m = 11.0 mm

11 毫米。用在机械臂上远远不够。所以要用细分驱动(microstepping):不让线圈电流呈阶梯状变化,而是按正弦波近似输出,把每一步再切分开的技术。

驱动器最大细分每转步数每步角度0.35m处的末端移动量
无(整步)1/12001.8度11.00 mm
A49881/1632000.1125度0.687 mm
DRV88251/3264000.0563度0.344 mm
TMC22091/256512000.0070度0.043 mm

TMC2209 的 1/256 是靠一个叫 MicroPlyer 的插值功能实现的,能用引脚直接选择的数值是 8、16、32、64。

这里有件必须知道的事:细分驱动提高的是分辨率,不是精度。 步分得越细,每个微步产生的保持扭矩就越小,一旦静摩擦或负载扭矩比这个值更大,转子实际上根本不会动。指令上看起来是每次走 1/256 步,但物理上却是每隔几步才猛地跳一下。

而且步进电机还有一个根本性的危险:失步。

步进电机是开环的。它只是假设转子在跟随定子的磁场,从不做确认。这种同步会在三种条件下被打破。

一,负载扭矩超过了该转速下电机能输出的扭矩。步进电机的扭矩会随转速急剧下降,所以不能只看静止时的保持扭矩来选型。厂商资料建议在扭矩-转速曲线上留出 30% 的余量。

二,加速太猛。转子和负载的惯量瞬间要求的扭矩超标了。

三,低频共振。大致在每分钟 50 到 150 转的区间,也就是每秒 167 到 500 整步对应的范围内,转子会像扭转摆一样振鸣,有效扭矩会被抽掉。如果在别的转速下都正常,却单单在某个转速区间丢步,原因就是这个。

失步之所以可怕,是因为它很安静。 丢了十步,驱动器什么都不会说,控制器依然相信自己知道的那个角度。这份误差会一直留着,直到重新回零才会消失。在机械臂上,这意味着关节角度和实际情况不符,也就意味着正运动学算出来的末端位置全都是错的。

顺带一提,常用的 17HS4401S 厂商规格是保持扭矩 43 N·cm,相电流 1.7A,也就是 0.43 N·m,连后面要算的肩关节所需扭矩的四分之一都不到。不经减速就直接联接,是行不通的。

BLDC 与编码器 —— 真正的闭环

如果想要性能的天花板,就得给无刷电机配上编码器,自己直接控制。协作机器人和最近的高性能业余机械臂,走的就是这条路。

BLDC 没有电刷,所以没有磨损,同样体积下扭矩密度比有刷电机高,散热也更有利。代价是必须知道转子的位置,才能决定什么时候给线圈通电,所以位置传感器是必需的。

位置传感器广泛使用磁性旋转编码器。轴端装一块小磁铁,芯片读取磁场的方向。

元件分辨率每转分割数角度换算到0.35m末端
AS560012位40960.0879度0.537 mm
AS5047P14位163840.0220度0.134 mm
Dynamixel AX-12A1024分割/300度10240.2930度1.790 mm
Dynamixel X系列4096脉冲/转40960.0879度0.537 mm

AS5047P 支持每分钟 28000 转,在 ABI 增量输出的二进制模式下每转能给出 4096 步。

想把 BLDC 驱动得好,正确方法是磁场定向控制(FOC)。不直接处理三相电流,而是经过两次坐标变换:克拉克变换把三相映射到静止的两轴坐标系,帕克变换再把它映射到跟着转子一起转动的坐标系。在这个坐标系里,电流变成了直流量,普通的 PI 控制器就能处理,两个分量的作用也彻底分开了。d 轴电流产生磁通,q 轴电流产生扭矩。 所以才能直接下达扭矩指令。

在业余领域,SimpleFOC 库替你干了这件事。截至 2026 年 2 月发布的 v2.4.0,它支持 AVR、STM32、ESP32、Teensy、RP2040 等一大批板子,文档里提到,如果要考虑电流检测,推荐用 STM32 系列。

三种方式总结如下:

标准RC舵机步进电机BLDC+编码器
控制回路内置闭环开环自行搭建的闭环
下达的指令角度步数电流、速度、位置三选一
读取当前角度不行(智能舵机可以)不行可以
扭矩控制不行不行可以
静默失败不知道有没有到位不知道丢没丢步误差立刻暴露
接线难度3线4线+驱动器三相+编码器+驱动器
上手难度最简单中等最难
减速器大多内置另配另配

减速器 —— 传动比对扭矩和背隙做了什么

选好电机还没结束。机械臂的关节大多是经过减速器驱动的。原因有三个,第三个最重要,却也最少被提起。

把传动比记为 N

第一,扭矩会放大 N 倍。 更精确地说,是再乘以机械效率 η

输出扭矩 = 电机扭矩 × N × η

第二,速度会降到 N 分之一。 这是代价。电机每分钟转 3000 圈,经过 100:1 的减速器之后就变成每分钟 30 圈。

第三,负载惯量看起来会降到 N 的平方分之一。 这就是反射惯量,也是减速器真正让控制变简单的原因。20:1 的减速比下,电机感受到的手臂惯量会变成四百分之一。惯量看起来变小,同样的扭矩就能加速得更快;更重要的是,负载的变化传到电机这边会被削弱很多,控制器也就能更稳定地工作。

用数字来看看。给一个输出 0.09 N·m 的小电机配上几种不同的减速比:

传动比假设效率输出扭矩速度反射惯量
5:10.970.437 N·m1/51/25
20:10.941.692 N·m1/201/400
50:10.904.050 N·m1/501/2500
100:10.908.100 N·m1/1001/10000

效率数值只是假设,实际值会因减速器类型和等级不同而有很大差异。精密行星减速器厂商公布的数据,单级 97% 以上、两级 94% 以上,但业余用的廉价减速箱要比这低得多。

背隙 —— 减速器拿走的东西

减速器给出扭矩不是白给的。最大的代价就是背隙。

齿轮要啮合,齿与齿之间必须留有间隙。没有间隙的话,热胀冷缩或者加工误差就会把齿卡死。可正是因为这个间隙,输入一旦反向,输出要先跨过这段间隙,才会跟着动起来。这个角度就是背隙。

在机器人领域,背隙是按角分来管理的。1 角分是 1/60 度。换算到 0.35 米长的手臂:

背隙弧度末端处的间隙
10角分2909 μrad1.018 mm
5角分1454 μrad0.509 mm
3角分873 μrad0.305 mm
1角分291 μrad0.102 mm
36角秒175 μrad0.061 mm
2角秒9.7 μrad0.003 mm

精密行星减速器厂商公布的数值,按等级不同,单级在 1、3、5 角分,两级在 3、5、7 角分。就算是好等级,末端处依然会留下大约 0.1 毫米左右的间隙。

背隙为什么会造成这么大的问题,在控制回路那篇里会再次讲到。简单说:在间隙区间里,电机在转,关节却不动,控制器看到的增益就变成了零;齿一旦重新啮合上,又会突然恢复正常。一个增益在不同区间不一样的系统,很难用单一一组增益去稳定,还会产生极限环——手臂在目标附近来回晃个不停。

谐波减速器为什么用在机器人上

打开工业机械臂的关节,尤其是手腕那一侧,里面装的通常是波动齿轮装置,更广为人知的名字是它的商标——谐波减速器(Harmonic Drive)。

结构很特别,由三个部件组成。

波发生器      椭圆形毂+薄壁轴承。输入轴。
柔轮          薄壁杯状。径向可挠曲,抗扭却很强。
              外表面有齿。输出轴。
刚轮          厚圆环。内侧有齿,比柔轮多两个齿。

波发生器把柔轮撑成椭圆形,
只有椭圆长轴附近的齿才会啮合。
输入转一整圈,柔轮就会往后退两个齿的量。

由此产生两个结果。

单级就能得到很大的减速比。 因为齿数差只有 2,减速比可以做得非常大。按厂商资料,元件套件提供 30、50、80、100、120、160:1 等规格,技术文档中提到单级减速比可以从 50:1 到 320:1。用行星减速器要达到 100:1,需要两级甚至三级,而每多一级,背隙就会累积一次。

总是有多个齿同时啮合。 因为椭圆长轴两侧都有大片区域同时啮合,所以厂商把这种啮合描述为零背隙。

这里有一点必须精确地讲清楚。「零背隙」说的是这种啮合本身,不代表输入轴和输出轴之间整体的间隙就是零。 厂商自己也说明,杯型齿轮在啮合处的背隙确实是零,但来自输入联轴器的轴间背隙有 2 到 36 角秒。上表里,36 角秒换算到 0.35 米手臂的末端是 0.061 毫米。而且除此之外,还存在因扭转刚度导致的弹性变形,实际上这一部分往往才是更大的误差来源。

效率方面,厂商给出的数据是最高能到 90%,比精密行星减速器单级 97% 要低。谐波减速器是用效率去换精度和减速比的一种选择。

第三个选项是摆线减速器,用在大型机器人的肩部或腰部这类需要大扭矩的位置。这类元件的资料特别有用,因为它会把误差拆成三部分分别公布:机械背隙 0.1 到 0.3 角分,空程(lost motion)0.3 到 0.6 角分,迟滞损失 0.2 到最多 1 角分。由此可以看出,背隙、空程和迟滞是三个真正不同的量——这正是「零背隙」这个说法能够诚实存在的原因,也正是不能只凭这一句话就去选型的原因。

用真实数字算出静态扭矩 —— 为什么肩部比腕部大

现在来算引言里那个数字。

把手臂设定成这样。

部位长度质量
上臂(肩到肘)0.20 m0.15 kg
前臂(肘到腕)0.15 m0.10 kg
夹爪(腕部末端)距腕轴0.05 m0.15 kg
负载(抓取的物体)与夹爪同一位置0.25 kg

要计算的姿态是手臂完全水平伸展。这是重力产生的扭矩最大的最坏情况,而选型就应该按最坏情况来做。

扭矩等于力乘以力臂长度。把均匀杆的重量看作作用在它的中点上。

先算肘部。只统计肘部以外的部分。

前臂: 0.10 kg × 9.81 × 0.075 m = 0.073575 N·m
夹爪: 0.15 kg × 9.81 × 0.15  m = 0.220725 N·m
负载: 0.25 kg × 9.81 × 0.15  m = 0.367875 N·m
------------------------------------------------
合计                              0.662175 N·m

再算肩部。把所有距离都重新从肩部量起。

上臂: 0.15 kg × 9.81 × 0.10 m  = 0.147150 N·m
前臂: 0.10 kg × 9.81 × 0.275 m = 0.269775 N·m
夹爪: 0.15 kg × 9.81 × 0.35 m  = 0.515025 N·m
负载: 0.25 kg × 9.81 × 0.35 m  = 0.858375 N·m
------------------------------------------------
合计                              1.790325 N·m

腕部只看夹爪加物体的重心到腕轴的距离。

(0.15 + 0.25) kg × 9.81 × 0.05 m = 0.196200 N·m

把三个值摆在一起,

肩部   1.790325 N·m
肘部   0.662175 N·m   (肩部的1/2.704)
腕部   0.196200 N·m   (肩部的1/9.125)

肩部要求的扭矩是腕部的 9.1 倍。

原因是两件事叠加在一起。一,肩部要承担它外侧所有部件的重量。二,那些重量距离肩部更远。距离和质量同时变大,乘积自然急剧变大。

所以机械臂才会越往下越粗。工业机器人的轮廓根部粗、末端细,不是设计上的偏好,而是这个计算的结果。

import numpy as np

G = 9.81
KGCM_PER_NM = 1.0 / 0.0980665      # 1 kg·cm = 0.0980665 N·m (定义值,所以精确)

# 从肩部到腕部方向: (连杆长度 m, 连杆质量 kg)
LINKS = [(0.20, 0.15),             # 上臂
         (0.15, 0.10)]             # 前臂
GRIPPER_MASS = 0.15                # 装在腕部末端的夹爪
PAYLOAD_MASS = 0.25                # 抓取的物体
WRIST_OFFSET = 0.05                # 从腕轴到夹爪+物体重心的距离


def static_torque(joint_index):
    """手臂完全水平伸展的最坏姿态下,某个关节承受的重力扭矩。
    只统计该关节外侧的质量。"""
    outer = LINKS[joint_index:]
    reach, total = 0.0, 0.0
    for length, mass in outer:
        total += mass * G * (reach + length / 2)     # 均匀杆的重心在中点
        reach += length
    total += (GRIPPER_MASS + PAYLOAD_MASS) * G * reach
    return total


rows = [("肩部", static_torque(0)),
        ("肘部", static_torque(1)),
        ("腕部", (GRIPPER_MASS + PAYLOAD_MASS) * G * WRIST_OFFSET)]

print("手臂完全水平伸展的最坏姿态下的静态扭矩")
print(f"{'关节':<6}{'N·m':>10}{'kg·cm':>10}{'2倍安全系数(kg·cm)':>22}")
for name, t in rows:
    print(f"{name:<6}{t:10.4f}{t * KGCM_PER_NM:10.3f}{t * 2 * KGCM_PER_NM:22.3f}")

print(f"\n肩部 / 肘部 = {rows[0][1] / rows[1][1]:.3f}倍")
print(f"肩部 / 腕部 = {rows[0][1] / rows[2][1]:.3f}倍")

MG996R_6V = 11.0 * 0.0980665       # 厂商公布的堵转扭矩 11 kg·cm @ 6.0V
print(f"\nMG996R的6V堵转扭矩 11 kg·cm = {MG996R_6V:.4f} N·m")
print(f"肩部所需的扭矩是它的{rows[0][1] / MG996R_6V:.3f}倍(还没算上安全系数)")

运行结果如下。

手臂完全水平伸展的最坏姿态下的静态扭矩
关节         N·m     kg·cm     2倍安全系数(kg·cm)
肩部      1.7903    18.256                36.512
肘部      0.6622     6.752                13.505
腕部      0.1962     2.001                 4.001

肩部 / 肘部 = 2.704倍
肩部 / 腕部 = 9.125倍

MG996R的6V堵转扭矩 11 kg·cm = 1.0787 N·m
肩部所需的扭矩是它的1.660倍(还没算上安全系数)

用这个数字来选型

算完了,拿去和数据手册比对。

元件厂商公布扭矩能否用于肩部(1.790 N·m)
SG901.8 kg·cm @ 4.8V = 0.177 N·m不行,只有需求的十分之一
MG996R11 kg·cm @ 6.0V = 1.079 N·m不行,只有需求的60%
Dynamixel AX-12A1.5 N·m @ 12V刚好不够,没有安全余量
Dynamixel XL430-W250-T1.4 N·m @ 11.1V不行
Dynamixel XM430-W350-R3.8 N·m @ 11.1V可以,安全系数2.1倍
NEMA 17(17HS4401S)直连0.43 N·m保持扭矩不行,只有需求的四分之一

引言里那条手臂为什么会垮,答案就在这里。MG996R 的堵转扭矩,只有肩部所需数值的 60%。

而且这张表里还藏着一个陷阱。堵转扭矩是轴完全停止时能短暂输出的最大值。 那种状态下没有反电动势,电流会冲到最大,电机要是一直这样,线圈会被烧毁。惯例是把连续可用扭矩估计为堵转扭矩的 20% 到 30%,所以 2 倍安全系数只是最低要求,3 倍安全系数是更常见的建议值。

套用 2 倍安全系数,肩部就需要 36.5 kg·cm,也就是 3.58 N·m。上表里能满足这个数值的只有 XM430-W350-R,而且余量也只有 1.06 倍。

另一个方案是加减速器。如果给一个 0.09 N·m 的小型 BLDC 配减速器,所需的传动比是:

N = 3.58 N·m / (0.09 N·m × 0.94) = 42.3

用 50:1 的减速器就够了。这样输出扭矩变成 4.05 N·m,反射惯量降到 1/2500,控制也会更容易。代价是速度:电机每分钟 3000 转,到了关节这里就变成每分钟 60 转。对机械臂来说,关节每分钟 60 转已经足够快了。

还有一个方案是给手臂减重。上面的计算里,0.25kg 的负载占了肩部扭矩的 48%。把负载降到 0.1kg,肩部扭矩就会降到 1.28 N·m,连 AX-12A 都能有 1.2 倍的安全余量。当零件不够用的时候,把电机做大并不是唯一的答案。

电源必须单独计算

就算扭矩对上了,电源跟不上,手臂照样动不了。

六个舵机同时动作,电流会叠加起来。单个 MG996R 的堵转电流是安培量级,六个同时撞上负载,就是好几安培。这份电流要是从单片机板子的 5V 电源轨上取,一定会导致欠压复位。

这个问题的物理原理和对策,在驱动电机与感性负载那篇里已经详细讲过。简单总结就是三条:舵机电源从独立供电装置获取,GND 必须和板子在一点上接在一起,电源输入处要加足够容量的电容。

逻辑电压不匹配的情况也很常见,比如用树莓派的 3.3V 信号驱动 5V 舵机,或者把 12V 步进驱动器的信号线接到 3.3V 板子上。哪个方向安全、哪个方向会烧芯片,已经整理在逻辑电平与电平转换那篇里。接限位开关或回零传感器时需要的上拉电阻和消抖,则在GPIO 上拉与消抖那篇里。

结语 —— 手臂的形状是扭矩计算的结果

这篇文章讲的所有内容,最终都会汇聚到一个计算上:这个关节要承受多少牛顿米。

这个值决定了手臂的形状。肩部要求的扭矩是腕部的九倍,所以肩部一侧的电机更大;电机大了,自身的重量又会进一步增加扭矩需求,于是又有了把连杆做得更短更轻的理由。工业机器人的轮廓之所以都长得很像,是因为它们做的是同一套计算。

这个值也决定了减速器的选择。如果单靠电机达不到所需扭矩,就得靠传动比来凑;买了传动比,就等于同时买了背隙;想减少背隙,就得接受谐波减速器带来的效率损失。没有一样是免费的。

这个值同样决定了驱动方式。舵机简单,但不知道自己的实际状态;步进电机便宜又精确,却会悄无声息地丢步;BLDC 什么都能做到,但控制回路得自己写。

买零件之前,能在纸上完全算完的计算,就是这整篇文章。 定下连杆长度,定下想举起的重量,乘一乘、加一加,每个关节所需的扭矩就出来了。在这个数字上再乘以 2 倍或 3 倍,就是要去数据手册里找的那个数字。不做这一步就去买舵机,得到的就是引言里那条垮掉的手臂。

下一步,是根据这些关节构成的姿态,计算末端到底在哪里。接下来是正运动学那篇。