SDK 怎么用
Linux 有两套 1.0.6 压缩包(Ubuntu 22.04 及以上),按机器选:
| 机器 | 文件 |
|---|---|
| PC / x86 工控机 | Humanhand_G7_sdk_1.0.6_linux_x86_64.tar.gz |
| ARM64 板 | Humanhand_G7_sdk_1.0.6_linux_aarch64.tar.gz |
- 先不写代码,用包里的
run.sh看手能不能动、做一次标定。 - 确认没问题后,再把库接到你自己的程序里,循环读取 21 个关节位置(接了小臂模块可以再要 22 个点)。
Windows 上请用 HumanHand 上位机 发关节,接收格式见 UDP接收-关节位姿。本页只讲这个 Linux 压缩包。
先选你现在要做的事
| 你现在的情况 | 往下看 |
|---|---|
| 刚解压,不知道这些文件是干什么的 | 包里每个文件 |
| 想先看手套好不好用,还不写程序 | 第一次:用 run.sh |
| 菜单里已经在「发送关节」,想在电脑上看到手 | 看手的画面 |
| 要把手套编进自己的软件 | 接到自己的程序 |
| 想知道读出来的数是什么意思 | 读到的数据 |
下载
到飞书下载页取 Humanhand G7 SDK 1.0.6(文件名 Humanhand_G7_sdk_1.0.6_linux_x86_64.tar.gz)。同一链接也在软件包。
tar -xzf Humanhand_G7_sdk_1.0.6_linux_x86_64.tar.gz
cd Humanhand_G7_sdk_1.0.6_linux_x86_64后面的路径都相对这个目录。
包里每个文件
解压后大致是这样。第一次用只需要 demo/examples/run.sh。 其它文件先不用打开。
Humanhand_G7_sdk_1.0.6_linux_x86_64/
├── README.md 包内说明书(和本页同一条路)
├── LICENSE NOTICE 许可,发布产品时保留
├── include/hand_sdk.h 写自己程序时 #include 这一个头
├── lib/linux/x86_64/
│ ├── libhand_runtime.so 真正干活的库(链接它)
│ ├── libtensorflowlite_c.so.2.17.1 库的依赖,必须和上一行放在同一目录
│ ├── deps/ 其余运行库,不用打开、不要删
│ └── param/ 手套出厂参数缓存,程序自己写入,不用改
└── demo/
├── examples/
│ ├── run.sh 开箱脚本:第一次就跑这个
│ ├── hand_mocap 已经编好的演示程序(run.sh 会启动它)
│ ├── 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* 和 deps/)。 |
param/ | 第一次连这只手套时,程序会从硬件把参数存到这里。不要手工改。 |
demo/docs/ | 写代码时再打开;先跑 run.sh 不必看。 |
第一次用之前
手套走 USB 串口。当前用户要能读写串口,做一次后重新登录:
sudo usermod -aG dialout $USER插上手套,看系统给了哪个口:
ls /dev/ttyACM* /dev/ttyUSB*记下名字(常见 /dev/ttyACM0)。口被上位机或其它程序占用时,这里会打不开。
第一次:用 run.sh
run.sh 做三件事:设好库需要的环境、找到旁边的 hand_mocap、把它启动起来。你只要进到 demo/examples 再执行它。
cd demo/examples
chmod +x run.sh
./run.sh它会问:单手还是双手、波特率(直接回车即可,默认 921600)、串口。然后出现菜单:
======== 手部动捕 ========
1) 标定手型
2) 发送关节位置(相对手腕)
3) 发送关节位置(相对小臂)系统内置了标准手型参数,无需标定即可获得良好的动捕体验。若需追求更高精度,可选择 1) 标定手型 标定个人手型(标定文件生成在当前目录:右手 hand_profile_right.bin,左手 hand_profile_left.bin)。
已经知道串口时,可以跳过提问:
./run.sh --port /dev/ttyACM0
./run.sh --port /dev/ttyACM0 --port2 /dev/ttyACM1双手必须在同一个 run.sh 进程里打开两只手套,不要开两个窗口各跑一次。
标定怎么做(菜单 1)
共 8 段。摆好姿势后按回车开始采;采完回车进下一段;输入 r 再回车重录本段。八段都完会自动计算。
| 序号 | 手势 | 时长 | 怎么摆 |
|---|---|---|---|
| 1 | 平放静止 | 2 s | 手掌平放,五指自然伸直张开 |
| 2 | 握拳静止 | 2 s | 握紧拳后保持静止 |
| 3 | 重复握拳 | 5 s | 缓慢握拳—张开循环 |
| 4 | 拇指伸展 | 5 s | 动拇指,其余四指稳住 |
| 5 | 食指对指 | 2 s | 拇指腹贴食指腹,不要用力压 |
| 6 | 中指对指 | 2 s | 拇指腹贴中指腹 |
| 7 | 无名指对指 | 2 s | 拇指腹贴无名指腹 |
| 8 | 小指对指 | 2 s | 拇指腹贴小指腹 |
发出关节(菜单 2 / 3)
标定完成后选 2)。程序按求解节拍往本机 127.0.0.1:15001 发关节 UDP(双手也是这个端口,左右各一包)。
3) 要手套接了小臂模块。没接小臂时用 2)。
字节格式见 UDP接收-关节位姿。自己的程序也可以不经过 UDP,直接读 SDK 数组,见下一节。
看手的画面
菜单已经在发送关节之后,另开一个终端(仍在 demo/examples):
python3 recv_hand_udp.py和演示一样提问:1 单手一个窗口,2 双手两个窗口,回车默认双手。再选监听地址和端口,回车=0.0.0.0:15001(双手共用)。刷新选 1–6 对应 20/40/60/80/100/120 Hz,回车默认 120。左键拖转动,右键平移,滚轮缩放。

