控制模式#
P7 使用控制模式决定后续运动命令的处理方式。单次关节目标通常选择
Controller.planning_control;连续目标跟踪使用 Controller.servo_control;停止发送目标后应切回
Controller.idle。重力补偿通过专用方法进入,不属于 Controller 枚举。
如何选择#
| SDK 入口 | ServiceState.fsm_state |
适用任务 | move_joint() 的行为 |
|---|---|---|---|
Controller.idle |
IDLE |
不再接受普通运动目标;运动前后的默认停留状态 | 返回 False |
Controller.planning_control |
PLANNING_CONTROL |
PTP 或 OMPL 单次关节运动 | 先规划,再执行轨迹 |
Controller.servo_control |
SERVO_CONTROL |
连续关节目标或单个 Servo 目标 | 非阻塞时发送一帧 Servo 目标;阻塞时等待目标到达判据 |
Controller.mit_control |
FORCE_CONTROL |
专项调试的低层 MIT 指令 | 发送位置、速度、前馈力矩和增益,不支持阻塞完成判据 |
enter_gravity_compensation_mode() |
GRAVITY_COMPENSATION |
人工拖动、示教前的重力补偿 | 返回 False;该状态不接受 move_joint() |
MIT 模式需要专项参数和现场评审
mit_control 会把 JointMoveOptions.torque、kp、kd 直接用于低层命令,并把 SDK 当前保存的
关节速度数组作为目标速度。数组长度错误还可能触发静默回退。没有与当前负载、安装方式和整机
版本匹配的参数集时,不要进入该模式。
当前公开 Controller 只有 idle、servo_control、planning_control 和 mit_control。线协议中仍可
观察到 POSITION_CONTROL,但 SDK 已移除对应的直接位置/PVT 客户入口。应用不应根据该状态名构造
未公开的控制命令。
switch_controller()#
gRPC 和 DDS 均支持此方法。调用前服务必须可用,客户端还必须持有控制租约。SDK 在没有本地租约时会
尝试按默认参数申请一次,但多客户端系统应先显式调用 acquire_control(),以便明确租期和协调结果。
| 参数 | 类型 | 单位 | 默认值 | 规则 |
|---|---|---|---|---|
controller |
Controller |
— | 无 | 只能使用当前公开的四个枚举成员 |
timeout_ms |
int |
ms | 1000 |
应为正数;gRPC 小于 50 ms 时按 50 ms RPC deadline 处理 |
SDK 总是发送阻塞式模式切换请求。服务端确认目标 FSM 状态已经到达后,方法返回 True;请求被拒绝、
控制权失效或通信超时时返回 False。返回后仍应读取 get_service_state(),因为状态缓存可能稍有延迟,
也可能在切换完成后因故障或其他事件再次变化。controller_state 是底层 controller 名称,确认模式时应
检查 fsm_state。
from arm_p7_sdk import Controller
if not client.switch_controller(Controller.planning_control, timeout_ms=5000):
raise RuntimeError("无法进入 planning_control;检查 SDK 日志和服务状态")
state = client.get_service_state()
if state is None or state.fsm_state != "PLANNING_CONTROL":
raise RuntimeError("状态缓存尚未确认 PLANNING_CONTROL")
后端等待差异#
- gRPC 从
idle切到活动模式后最多再等待 0.5 秒稳定时间,其他切换最多等待 0.2 秒。timeout_ms已耗尽时会缩短这段本地等待;服务端已经完成的切换不会因此改回失败。 - DDS 在服务端确认后固定等待相同的 0.5 秒或 0.2 秒,不从
timeout_ms中扣除,因此方法总耗时可能 超过传入值。 - 正在执行规划轨迹时,切出
planning_control会被拒绝。release_control()也不会取消已经接受的 轨迹。
enter_gravity_compensation_mode()#
此方法需要可用服务和控制权,gRPC、DDS 均支持。timeout_ms 单位为 ms;gRPC 对小于 50 ms 的值使用
50 ms RPC deadline,DDS 把该值交给 route 调用。两种后端都发送阻塞式切换请求,并在成功后分别追加
从 idle 离开时 0.5 秒、其他切换 0.2 秒的本地等待。成功返回 True 后,
ServiceState.fsm_state 应变为 GRAVITY_COMPENSATION。
进入重力补偿可能让机械臂在外力作用下移动。确认工具和负载安装牢固、运动范围内无人和障碍物、 实体急停可立即操作后,再托住机械臂并进入该模式。退出时调用:
if not client.switch_controller(Controller.idle, timeout_ms=5000):
raise RuntimeError("无法退出重力补偿;保持现场警戒并检查当前状态")
重力补偿成功后,SDK 的本地 controller 缓存记为 idle,因为该模式没有对应的 Controller 枚举值。
随后调用 move_joint() 会返回 False;若要运动,必须显式切入 planning、Servo 或 MIT 模式。
只读取并确认模式#
以下代码不申请控制权、不切换模式,也不发送运动目标。它适合在操作前确认服务当前处于哪个状态。
from arm_p7_sdk import AirbotClient
with AirbotClient(host="P7_IP_ADDRESS", port=50071, backend="grpc") as client:
state = client.get_service_state()
if state is None:
raise RuntimeError("服务状态缓存尚未建立")
if not state.valid or not state.service_state:
raise RuntimeError("服务状态不可用或已经过期")
print("FSM:", state.fsm_state)
print("controller:", state.controller_state)
DDS 后端的 ServiceState.valid 可能在健康连接的两个轮询周期之间短暂为 False,处理方式见
状态读取参考。模式切换失败时先停止下发新目标,再按
状态参考确认当前状态,并按
异常恢复区分急停、碰撞和未知错误。同名模式命令及确认口令见
SDK 最小可执行用例。