Orca Hand Setup Guide

Complete step-by-step path from unboxing through first grasp. Plan for 3–4 hours total on your first build.

1

Assembly & Inspection

Lay out all components before beginning: finger modules (5×), palm/wrist mount, tendon routing hardware, fasteners, and any optional fingertip sensor modules.

  • Finger modules: Snap each finger module into the palm frame in order — thumb, index, middle, ring, little. Verify each joint moves freely before routing tendons.
  • Wrist mount: Attach the palm assembly to the wrist plate using the provided fasteners. Confirm the flange pattern matches your robot arm.
  • Tendon routing: Route each tendon (one per finger) from the actuator pulley through the conduit guides. Leave 2–3 mm of slack before tensioning — over-tensioning at this stage causes binding.
  • Tactile sensors (optional): If installing fingertip tactile sensors, seat them into the fingertip housings before closing the finger shells. Route sensor cables back through the finger body to the palm connector.
Check the official docs for your hardware revision. Assembly details vary between Orca Hand hardware revisions. Always verify against the official Orca Hand documentation for your specific version.
2

Software Install

The orca_core Python package is the only software dependency — there is no ROS requirement. It communicates with all 17 Feetech STS3215 motors over a single USB serial connection at 3 Mbps using the Dynamixel protocol. Python 3.9+ is required.

Option A — Install via Poetry (recommended):

git clone https://github.com/orcahand/orca_core.git
cd orca_core
poetry install

Option B — Install via pip:

pip install orca_core

Grant USB serial port access on Linux:

# Add your user to the dialout group (requires logout/login to take effect)
sudo usermod -aG dialout $USER

# Or grant temporary access without logging out
sudo chmod 666 /dev/ttyUSB0
macOS port name. On macOS the USB serial port is typically /dev/tty.usbserial-FT4TFV01. Open orca_core/models/orcahand_v1/config.yaml and update the port field before connecting, or pass the port string explicitly when constructing OrcaHand().

Connect and verify:

from orca_core import OrcaHand

hand = OrcaHand()
status = hand.connect()
print(status)  # (True, 'Connection successful')
3

Calibration

Calibration drives each of the 17 joints to its mechanical hard stop at a reduced current limit (450 raw units) to establish per-motor zero offsets. Always calibrate before issuing position commands — skipping this step may cause large position errors or unexpected motion.

from orca_core import OrcaHand

hand = OrcaHand()
hand.connect()

# Drives all joints to hard stops at calib_current=450 to establish zero offsets
hand.calibrate()

# Calibration results are saved automatically to:
# models/orcahand_v1/calibration.yaml
Calibration is automatic. The calibrate() method iteratively steps each joint toward its hard stop in 0.3° increments (configurable via calib_step_size), declares a joint homed after 10 consecutive stable readings within 0.01° (configurable via calib_num_stable and calib_threshold), then saves offsets to calibration.yaml. Re-run only after hardware changes.

After calibration, move all joints to the open/zero position:

# Command all 17 joints to 0° (open position)
hand.set_joint_pos({joint: 0 for joint in hand.joint_ids})
4

First Grasp Test

Verify joint control using the orca_core Python API. Command individual joints by name — the SDK translates joint names to motor IDs automatically via the joint_to_motor_map in config.yaml.

from orca_core import OrcaHand

hand = OrcaHand()
hand.connect()
hand.calibrate()

# --- Read current joint positions (degrees) ---
positions = hand.get_joint_pos()
print(positions)
# e.g. {'thumb_mcp': 0.0, 'thumb_abd': 0.0, 'index_mcp': 0.0, ...}

# --- Make a fist: flex all MCP and PIP joints ---
hand.set_joint_pos({
    "index_mcp":  90, "index_pip":  110,
    "middle_mcp": 90, "middle_pip": 110,
    "ring_mcp":   90, "ring_pip":   110,
    "pinky_mcp":  90, "pinky_pip":  110,
    "thumb_mcp":  30, "thumb_pip":  100,
})

# --- Open hand back to zero ---
hand.set_joint_pos({joint: 0 for joint in hand.joint_ids})

# --- Torque control ---
hand.enable_torque()                    # Enable torque on all motors
hand.disable_torque(motor_ids=[1, 2])   # Disable specific motors (by ID)

# --- Disconnect (disables torque, closes serial port) ---
hand.disconnect()
Joint ROM limits. MCP and PIP joints on fingers 2–5 range from −20° to +120° (MCP) and −20° to +140° (PIP). The thumb has the widest abduction range: ±65°. The wrist operates ±60°. Commanding values outside these limits may stall the motor at its mechanical stop.

If any joint does not reach the commanded angle, check cable routing and tendon tension for that motor. Each finger uses a dedicated Feetech STS3215 servo; binding is usually a routing or tension issue, not a software one.

5

Integration with Robot Arm

Mount the Orca Hand onto your robot arm using the standard wrist flange adapter. The hand is compatible with OpenArm 101, and most arms with a standard ISO 9283 flange pattern.

  • Attach the wrist plate to the arm's end-effector flange using M4 bolts in the provided pattern.
  • Route signal and power cables along the arm structure, secured with cable ties to prevent snagging during motion.
  • In your arm's ROS2 workspace, add the Orca Hand as an end-effector node and launch both arm and hand controllers together.
Using with OpenArm 101? See the OpenArm teleoperation setup step for instructions on connecting an end-effector and recording your first data collection session.

For a full walkthrough of dexterous manipulation research workflows with the Orca Hand, see the SVRC research guide.

Setup Complete?

Check the full specs or join the community to share your build notes.