Skip to content
FORSENSE

SDK 怎么用 ​

Linux 有两套 1.2.1 压缩包(Ubuntu 22.04 及以上),按机器选:

机器文件大小
PC / x86 工控机Humanhand_G7_sdk_1.2.1_linux_x86_64.tar.gz4.09 MB
ARM64 板Humanhand_G7_sdk_1.2.1_linux_aarch64.tar.gz3.46 MB

Windows 有一套 1.2.1 压缩包,按机器选:

机器文件大小
Windows x86_64 SDKHumanhand_G7_sdk_1.2.1_windows_x86_64.zip86.45 MB
  1. 先不写代码,用包里的 run.sh 看手能不能动、做一次标定。
  2. 确认没问题后,再把库接到你自己的程序里,循环读取 21 个关节位置(接了小臂模块可以再要 22 个点)。

Windows 上请用 HumanHand 上位机 发关节,接收格式见 UDP接收-关节位姿。本页只讲这个 Linux 压缩包。

先选你现在要做的事 ​

你现在的情况往下看
刚解压,不知道这些文件是干什么的包里每个文件
想先看手套好不好用,还不写程序第一次:用 run.sh
菜单里已经在「发送关节」,想在电脑上看到手看手的画面
要把手套编进自己的软件接到自己的程序
想知道读出来的数是什么意思读到的数据

下载 ​

从上表或软件包下载 Humanhand G7 SDK 1.2.1。以下以 x86_64 版为例;ARM64 板请选择对应的 aarch64 压缩包。

bash
tar -xzf Humanhand_G7_sdk_1.2.1_linux_x86_64.tar.gz
cd Humanhand_G7_sdk_1.2.1_linux_x86_64

后面的路径都相对这个目录。

包里每个文件 ​

解压后大致是这样。第一次用只需要 demo/examples/run.sh。 其它文件先不用打开。

text
Humanhand_G7_sdk_1.2.1_linux_x86_64/
├── README.md                          包内说明书(和本页同一条路)
├── CHANGELOG.md                       SDK 各版本更新说明
├── LICENSE  NOTICE                    许可,发布产品时保留
├── include/hand_sdk.h                 写自己程序时 #include 这一个头
├── lib/linux/x86_64/
│   ├── libhand_runtime.so             真正干活的库(链接它)
│   ├── libtensorflowlite_c.so.2.17.1  库的依赖,必须和上一行放在同一目录
│   └── param/                         手套出厂参数缓存,程序自己写入,不用改
└── demo/
    ├── examples/
    │   ├── run.sh                     开箱脚本:第一次就跑这个
    │   ├── hand_mocap                 已经编好的演示程序(run.sh 会启动它)
    │   ├── udp_receiver.py            终端打印 UDP 数字,不存盘
    │   ├── udp_receiver.md            上面脚本的包格式
    │   ├── recv_hand_udp.py           收关节 UDP,画点线图
    │   ├── hand_example.cpp           示例源码,接到自己工程时抄它
    │   └── compile.sh                 编译上面那份示例
    └── docs/
        ├── Integration.md             怎么链进自己的工程
        ├── API.md                     每个函数做什么
        └── DataFormat.md              21 / 22 个点怎么排、单位
文件你怎么用
run.sh开箱入口。 设好运行环境,并启动 hand_mocap。不要先去点 hand_mocap。
hand_mocap预编译好的演示:选串口、标定、发关节。由 run.sh 拉起。
recv_hand_udp.py演示开始发关节之后,另开一个终端跑它,才能看见手。需要本机已装 python3 和 python3-tk。
hand_example.cpp + compile.sh要自己编译一份和演示相同流程的程序时用。
hand_sdk.h + libhand_runtime.so接到你自己软件时,只要这两个(外加与运行库同目录的 libtensorflowlite_c.so*)。
param/第一次连这只手套时,程序会从硬件把参数存到这里。不要手工改。
demo/docs/写代码时再打开;先跑 run.sh 不必看。

第一次用之前 ​

手套走 USB 串口。当前用户要能读写串口,做一次后重新登录:

bash
sudo usermod -aG dialout $USER

插上手套,看系统给了哪个口:

bash
ls /dev/ttyACM* /dev/ttyUSB*

记下名字(常见 /dev/ttyACM0)。口被上位机或其它程序占用时,这里会打不开。

第一次:用 run.sh ​

run.sh 做三件事:设好库需要的环境、找到旁边的 hand_mocap、把它启动起来。你只要进到 demo/examples 再执行它。

bash
cd demo/examples
chmod +x run.sh
./run.sh

它会问:单手还是双手、波特率(直接回车即可,默认 921600)、串口。然后出现菜单:

text
======== 手部动捕 ========
  1) 标定手型
  2) 手套数据读取
  3) 发送关节位姿(相对手腕)
  4) 发送关节位姿(相对小臂)
  5) 发送传感器原始数据(线圈位姿 + 线圈IMU + 磁源IMU)
  6) 对指优化-开启
  7) 抗磁干扰-弱
  8) 退出
  b) 上一步

