机械臂调试这件事,说复杂能复杂到写论文,说简单也能简单到三条命令。OpenArm 7 自由度机械臂的 CAN 演示就是后者——它把"上电、通信、动起来"这条链路压缩成了一个极短的最小闭环,让刚拿到设备的人能在半小时内看到关节真的按指令动一下。这不是炫技,而是把工程上最容易出问题的部分提前暴露出来:总线拉不拉得起来、帧到底有没有收到、关节 ID 和方向对不对。我把这套流程在自己的工作台上反复跑过十几遍,也踩过不少坑,这篇就把这三条命令背后的东西一层层剥开讲清楚,从总线物理层讲到应用层的参数对齐,适合刚接触 CAN 总线机械臂的新手,也适合已经能跑通但说不清原理的老手对照检查。
1. 为什么是"三条命令":从系统分层看 CAN 演示的最小闭环
很多人拿到机械臂第一反应是直接跑官方 demo,结果报一堆错,然后在论坛里翻半天也找不到原因。问题往往不在代码,而在于把三个完全不同的层次混在一起排查了。CAN 演示之所以能被压缩成三条命令,是因为它恰好对应了三个正交的层次:内核网络设备层、总线链路层、应用控制层。每一层有独立的失败模式,也有独立的验证手段。把这三层分开看,调试效率会提升一个数量级。
我习惯把这三条命令理解成三个"开关",它们必须依次合上,顺序错了就没有意义。第一条是把操作系统里的 CAN 设备变成一个真正能收发帧的网络接口,第二条是确认总线上真的有电平变化、有帧在流动,第三条才是让程序按照约定的协议去解析这些帧并驱动关节。跳过第二条直接跑第三条,是最常见的错误做法,因为你会同时面对"链路不通"和"协议不匹配"两种可能,排查起来像在黑箱里找针。
1.1 一条 CAN 链路上的四个物理环节
在敲任何命令之前,先把硬件链路在心里过一遍,这比背命令重要得多。一条完整的 CAN 链路通常包含四段:主控计算单元(一般是单板计算机或工控机)、CAN 收发器与控制器、双绞线总线本身、以及各个关节电机内部的驱动板。四段里任何一段接触不良、阻抗不对、供电异常,表现出来的现象都可能是"命令没反应"。
控制器与收发器这一段经常被忽略。控制器负责按协议组帧、算 CRC、做位填充,收发器负责把逻辑电平转成差分电平。如果收发器供电是 5V 而控制器 IO 是 3.3V,某些型号会出现电平不匹配导致的间歇性错误帧,表现是偶尔能通、跑一会儿就掉线。我遇到过一块板子,静止时通信正常,一旦电机开始转动、电流上来,误码率立刻飙升,最后查出来是收发器附近的地回路设计不合理,加了共模电感才稳定。
双绞线与终端电阻这一段是新手最容易翻车的。CAN 总线是差分总线,标准要求总线两端各有一个 120 欧姆终端电阻,中间节点不应再加。整条总线在断电状态下用万用表量 CAN_H 与 CAN_L 之间,应该读到大约 60 欧姆(两个 120 欧姆并联)。如果读到 120 欧姆,说明只接了一端;读到 40 欧姆,说明多接了一端;读到无穷大,说明一端都没接。这个测量动作花不了一分钟,却能排除掉相当一部分"通信不上"的问题。
总线拓扑要求尽量是手拉手的菊花链,支线长度要短。7 自由度机械臂的关节是串联结构,天然适合菊花链走线,但如果为了布线方便搞了星形分支,每个分支超过二三十厘米,在 1 Mbps 速率下就容易出现反射和振铃。速率越高,对拓扑越敏感,这也是为什么高带宽场景下要么缩短总线、要么降低速率。
关节驱动板这一段的关键是共地与共电源参考。多个关节由同一路电源供电时,地线上的电流会在各节点地之间产生压差,这个压差叠加在差分信号上,会吃掉接收端的共模抑制余量。实操中建议至少保证信号地与功率地在单点汇合,不要在总线中途随意取地。
1.2 三条命令与三个层次的对应关系
下面这张表是我自己贴在工位上的对照表,把命令、层次、验证目标和典型失败现象放在一起,出问题时先看表再动手。
| 命令序号 | 操作对象 | 系统层次 | 验证目标 | 典型失败现象 |
|---|---|---|---|---|
| 第一条 | 网络接口 | 内核设备层 | 接口存在、位速率正确、处于 UP 状态 | 提示设备不存在、参数不支持、接口起不来 |
| 第二条 | 帧流 | 总线链路层 | 总线上有合法帧、无错误帧计数增长 | 一条帧都收不到、或全是错误帧 |
| 第三条 | 应用协议 | 应用控制层 | 关节 ID、方向、限位、增益匹配 | 有关节不动、动反方向、抖动或过流保护 |
这张表的价值在于:当你看到某个现象时,能立刻定位到应该在哪一层动手,而不是盲目地重装驱动或者换线。比如"接口起不来"永远不是应用层的问题,去改 Python 脚本毫无意义;而"关节动反了"则一定是应用层的映射问题,再怎么检查总线也查不出来。
需要说明的是,三条命令是一个高度抽象的说法。实际执行时第一条可能拆成几行(先 down 再配置再 up),第二条可能是一个持续运行的监听进程,第三条是一段带参数的启动脚本。但它们在内核里完成的事情是确定的,理解了这个确定性,命令怎么写都能自己推导出来。下面的内容里,涉及具体脚本名和参数名的地方,我会按照这类开源机械臂项目的常见组织方式来写,如果你的仓库命名不同,按语义对应即可。
2. 第一条命令:把 CAN 接口从"存在"变成"可用"
Linux 下 CAN 设备默认只是一个网络设备,处于 DOWN 状态,且没有配置位速率。第一条命令的本质就是给它配置时序参数并拉起来。这一步做对了,后面才有得谈。很多人以为这一步就是一句ip link set can0 up,实际上不带参数的 up 在某些内核版本上会用默认的极低速率,或者直接报错,所以参数必须写全。
2.1 位速率、采样点与那些看起来没用的数字
CAN 的位速率不是一个孤立的数字,它由一串时序参数共同决定:预分频、时间段 1、时间段 2、同步跳转宽度。这些参数共同决定了每一位被划分成多少个时间份额(tq),以及采样点落在哪一位。
拿最常见的 1 Mbps 举例。假设 CAN 控制器的时钟是 80 MHz,我们希望每一位由 16 个 tq 组成,那么 tq 频率就是 16 MHz,预分频系数为 80 MHz / 16 MHz = 5。在这 16 个 tq 里,传播段加相位段 1 占 11 个,相位段 2 占 4 个,剩下 1 个是同步段。采样点位置就是(1 + 11)/ 16 = 75%。这个 75% 是一个很常见的经验值,总线较长、节点较多时,为了容忍传播延迟,一般会把采样点往后推,80% 到 87.5% 都有人用。
为什么采样点这么重要?因为总线上的电平不是理想方波,边沿有上升下降时间,多个节点同时发送时还有仲裁和应答位。采样点太靠前,可能采到尚未稳定的电平;太靠后,留给相位段 2 的余量不足,遇到时钟偏差就无法重新同步。工程上的做法是:短总线、少节点,75% 够用;长总线或多节点,往 80% 以上调。
下面这条命令把 1 Mbps 经典 CAN 和 5 Mbps 数据段的 CAN FD 一起配上了,这是目前这类机械臂比较常见的组合:
sudo ip link set can0 down 2>/dev/null sudo ip link set can0 type can \ bitrate 1000000 \ sample-point 0.75 \ dbitrate 5000000 \ dsample-point 0.8 \ fd on \ restart-ms 100 sudo ip link set can0 txqueuelen 1000 sudo ip link set can0 up逐项解释一下。bitrate是仲裁段速率,所有节点必须完全一致,不一致就会疯狂产生错误帧。sample-point是仲裁段采样点,0.75 是保守值。dbitrate与dsample-point只在 CAN FD 下生效,数据段可以用更高速率,因为数据段没有仲裁,对拓扑宽容度稍高,但也不能乱来,5 Mbps 对应的总线长度上限通常在一米到两米量级。fd on打开灵活数据速率模式。restart-ms 100表示总线进入错误被动或离线状态后 100 毫秒自动重启,这个参数在调试阶段强烈建议加上,否则一次偶发错误就可能让接口卡死在 BUS-OFF 状态,你还以为是代码问题。
txqueuelen 1000是发送队列长度。默认值往往只有 10,对于 7 自由度、每毫秒发一帧的控制频率来说,队列很容易被打满,表现为发送阻塞或者帧被丢弃。把它调大是一个成本极低但收益明显的动作,我基本是见到 CAN 接口就先设这个值。
提示:如果你的机械臂使用 CAN FD,务必确认总线上所有节点都支持 FD,包括每一个关节驱动。混入一个只支持经典 CAN 的节点,整条总线要么报错,要么被迫降级,此时 FD 的高速数据段完全用不上,反而增加了调试复杂度。
2.2 终端电阻:一分钟测量省下三小时排查
我在前面提过终端电阻,这里展开说一下实操。测量必须在全部断电的情况下进行,因为带电测量时收发器内部的等效电阻会并联进来,读数没有意义。万用表打到电阻档,红黑表笔分别接 CAN_H 和 CAN_L,读数应该在 60 欧姆附近。
如果读到 120 欧姆,说明只有一端有终端电阻。这种情况在中低速、短总线上有时也能勉强通信,但误码率会明显偏高,表现为长时间运行后偶发错误帧、关节偶尔丢指令。如果读到 40 欧姆左右,说明有三个终端电阻并联,可能是某个关节板内部自带了 120 欧姆而外部又加了一个。这种情况在集成度高的机械臂里很常见,处理方式是拆掉外部那个。
还有一个隐蔽问题:某些关节驱动板的终端电阻是通过跳线或者拨码开关控制的。默认状态可能全部使能,7 个关节串起来就有 7 个 120 欧姆并联,等效阻抗只有十几欧姆,总线根本驱动不起来。拿到设备第一件事应该是逐个数清楚有几个终端电阻在生效,只保留物理两端各一个。
2.3 接口命名、权限与开机自启
接口名can0是内核枚举出来的,顺序取决于 USB 转 CAN 设备插入的先后。桌面上只有一个适配器时无所谓,接了两个以上就很容易搞混,A 机械臂的命令发到了 B 机械臂上。解决办法是用 udev 规则根据设备序列号绑定固定名字,或者在启动脚本里先枚举所有 can 接口再按规则筛选。调试阶段图省事可以用ip -details link show type can看一眼每个接口的位速率和状态,确认自己操作的是对的那个。
权限方面,配置接口需要 root,收发帧一般也需要。长期方案是加一条 udev 规则把设备属主设成当前用户,或者给可执行文件加相应能力,而不是每次都用 sudo 跑应用脚本。用 sudo 跑 GUI 或 Python 脚本会带来环境变量、图形库路径等一系列额外问题,得不偿失。
开机自启这块,建议把配置写成一个 systemd 服务,依赖网络设备就绪,并且加上失败重试。机械臂这种设备经常是断电重启、USB 重新枚举,靠手工敲命令迟早会忘。我自己的做法是服务里先 sleep 一小段时间等待枚举完成,再执行配置,最后用一个状态检查命令确认接口确实是 UP 且位速率符合预期,不符合就退出并记录日志。
3. 第二条命令:确认总线上真的有帧在流动
接口拉起来只代表本机准备好了,不代表总线上有东西。第二条命令的作用是"听"。在 CAN 的世界里,听比说安全得多,因为发送会在总线上产生显性电平,一旦时序不对就可能干扰其他节点,而监听只是被动接收。
3.1 监听、回环与自发自收的三种验证路径
最基础的监听命令是持续打印收到的帧:
candump -ta can0-t加时间戳,a表示绝对时间。输出形如(1690000000.123456) can0 01A#0102030405060708,前面是时间,中间是接口名,后面是帧 ID 和十六进制数据。如果上电后能看到规律的帧流,说明至少有一个节点在主动发送,链路是通的。
如果一条都看不到,先别怀疑机械臂,用回环模式验证本机链路:
sudo ip link set can0 down sudo ip link set can0 type can bitrate 1000000 loopback on sudo ip link set can0 up cansend can0 123#DEADBEEF candump -ta can0loopback on让控制器把发出的帧直接回送给接收路径,不经过物理总线。能收到自己发的帧,说明控制器、驱动、套接字这一整套是好的,问题就锁定在收发器、线缆或对端节点上。这个二分法非常有效,我几乎每次遇到"收不到帧"都先做这一步。
还有一种是listen-only模式,只接收不发送、不应答,适合在不确定总线状态时做纯观察。但要注意,CAN 协议里接收方是要发应答位的,纯监听模式下不应答,发送方会认为没人收到而不断重发,长时间会让对方进入错误状态。所以 listen-only 只适合短时间诊断,不适合长期挂着。
3.2 从帧 ID 分布反推系统状态
能看到帧流只是第一步,第二步是看懂帧流。7 自由度机械臂的 CAN 帧通常有这么几类:关节状态反馈帧、关节指令帧、握手或心跳帧、以及可能的广播同步帧。不同项目的 ID 分配策略不同,常见的有按关节编号左移若干位、加上功能码的方式,也有用固定基础 ID 加偏移的方式。
判断系统是否正常,可以看三件事。第一是帧率是否稳定。以 1 kHz 控制周期为例,每个关节每毫秒应该有一帧状态反馈,7 个关节就是每秒 7000 帧左右。如果实际只有每秒几百帧,要么是控制频率被降了,要么是有节点掉线。第二是有没有错误帧。ip -s -details link show can0会给出总线错误、错误被动、BUS-OFF 等计数,这些计数在一次上电周期内应该是零或者极小,持续增长就说明物理层有问题。第三是 ID 是否齐全。把所有出现过的 ID 排序去重,对照配置文件里的关节数量,少一个就说明那个关节没上线。
这里有个很容易被忽略的细节:帧的时间间隔抖动。用candump -ta看时间戳,正常情况下相邻帧的间隔应该相当均匀。如果出现明显的周期性聚集,比如每隔几十毫秒来一大串,说明发送侧有缓冲或者调度问题,可能是发送队列太小、也可能是应用层用了阻塞写。这种抖动在低速演示时看不出来,一旦上轨迹控制就会表现为关节运动不平滑。
3.3 带宽预算:为什么 7 自由度值得算一算
很多人不觉得 CAN 带宽是问题,直到加了几个关节之后开始丢帧。算一笔账:一个经典 CAN 标准数据帧,包含仲裁段、控制段、最多 8 字节数据、CRC、应答和帧结束,最坏情况下总位数在 130 位上下(含位填充)。7 个关节,每个关节每周期一帧指令、一帧反馈,就是 14 帧,乘以 130 位约 1820 位。在 1 Mbps 下,这占用了约 1.82 毫秒的总线时间。如果控制周期是 1 毫秒,需求已经超过了供给,必然丢帧或者阻塞。
这就解释了为什么这类机械臂要么把控制频率降到 500 Hz 甚至更低,要么上 CAN FD。CAN FD 的数据段可以跑到 5 Mbps,同样是 8 字节有效载荷,数据段耗时大幅缩短,整体帧时间可能降到原来的三分之一左右,1 kHz 就变得可行。
| 方案 | 仲裁段速率 | 数据段速率 | 单帧大致位数 | 14 帧占用时间 | 1 kHz 可行性 |
|---|---|---|---|---|---|
| 经典 CAN | 1 Mbps | 无 | 约 130 位 | 约 1.8 ms | 不可行 |
| 经典 CAN 降频 | 1 Mbps | 无 | 约 130 位 | 约 1.8 ms | 500 Hz 可行 |
| CAN FD | 1 Mbps | 5 Mbps | 约 90 位等效 | 约 0.9 ms | 勉强可行 |
| CAN FD 优化 | 1 Mbps | 5 Mbps,合并反馈 | 约 60 位等效 | 约 0.6 ms | 可行 |
这张表里的数字是估算,实际取决于 ID 长度、填充位分布和是否有多个节点同时发送。但它给出的结论是可靠的:在动手调参之前先做带宽预算,比调完之后发现抖动再去猜原因要省事得多。我自己就吃过这个亏,一开始把控制频率设成 1 kHz,关节一直在轻微抖动,查了整整两天,最后发现是总线饱和导致的指令延迟不均。
4. 第三条命令:让演示脚本真正驱动关节
前两条命令搞定的是"能通信",第三条命令搞定的是"通信的内容对不对"。这一步的失败往往不是报错,而是"看起来跑了但关节不动"或者"动了但不对劲",排查难度更高,因为它涉及协议约定和机械参数。
4.1 关节 ID、方向与零点:三个必须对齐的映射
演示脚本启动时通常会读一份配置文件,里面定义了每个关节的 CAN ID、减速比、方向符号、零点偏移、限位范围。这五项里任何一项错了,表现都不一样,值得单独列出来。
CAN ID 错:那个关节完全没反应,其他关节正常。如果 ID 撞车了,两个关节会同时收到同一条指令,表现为两个关节做同样的动作,这个现象非常有辨识度。
方向符号错:关节动了,但方向和预期相反。单关节测试时容易发现,多关节联动时就容易和别的错误混淆。
零点偏移错:关节能动,但静止位置不在预期姿态,或者一上电就往限位方向冲。这个最危险,因为可能直接撞到机械限位。
减速比错:关节能动,角度也能读,但实际转过的角度和指令角度差一个比例。比如指令 90 度实际只转了 9 度,那就是减速比差了一个数量级。
限位错:平时正常,一到边界就触发保护或者直接顶死。
我建议的验证顺序是:先单关节、小幅度、低速,确认 ID 和方向;再逐个关节重复;最后才做多关节联动。演示脚本一般会提供单关节测试的参数,比如指定只使能某一个关节、给定一个小角度。这个笨办法比一上来就跑整套动作安全得多。
4.2 控制模式与增益:为什么一上电就抖
这类机械臂的关节通常支持多种控制模式:位置模式、速度模式、力矩模式,以及一种把位置、速度、前馈力矩和 PD 增益打包在一帧里的阻抗类模式。演示脚本一般默认用最后这种,因为它一帧就能表达完整的控制意图,适合做柔顺演示。
这种模式的帧结构通常是 8 字节,把位置、速度、增益和力矩按位宽切分打包。位置和速度各占 16 位,增益和力矩各占 12 位,加起来正好 64 位。发送前要做量程映射:比如位置的实际范围是正负 12.5 弧度,映射到 16 位无符号整数,分辨率大约是 12.5 × 2 / 65535 ≈ 0.00038 弧度,约 0.022 度。这个精度对演示足够了。
增益是最容易出问题的地方。位置增益给太大,关节会在目标附近高频抖动,听起来像蜂鸣;给太小,关节软绵绵的,重力一压就往下掉。速度增益(阻尼)给太小,到位时会来回振荡;给太大,运动发涩、响应迟滞。
我自己的整定顺序是这样的:先把位置增益设为很小的值,速度增益设一个中等值,让关节处于"能支撑但不硬"的状态;然后缓慢增加位置增益,直到出现轻微的高频抖动,再回退 30% 左右;最后微调速度增益,观察阶跃响应的过冲和稳定时间。整个过程在小幅度、低速度下做,一旦发现异常立刻断电,不要指望软件急停能救回来。
注意:带重力负载的关节和空载关节的增益不能通用。机械臂伸展姿态下,肩部关节承受的力矩可能是收拢姿态的好几倍。建议在演示前先把机械臂摆到中间姿态,用一个较小的增益让所有关节都能撑住,再逐步调整。
4.3 上电顺序、使能与安全边界
上电顺序这件事,说明书上写得很平淡,实操中却是事故高发点。合理的顺序是:先确认机械臂处于安全姿态并有人扶着或者有支撑,再给驱动供电,再启动通信,再逐个使能关节,最后才发运动指令。断电顺序反过来:先让关节回到安全姿态并失能,再停通信,最后断驱动电。
使能这一步要特别注意。很多驱动在使能瞬间会按照当前指令值立刻闭环,如果此时指令值和实际位置差很多,关节会猛地一跳。稳妥的做法是使能前先把指令位置写成当前实际位置,让误差为零,再使能,然后再慢慢移动。演示脚本如果有"软启动"或"平滑使能"的参数,一定要打开。
安全边界包括三层:机械限位、软件限位、电流或力矩保护。机械限位是最后的物理防线,不应该被触发;软件限位设在机械限位内侧留出余量;力矩保护用来兜住碰撞和卡死。三层都配好,才敢跑大幅度动作。
5. 常见问题与排查技巧实录
下面这些是我在实际调试中反复遇到的,按现象分类整理。每一条都附了判断依据,方便你对照自己的情况。
5.1 链路层:接口起来了但收不到帧
现象一:candump一条帧都没有。先做回环测试,能收到自己的帧就说明本机没问题,重点查线缆、终端电阻、对端供电。用万用表量 CAN_H 与 CAN_L 之间的电阻,60 欧姆左右为正常。再看对端节点的电源指示灯和状态指示灯,有些驱动板在未使能时不会主动发状态帧。
现象二:能收到帧但错误计数持续增长。大概率是位速率不一致或者采样点偏差过大。逐节点确认配置,特别注意某些驱动板出厂固件里写死了速率,软件配置改不动。还有一种可能是总线过长或分支过多,试着临时把速率降到 500 kbps 看是否改善,如果降速就好了,基本可以确定是信号完整性问题。
现象三:跑一段时间后接口进入 BUS-OFF。查ip -s -details link show can0里的错误计数,如果发送错误计数很高,说明本机发的帧没被应答,可能是总线上没有其他节点在听,或者应答位被干扰。restart-ms能自动恢复,但根治还是要找到干扰源。
5.2 应用层:通信正常但关节行为异常
现象四:某个关节完全不动。先确认这个关节的 ID 是否在总线上出现过,用candump抓一段时间再统计唯一 ID。如果 ID 出现了但关节不动,检查配置里的使能标志和限位范围,有可能是初始位置被判在限位之外。
现象五:关节动但方向相反。改配置里的方向符号即可,注意改完之后零点偏移可能也要跟着调整,因为方向翻转会改变偏移的计算方式。
现象六:关节高频抖动。位置增益过大或者速度增益过小。先把位置增益降到原来的三分之一试试,如果抖动消失就说明是增益问题,再按 4.2 节的顺序重新整定。如果降增益后变成低频振荡,那是速度环的问题,需要加阻尼。
现象七:运动轨迹不平滑,有顿挫感。先看带宽预算是否够,再看指令发送是否用了阻塞写导致周期抖动。用时间戳统计相邻指令的间隔方差,方差大的话考虑改用非阻塞发送加发送完成回调。
5.3 问题速查表
| 现象 | 最可能的层次 | 首查项 | 快速验证方法 |
|---|---|---|---|
| 接口报参数不支持 | 内核设备层 | 控制器是否支持 FD、内核版本 | 去掉 fd 参数重试 |
| 收不到任何帧 | 物理层 | 终端电阻、供电、线序 | 回环测试 + 万用表量电阻 |
| 错误计数持续增长 | 物理层/时序 | 位速率一致性、采样点 | 降速到 500 kbps 对比 |
| 偶发丢帧 | 带宽/队列 | txqueuelen、控制频率 | 增大队列、降频对比 |
| 单关节无响应 | 应用层 | CAN ID 配置 | 抓帧统计唯一 ID |
| 关节方向相反 | 应用层 | 方向符号 | 单关节小幅测试 |
| 高频抖动 | 应用层 | 位置增益 | 降增益三分之一 |
| 上电瞬间猛跳 | 应用层 | 使能前指令是否对齐实际位置 | 打开平滑使能 |
6. 从跑通演示到真正用起来
演示跑通只是起点,接下来通常要做的是自定义轨迹、加传感器反馈、做多臂协同。这几步里有几个经验值得提前说,能省下不少返工。
6.1 用自己的上位机替换演示脚本时要注意什么
演示脚本封装了很多细节,自己写上位机时容易漏掉。第一是收发线程分离。发送要严格按周期走,接收不能阻塞发送。我见过用单线程"发一帧等一帧"的写法,结果控制频率取决于对端响应速度,一负载就掉到几十赫兹。第二是时间基准统一。指令里的时间戳、本地定时器、系统时钟三者要明确用哪个,混用会导致轨迹插值出现跳变。第三是异常处理。总线错误、节点掉线、指令超时这三种情况要有明确的降级策略,最简单的策略是超时即停发并让关节进入阻尼状态,避免失控。
还有一个容易忽略的点:socket 的接收缓冲区。默认缓冲区不大,如果接收线程偶尔被调度延迟,缓冲区满了就会丢帧。可以通过系统参数调大,或者在应用层用独立的接收线程加队列。丢帧在状态反馈上表现为数据跳变,如果拿这个数据去做闭环,后果可想而知。
6.2 轨迹控制的几个实用参数
点位运动用得多,但真正体现效果的是连续轨迹。这里涉及三个参数:插补周期、速度前馈系数、加速度限制。插补周期建议和总线控制周期一致,避免二次采样带来的抖动。速度前馈能显著减小跟踪滞后,但系数给大了会引入过冲,一般从 0.5 开始试。加速度限制决定了启停的柔和程度,给得太激进,机械结构会有明显冲击,长期下来对减速器和联轴器都不友好。
我自己的习惯是先用一个很保守的速度跑完整条轨迹,确认没有碰撞和奇异点,再逐步提速到结构能接受的程度。奇异点这个问题在多关节臂上很现实,某些姿态下关节速度会突然变得极大,即使末端速度很慢。演示脚本通常不涉及复杂轨迹,一旦自己写路径就要留意。
6.3 长期运行稳定性
连续跑几个小时不出问题和跑几分钟不出问题,完全是两个难度。长时间运行最常见的问题是温升导致的参数漂移和内存或句柄泄漏。前者表现为跑一段时间后关节开始轻微抖动或者力矩偏大,因为电机电阻随温度变化,电流环的标定值不再准确。后者在 Python 脚本里特别常见,日志文件句柄、socket 对象、定时器没有正确释放,跑一晚上就崩。
建议在正式使用前做一次至少两小时的连续运行测试,中间记录总线错误计数、各关节温度、指令周期抖动。这三个指标稳定,基本可以认为系统是可用的。
最后分享一个我自己的小习惯:每次改动配置或者脚本之后,先用一个"最小动作"验证,即让所有关节做一个幅度很小、速度很慢的同步动作。这个动作能同时检验通信、映射、增益和限位,几十秒就能跑完,比直接上复杂轨迹安全得多。这个习惯帮我避免了好几次因为改了一个方向符号却忘了同步改零点而导致的撞限位。机械臂这种设备,慢一点、稳一点,永远比快一点划算。