Skip to main content
This guide walks through integrating a new robot arm with DimOS, from writing the hardware adapter to creating blueprints for planning and control. If you are packaging an arm outside the DimOS repository, start with External Robot Packages. That guide shows how to register adapters and control tasks from an installed package without placing files under dimos/hardware/ or dimos/robot/.

Architecture Overview

DimOS uses a Protocol-based adapter pattern — no base class inheritance required. Your adapter wraps the vendor SDK and exposes a standard interface that the rest of the system consumes:
See also: dimos/hardware/manipulators/README.md for a quick reference.

Prerequisites

  1. Vendor SDK — The Python SDK for your robot arm (e.g., xarm-python-sdk, piper-sdk)
  2. URDF/xacro — A robot description file (only needed if you want motion planning)
  3. Connection info — IP address, CAN port, serial device, etc.

Step 1: Create the Adapter

Create a new directory for your arm under dimos/hardware/manipulators/:

adapter.py — Full Skeleton

Below is a complete annotated adapter. Implement each method by wrapping your vendor SDK calls. All values crossing the adapter boundary must use SI units.
skip
Then declare the adapter in a _registry.py manifest next to it:

Key implementation notes

  • Unsupported features — Return None for reads and False for writes. Never raise exceptions for optional features.
  • Velocity/effort feedback — If your SDK doesn’t provide these, return zeros. The coordinator handles this gracefully.
  • Lazy SDK import — If the vendor SDK is an optional dependency, you can import it inside connect() instead of at module level (see Piper adapter for this pattern):

Step 2: Create Package Files

How discovery works

The AdapterRegistry in dimos/hardware/manipulators/registry.py discovers adapters from _registry.py manifests at import time:
  1. It iterates over all subpackages under dimos/hardware/manipulators/
  2. For each subpackage, it loads <subpackage>._registry and records each ADAPTER_FACTORIES entry (name → "module:attr" import path)
  3. Your adapter module is imported only when create("yourarm") is first called
The manifest must import nothing beyond stdlib — it is loaded even when your vendor SDK is missing, so the name always shows up in available() and a missing SDK fails loudly at create() instead of silently dropping the adapter. A CI test (dimos/hardware/test_adapter_registries.py) fails if an adapter directory has no manifest or a manifest path doesn’t resolve. You can verify discovery works:
skip

Step 3: Create Your Robot Folder and Blueprints

Each robot in DimOS gets its own folder under dimos/robot/. This is where you define all blueprints for your arm — coordinator, planning, perception, etc. This follows the same pattern as Unitree robots (dimos/robot/unitree/).

3a. Create the robot directory

3b. Define your blueprints

Create dimos/robot/yourarm/blueprints.py with your coordinator and (optionally) planning blueprints:
skip

Blueprint field reference

Step 4: Add URDF and Planning Integration (Optional)

If you want motion planning (collision-free trajectories via Drake), you need a URDF and a planning blueprint. Add these to your robot’s own blueprints.py.

4a. Add your URDF

Place your URDF/xacro files under LFS data so they can be resolved via LfsPath. LfsPath is a Path subclass that lazily downloads LFS data on first access — this avoids downloading at import time when the blueprint module is loaded.
skip

4b. Create a robot model config helper

skip

4c. Create a planning blueprint

Add this to your dimos/robot/yourarm/blueprints.py alongside the coordinator blueprint:
skip

Key config fields

Coordinator-facing joint states and trajectories use global joint names derived mechanically as {robot_name}/{local_joint_name} (for example, arm/joint1). Keep hardware-native name translation inside the hardware adapter; manipulation planning config uses local model joint names. Planning-group base_link/tip_link values define kinematic chains and pose target frames. base_link is only the robot-scoped link placed by base_pose; do not use it as a substitute for planning-group chain metadata. See Planning Groups.

Step 5: Register Blueprints

The blueprint registry in dimos/robot/all_blueprints.py is auto-generated by scanning the codebase for blueprint declarations. After adding your blueprints:
  1. Run the generation test to update the registry:
  2. Now you can run your arm via CLI:

Step 6: Testing

Verify adapter registration

skip

Unit test with mock

You can test coordinator logic without hardware by using unittest.mock:
skip

Integration test with coordinator

skip

Test the real adapter standalone

skip

Quick Reference Checklist

Files to create:
  • dimos/hardware/manipulators/yourarm/__init__.py
  • dimos/hardware/manipulators/yourarm/adapter.py (implements Protocol)
  • dimos/hardware/manipulators/yourarm/_registry.py (declares ADAPTER_FACTORIES)
  • dimos/robot/yourarm/__init__.py
  • dimos/robot/yourarm/blueprints.py (coordinator + planning blueprints)
Files to modify:
  • pyproject.toml — Add vendor SDK to optional dependencies (if applicable)
Verification:
  • adapter_registry.available() includes "yourarm"
  • pytest dimos/robot/test_all_blueprints_generation.py passes (regenerates all_blueprints.py)
  • dimos run coordinator-yourarm starts successfully