新手套或新佩戴者建议先选择 1) 标定手型。标定文件生成在当前目录:右手 hand_profile_right.bin,左手 hand_profile_left.bin。

菜单 2 读取手套信息,不发送关节位姿;菜单 5 发送线圈位姿和惯性数据,不用于关节画面。菜单 6 切换对指优化(默认开启):拇指尖靠近某指尖时,求解会把这两点再收近一点;标定结束后开关状态保持不变,不要每帧反复开关。菜单 7 在弱、强、关之间切换抗磁干扰(默认弱),菜单 8 退出,b 返回上一步。

已经知道串口时,可以跳过提问:

bash
./run.sh --port /dev/ttyACM0
./run.sh --port /dev/ttyACM0 --port2 /dev/ttyACM1

双手必须在同一个 run.sh 进程里打开两只手套,不要开两个窗口各跑一次。

标定怎么做(菜单 1) ​

共 8 段。每段先倒计时 3 秒,再自动采集,不是按回车才开始采;采完按回车进下一段,输入 r 重录本段,输入 b 回到上一步。八段都完会自动计算。

序号手势时长怎么摆
1平放静止2 s手掌贴紧水平桌面,四指伸直并尽量并拢,保持平稳,拇指自然放松
2握拳静止2 s保持握拳并静止
3重复握拳5 s持续握拳与张开交替,四指尽量并拢,拇指自然放松
4拇指伸展5 s反复屈伸大拇指
5食指对指2 s拇指与食指指尖相对,不要压紧指腹
6中指对指2 s拇指与中指指尖相对,不要压紧指腹
7无名指对指2 s拇指与无名指指尖相对,不要压紧指腹
8小拇指对指2 s拇指与小指指尖相对,不要压紧指腹

发出关节(菜单 3 / 4) ​

标定完成后选 3)。程序按求解节拍往本机 127.0.0.1:15001 发关节 UDP(双手也是这个端口,左右各一包)。

4) 要手套接了小臂模块。没接小臂时用 3)。

字节格式见 UDP接收-关节位姿。自己的程序也可以不经过 UDP,直接读 SDK 数组,见下一节。

看手的画面 ​

菜单已经在发送关节之后,另开一个终端(仍在 demo/examples):

bash
python3 recv_hand_udp.py

和演示一样提问:1 单手一个窗口,2 双手两个窗口,回车默认双手。再选监听地址和端口,回车=0.0.0.0:15001(双手共用)。刷新选 1–6 对应 20/40/60/80/100/120 Hz,回车默认 120。左键拖转动,右键平移,滚轮缩放。

recv_hand_udp.py 关节位姿点线图

没有画面时:确认演示还在菜单 3 或 4 发送关节、本机装了 python3-tk(Ubuntu:sudo apt install python3-tk)、没改默认端口。

接到自己的程序 ​

确认 run.sh 已经能标定、能看见手,再改你的工程。

你要带上的只有:

  • include/hand_sdk.h
  • lib/linux/x86_64/libhand_runtime.so
  • 同目录的 libtensorflowlite_c.so.2.17.1

可抄的完整流程:demo/examples/hand_example.cpp。在 demo/examples 里执行 ./compile.sh 就能编出一份和演示相同菜单的程序。

关节计算在 libhand_runtime.so 内完成,并使用 1 个线程。演示程序直接运行 ./run.sh;自己写程序时包含 include/hand_sdk.h、链接 libhand_runtime.so,./compile.sh 已按此配置。不需要设置 OMP_NUM_THREADS 或 OPENBLAS_NUM_THREADS。libtensorflowlite_c.so.2.17.1 必须与 libhand_runtime.so 放在同一目录。

一只手套 = 一次 hh_sdk_create。取数只用一个线程调用 hh_sdk_poll。两只手套在同一个程序里 create 两次,同一个循环里轮流 poll。

c
#include "hand_sdk.h"

HhSdkConfig cfg = {
    .serial_port = "/dev/ttyACM0",
    .baud = 0,                          /* 0 = 921600 */
    .hand = HH_SDK_HAND_RIGHT,          /* 1 左 / 2 右,和 UDP 包头 hand 相同 */
    .profile_path = "hand_profile_right.bin",
    .cache_dir = NULL,                  /* NULL = 用库旁边的 param/ */
};
HhSdkHandle* h = hh_sdk_create(&cfg);   /* 失败为 NULL */
HhSdkFrame frame;
int rc = hh_sdk_poll(h, &frame);        /* 调用成功为 HH_SDK_OK;好不好用看 frame.status */
hh_sdk_destroy(h);

hand 也可以填 HH_SDK_HAND_AUTO(0),让库读手套上的左右标记。

frame.status:

