orca_core: the Python layer under the ORCA robotic hand
Core Python Controller of the ORCA Hand
At a glance
- What is it?
- orca_core is the control package for the ORCA Hand, abstracting the hardware, shipping calibration and tensioning scripts, and exposing high-level joint space commands. Communication goes over a serial port to Dynamixel or Feetech servos, and the config file is what selects a hand model and its motor settings.
- Who is it for?
- orca_core suits a robotics researcher who owns an ORCA Hand and wants to script it directly rather than go through the graphical tool, since the calibration, tensioning and neutral position scripts are the operations you need before anything else works. It does not suit you as a general robot arm library, because the configuration is tied to specific hand model folders under orca_core/models.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One library for the hand, one separate project for the interface
Orca Core is the core control package of the ORCA Hand, and the README is clear about what that means in practice.
It is used to abstract hardware, to provide scripts for calibration and tensioning, and to control the hand with simple high-level control methods in joint space. So the abstraction is the point. You do not address individual servos, you ask the hand to move to a set of joint angles.
The sibling project matters for how you start. Working directly with core lets you interact with the hand on a deep level, and the Orca Ui repository is the alternative for users who want to get started right away. The README describes that repository as helping users set up and maintain the hand, tune its performance, and better understand its capabilities.
That division is sensible for hardware. The calibration and tensioning steps are fiddly, need to happen once per hand or after a mechanical change, and a graphical tool is the right interface for them. The high-level joint space control is what a research script wants, and that is what this package provides.
The project is Python, MIT licensed, with a pyproject version of 0.8.0 and a requires-python of 3.10 or newer. The authors listed in the metadata are affiliated with ETH Zurich and the University of Oxford. There is an arXiv reference, 2504.04259, in the badge row, along with Discord and Twitter links and the project website at orcahand.com.
Getting set up with uv, and the three scripts that come first
The installation path is uv based, and the README covers both the developer flow and the end user flow.
First you clone the repository, with an ssh clone shown:
git clone [email protected]:orcahand/orca_core.gitThen you install uv, and sync a local development environment with the dev group:
uv sync --group devThat creates a local .venv and installs the package plus the development dependencies. Commands are then run through uv:
uv run pytestAnd if you prefer an activated shell, you can still use:
source .venv/bin/activate # macOS / Linux
.venv\Scripts\activate # WindowsEnd users who do not use uv can still install the package with pip install .
The part that matters is the order of operations after installation, and the README is explicit about it. First, check the configuration file, for example orca_core/models/v2/orcahand-right/config.yaml, and make sure it matches your hardware setup. Then run the tension and calibration scripts:
uv run python scripts/tension.py orca_core/models/v2/orcahand-right/config.yaml
uv run python scripts/calibrate.py orca_core/models/v2/orcahand-right/config.yamlAnd only then move the hand to the neutral position:
uv run python scripts/neutral.py orca_core/models/v2/orcahand-right/config.yamlYou replace the path with your specific hand model folder if needed. The ordering is mechanical: tension sets the preload in the tendon or gearing, calibration records the limits of travel, and neutral is a pose that is only meaningful once those two are correct.
Serial permissions are the failure you will hit first
The troubleshooting section covers Linux serial port permissions, and it is the most likely thing to stop a new user.
On Linux, the serial port, for example /dev/ttyACM0, is owned by the dialout group. If your user is not in that group, you get a permission denied error and the motors will not be detected. The permanent fix, which requires a re-login, is:
sudo usermod -aG dialout $USERThe temporary fix, which resets on reboot or on replugging the device, is:
sudo chmod 666 /dev/ttyACM0The distinction matters because the temporary fix is much easier to reach for and quietly leaves a world writable device node behind.
On Windows the situation is simpler. It is supported on Windows 10 and 11, no permission setup is needed, and the ports are named COM3, COM4 and so on, and you can list them with:
uv run python -m serial.tools.list_ports -vThere is a separate document for driver notes, latency settings and a first-connection checklist, at docs/pages/getting-started-docs/windows.md.
The diagnosis worth internalising is that a permission problem and a missing hand look the same from the script's point of view. The motor is not detected either way, so the first thing to check is the group membership and the port name rather than the hardware.
Auto-detection by default, with three config keys to override it
The configuration file is the interface between the code and your particular hand, and the default is to detect everything.
By default the serial port, the baudrate and the motor type are all auto-detected at connect time. That is convenient for a single hand on a single machine, and the README explains the three cases where you want to declare them explicitly instead.
If multiple hands are connected at once, port disambiguates which one. If motors run at a non-default baudrate, baudrate skips the probe sweep, which is both faster and the only way to connect when the sweep itself does not find them. And if the auto-detection picks the wrong family, motor_type forces a specific one.
# Optional overrides: auto-detected if omitted
port: /dev/ttyACM0 # /dev/cu.usbmodemXXXX on macOS, COM3 on Windows
baudrate: 1000000 # 1M for v2; 3M for v1
motor_type: dynamixel # or 'feetech'The comments in that block carry information that is not obvious from the key names. The port path differs per platform, so the same field is a device node on Linux, a cu.usbmodem style path on macOS and a COM port on Windows. The baudrate depends on the hardware version, 1M for v2 and 3M for v1, which is exactly the kind of thing that gets missed when a script written for one hand is run against another.
The motor_type value has two options, dynamixel and feetech, and the naming of the SDK dependency confirms the split. The pyproject lists dynamixel-sdk at 3.7.31 or newer within the 4.0 series, pyserial, and pyyaml for reading the config file, alongside fastapi, uvicorn and numpy, which cover the web service and the numeric side of the joint space work.
The examples directory shows what a research script actually does
The repository layout is telling about the intended use.
There is an orca_core/ package directory, a scripts/ directory for the operational scripts, an examples/ directory, a tests/ directory, a docs/ directory with an mkdocs setup, a tools/ directory, a mkdocs.yml at the root, a pyproject.toml, a uv.lock, and a CLAUDE.md file. The build backend is hatchling with hatchling 1.27.0 or newer, and the wheel target packages only orca_core, so the scripts and examples stay out of the installed distribution.
The example files are the interesting part for someone learning the API. There is a demo_runner.py and a main_demo.py, plus a main_demo_abduction.py, which is the abduction movement, the spreading of the fingers. There are record_angles.py and record_continuous.py, and matching replay_angles.py and replay_continuous.py, and a sequences/ directory, and a taxel_frames.py.
The record and replay pairing is the pattern most research code around a dexterous hand converges on. You record a motion as a sequence of joint angles, then replay it, and the pairing of a discrete recording with a continuous one and both with their replays suggests the library supports both a list of keyframes and a stream of positions.
The test setup is worth a note. The pytest configuration sets testpaths to tests and adds -n auto to addopts, which fans the suite across cores. The comment in the config explains that it is thread and file safe because every test that writes goes through tmp_path, and that you should pass -n0 for readable output when debugging a single failure. The dev group carries pytest 8.3.5 or newer, httpx, and pytest-xdist, and the docs group pins the whole mkdocs theme stack with mkdocstrings for the API reference.
Editorial conclusion
orca_core suits a robotics researcher who owns an ORCA Hand and wants to script it directly rather than go through the graphical tool, since the calibration, tensioning and neutral position scripts are the operations you need before anything else works. It does not suit you as a general robot arm library, because the configuration is tied to specific hand model folders under orca_core/models. Before you run anything, check the config file for your hand against your actual hardware, run the tension and calibration scripts before the neutral position script, and on Linux make sure your user is in the dialout group, since a missing serial port permission looks like a missing hand.
Frequently asked questions
What do I need to do first when setting up an ORCA Hand with orca_core?
Check the config file for your hand model, for example orca_core/models/v2/orcahand-right/config.yaml, then run the tension script, then the calibration script, and only then the neutral position script. The order matters because tension sets the preload and calibration records the travel limits.
How do I fix permission denied on the serial port in Linux?
The port is owned by the dialout group. The permanent fix is sudo usermod -aG dialout $USER followed by a re-login, and the temporary fix that resets on reboot is sudo chmod 666 /dev/ttyACM0.
Can I install orca_core without uv?
Yes. End users who do not use uv can install the package with pip install . . The uv path, uv sync --group dev, creates a local .venv and installs the package with its development dependencies.
How do I specify the serial port, baudrate and motor type in orca_core?
All three are auto-detected at connect time, and you declare them explicitly in the config.yaml when you have multiple hands, use a non-default baudrate, or need to force a motor family. The keys are port, baudrate and motor_type, with motor_type being dynamixel or feetech and the baudrate being 1M for v2 and 3M for v1.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/orcahand-orca-core)Was this useful?