How to use the SDK
This tarball is for Linux x86_64 (Ubuntu 22.04 and later). With a G7 glove plugged in you can:
- Write no code yet — use
run.shin the package to see the hand move and to calibrate once. - After that works, link the library into your own program and poll 21 joint positions (22 if a forearm module is attached).
On Windows, send joints from the HumanHand host. Packet layout: UDP Reception – Joint Poses. This page covers only the Linux tarball.
Pick what you need right now
| Your situation | Jump to |
|---|---|
| Unpacked the archive and do not know the files | Every file in the pack |
| Want to try the glove before writing software | First run: run.sh |
| The menu is already sending joints; you want to see the hand | See the hand |
| Want the glove inside your own software | Your own program |
| Want to know what the numbers mean | What you read |
Download
Get Humanhand G7 SDK 1.0.5 from the Feishu download page (Humanhand_G7_sdk_1.0.5_linux_x86_64.tar.gz). The same link is on Packages.
tar -xzf Humanhand_G7_sdk_1.0.5_linux_x86_64.tar.gz
cd Humanhand_G7_sdk_1.0.5_linux_x86_64Paths below are relative to that directory.
Every file in the pack
The first time, you only need demo/examples/run.sh. Leave the rest closed.
Humanhand_G7_sdk_1.0.5_linux_x86_64/
├── README.md in-pack guide (same path as this page)
├── LICENSE NOTICE keep these when you ship a product
├── include/hand_sdk.h the only header to #include
├── lib/linux/x86_64/
│ ├── libhand_runtime.so the library you link
│ ├── libtensorflowlite_c.so.2.17.1 must sit next to the line above
│ ├── deps/ other runtime libs; do not delete
│ └── param/ factory-parameter cache; the program writes here
└── demo/
├── examples/
│ ├── run.sh unpack-and-run script; start here
│ ├── hand_mocap prebuilt demo (run.sh starts it)
│ ├── recv_hand_udp.py receive joint UDP and plot
│ ├── hand_example.cpp sample source to copy
│ └── compile.sh builds that sample
└── docs/
├── Integration.md how to link into your project
├── API.md what each function does
└── DataFormat.md 21 / 22 point layout and units| File | How you use it |
|---|---|
run.sh | Entry point. Sets the environment and starts hand_mocap. Do not launch hand_mocap by hand the first time. |
hand_mocap | Prebuilt demo: pick a serial port, calibrate, send joints. Started by run.sh. |
recv_hand_udp.py | After the demo is sending joints, run this in another terminal to see the hand. Needs python3 and python3-tk. |
hand_example.cpp + compile.sh | When you want a locally built copy of the same flow. |
hand_sdk.h + libhand_runtime.so | What you take into your app (plus libtensorflowlite_c.so* and deps/ next to the library). |
param/ | Filled from the glove on first connect. Do not edit by hand. |
demo/docs/ | Open when you write code; not needed for run.sh. |
Before the first run
The glove is a USB serial device. Add yourself to dialout, then log in again:
sudo usermod -aG dialout $USERPlug in the glove and list ports:
ls /dev/ttyACM* /dev/ttyUSB*Note the name (often /dev/ttyACM0). The port will not open if the host software or another program already holds it.
First run: run.sh
run.sh sets the environment the library needs, finds hand_mocap beside it, and starts that program. Go to demo/examples and run it:
cd demo/examples
chmod +x run.sh
./run.shIt asks: one hand or two, baud (Enter keeps 921600), serial port. Then:
======== 手部动捕 ========
1) 标定手型
2) 发送关节位置(相对手腕)
3) 发送关节位置(相对小臂)New glove or new wearer: choose 1) first. The profile is written in the current directory (hand_profile_right.bin / hand_profile_left.bin). Tracking is poor without it.
If you already know the port:
./run.sh --port /dev/ttyACM0
./run.sh --port /dev/ttyACM0 --port2 /dev/ttyACM1Two gloves must be opened in one run.sh process, not two windows.
Calibration (menu 1)
Eight takes. Pose, then Enter to capture; Enter for the next take; r then Enter to recapture this take. After all eight, it computes automatically.
| # | Gesture | Time | Pose |
|---|---|---|---|
| 1 | Palm flat, still | 2 s | Palm down, fingers naturally open |
| 2 | Fist, still | 2 s | Tight fist, hold |
| 3 | Repeated fist | 5 s | Slow fist–open cycles |
| 4 | Thumb motion | 5 s | Move the thumb; keep the other four still |
| 5 | Index pinch | 2 s | Thumb pad on index pad, no hard press |
| 6 | Middle pinch | 2 s | Thumb pad on middle pad |
| 7 | Ring pinch | 2 s | Thumb pad on ring pad |
| 8 | Little pinch | 2 s | Thumb pad on little pad |
Send joints (menu 2 / 3)
After calibration, choose 2). Packets go to 127.0.0.1:15001 (both hands share that port, one packet each).
3) needs a forearm module. Use 2) if there is none.
Wire format: UDP Reception – Joint Poses. Your app can also skip UDP and read the SDK arrays (next section).
See the hand
With sending already started, open another terminal in demo/examples:
python3 recv_hand_udp.pySame prompts as the demo: 1 one window, 2 two windows (Enter = both). Then bind address and port (Enter = 0.0.0.0:15001, both hands share that port). Draw rate 1–6 = 20/40/60/80/100/120 Hz (Enter = 120). Left-drag orbit, right-drag pan, wheel zoom.