没有画面时:确认演示还在发送、本机装了 python3-tk(Ubuntu:sudo apt install python3-tk)、没改默认端口。
接到自己的程序
确认 run.sh 已经能标定、能看见手,再改你的工程。
你要带上的只有:
include/hand_sdk.hlib/linux/x86_64/libhand_runtime.so- 同目录的
libtensorflowlite_c.so.2.17.1和deps/
可抄的完整流程:demo/examples/hand_example.cpp。在 demo/examples 里执行 ./compile.sh 就能编出一份和演示相同菜单的程序。
进程一启动、还没加载这个库之前必须设(run.sh 已经设过;你自己的启动脚本也要设):
export OMP_NUM_THREADS=1
export OPENBLAS_NUM_THREADS=1一只手套 = 一次 hh_sdk_create。取数只用一个线程调用 hh_sdk_poll。两只手套在同一个程序里 create 两次,同一个循环里轮流 poll。
#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 | 出了姿态,但不够稳 |
接了小臂模块、要相对小臂的 22 点:同一次 poll 成功后再调 hh_sdk_forearm_root。
在自己程序里做标定时,采集那段时间必须继续 hh_sdk_poll,这段才会有数据。步骤见包内 demo/docs/API.md。
从 SDK 根目录编译示例:
export OMP_NUM_THREADS=1
export OPENBLAS_NUM_THREADS=1
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:lib/linux/x86_64/deps"
./hand_example函数表:demo/docs/API.md。链接细节:demo/docs/Integration.md。点的排列:demo/docs/DataFormat.md。
读到的数据
位置单位是米。朝向是四个数,顺序 w, x, y, z。都相对手掌(菜单 2 / hh_sdk_poll)。左右手编号:1 左、2 右(和 UDP 包头相同)。
前后、左右、上下以手的解剖方向为准:

| 手 | +X | +Y | +Z |
|---|---|---|---|
| 左手 | 右 | 前(沿手指) | 上 |
| 右手 | 左 | 后 | 上 |
21 个点(相对手掌):0 掌根;每指四个点(掌指、近节、远节、指尖),顺序拇指 → 食指 → 中指 → 无名指 → 小指。
22 个点(相对小臂,需小臂模块):0 小臂(位置为 0),1 手腕(即上面的掌根),2–21 对应上面的 1–20。
网上收这些点的包格式:UDP接收-关节位姿。轴的图解也可以看坐标系定义。
run.sh 参数(可选)
一般跟着提问走即可。需要写进脚本时:
| 参数 | 默认 | 含义 |
|---|---|---|
--port | (提问) | 手套串口 |
--port2 | (无) | 第二只手套串口 |
--hand | right | left 或 right |
--baud | 921600 | 0 也表示 921600 |
--profile | hand_profile_{hand}.bin | 标定写入、跟踪读取的手型档案 |
--cache-dir | 库旁 param/ | 出厂参数缓存目录 |
这些参数同样适用于直接启动 hand_mocap(日常仍建议用 run.sh,以免漏设环境变量)。
常见问题
| 现象 | 处理 |
|---|---|
| 打不开手套 | 口是否存在;是否已加入 dialout 并重新登录;串口是否被其它程序占用 |
version query timeout | 串口选错,换同一个设备上的另一个 /dev/ttyACM* |
| 第一次连上提示参数下载失败 | 手套已上电,串口空闲,再试一次 |
| 手指几乎不动 / 位置不准 | 指套戴好;用菜单做完 8 段标定 |
recv_hand_udp.py 没有画面 | 演示是否已在菜单 2 或 3;是否装了 python3-tk |
| 自己的程序一跑 CPU 打满 | 启动前是否设了两个 *_NUM_THREADS=1 |
libtensorflowlite_c.so 找不到 | 必须和 libhand_runtime.so 放在同一目录 |
hh_sdk_create 返回空 | 串口、左右手、profile_path 非空 |
