跳转至
客户端生命周期

客户端生命周期#

创建 AirbotClient 会立即初始化所选传输并注册客户端身份。优先使用 context manager;长生命周期 对象也必须在不再使用时调用 close()

AirbotClient(...)#

AirbotClient(
    host="localhost",
    port=50071,
    *,
    backend="grpc",
    domain_id=0,
    side="none",
    participant_name=None,
    use_shared_memory=True,
    use_udp=True,
    default_timeout_ms=3000,
    rpc_retry_count=1,
    shutdown_on_close=False,
    source_name="default",
    client_name=None,
    client_instance_id=None,
)

通用参数#

参数 类型 默认值 说明
backend str "grpc" "grpc"/"grpc_route" 选择 gRPC;"dds"/"cora"/"cora_dds"/"dds_route" 选择 DDS。忽略首尾空白和大小写
rpc_retry_count int 1 瞬时同步 RPC 失败后的重试次数;必须不小于 0。重试会延长一次调用的总等待时间
source_name str "default" 控制来源类别;转为小写,空字符串归一化为 "default"。必须匹配 [a-z0-9][a-z0-9._-]{0,63},并已在目标服务配置中存在
client_name str \| None None 当前服务注册域内唯一的人类可读名称。显式值转为小写并使用与 source_name 相同的字符规则;None 自动生成唯一名称
client_instance_id str \| None None 当前进程实例的 UUID;None 自动生成 UUID4。不要跨进程启动固定复用同一个值

source_name 决定服务端配置的控制优先级,client_name 标识具体客户端,二者不能互换。当前核对的 产品基线只配置了 default 来源;其他名称只有在目标项目明确配置后才可使用。

gRPC 参数#

参数 类型 默认值 说明
host str "localhost" P7 主机名或 IP;必须非空且可解析
port int 50071 TCP 端口,范围 1..65535

gRPC 构造最多等待 3 秒让通道就绪。通道就绪后还会注册客户端、启动状态后台任务并读取一次固件信息。 hostport 对 DDS 后端不起作用。

DDS 参数#

参数 类型 默认值 说明
domain_id int 0 DDS Domain ID,必须与目标服务一致
side str "none" "none""left""right"。还接受 l/rleft_arm/right_arm 等别名;未知值会落入 "none",因此建议只用三个规范值
participant_name str \| None None DDS participant 名称;None 时按当前进程生成
use_shared_memory bool True 启用 DDS 共享内存传输
use_udp bool True 启用 DDS UDP 传输
default_timeout_ms int 3000 DDS 同步 RPC 的默认单次超时,单位毫秒
shutdown_on_close bool False 请求在最后一个 SDK DDS 客户端关闭后终止由 SDK 创建的进程级 CORA participant

DDS 需要匹配的 CORA Python SDK。SDK 在首次 DDS 客户端创建时初始化进程级 participant;多个客户端 会共享它。默认 shutdown_on_close=False 只释放当前客户端的 Reader、Writer 和 RPC Client 引用, 不关闭共享 participant。只有 participant 由 SDK 创建、已请求 shutdown 且最后一个 DDS 客户端关闭时, 才会调用 CORA shutdown。

domain_id=0 是 SDK 默认值,不是所有整机配置的固定值。当前单臂默认运行配置可能由 CORA 派生 Domain;连接前按DDS 命名与连接确认实际值。

构造成功后还要检查什么#

构造函数返回时只能确认以下工作已经完成:

  1. gRPC 通道已就绪,或 CORA/DDS 环境已初始化;
  2. 客户端注册已成功,或兼容旧服务时进入 default legacy 模式;
  3. 服务探测和服务状态轮询任务已启动;
  4. 固件信息已经尝试读取一次。

服务状态缓存由后台异步填充,其他遥测也可能尚未到达。先读取 get_service_state(),再按 状态读取参考处理 None、服务不可用和陈旧缓存。构造过程不会申请控制租约。

构造异常#

异常 常见原因 下一步
ValueError 后端名、gRPC 地址/端口、重试次数或身份格式无效 修正参数;不要捕获后继续使用未构造完成的对象
ConnectionError gRPC 通道 3 秒内未就绪,或 DDS 环境缺少 CORA Python SDK 检查地址、进程、端口或安装匹配的 CORA 包
ClientNameConflictError 另一活动进程已注册同一个 client_name 为每个进程使用唯一名称;不要通过复用 client_instance_id 绕过冲突
UnsupportedOperationError 旧服务不支持注册协议,而 source_name 不是 default 使用匹配版本;legacy 回退只允许 default
后端原生 RPC 异常 注册服务不可用、来源未配置或 DDS 路由返回错误 记录后端、服务日志和完整异常,核对版本与服务配置

构造中任何步骤失败时,SDK 会尝试注销已经建立的注册并关闭传输。

context manager#

from arm_p7_sdk import AirbotClient

with AirbotClient(host="P7_IP_ADDRESS", port=50071) as client:
    print(client.get_service_state())

__enter__() 返回同一个客户端。无论代码块正常结束还是抛出异常,__exit__() 都调用 close(); 它不会吞掉代码块中的异常。

close()#

client.close() -> None

close() 按顺序停止状态任务和租约续期、尝试释放当前租约、停止注册心跳、注销注册,然后关闭传输。 它可以重复调用;第二次及后续调用直接返回。

关闭过程为尽力清理:释放或注销 RPC 失败不会从 close() 重新抛出。网络中断时,客户端会清除本地 租约,但服务端可能要等租约到期才把资源标为未占用。因此 close() 返回不等同于服务端已经确认释放。 关闭后不要继续调用该对象。

不要依赖 __del__() 或进程退出完成清理。对象析构时机不确定,异常退出也可能来不及发送 Release; context manager 或 try/finally 才能提供确定的本地关闭路径。

client = AirbotClient(host="P7_IP_ADDRESS", port=50071)
try:
    print(client.get_service_state())
finally:
    client.close()

相关页面#