No plot: confirm the demo is still sending, python3-tk is installed (Ubuntu: sudo apt install python3-tk), and the default port was not changed.
Your own program
Wire this in only after run.sh can calibrate and you can see the hand.
Take:
include/hand_sdk.hlib/linux/x86_64/libhand_runtime.solibtensorflowlite_c.so.2.17.1anddeps/next to that library
Copy demo/examples/hand_example.cpp. From demo/examples, ./compile.sh builds the same menu as the demo.
Before the process loads this library ( run.sh already does this; your launcher must too):
export OMP_NUM_THREADS=1
export OPENBLAS_NUM_THREADS=1One glove = one hh_sdk_create. Poll on one thread. Two gloves: two creates in the same program, poll both in the same loop.
#include "hand_sdk.h"
HhSdkConfig cfg = {
.serial_port = "/dev/ttyACM0",
.baud = 0, /* 0 = 921600 */
.hand = HH_SDK_HAND_RIGHT, /* 1 left / 2 right, same as UDP header hand */
.profile_path = "hand_profile_right.bin",
.cache_dir = NULL, /* NULL = param/ next to the library */
};
HhSdkHandle* h = hh_sdk_create(&cfg); /* NULL on failure */
HhSdkFrame frame;
int rc = hh_sdk_poll(h, &frame); /* HH_SDK_OK = call worked; quality is frame.status */
hh_sdk_destroy(h);hand may be HH_SDK_HAND_AUTO (0) to read the left/right tag on the glove.
frame.status:
| status | Meaning |
|---|---|
HH_SDK_STATUS_OK | New pose this tick; usable |
HH_SDK_STATUS_NO_UPDATE | No new glove frame yet; poll again |
HH_SDK_STATUS_NO_SIGNAL | Glove online; fingers have not caught up |
HH_SDK_STATUS_UNSTABLE | A pose is out, but not steady |
Forearm module, 22 points relative to the forearm: call hh_sdk_forearm_root after a successful poll in the same tick.
While capturing calibration in your app, keep calling hh_sdk_poll or that take is empty. Sequence in demo/docs/API.md.
Build the sample from the SDK root:
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_exampleFunctions: demo/docs/API.md. Linking: demo/docs/Integration.md. Point map: demo/docs/DataFormat.md.
What you read
Position is in metres. Orientation is four numbers w, x, y, z. All are palm-relative (menu 2 / hh_sdk_poll). Hand IDs: 1 left, 2 right (same as the UDP header).
Front / right / up follow hand anatomy:

| Hand | +X | +Y | +Z |
|---|---|---|---|
| Left | right | forward (along the fingers) | up |
| Right | left | back | up |
21 points (palm-relative): 0 palm root; four points per finger (knuckle, near, far, tip), thumb → index → middle → ring → little.
22 points (forearm-relative, needs the module): 0 forearm (position 0), 1 wrist (the palm root above), 2–21 match 1–20 above.
UDP packet layout: UDP Reception – Joint Poses. Diagrams: Coordinate systems.
run.sh arguments (optional)
Follow the prompts unless you are scripting:
| Argument | Default | Meaning |
|---|---|---|
--port | (prompt) | Glove serial device |
--port2 | (none) | Second glove |
--hand | right | left or right |
--baud | 921600 | 0 also means 921600 |
--profile | hand_profile_{hand}.bin | Hand-shape file (calibration writes; tracking reads) |
--cache-dir | param/ next to the library | Factory-parameter cache |
The same flags work if you start hand_mocap directly. Prefer run.sh so the environment is set.
FAQ
| Symptom | What to do |
|---|---|
| Cannot open the glove | Port exists; you are in dialout and logged in again; nothing else holds the serial device |
version query timeout | Wrong node; try another /dev/ttyACM* on the same device |
| First-connect parameter download fails | Glove powered, port free, retry |
| Fingers barely move / pose is off | Wear the finger modules; finish the 8-take calibration |
recv_hand_udp.py shows nothing | Demo is on menu 2 or 3; python3-tk installed |
| Your app saturates CPU at start | Set both *_NUM_THREADS=1 before launch |
libtensorflowlite_c.so missing | It must sit next to libhand_runtime.so |
hh_sdk_create returns null | Serial port, hand id, non-empty profile_path |
