跳转至
安全与恢复命令

安全与恢复命令#

急停复位、清除电机错误和回到零位解决的是不同问题。恢复操作前先读取 ServiceStateArmMotorState,确认现场人员已经排除导致错误或急停的原因;不要用反复调用清错命令代替故障检查。

命令对照#

方法 主要用途 需要控制权 会主动运动 成功后的模式/状态
set_arm_emergency_stop(True) 请求进入软件急停状态 请求停止当前运动 预期为 EMERGENCY_STOPPED
set_arm_emergency_stop(False) 复位软件急停状态 预期回到 IDLE,不会恢复旧模式或旧目标
clear_error() 清除并验证受支持的 UNKNOWN_ERROR 来源 不发送运动目标 成功后为 IDLE
clear_arm_motor_err(retry=...) 使用同一清除入口,并选择机械臂电机错误的重试策略 不发送运动目标 成功后为 IDLE
clear_eef_motor_err() 当前没有可用后端实现 gRPC、DDS 均抛出 UnsupportedOperationError
return_zero() 切入 Servo 并把 7 个关节移动到 0 rad 保持在 SERVO_CONTROL

实体急停必须保持可用

set_arm_emergency_stop(True) 依赖上位机、网络、SDK 和板端服务共同工作,不能替代实体 急停。机械臂出现意外运动、人员侵入或失控风险时,应由现场人员立即按下实体急停,并按现场安全 流程处理。

软件急停和复位#

client.set_arm_emergency_stop(mode: bool) -> bool

gRPC、DDS 均支持,方法没有公开超时参数,也不要求控制权。

mode 请求 返回 True 的含义
True 软件急停 服务端接受急停请求
False 急停复位 服务端接受复位请求

两种调用都会停止 SDK 本地 Servo 数据流,并把本地 controller 缓存置为 idleFalse 只复位急停 状态,不清除 UNKNOWN_ERROR,也不会重新进入急停前的模式或继续旧目标。复位后先确认现场条件,再 重新获取控制权并切换所需模式。

软件急停请求只在当前 FSM 支持该转移时返回接受。IN_COLLISIONUNKNOWN_ERROR 需要各自的 恢复流程;不要先调用急停复位尝试跳过保护状态。状态和操作对照见 异常恢复。

if not client.set_arm_emergency_stop(True):
    raise RuntimeError("软件急停请求未被确认;执行现场急停流程")

state = client.get_service_state()
print(state.fsm_state if state else "状态不可用")

方法返回 False 时不能据此判断机械臂已经停止,因为请求可能没有到达或回包可能丢失。保持现场隔离, 使用实体急停,并从独立的状态与设备指示确认结果。

清除 UNKNOWN_ERROR#

clear_error()#

client.clear_error() -> bool

clear_arm_motor_err()#

client.clear_arm_motor_err(retry: bool = True) -> bool

两个方法当前调用同一个 UNKNOWN_ERROR 清除入口,gRPC、DDS 均支持。服务必须处于 UNKNOWN_ERROR,并且最新机械臂电机状态必须完整。该入口可以处理已经恢复稳定的通信错误,也可以 请求清除机械臂电机错误;持续通信错误和其他硬件错误会被拒绝。方法需要控制权;SDK 没有本地租约 时会尝试按默认参数申请一次,恢复程序仍应显式申请并处理失败。

方法/参数 默认值 行为
clear_error() 使用后端默认的重试策略;机械臂电机错误路径当前等同 retry=True
clear_arm_motor_err(retry=True) True 同一通用入口;电机错误首次清除后仍存在时,最多再尝试一次
clear_arm_motor_err(retry=False) 电机错误只尝试一次;旧版消息定义没有 disable_retry 字段时,此选项会被忽略并保留服务端默认行为

机械臂电机错误的每次尝试最多等待约 4 秒,并要求连续 3 帧正常电机状态完成验证。通信错误路径要求 错误已经解除,并通过健康状态检查。gRPC 为整个清错 RPC 使用固定 12 秒 deadline,DDS 使用固定 10 秒等待,不读取调用方自定义超时。成功返回 True 并回到 IDLE;以下情况返回 False

  • 当前 FSM 不是 UNKNOWN_ERROR
  • 电机状态尚不可用或不完整;
  • 通信错误仍活动,或当前错误来源不属于受支持的通信/机械臂电机路径;
  • 最新状态没有需要清除的机械臂电机错误,且没有已恢复的通信错误;
  • 电机拒绝清错,验证后错误仍存在,或状态未回到 IDLE
  • 控制权申请、传输或等待超时失败。
