Skip to main content

Tendon-driven dexterous hand physics/control abstraction layer

Project description

Tendon-Driven Dexterous Hand Library

A Python library for simulating, controlling, and training tendon-driven dexterous hands.

This library does NOT include any robot model (URDF/STL). You must provide your own URDF file.

Design Philosophy

  • Motor-centric API: The library exposes motor commands, not joint targets.
  • Physics abstraction first: Tendon routing, tension, and compliance are modeled in the core library.
  • Simulator-agnostic core: PyBullet is an adapter, not a dependency of the physics core.
  • Composable architecture: Finger, tendon, joint, actuator, hand, and controller are layered.
  • Deterministic by default: Same input reproduces same output.

Architecture

User / Policy / RL
        ↓
Controller Layer
        ↓
Hand Model API
        ↓
Actuation Model  (motor → tendon displacement / tension)
        ↓
Tendon Physics Layer  (routing, friction, elasticity)
        ↓
Joint Response Layer  (torque, stiffness, limits, coupling)
        ↓
Simulation Adapter  (PyBullet / dummy backend / real hardware)

Installation

From source (development)

git clone https://github.com/YOUR_USERNAME/tendon-hand.git
cd tendon-hand
pip install -e ".[all]"

From PyPI

pip install tendon-hand        # core only
pip install "tendon-hand[sim]" # core + PyBullet simulation
pip install "tendon-hand[rl]"  # core + RL dependencies
pip install "tendon-hand[all]" # everything

Quick Start

1. Pure control (no simulator)

from tendon_hand.control.hand_controller import HandController

ctrl = HandController()

# Open / close poses
ctrl.open_pose()
ctrl.close_pose()

# Per-finger control
ctrl.set_index(m1=4.0, m2=3.0, m3=-0.3)

# Read joint targets
targets = ctrl.get_joint_targets()
print(targets["finger_2_link3_joint"])  # rad

2. PyBullet simulation (provide your own URDF)

from tendon_hand.control.hand_controller import HandController
from tendon_hand.sim.pybullet_adapter import PyBulletHandAdapter

ctrl = HandController()

# You must provide your own URDF file
sim = PyBulletHandAdapter(
    hand=ctrl.hand,
    urdf_path="/path/to/your/hand.urdf",
    gui=True,
)
sim.reset()

# Close hand
ctrl.close_pose()
sim.apply_joint_targets(ctrl.get_joint_targets())
sim.step(120)

# Read actual joint angles
states = sim.get_joint_states()
pos, vel = states["finger_2_link3_joint"]

3. Transmission model (motor → joint mapping)

from tendon_hand.core.models.transmission import CascadeTransmissionModel
import numpy as np

model = CascadeTransmissionModel()

# 17-D normalized motor action → 22-D joint targets
action = np.zeros(17)
action[3] = 1.0   # index_m1 full flex
action[4] = 0.8   # index_m2 partial flex
action[5] = 0.5   # index_m3 knuckle outward

targets = model.map(action)

4. Gymnasium RL environment

import gymnasium as gym
import tendon_hand.env.gym_env  # registers the env

# You must provide your own URDF file
env = gym.make(
    "TendonHand-v1",
    render_mode="human",
    urdf_path="/path/to/your/hand.urdf",
)
obs, info = env.reset()

for _ in range(100):
    action = env.action_space.sample()
    obs, reward, terminated, truncated, info = env.step(action)
    if terminated or truncated:
        obs, info = env.reset()

Demos

All demos require you to provide your own URDF via --urdf:

# Precise angle control (shows cable-driven cascade mechanics)
python examples/demo_precise_angle.py --urdf /path/to/your/hand.urdf index --no-gui

# Full hand demo
python examples/demo_hand.py --urdf /path/to/your/hand.urdf sim

# Finger-by-finger sign verification
python examples/demo_finger_test.py --urdf /path/to/your/hand.urdf all --no-gui

Cable-Driven Cascade Mechanics

This is an underactuated tendon-driven hand. You cannot independently set each joint angle.

Motor1 (Tendon-1): distal → middle → proximal → palm
Motor2 (Tendon-2): middle (distal follows) → proximal → palm
Final angle      : max(motor1_effect, motor2_effect) per joint

Key constraint: To get proximal movement, distal and middle must already be at their limits.

See examples/demo_precise_angle.py for a step-by-step demonstration.

Project Structure

tendon-hand/
├── src/tendon_hand/
│   ├── core/          # Physics-agnostic hand model
│   ├── control/       # High-level controller API
│   ├── sim/           # PyBullet adapter
│   ├── env/           # Gymnasium RL environment
│   ├── io/            # Config loading
│   └── utils/         # Math utilities + asset resolver
├── examples/          # Demo scripts (require your own URDF)
├── tests/             # pytest suite
└── pyproject.toml

No robot models are included. The library is designed to work with any tendon-driven hand URDF that follows the expected joint naming convention.

Development

# Run tests (core tests do not require a URDF)
pytest tests/ -v

# Run simulation tests (provide your own URDF)
pytest tests/test_gym_env.py -v  # requires URDF in your local assets/

# Format code
black src/ tests/ examples/
ruff check src/ tests/ examples/

License

MIT

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

tendon_hand-0.1.2.tar.gz (27.5 kB view details)

Uploaded Source

Built Distribution

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

tendon_hand-0.1.2-py3-none-any.whl (30.3 kB view details)

Uploaded Python 3

File details

Details for the file tendon_hand-0.1.2.tar.gz.

File metadata

  • Download URL: tendon_hand-0.1.2.tar.gz
  • Upload date:
  • Size: 27.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for tendon_hand-0.1.2.tar.gz
Algorithm Hash digest
SHA256 f8902379eb198078e8539a6a413e61a2acc0b1bc5110bbe930d90af8703fedd7
MD5 23f3fc145928639081a6fe67d6870a8b
BLAKE2b-256 16130eb6101e6d2677ef20c8a45a12e4ded4d30ecd1fe279ddefc68e7d6b0cc9

See more details on using hashes here.

File details

Details for the file tendon_hand-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: tendon_hand-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 30.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for tendon_hand-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 f4e48dcd8508d343c217c22bdb4a84041a9d010f4d0cc5d0037b92c62dbdb01d
MD5 58a6610f56e391e55d69d8b0a7add960
BLAKE2b-256 7d4b67d652c55e53d8cafa29a2e19c3197ae924a871a7cb248c2d203fca8b89e

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