Skip to main content

Python SDK for the Digity sensorized exohand

Project description

digity SDK

Python SDK for the Digity sensorized exohand — plug in the glove, stream live sensor data directly into your Python code in three lines.

The Digity exohand is a sensorized glove that captures real-time hand motion data: joint angles for every finger, 6-axis IMU (accelerometer + gyroscope), and 6-channel capacitive touch per node. This SDK handles the USB connection, binary protocol decoding, and threading — so you get clean, typed Python objects at ~50 Hz without any low-level plumbing.

from digity import GloveStream, AnglesSensor

with GloveStream() as stream:
    for frame in stream:
        for sensor in frame.sensors:
            if isinstance(sensor, AnglesSensor):
                print(sensor.finger, sensor.samples[-1].angles_deg)

Use cases: motion capture, rehabilitation, robotics control, gesture recognition, HCI research, data collection.


Requirements

  • Python 3.9 or later
  • The Digity exohand connected via USB

Installation

pip install digity

Quick start

Plug in the glove, then run:

from digity import GloveStream, AnglesSensor, ImuSensor, TouchSensor

with GloveStream() as stream:
    for frame in stream:
        print(f"side={frame.side}  node={frame.node_id}  seq={frame.seq}")

        for sensor in frame.sensors:

            if isinstance(sensor, AnglesSensor):
                angles = sensor.samples[-1].angles_deg
                print(f"  finger {sensor.finger} angles: {angles}")

            elif isinstance(sensor, ImuSensor):
                s = sensor.samples[-1]
                print(f"  finger {sensor.finger} acc={s.acc}  gyro={s.gyro}")

            elif isinstance(sensor, TouchSensor):
                print(f"  finger {sensor.finger} touch={sensor.channels}")

The with block handles connection and cleanup automatically. Press Ctrl+C to stop.


Specifying the USB port

The SDK auto-detects the glove port on all platforms. If auto-detection fails, pass the port explicitly:

GloveStream(port="/dev/ttyUSB0")   # Linux
GloveStream(port="/dev/tty.usbserial-0001")  # macOS
GloveStream(port="COM3")           # Windows

Data types

GloveFrame

Every iteration of GloveStream yields one GloveFrame:

Field Type Description
ts float Host timestamp (seconds since epoch) when the frame arrived
side str "right" or "left"
group str "hand" or "arm"
node_id int PCB node number on the glove
seq int Packet counter 0–65535, wraps around
sensors list[Sensor] List of sensor readings in this frame

AnglesSensor

Joint angles for one finger node.

Field Type Description
finger int Finger index (0=thumb, 1=index, …, 4=pinky)
com int Communication line index
samples list[AnglesSample] One or more timestamped angle readings

AnglesSample

Field Type Description
ts_us int Sensor timestamp in microseconds
angles_deg list[float] Joint angles in degrees (5 values for hand group)
if isinstance(sensor, AnglesSensor):
    latest = sensor.samples[-1]
    print(latest.angles_deg)   # e.g. [12.3, 45.1, 30.0, 5.5, 2.0]

ImuSensor

6-axis IMU (accelerometer + gyroscope) for one finger node.

Field Type Description
finger int Finger index
com int Communication line index
samples list[ImuSample] One or more timestamped IMU readings

ImuSample

Field Type Description
ts_us int Sensor timestamp in microseconds
acc tuple[int, int, int] Accelerometer x/y/z, raw i16 counts
gyro tuple[int, int, int] Gyroscope x/y/z, raw i16 counts
if isinstance(sensor, ImuSensor):
    s = sensor.samples[-1]
    print(s.acc)    # e.g. (312, -128, 16384)
    print(s.gyro)   # e.g. (5, -12, 3)

TouchSensor

6-channel capacitive touch for one finger node.