state = client.get_service_state()
motors = client.get_arm_motor_state()
if state is None or state.fsm_state != "UNKNOWN_ERROR":
    raise RuntimeError("当前不是可执行电机清错的 UNKNOWN_ERROR 状态")
if motors is None or not any(code != 0 for code in motors.error_ids):
    raise RuntimeError("没有可供诊断的非零机械臂电机错误码")

if not client.acquire_control(lease_ms=15_000, renew_period_s=5.0):
    raise RuntimeError("无法获取清错所需的控制权")
try:
    if not client.clear_arm_motor_err(retry=False):
        raise RuntimeError("清错失败;保留错误码并查看 SDK 与设备日志")
finally:
    client.release_control()

清错前记录原始 error_ids。失败后不要无界重试;检查供电、线缆、负载、温度和对应固件错误码, 确认故障原因已经排除后再决定是否重试。

clear_arm_motor_err() 的名称比实际服务端入口更窄:通信错误已恢复且没有电机错误时,它也可能通过 同一入口回到 IDLE。通用恢复程序优先调用 clear_error();只有明确处理机械臂电机错误并需要控制 retry 时才使用 clear_arm_motor_err()

末端执行器电机清错#

client.clear_eef_motor_err() -> bool

该方法虽然存在于公开 AirbotClient,当前 gRPC 和 DDS 后端都会抛出 UnsupportedOperationError,不会返回 False。不要把它放入自动恢复流程;使用与当前末端执行器和 交付版本匹配的恢复说明。

from arm_p7_sdk import UnsupportedOperationError

try:
    client.clear_eef_motor_err()
except UnsupportedOperationError:
    print("当前 SDK 后端不支持 EEF 电机清错")

回到关节零位#

client.return_zero(timeout_ms: int = 3000) -> bool

return_zero() 会先切换到 Controller.servo_control,再以阻塞方式发送 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] rad。它是运动命令,不是编码器标定、回原点搜索或清错命令。

执行前必须确认:

  1. 现场运动范围清空,工具和负载安装牢固,实体急停可立即操作;
  2. 服务状态、7 轴关节状态和电机错误状态可读且正常;
  3. 从当前位置到全零位的运动路径适合当前工位,不会撞到外部设备;
  4. 已与其他控制客户端协调并显式取得控制权。
项目 gRPC DDS
控制权 需要;缺失时 SDK 会自动尝试申请 相同
timeout_ms 正数,最小 RPC deadline 50 ms;模式切换和 Servo 运动共享同一总预算 正数;模式切换和 Servo 运动共享同一总预算
模式切换失败 返回 False,不发送零位目标 相同
成功返回 阻塞 Servo 目标完成判据已满足 相同

不要使用默认 3 秒推断机械臂必定能回零

完成时间取决于初始位置和运行配置。超时或返回 False 后,目标可能已经被接受;停止发送新目标, 读取 FSM 和关节状态。若无法确认运动已经停止,不要释放现场警戒或继续发送恢复命令。

当前 SDK 的 gRPC、DDS 实现都在模式切换失败时停止,并把切换耗时计入同一 deadline(修复版本: 18e904285779537b2fbbc3ae672e7112e1b51caf)。正式版本和真机回归完成前,仍应在调用后读取 ServiceState.fsm_state 和实际关节位置。需要逐步确认模式的应用可以显式调用 switch_controller(Controller.servo_control)、核对 FSM,再调用阻塞式 move_joint()

恢复后重新开始#

  1. 保留错误码、FSM 状态、SDK/Arm App 版本和发生时间。
  2. 排除触发原因,确认实体急停已经按现场流程复位。
  3. 使用与当前状态匹配的流程:EMERGENCY_STOPPED 使用急停复位,UNKNOWN_ERROR 先判断错误来源, IN_COLLISION 按交付恢复流程处理。
  4. 读取 ServiceState,确认回到 IDLE;再读取电机和关节状态。
  5. 重新申请控制权、切换模式,并从当前实测关节位置构造新目标。不要重放故障前缓存的目标。

release_control() 和关闭客户端只清理租约及本地命令流,不是停止命令。基础运动的正常退出和异常 处理见关节运动,保护状态见 异常恢复。五个恢复入口的独立运行命令见 SDK 最小可执行用例