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
- Vendor SDK — The Python SDK for your robot arm (e.g.,
xarm-python-sdk,piper-sdk) - URDF/xacro — A robot description file (only needed if you want motion planning)
- Connection info — IP address, CAN port, serial device, etc.
Step 1: Create the Adapter
Create a new directory for your arm underdimos/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
_registry.py manifest next to it:
Key implementation notes
-
Unsupported features — Return
Nonefor reads andFalsefor 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
TheAdapterRegistry in dimos/hardware/manipulators/registry.py discovers adapters from _registry.py manifests at import time:
- It iterates over all subpackages under
dimos/hardware/manipulators/ - For each subpackage, it loads
<subpackage>._registryand records eachADAPTER_FACTORIESentry (name →"module:attr"import path) - Your adapter module is imported only when
create("yourarm")is first called
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 underdimos/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
Createdimos/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 ownblueprints.py.
4a. Add your URDF
Place your URDF/xacro files under LFS data so they can be resolved viaLfsPath. 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 yourdimos/robot/yourarm/blueprints.py alongside the coordinator blueprint:
skip
Key config fields
Step 5: Register Blueprints
The blueprint registry indimos/robot/all_blueprints.py is auto-generated by scanning the codebase for blueprint declarations. After adding your blueprints:
- Run the generation test to update the registry:
- 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 usingunittest.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(declaresADAPTER_FACTORIES) -
dimos/robot/yourarm/__init__.py -
dimos/robot/yourarm/blueprints.py(coordinator + planning blueprints)
-
pyproject.toml— Add vendor SDK to optional dependencies (if applicable)
-
adapter_registry.available()includes"yourarm" -
pytest dimos/robot/test_all_blueprints_generation.pypasses (regeneratesall_blueprints.py) -
dimos run coordinator-yourarmstarts successfully
