Configuration reference
Fields, types and defaults for every configuration object.
Configuration reference
The source, target, algorithm, calibration, and Debug configuration must all be provided at
once when the Sdk is created; an existing SDK does not support dynamic addition, removal, or
modification. After the configuration or the installed algorithm packages change, close and
recreate the Sdk.
| Configuration item | When it is needed |
|---|---|
source | The default configuration can be used for single-glove auto-discovery; explicit configuration is needed for multiple gloves or a fixed device |
target | When retargeting output is needed |
| algorithm package configuration | When retargeting output is needed |
| Capture and calibration | Can be omitted for the default wearer with terminal interaction; configure it when changing or distinguishing wearers, when an external interactive host takes over, or when recomputation is required |
| Debug | Configure it when troubleshooting or recording Debug logs; off by default |
When only reading glove poses, start from the minimal configuration. When retargeting output is needed, configure the target first and specify its algorithm package within that section; enable calibration and Debug as the application requires.
source configuration
GloveConfig
| Field | Type | Default |
|---|---|---|
name | std::optional<std::string> | Defaults to empty |
side | std::optional<Side> | For serial devices, read from the verified identity |
connection | ConnectionConfig | Defaults to SerialConnection{} |
enabled | bool | Defaults to true |
name: when provided it must be a non-empty name and unique among enabled devices.name: it can be omitted when the selection is already unambiguous.side: required for external input.side: an explicit value must match the device or the input frame.connection: serial is used for physical gloves.connection:ExternalConnectionis used for frame-by-frame input from the application.enabled: whenfalse, the device is not connected, not started, not selectable, and cannot be used as a target source.
SerialConnection
| Field | Type | Default |
|---|---|---|
auto_discover | bool | Treated as true when all three locating fields are omitted |
port | std::optional<std::string> | Defaults to empty |
serial_number | std::optional<std::string> | Defaults to empty |
baudrate | std::optional<std::uint32_t> | Uses the SDK default when omitted |
auto_discover: choose one of three withportandserial_number.auto_discover: the discovery result must be unique and pass identity verification.port: specifies the serial port.port: the legacy firmware identity fallback is allowed only when theport + sideconditions below are met.serial_number: discover by USB serial number; a valid device identity is always required.baudrate: must be a positive integer when provided.
Exactly one of auto_discover, port, and serial_number must be specified; when all three
locating fields are omitted, automatic discovery is used. When only port is provided, the side
must be obtained from the device identity; when only side is provided, or neither is provided,
automatic discovery is still used with strict identity verification; no fallback is used with
serial_number either.
ExternalConnection
ExternalConnection has no configuration fields. When using it, GloveConfig::side is
required, and every frame submitted by the application must match that side; it does not perform
serial discovery, and it does not support device information, haptics, or other physical device
control.
target configuration
TargetConfig
| Field | Type | Default |
|---|---|---|
type | std::optional<TargetType> | Inferred when the candidate is unique |
name | std::optional<std::string> | Stays omitted; not generated from the algorithm package |
side | std::optional<Side> | Inferred when the candidate is unique |
source | std::optional<DeviceSelector> | Inferred when the candidate is unique |
algorithms | std::vector<TargetAlgorithm> | Defaults to empty |
type: an explicit value narrows down and validates the candidates.type: the currently public values arehandandarm.name: when provided it must be a non-empty name.name: the reserved nameskeletoncannot be used for an ordinary target.side: an explicit value must be compatible with the source and the algorithm capabilities.source: zero candidates or multiple candidates both make SDK creation fail.algorithms: executed in declaration order.algorithms: an empty list means the input is passed through directly.
DeviceSelector
| Field | Type | Default |
|---|---|---|
type | std::string | No default |
name | std::optional<std::string> | Defaults to empty |
side | std::optional<Side> | Defaults to empty |
type: must be a non-empty device type.type: gloves use"glove".name: matches the source name in the configuration.side: matches the left/right hand of the device.side: the combined conditions must uniquely select one enabled source.
TargetAlgorithm
| Field | Type | Default |
|---|---|---|
id | std::string | No default |
id: must be a non-empty algorithm package ID.id: the corresponding package must already be installed through the Qnbot CLI.id: the corresponding package must be compatible with the current platform and SDK.
Custom retargeting packages must be installed via Qnbot CLI before creating the Sdk. See algorithm package configuration below for the installation steps.
In a single-glove, single-target scenario, you can declare only the algorithm:
qnbot::TargetConfig target_config;
target_config.algorithms = {
qnbot::TargetAlgorithm{"<package-id>"},
};type, side, and source can be omitted and are inferred only when the candidate is unique;
an omitted name stays omitted. A fixed deployment can provide constraints explicitly:
qnbot::TargetConfig target_config;
target_config.source = qnbot::DeviceSelector{
"glove", std::string("primary"), std::nullopt,
};
target_config.name = "dexhand";
target_config.side = qnbot::Side::right;
target_config.algorithms.push_back(qnbot::TargetAlgorithm{"<package-id>"});TargetAlgorithm contains only id, whose value is the package ID of an installed algorithm
package. The SDK uses the algorithm packages specified in the configuration that have already
been installed through the product CLI; it does not install algorithm packages.
Omitting algorithms or using an empty list means that no conversion algorithm is executed and
the input is passed through directly. One source can be configured with multiple targets; when
reading multiple outputs, select the corresponding output by the instance name provided by the
application. An omitted public instance name stays omitted and is not generated automatically
from the algorithm package. The package ID is responsible for selecting the algorithm package;
resource names inside the package do not override, generate, or constrain the instance name;
TargetConfig::name is defined solely by the application and is used to read the output by
instance name.
Capture and calibration configuration (optional)
Calibration usually does not need to be configured explicitly. If the selected retargeting algorithm requires calibration, the SDK guides the operation at runtime and reuses the saved calibration record in subsequent runs.
When wearers need to be distinguished, provide the calibration configuration:
qnbot::SdkConfig config;
config.algorithms.capture.operator_id = "operator-a";When a GUI or remote application needs to present the calibration interaction itself, see External takeover of guided interaction.
AlgorithmsConfig
| Field | Type | Default |
|---|---|---|
calibration | CalibrationConfig | Uses the default configuration |
capture | CaptureConfig | Uses the default configuration |
calibration: controls whether the calibration is recomputed.capture: controls whether an existing capture is reused, the interaction method, and the wearer identifier.
CaptureConfig
| Field | Type | Default |
|---|---|---|
force | bool | Defaults to false |
interaction | CaptureInteractionMode | Defaults to auto_terminal |
operator_id | std::string | Defaults to "default" |
force: whentrue, reusable raw frames are ignored and resampled.force: it is not continuous capture and does not resample on every update.interaction: terminal programs useauto_terminal.interaction: GUI, remote, or no-TTY applications useexternaland handle capture control.operator_id: must be a non-empty string.operator_id: used to distinguish the calibration records of different wearers.
CalibrationConfig
| Field | Type | Default |
|---|---|---|
force | bool | Defaults to false |
force: whentrue, the calibration is recomputed using the currently available capture.force: resampling is not forced.force: after it succeeds the same instance reuses the new result on stop or reconnection, and a newly created forced instance computes again.force: it ignores compatible records that existed before this instance was created and forces one calibration per target.
The two force settings are not interchangeable: use CaptureConfig.force to resample raw frames, or CalibrationConfig.force to recompute calibration from the available capture.
Debug configuration (optional)
When the Debug configuration is omitted, no logs are generated. When runtime problems need to be troubleshot, you can choose the modules to record and the sample rate:
qnbot::DebugConfig debug_config{
{qnbot::DebugModule::transport, qnbot::DebugModule::device,
qnbot::DebugModule::capture, qnbot::DebugModule::calibration,
qnbot::DebugModule::retargeting, qnbot::DebugModule::output},
qnbot::DebugDetail::summary,
10,
};DebugConfig
| Field | Type | Default |
|---|---|---|
modules | std::vector<DebugModule> | Defaults to empty |
detail | DebugDetail | Defaults to summary |
sample_rate | std::optional<std::uint32_t> | Defaults to empty |
modules: available values aretransport,device,capture,calibration,retargeting,output.detail:summarysuits ordinary troubleshooting.detail:fullrecords more data and may contain sensitive values.sample_rate: must be a positive integer.sample_rate: a value of N means one out of every N ordinary records is kept.
For log locations and the scope of recorded content, see Debug logs.
Complete configuration
SdkConfig and Sdk(...)
| Field | Type | Default |
|---|---|---|
SdkConfig::devices | std::vector<DeviceConfig> | Defaults to empty |
SdkConfig::targets | std::vector<TargetConfig> | Defaults to empty |
SdkConfig::debug | std::optional<DebugConfig> | Defaults to empty |
SdkConfig::algorithms | AlgorithmsConfig | Uses the default configuration |
Sdk(SdkConfig) | SdkConfig | Required |
SdkConfig::devices: names and final sources must be unique.SdkConfig::targets: each target must uniquely match one enabled source.SdkConfig::debug: when provided, Debug logs are recorded for this SDK instance.SdkConfig::algorithms: controls capture and calibration.Sdk(SdkConfig): the configuration is moved into the SDK by value.Sdk(SdkConfig): device and target resolution is completed during construction.
The following combines a fixed device, a retargeting algorithm package, a target, calibration, and Debug. When using only some of these capabilities, just delete the corresponding optional configuration:
qnbot::SerialConnection connection;
connection.serial_number = "YOUR-SERIAL-NUMBER";
qnbot::GloveConfig device_config{qnbot::Side::right, connection};
device_config.name = "primary";
qnbot::TargetConfig target_config;
target_config.name = "dexhand";
target_config.side = qnbot::Side::right;
target_config.source = qnbot::DeviceSelector{
"glove", std::string("primary"), std::nullopt,
};
target_config.algorithms = {
qnbot::TargetAlgorithm{"<package-id>"},
};
qnbot::SdkConfig config;
config.devices = {device_config};
config.targets = {target_config};
config.algorithms.capture.operator_id = "operator-a";
config.algorithms.capture.force = false;
qnbot::DebugConfig debug_config{
{qnbot::DebugModule::transport, qnbot::DebugModule::device,
qnbot::DebugModule::capture, qnbot::DebugModule::calibration,
qnbot::DebugModule::retargeting, qnbot::DebugModule::output},
qnbot::DebugDetail::summary,
10,
};
config.debug = debug_config;
qnbot::Sdk sdk(std::move(config));Application data directory
When QNBOT_HOME is not set, the SDK uses ~/.qnbot as the application data root directory.
Set that environment variable to use a different directory. Calibration records are stored in <QNBOT_HOME>/glove/calibrations, and Debug logs in <QNBOT_HOME>/logs.
- Timing: it must be set before creating the
Sdk - Consistency: the CLI and the SDK should use the same value, otherwise the SDK may not find the algorithm packages the CLI installed
Terminal output and interaction
With nothing configured, the built-in terminal enables level colors only in an interactive TTY: the Error label is bold red, the Warning label is yellow, the Info label uses the terminal's default foreground color, and Success key results use green. Only level labels and key results are colored; the whole message is not colorized. Debug logs and diagnostic JSON never contain ANSI colors.
NO_COLOR keeps messages plain text; QNBOT_INTERACTIVE_CONSOLE=1 tells the SDK that the current console can receive user input; PYCHARM_HOSTED=1 is set by JetBrains and makes the JetBrains Python Run/Debug Console input-capable even when it uses a pipe.
- Coloring scope: only level labels and key results are colored, never the whole message
- Non-TTY: redirected output, pipes and other non-TTY environments behave the same as setting
NO_COLOR - Setting only
TERM: does not make the SDK treat the console as input-capable - Interaction mode: these variables do not change the configured
interactionmode; taking over the interaction still requiresCaptureConfig.interactionto beexternal, see Capture