SDKC++ SDK

Common questions

Installation, connection and data problems, plus design questions about C++ link requirements, async operations and runtime models.

Current version · 1.4.0

Common questions

When the steps in a section do not help, reproduce the problem once with the Debug logs turned on, then provide that run's logs together with the terminal output to our technical support.

Cannot install the SDK or an algorithm package

Check that the delivery package matches the current platform and that the CMake setup and build follow the steps in Installation & requirements.

Check that the algorithm package is installed through Qnbot CLI before the Sdk is created: qnbot algorithm list shows the target package and its ID matches TargetAlgorithm. The full install, upgrade and removal steps are in Package management.

What to do: recreate the Sdk after installing the package; a running instance does not pick up package changes. If it still fails, attach the install command, the CMake output and the error to the Debug logs; see Debug logs for how to turn them on.

Cannot find the device

Check: run discover_gloves() to see the candidate ports, hand sides and device identities; in an already created SDK, read connected and last_error from device.status().

  • No candidates: check the USB connection, cable and serial port permissions, then try another port.
  • More than one candidate: fix the port or serial number through SerialConnection, or give the GloveConfig a name / side.
  • glove.device() raises AmbiguousSelectionError: select explicitly with device(name=...) or device(side=...); NotFoundSelectionError carries the candidates.

For the full configuration, see Device discovery & connection.

Connected but no data

Check: is connected true and stale stuck at true in device.status(); does pose().latest() return std::nullopt.

  • latest() returning std::nullopt is not an error: it means no data is readable yet. To wait, use subscribe() or next().
  • Raw data: make sure subscribe() was registered before start(), or wait after startup with next(); calling latest() once does not wait.
  • SDK-processed data: choose a runtime mode and keep it advancing; the target needs an installed algorithm package, see Reading retargeting data.

If data still does not arrive, read last_error and stale in Status and diagnostics and turn on the Debug logs in Debug logs.

Calibration did not pass

Check: which stage device.capture_progress() is stuck at, and the state of the matching target in device.calibration_progress(...); which guided motion failed in the terminal.

  • Retry the failed motion; resample with CaptureConfig::force, or recompute only the calibration with CalibrationConfig::force — the two mean different things.
  • In an external-takeover flow, use device.capture_control() and the matching session calls to confirm, skip, retry or cancel, see Capture.

If it still fails, keep the capture and calibration modules in the Debug logs and report them with the terminal output.

Data is late or the output stops updating

Check: runtime_overrun and topic_callback_error in glove.health(); is SDK scheduling still advancing.

  • Processed data depends on the runtime: keep calling glove.update(), or keep run_forever() / run_background() running; waiting for output without advancing the schedule never produces new data, see Runtime modes.
  • Do not do time-consuming work in a callback: the SDK runs callbacks in sequence, and slow callbacks delay later data processing. Put the data into a queue and process it on a worker thread.
  • Mixing runtime modes in the same run raises LifecycleError; pick one.

Does linking only qnbot::glove require C++20?

No. The public compile feature of qnbot::glove and qnbot::core is C++17. Only targets that additionally link qnbot::core_coro require C++20.

Why does next() not return a future?

The C++17 core uses a move-only NextOperation<T>, which gives synchronous waiting and cancellation a clear cleanup boundary. C++20 applications can use qnbot::coro::next() to turn the same operation into a co_await.

How does run_forever() end?

The public command-line examples end the process with Ctrl+C. When stopping must be controlled by the application, use background mode and call request_stop() and join() in the application's stop path.

When should background mode be used?

Use it when the main thread must continue handling the UI, the application event loop, stop coordination, or other work. Ordinary blocking command-line programs should prefer foreground; an application-owned scheduling loop uses manual.

Can an external connection set haptics?

No. It has no physical haptic device and writes are rejected; only supported gloves connected over serial can control fingertip haptics.