Skip to content
FORSENSE

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:

  1. Write no code yet — use run.sh in the package to see the hand move and to calibrate once.
  2. 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 situationJump to
Unpacked the archive and do not know the filesEvery file in the pack
Want to try the glove before writing softwareFirst run: run.sh
The menu is already sending joints; you want to see the handSee the hand
Want the glove inside your own softwareYour own program
Want to know what the numbers meanWhat 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.

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

Paths 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.

text
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
FileHow you use it
run.shEntry point. Sets the environment and starts hand_mocap. Do not launch hand_mocap by hand the first time.
hand_mocapPrebuilt demo: pick a serial port, calibrate, send joints. Started by run.sh.
recv_hand_udp.pyAfter the demo is sending joints, run this in another terminal to see the hand. Needs python3 and python3-tk.
hand_example.cpp + compile.shWhen you want a locally built copy of the same flow.
hand_sdk.h + libhand_runtime.soWhat 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:

bash
sudo usermod -aG dialout $USER

Plug in the glove and list ports:

bash
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:

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

It asks: one hand or two, baud (Enter keeps 921600), serial port. Then:

text
======== 手部动捕 ========
  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:

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

Two 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.

#GestureTimePose
1Palm flat, still2 sPalm down, fingers naturally open
2Fist, still2 sTight fist, hold
3Repeated fist5 sSlow fist–open cycles
4Thumb motion5 sMove the thumb; keep the other four still
5Index pinch2 sThumb pad on index pad, no hard press
6Middle pinch2 sThumb pad on middle pad
7Ring pinch2 sThumb pad on ring pad
8Little pinch2 sThumb 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:

bash
python3 recv_hand_udp.py

Same 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 16 = 20/40/60/80/100/120 Hz (Enter = 120). Left-drag orbit, right-drag pan, wheel zoom.

recv_hand_udp.py joint-pose skeleton plot

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.h
  • lib/linux/x86_64/libhand_runtime.so
  • libtensorflowlite_c.so.2.17.1 and deps/ 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):

bash
export OMP_NUM_THREADS=1
export OPENBLAS_NUM_THREADS=1

One glove = one hh_sdk_create. Poll on one thread. Two gloves: two creates in the same program, poll both in the same loop.

c
#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:

statusMeaning
HH_SDK_STATUS_OKNew pose this tick; usable
HH_SDK_STATUS_NO_UPDATENo new glove frame yet; poll again
HH_SDK_STATUS_NO_SIGNALGlove online; fingers have not caught up
HH_SDK_STATUS_UNSTABLEA 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:

bash
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

Functions: 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:

Coordinate definition: front, right, up

Hand+X+Y+Z
Leftrightforward (along the fingers)up
Rightleftbackup

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:

ArgumentDefaultMeaning
--port(prompt)Glove serial device
--port2(none)Second glove
--handrightleft or right
--baud9216000 also means 921600
--profilehand_profile_{hand}.binHand-shape file (calibration writes; tracking reads)
--cache-dirparam/ next to the libraryFactory-parameter cache

The same flags work if you start hand_mocap directly. Prefer run.sh so the environment is set.

FAQ

SymptomWhat to do
Cannot open the glovePort exists; you are in dialout and logged in again; nothing else holds the serial device
version query timeoutWrong node; try another /dev/ttyACM* on the same device
First-connect parameter download failsGlove powered, port free, retry
Fingers barely move / pose is offWear the finger modules; finish the 8-take calibration
recv_hand_udp.py shows nothingDemo is on menu 2 or 3; python3-tk installed
Your app saturates CPU at startSet both *_NUM_THREADS=1 before launch
libtensorflowlite_c.so missingIt must sit next to libhand_runtime.so
hh_sdk_create returns nullSerial port, hand id, non-empty profile_path

Copyright © 2026 Forsense. All rights reserved.