Field Type Description
finger int Finger index
com int Communication line index
ts_us int Sensor timestamp in microseconds
channels list[float] 6 values normalised 0.0–1.0
channels_raw list[int] 6 raw ADC counts 0–4095
if isinstance(sensor, TouchSensor):
    print(sensor.channels)      # [0.0, 0.82, 0.0, 0.0, 0.41, 0.0]
    print(sensor.channels_raw)  # [0, 3358, 0, 0, 1680, 0]

Type annotation helper

from digity import Sensor  # Union[AnglesSensor, ImuSensor, TouchSensor]

def process(sensor: Sensor) -> None:
    if isinstance(sensor, AnglesSensor):
        ...

Common patterns

Record data to a file

import csv
from digity import GloveStream, AnglesSensor

with GloveStream() as stream, open("recording.csv", "w", newline="") as f:
    writer = csv.writer(f)
    writer.writerow(["ts", "finger", "a0", "a1", "a2", "a3", "a4"])

    for frame in stream:
        for sensor in frame.sensors:
            if isinstance(sensor, AnglesSensor):
                a = sensor.samples[-1].angles_deg
                writer.writerow([frame.ts, sensor.finger] + a)

Detect a closed fist

from digity import GloveStream, AnglesSensor

with GloveStream() as stream:
    finger_angles = {}

    for frame in stream:
        for sensor in frame.sensors:
            if isinstance(sensor, AnglesSensor):
                finger_angles[sensor.finger] = sensor.samples[-1].angles_deg

        if len(finger_angles) == 5:
            avg_flex = [sum(finger_angles[f][1] for f in range(1, 5)) / 4]
            if avg_flex[0] > 60:
                print("Fist detected!")

Stop the stream from another thread

import threading
from digity import GloveStream

stream = GloveStream()
stream.connect()

def stop_after(seconds):
    import time; time.sleep(seconds)
    stream.disconnect()

threading.Thread(target=stop_after, args=(10,), daemon=True).start()

for frame in stream:
    print(frame.seq)

Remote mode (ZMQ)

If the glove is connected to a remote machine running glove-core, you can receive frames over the network:

GloveStream(host="192.168.1.10")          # default port 5555
GloveStream(host="192.168.1.10", zmq_port=5556)

No USB connection is needed on the client machine in this mode.


Error handling

from digity import GloveStream, GloveNotFoundError

try:
    with GloveStream() as stream:
        for frame in stream:
            ...
except GloveNotFoundError:
    print("Glove not found — check the USB cable")
except KeyboardInterrupt:
    pass

GloveNotFoundError is raised at connection time if the glove port cannot be found.


Connection speed

The glove streams at approximately 50 Hz. Each call to for frame in stream blocks until the next frame arrives (up to 1 second timeout before checking for errors).

The SDK uses a background thread and an internal queue so that your processing code never blocks the serial buffer. If your code is slower than 50 Hz, frames are dropped to keep the stream live rather than accumulating memory.


License

© Digity. All rights reserved.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

digity-0.1.1.tar.gz (11.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

digity-0.1.1-py3-none-any.whl (10.8 kB view details)

Uploaded Python 3

File details

Details for the file digity-0.1.1.tar.gz.

File metadata

  • Download URL: digity-0.1.1.tar.gz
  • Upload date:
  • Size: 11.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.2

File hashes

Hashes for digity-0.1.1.tar.gz
Algorithm Hash digest
SHA256 c98d1553facc8d0c04af224c79a83f9b3ad024cb273ec35d5849ccb095cfbd2a
MD5 2a3bb7b908160e7a530d39a4e6f44db9
BLAKE2b-256 2ac66fa92098f369166ae6c8f14504513f9c6b5d2fd7aa3e9e0f226795462878

See more details on using hashes here.

File details

Details for the file digity-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: digity-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 10.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.2

File hashes

Hashes for digity-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 71123e31fab6821b36b36d9c34932cec3652ff3be43432316b4c956cb7815b0a
MD5 0bf472bc2fa1341be3fc67299217d807
BLAKE2b-256 092b71cbad435232b384e12a2bb9b75dae817a7c76b9862a58024f787ab39a63

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page