概述
使能灵巧手,向关节 0 发送一段固定的余弦位置序列,然后失能断开。整个过程 2 秒。 这是两个运动示例里幅度最小的一个,用途是验证指令链路通不通,不是观察手指动作。关节 0 的余弦幅度只有 0.02 rad,约合 1.15 度,实测在静摩擦下几乎不产生可见位移。 但它的实际运动幅度取决于开始时的手部姿态。 每帧发送的是完整的 20 维指令,关节 0 之外的 19 个目标位置全部是 0。手若原本是弯曲的,第一帧就会把这 19 个关节一起拉向零位,而且不做插值缓冲。实测中一次运行把 nid 19 从 0.6498 rad 拉到 0.0143 rad,实际动了约 36 度,远超关节 0 那 1.15 度。 对应的 Python 示例为 7.mit_sweep.py,C 示例为 7_mit_sweep.c。 MIT 控制模式与参数安全边界见控制指南,力矩与 MIT 参数的接口见力矩与 MIT 参数,本页只讲怎么跑起来与实测结果。本示例会使能电机。开始前清空手部周围的人员、线缆与台面物品,全程有人监护,并保持随时断电的条件。手部原本不在零位时,第一帧就会把 20 个关节一起拉向零位,没有插值缓冲。需要柔和归零请先运行发布控制指令的平滑归零流程。
前置条件
硬件
软件
本示例不接受任何命令行参数。
前序步骤
确认设备的 MIT 参数与力矩上限处于出厂值。实测值:kp 被改小会让本就微弱的位移进一步消失,改大则超出本示例的安全设定。
数据流
序列在本地一次生成完毕再逐帧发送,不做插值也不做重规划。每条JointCommand 是「位置 + 速度 + 力矩」三元组,本示例只填位置,速度与力矩都是 0。
注意每帧都是完整的 20 维指令。关节 0 之外的 19 个位置写死为 0,等于持续命令它们回到零位,这部分运动不受 0.02 rad 这个幅度约束。
运行时分支
无论哪条路径,清理流程都会执行失能、关闭发布器、断开设备。异常与中断都不会添加恢复动作,手不会自动回到初始姿态。
调用顺序
- Python
- C
运行与输出
- Python
- C
实测数据
在 20 关节全在线的右手 Wuji Hand 2 上实跑,同步订阅joint_states 记录关节 0 的响应:
关节 0 几乎不动,这是正常的。 力矩严格跟随指令上升与回落,说明指令已经下发、电机已按 MIT 阻抗响应。但 0.02 rad 的目标偏差在
kp=3 下只产生约 0.06 的力矩,克服不了关节静摩擦,实际位移只有 0.0004 rad,约合 0.023 度,肉眼不可见。
上表是手已处于零位附近时的数据。另一次运行的对照:手部原本弯曲时跑同一个示例,其余 19 个关节被拉向零位,实测位移如下。
nid 19 动了 0.6355 rad,约合 36 度。所以「幅度最小」只在手已经归零时成立。
判断本示例成功的依据是进程安静退出且退出码为 0,以及订阅
joint_states 能看到力矩响应,而不是看到手指摆动。要观察真实运动请看回放拇指对指动作。
调整与适配
多设备网络下必须指定 SN
auto_connect() 的语义是「连接总线上发现的唯一设备」。网络上不止一台时它拒绝连接并列出全部 SN,不会盲选。实测报错:
想看到关节真的动
本示例不适合观察运动。要看幅度,用回放拇指对指动作的完整运动序列。自行加大本示例幅度会越过其安全设定,不建议。读取关节状态的方式
joint_states 是订阅类资源,没有 get() 方法。想在发指令的同时读实际位置,要先 subscribe_with_callback() 持续接收,再从最新帧取值。直接调用 hand.joint_states().get() 会抛 AttributeError。