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.1.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.1-py3-none-any.whl (30.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: tendon_hand-0.1.1.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.1.tar.gz
Algorithm Hash digest
SHA256 b2e97bcb80ec828558e7d4ac11fb128b194c0c1d402ef64c933a6af965336870
MD5 6d9818a5638d72331b677b1fbe1a68c4
BLAKE2b-256 ae5c22a2b61ac4c693297bdf16d65a68cfab9222b4d0f13dc71ae3d2fe918047

See more details on using hashes here.

File details

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

File metadata

  • Download URL: tendon_hand-0.1.1-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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 94de0d6bf04211a7f35783945becf7c083e035d3d57acc28ffd1d228e05a88d4
MD5 ff17588b1ee54dae048395bd4cfc3fb3
BLAKE2b-256 843ed4933b8329e627b012b1fbb25a17b95f02205ecbcdbbc436efe173851695

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