SDKC++ SDK

常见问题

装不上、连不上、读不到数据等使用问题,以及 C++ 链接要求、异步与运行模型的接口疑问。

当前版本 · 1.4.0

常见问题

每一节的处理步骤都无效时,先按 Debug 日志 复现一次,再把这次运行的日志连同终端输出提供给我们的技术支持。

装不上 SDK 或算法包

确认交付包与当前平台匹配,CMake 配置和构建按 安装与环境要求 的步骤完成。

确认算法包在创建 Sdk 前通过 Qnbot CLI 安装:qnbot algorithm list 能看到目标包,包 ID 与 TargetAlgorithm 一致。安装、升级和卸载的完整步骤见 算法包管理。

处理:装好算法包后重新创建 Sdk,运行中的实例不会热更新包列表;仍然失败时,把安装命令、CMake 输出和报错一起附到 Debug 日志,开启方式见 Debug 日志。

找不到设备

检查:运行 discover_gloves() 查看候选串口、左右手和设备身份;已经创建 SDK 时看 device.status() 的 connected 和 last_error。

  • 候选为空:检查 USB 连接、线缆和串口权限,换一个端口重试。
  • 候选不唯一:用 SerialConnection 固定端口或序列号,或为 GloveConfig 设置 name / side。
  • glove.device() 抛 AmbiguousSelectionError:用 device(name=...) 或 device(side=...) 显式选择;NotFoundSelectionError 的候选信息可以从异常里读取。

详细配置见 设备发现与连接。

连接成功但收不到数据

检查:device.status() 的 connected 是否为 true、stale 是否一直为 true;pose().latest() 是否返回 std::nullopt。

  • latest() 返回 std::nullopt 不是错误:它表示当前还没有可读取的数据。需要等待时用 subscribe() 或 next()。
  • 原始数据:确认在 start() 前注册了 subscribe(),或启动后用 next() 等待;只调用一次 latest() 不会等待。
  • SDK 处理后的数据:需要选择一种 运行方式 并持续推进;target 需要先安装算法包,见 读取 Retargeting 数据。

仍然没有数据时,在 设备状态与诊断 里看 last_error 和 stale,并先打开 Debug 日志。

标定没有通过

检查:device.capture_progress() 卡在哪个阶段,device.calibration_progress(...) 里对应 target 的状态;终端引导里哪个动作没有通过。

  • 按提示重试失败的动作;需要重新采集用 CaptureConfig::force,只重新计算标定用 CalibrationConfig::force,两者含义不同。
  • 外部接管流程用 device.capture_control() 和对应的 session 接口确认、跳过、重试或取消,见 采集。

仍然失败时,保留 Debug 日志里的 capture 与 calibration 模块输出,连同终端提示一起报告。

数据延迟或输出不更新

检查:glove.health() 的 runtime_overrun 和 topic_callback_error 字段;SDK 调度是否一直在推进。

  • 处理后的数据依赖运行方式:持续调用 glove.update(),或保持 run_forever() / run_background() 运行;只等待输出而不推进调度不会产生新数据,见 运行方式。
  • callback 里不要做耗时操作:SDK 依次执行 callback,耗时操作会耽误后续数据处理。把数据放进队列,交给工作线程处理。
  • 同一次运行中混用运行方式会抛出 LifecycleError,只选一种。

只链接 qnbot::glove 会要求 C++20 吗?

不会。qnbot::glove 和 qnbot::core 的 public compile feature 是 C++17。只有额外链接 qnbot::core_coro 的 target 需要 C++20。

为什么 next() 没有返回 future?

C++17 核心使用 move-only NextOperation<T>,让同步等待和取消具有明确的清理边界。C++20 应用可以使用 qnbot::coro::next() 将同一个 operation 转成 co_await。

run_forever() 如何结束?

公开命令行示例按 Ctrl+C 结束进程。需要由应用控制停止时,使用 background 模式,并在应用的停止路径调用 request_stop() 和 join()。

什么时候使用 background 模式?

主线程需要继续处理 UI、应用事件循环、停止协调或其他工作时使用。普通阻塞式命令行程序优先使用 foreground;应用自有调度循环使用 manual。

external connection 能设置 haptics 吗?

不能。它没有实体震动设备,写入会被拒绝;使用串口连接的受支持手套才能控制指尖震动。