SDKPython SDK

Device discovery & connection

Discover gloves, select fixed devices, run multiple gloves, and use a wireless Receiver.

Current version · 1.4.0

Device discovery & connection

Device discovery

When you need to list devices before creating the Sdk, you can call 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),
)

Commonly used fields:

Commonly used fieldMeaning
portDiscovered serial port path
handSuccessfully recognized left/right hand; may be None when recognition fails
snSuccessfully read device SN
errorDiscovery error for that port; None on success

For complete fields, types, and nullability behavior, see DiscoveredGlove and GloveDiscoveryIssue.

The return value is a read-only tuple[DiscoveredGlove, ...]. When the port is occupied by another process, the device still appears in the results, port is retained, and it is identified by GloveDiscoveryErrorCode.PORT_BUSY. Use error.code to determine the result; error.message is for display only.

The discovery result is a snapshot of the moment of the call. After devices are plugged or unplugged, call it again, then build the configuration from the port and hand of the selected record. For a complete runnable example, see discover_gloves.py.

Single glove

With one glove, you do not need to specify a port or side. The default configuration selects it automatically:

from qnbot_sdk import Sdk
from qnbot_sdk.glove import GloveConfig

devices = (GloveConfig(),)
sdk = Sdk(devices=devices)

A single GloveConfig() without a side requires exactly one unoccupied supported device. Fixed selection is only needed when automatic discovery cannot work, see Connecting the device.

Two gloves

When both hands are known, connection can be omitted for both:

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)

The SDK assigns devices to the left and right hand by side, and the device enumeration order does not affect the result. Each directly connected glove is assigned at most once; a supported Receiver can connect both hands at the same time. If a specified directly connected glove is missing, there is more than one device on the same side, or the device information read during SDK creation changes, the SDK stops creation and reports an error. How gloves in a Receiver that go offline during SDK creation are handled is described below.

When both gloves are on the same side (two right gloves, for example), configure a different port or serial_number for each of them.

Multiple gloves

When connecting three or more gloves, at least two gloves are on the same side. To select each glove separately, set a unique name for each configuration and pin gloves on the same side with different port or serial_number values:

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 is used to select a glove and does not replace device locating information. When three gloves can be uniquely determined by other conditions, the SDK does not refuse creation merely because name is omitted; however, gloves on the same side can no longer be selected individually by side.

No physical glove, or integrating your own device? Both cases can feed external hand frames frame by frame, and they are read through the same paths as a physical glove. See External input for the configuration and frame constraints.

Connecting the device

Sdk construction completes device discovery and identity verification; start() establishes the continuously running connection and data streams, see Lifecycle. Use the connection options below when you need to pin a specific device.

A fixed port or serial number

Using a specified serial port:

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"),
)

When the SDK can recognize the port as a supported wired directly connected glove and both port and side are explicitly provided, the SDK still validates the device identity first. For older wired directly connected gloves that cannot report a device identity, the SDK continues to connect using the configured serial port and left/right hand and issues an "identity not verified" warning. Disconnection recovery retries only that port and cannot confirm whether the recovered device is still the same physical glove. Automatic discovery, providing only port, providing only side, selecting by serial_number, the wireless Receiver, and cases where the port type cannot be recognized still require device identity validation and cannot use this compatibility behavior.

Selecting by USB serial number:

SerialConnection(serial_number="YOUR-SERIAL-NUMBER")

Automatic discovery can also be written explicitly:

SerialConnection(auto_discover=True)

When set explicitly, exactly one of auto_discover=True, port, and serial_number must be provided; baudrate is optional. If creating the Sdk already fails, start with Cannot find the device.

Wireless Receiver (experimental feature)

The Receiver is currently an experimental feature, and its stability, support scope, and usage may change in later versions.

A supported wireless Receiver uses the same GloveConfig and serial port selection method as a directly connected wired glove and does not require a Receiver-specific configuration type. Each GloveConfig still represents only one glove; when connecting both hands automatically, configure GloveConfig(side=Side.LEFT) and GloveConfig(side=Side.RIGHT) separately, and the SDK can find the gloves on both sides through the same Receiver.

In a fixed deployment, the two left and right configurations can select the same Receiver serial port. If the port is actually connected to a directly connected wired glove, the duplicate configuration is rejected. Gloves that are configured in the Receiver but go offline during SDK creation are not added: other online gloves and SDK features that do not depend on that glove can continue to be used, and the offline glove and its outputs do not appear in the current SDK. After turning on that glove, the SDK needs to be recreated; a running SDK does not add it automatically.

Identity-confirmed Receiver gloves support pose, status, Capture, Calibration, Skeleton, and Retargeting. Currently, haptics() wireless vibration control and other unspecified device control functions are not supported; when these functions are needed, use a connection method explicitly supported by the product.

Select and inspect a device

Sdk construction completes device discovery and identity verification. Once it succeeds, select a GloveDevice from the configured gloves. Use that device for capture, status queries, and calibration; register continuous callbacks before start().

Direct gloves are allocated when the Sdk is created, as shown below:

Rendering diagram

Select a device

from qnbot_sdk import Side

glove = sdk.glove()
device = glove.device()                 # One configured glove
left = glove.device(side=Side.LEFT)     # Select by side
primary = glove.device("left-primary")  # Select by GloveConfig.name

No match raises NotFoundSelectionError; multiple matches raise AmbiguousSelectionError. Give same-side gloves distinct GloveConfig.name values and select them by name.

For the scope of the selected device's start(), stop() and health(), see Core objects & lifecycle.

Inspect the device

device.get_device_info() returns the verified device information snapshot saved during SDK construction, including the serial number, device type, model, firmware version, hand, and hand source. It does not resend an identity command on each call.

IdentifierHow to obtain itPurpose
nameGloveConfig.nameApplication-defined logical name used by glove.device(name)
source_iddevice.source_idSDK data routing identifier
canonical_sndevice.get_device_info().canonical_snVerified device serial number; do not derive it from a port or name

For older wired firmware explicitly connected with port + side that cannot report identity, the SDK does not invent device information: get_device_info() raises UnavailableFeatureError, and capabilities requiring verified identity are unavailable.