设备发现与连接
发现手套、固定选择、多只手套与无线 Receiver。
设备发现与连接
发现设备
需要在创建 Sdk 前列出设备时,可调用 discover_gloves():
from qnbot_sdk import SerialConnection
from qnbot_sdk.glove import GloveConfig, discover_gloves
devices = discover_gloves()
selected = next(device for device in devices if device.error is None)
device_config = GloveConfig(
side=selected.hand,
connection=SerialConnection(port=selected.port),
)常用字段:
| 常用字段 | 含义 |
|---|---|
port | 发现的串口路径 |
hand | 成功识别的左右手;识别失败时可能为 None |
sn | 成功读取的设备 SN |
error | 该端口的发现错误;成功时为 None |
完整字段、类型和可空行为见 DiscoveredGlove 和
GloveDiscoveryIssue。
返回值是只读 tuple[DiscoveredGlove, ...]。端口被其他进程占用时,该设备仍会出现在结果中,port 保留,并通过 GloveDiscoveryErrorCode.PORT_BUSY 标识。应使用
error.code 判断结果,error.message 仅用于展示。
发现结果是调用时刻的快照。设备插拔后应重新调用,再用所选记录的 port 和 hand 构建配置。完整可运行示例见 discover_gloves.py。
单只手套
只有一只手套时,无需指定端口或左右手,使用默认配置即可自动选择:
from qnbot_sdk import Sdk
from qnbot_sdk.glove import GloveConfig
devices = (GloveConfig(),)
sdk = Sdk(devices=devices)单个 GloveConfig() 未指定 side 时,必须只有一个未占用的支持设备。只有自动发现不成立时才需要固定选择,见 连接设备。
两只手套
左右手均已知时,可以同时省略 connection:
from qnbot_sdk import Sdk, Side
from qnbot_sdk.glove import GloveConfig
devices = (
GloveConfig(side=Side.LEFT),
GloveConfig(side=Side.RIGHT),
)
sdk = Sdk(devices=devices)同侧两只手套需分别指定不同的 port 或 serial_number。
多只手套
连接三只及以上手套时,至少有两只手套位于同一侧。如需分别选择每只手套,应为每项配置设置唯一的 name,并用不同的 port 或 serial_number 固定同侧手套:
from qnbot_sdk import Sdk, SerialConnection, Side
from qnbot_sdk.glove import GloveConfig
devices = (
GloveConfig(
name="left-primary",
side=Side.LEFT,
connection=SerialConnection(port="/dev/ttyUSB0"),
),
GloveConfig(
name="left-backup",
side=Side.LEFT,
connection=SerialConnection(port="/dev/ttyUSB1"),
),
GloveConfig(
name="right",
side=Side.RIGHT,
connection=SerialConnection(port="/dev/ttyUSB2"),
),
)
sdk = Sdk(devices=devices)
glove = sdk.glove()
left_primary = glove.device(name="left-primary")name 用于选择手套,不替代设备定位信息。三只手套能够由其他条件唯一确定时,SDK 不会仅因省略 name 而拒绝创建;但同侧手套无法再通过 side 单独选择。
没有实体手套,或要接入自研设备? 这两种情况都可以用外部输入逐帧提供手部帧,读取路径与实体手套相同。配置方式与帧约束见 外部输入。
连接设备
创建 Sdk 时完成设备发现与身份校验,start() 才建立持续运行的连接与数据流,见 生命周期。需要指定具体设备时,用下面的连接方式。
指定端口或序列号
使用指定串口:
from qnbot_sdk import SerialConnection, Side
from qnbot_sdk.glove import GloveConfig
device_config = GloveConfig(
name="primary",
side=Side.RIGHT,
connection=SerialConnection(port="/dev/ttyUSB0"),
)身份校验与兼容路径:
| 创建时的条件 | SDK 行为 |
|---|---|
| 设备报告有效身份 | 核对指定的 side、序列号等条件;不一致则创建失败 |
已识别的受支持有线直连手套,显式提供 port + side,且限定时间内没有身份响应或返回 UNKNOWN_COMMAND、UNSUPPORTED_COMMAND、NOT_IMPLEMENTED 之一 | 使用指定端口和 side 继续创建,并发出“身份未验证”告警 |
自动发现、仅提供 port 或 side、按 serial_number 选择、无线 Receiver、端口类型无法识别 | 必须取得并验证身份,不能使用未验证身份的兼容路径 |
端口读写失败、身份响应格式错误或身份不匹配也不会触发兼容路径。未验证身份的手套断线恢复时只重试指定 port,SDK 无法确认恢复后是否仍为同一只实体手套。
通过 USB 序列号选择:
SerialConnection(serial_number="YOUR-SERIAL-NUMBER")也可以显式写出自动发现:
SerialConnection(auto_discover=True)显式设置时,auto_discover=True、port 和 serial_number 必须且只能提供一个;baudrate 可选。如果创建 Sdk 就报错,先看 找不到设备。
无线 Receiver(实验性功能)
Receiver 当前是实验性功能,稳定性、支持范围和使用方式在后续版本中可能调整。
受支持的无线 Receiver 与直连有线手套使用同一个 GloveConfig 和串口选择方式,不需要
Receiver 专用配置类型。每个 GloveConfig 仍只表示一只手套;自动连接左右手时,分别配置
GloveConfig(side=Side.LEFT) 和 GloveConfig(side=Side.RIGHT),SDK 可以通过同一个
Receiver 找到两侧手套。
固定部署时,左右两项配置可以选择同一个 Receiver 串口。若端口实际连接的是直连有线手套,重复配置会被拒绝。Receiver 中已配置但在 SDK 创建期间离线的手套不会加入:其他在线手套和不依赖该手套的 SDK 功能可以继续使用,离线手套及其输出不会出现在当前 SDK 中。打开该手套后需要重新创建 SDK;运行中的 SDK 不会自动添加它。
经过身份确认的 Receiver 手套支持 pose、status、Capture、Calibration、Skeleton 和 Retargeting。当前不支持 haptics() 无线震动控制或其他未说明的设备控制功能;需要这些功能时,请使用产品明确支持的连接方式。
选择和查看设备
直连手套在 Sdk 创建时按下图分配:
选择设备
创建成功后,从已配置的手套中选择 GloveDevice。采集、状态查询和标定作用于所选设备;持续 callback 建议在 start() 前注册。
from qnbot_sdk import Side
glove = sdk.glove()
device = glove.device() # 仅配置一只手套
left = glove.device(side=Side.LEFT) # 按左右手选择
primary = glove.device("left-primary") # 按 GloveConfig.name 选择没有匹配设备时抛出 NotFoundSelectionError,匹配多个设备时抛出 AmbiguousSelectionError。同侧有多只手套时,应分别设置 GloveConfig.name 并按名称选择。
选中的 GloveDevice 的 start()、stop()、health() 和 close() 作用范围见 核心对象与生命周期。
查看设备
device.get_device_info() 返回 SDK 创建期间保存的已验证设备信息快照,包括序列号、设备类型、型号、固件版本、hand 及其来源;调用时不会再次发送身份命令。
| 标识 | 获取方式 | 用途 |
|---|---|---|
name | GloveConfig.name | 应用设置的逻辑名称,用于 glove.device(name) 选择 |
source_id | device.source_id | SDK 的数据路由标识 |
canonical_sn | device.get_device_info().canonical_sn | 经过身份验证的设备序列号,不应从端口或名称推导 |
对于显式 port + side 连接且无法报告身份的旧固件,SDK 不会伪造设备信息;调用 get_device_info() 会抛出 UnavailableFeatureError,依赖已验证身份的能力不可用。