status含义
HH_SDK_STATUS_OK这一拍有新姿态,可以用
HH_SDK_STATUS_NO_UPDATE手套还没送来新的一帧,稍后再 poll
HH_SDK_STATUS_NO_SIGNAL手套在线,手指没跟上
HH_SDK_STATUS_UNSTABLE这一拍没有得到可用的解。正常动作不应出现。字段里仍有数字,请沿用上一拍可用的结果

抗磁干扰与磁场可信度 ​

抗磁干扰用 hh_sdk_set_mag_guard(h, mode) 设置。mode 只能是 2、1 或 0。请与 hh_sdk_poll 放在同一线程,不要每一帧都修改。

打开后,附近磁场受到干扰时,受影响手指的输出会保持平稳。关闭后,输出继续按传感器数据更新。三种设置下都可以读取磁场可信度。

  • 1(默认,菜单“弱”):按通常灵敏度启用。
  • 2(“强”):更早启用;启用之后的效果与“弱”相同。
  • 0(“关”):关闭;输出继续按传感器数据更新,可信度仍按上一次的“弱”或“强”计算。

当前设置用 hh_sdk_get_mag_guard 读回。头文件中的 HH_SDK_MAG_GUARD_STRONG、HH_SDK_MAG_GUARD_WEAK、HH_SDK_MAG_GUARD_OFF 分别对应 2、1、0。

磁场可信度每路为 0 到 1,越接近 1 越正常。它不在 UDP 包里,包长也不变。hh_sdk_poll 或 hh_sdk_poll_coils 读到新数据后,调用 hh_sdk_coil_confidence;还没有新数据时返回 HH_SDK_ERR_NOT_READY。下标 0 到 4 是拇指到小指,5 是小臂。演示在发送关节时大约每 2 秒打印一行,其中包含五根手指的可信度。

磁定位算法版本用 hh_sdk_magpose_version() 读取(当前 1.1.4),SDK 版本用 hh_sdk_version() 读取(1.2.1);这两个函数不需要打开手套。

接了小臂模块、要相对小臂的 22 点:同一次 poll 成功后再调 hh_sdk_forearm_root。

在自己程序里做标定时,采集那段时间必须继续 hh_sdk_poll,这段才会有数据。步骤见包内 demo/docs/API.md。

从 SDK 根目录编译示例:

bash
g++ -O2 -std=c++17 -Iinclude demo/examples/hand_example.cpp \
  -Llib/linux/x86_64 -lhand_runtime -ldl -o hand_example
export LD_LIBRARY_PATH="lib/linux/x86_64"
./hand_example

函数表:demo/docs/API.md。链接细节:demo/docs/Integration.md。点的排列:demo/docs/DataFormat.md。

读到的数据 ​

位置单位是米。朝向是四个数,顺序 w, x, y, z。都相对手掌(菜单 3 的输出;SDK 可用 hh_sdk_poll 读取)。左右手编号:1 左、2 右(和 UDP 包头相同)。

前后、左右、上下以手的解剖方向为准:

坐标系定义:前、右、上

手+X+Y+Z
左手右前(沿手指)上
右手左后上

21 个点(相对手掌):0 掌根;每指四个点(掌指、近节、远节、指尖),顺序拇指 → 食指 → 中指 → 无名指 → 小指。

22 个点(相对小臂,需小臂模块):0 小臂(位置为 0),1 手腕(即上面的掌根),2–21 对应上面的 1–20。

网上收这些点的包格式:UDP接收-关节位姿。轴的图解也可以看坐标系定义。

run.sh 参数(可选) ​

一般跟着提问走即可。需要写进脚本时:

参数默认含义
--port(提问)手套串口
--port2(无)第二只手套串口
--handrightleft 或 right
--baud9216000 也表示 921600
--profilehand_profile_{hand}.bin标定写入、跟踪读取的手型档案
--cache-dir库旁 param/出厂参数缓存目录

这些参数同样适用于直接启动 hand_mocap(日常仍建议用 run.sh,以免漏设环境变量)。

常见问题 ​

现象处理
打不开手套口是否存在;是否已加入 dialout 并重新登录;串口是否被其它程序占用
version query timeout串口选错,换同一个设备上的另一个 /dev/ttyACM*
第一次连上提示参数下载失败手套已上电,串口空闲,再试一次
手指几乎不动 / 位置不准指套戴好;用菜单做完 8 段标定
recv_hand_udp.py 没有画面演示是否已在菜单 3 或 4;是否装了 python3-tk
自己的程序一跑 CPU 打满关节计算已在库内使用 1 个线程;两只手套请在同一个线程里轮流调用 hh_sdk_poll,不要每只手各开一个计算线程
libtensorflowlite_c.so 找不到必须和 libhand_runtime.so 放在同一目录
hh_sdk_create 返回空串口、左右手、profile_path 非空

Copyright © 2026 Forsense. All rights reserved.