Add Robot
SkillFiles & storageUse when adding a new robot to EmbodiChain — scaffolds a RobotCfg subclass (single-file or package layout) with the _build_defaults hook, build_pk_serial_chain, registration, docs page, and test stub.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Add Robot skill
What this skill tells your AI
The instructions your AI receives, as published by dexforce/embodichain in .agents/skills/add-robot/SKILL.md and read by ahel’s review.
When to Use
- Adding a new robot to EmbodiChain.
- Adding a variant to an existing robot (a new version / arm kind / hand brand).
- Scaffolding a
RobotCfgsubclass.
The RobotCfg Protocol
Every robot config subclasses RobotCfg and overrides two hooks:
_build_defaults(self, init_dict=None)— read variant fields frominit_dict, set them onself, then populateurdf_cfg/control_parts/solver_cfg/joint_drive_props/attrs.build_pk_serial_chain(self, device=...)— return{control_part: pk.SerialChain}, reading the PK URDF from a single_pk_urdf_pathsource.
from_dict is a 3-line template (do not reimplement):
cfg = cls()
cfg._build_defaults(init_dict)
return merge_robot_cfg(cfg, init_dict)
to_dict / to_string / save_to_file are inherited from RobotCfg and round-trip.
Two Layouts
| Layout | When | Files |
|---|---|---|
| Single-file | Variant-less robot | my_robot.py |
| Package | Robot with variants (versions / arm kinds / hand brands) | types.py, cfg.py, optional params.py/utils.py, __init__.py |
The Contract (read first)
A cfg's _build_defaults must populate:
uid(str)urdf_cfg(URDFCfg) orfpathcontrol_parts(Dict[str, List[str]]; joint names support regex)solver_cfg(Dict[str, SolverCfg]; keys matchcontrol_parts)joint_drive_props(JointDrivePropertiesCfg)attrs(RigidBodyPhysicsCfg)
build_pk_serial_chain must read from _pk_urdf_path (a property for
constant-path robots, a method for variant-dependent paths). The PK chain's DOF
must match the matching control_parts entry (the test stub asserts this).
Steps
-
Pick a layout using the table above. Single-file for variant-less robots; package for robots with variants.
-
Create the cfg file(s). Subclass
RobotCfg. Declare variant fields (enums) if using the package layout. -
Implement
_build_defaults(self, init_dict=None). Set variant fields frominit_dict, then populate the Contract fields. Single-file template:def _build_defaults(self, init_dict=None): init_dict = init_dict or {} self.uid = "MyRobot" self.urdf_cfg = URDFCfg(components=[...]) self.control_parts = {"arm": ["JOINT[1-6]"]} self.solver_cfg = {"arm": OPWSolverCfg(end_link_name="link6", root_link_name="base_link")} self.joint_drive_props = JointDrivePropertiesCfg(stiffness={"JOINT[1-6]": 1e4})Variant-aware template (reads version / arm_kind):
def _build_defaults(self, init_dict=None): init_dict = init_dict or {} self.version = MyRobotVersion(init_dict.get("version", "v1")) self.arm_kind = MyRobotArmKind(init_dict.get("arm_kind", "default")) ... # then urdf_cfg / control_parts / solver_cfg / joint_drive_props / attrs -
Implement
build_pk_serial_chainreading from_pk_urdf_path:@property def _pk_urdf_path(self) -> str: return get_data_path("MyRobot/arm.urdf") def build_pk_serial_chain(self, device=torch.device("cpu"), **kwargs): chain = create_pk_serial_chain( urdf_path=self._pk_urdf_path, device=device, end_link_name="link6", root_link_name="base_link", ) return {"arm": chain} -
Keep
from_dictas the 3-line template — do not reimplement it. -
Add
__all__and register inembodichain/lab/sim/robots/__init__.py:from .my_robot import MyRobotCfg __all__ = ["MyRobotCfg"] -
Add documentation: create
docs/source/resources/robot/<name>.mdand add it todocs/source/resources/robot/index.rst. -
Add a test stub with a
__main__smoke test + the DOF drift guard. Use/add-testfor full test scaffolding; the guard snippet is:chains = cfg.build_pk_serial_chain() for part, chain in chains.items(): assert len(chain.get_joint_parameter_names()) == len(cfg.control_parts[part]) -
Verify:
preview-assetCLI +RobotCfg.from_dict(cfg.to_dict())round-trip.
Reusable embodiment handoff
RobotCfg owns simulation construction, control parts, solvers, and physical
properties. It does not own a task, sensor suite, or Task Program skill
profile.
If the user also wants the robot selectable from task deployments, invoke
$add-embodiment-component after the robot config passes its own tests. That
component selects the robot, owns its sensors, and optionally maps stable
logical resources/endpoints/capabilities/commands into skill_profile.
Do not copy those semantic declarations into the robot class.
Common Mistakes
| Mistake | Fix |
|---|---|
all instead of __all__ | Use __all__ — lowercase all breaks import *. |
solver_cfg set twice | Set it once in _build_defaults only. |
| PK URDF drifts from sim URDF | Route PK through _pk_urdf_path; keep the DOF guard. |
Reimplementing from_dict | Keep the 3-line template; put logic in _build_defaults. |
root_link_name as a tuple | It must be a str. |
Calling a nonexistent validate | Don't call methods that don't exist. |
Quick Reference
| Parameter | Type | Description |
|---|---|---|
uid | str | Unique robot identifier |
urdf_cfg | URDFCfg | URDF file and components |
control_parts | Dict[str, List[str]] | Joint groups for control |
solver_cfg | Dict[str, SolverCfg] | IK solver configurations |
joint_drive_props | JointDrivePropertiesCfg | Joint drive, limits, friction, and armature |
attrs | RigidBodyPhysicsCfg | Rigid-body physics attributes |
| variant fields | enum / str / bool | Optional subclass fields |
_pk_urdf_path | property or method → str | URDF for the FK/IK serial chain |
File locations:
- Config:
embodichain/lab/sim/robots/<name>.pyorembodichain/lab/sim/robots/<name>/ - Registry:
embodichain/lab/sim/robots/__init__.py - Docs:
docs/source/resources/robot/<name>.md - Tests:
tests/sim/objects/test_robot_cfg.py - Base class:
embodichain/lab/sim/cfg/robot.py(RobotCfg) - Guide:
docs/source/guides/add_robot.rst· Tutorial:docs/source/tutorial/add_robot.rst
Signals
- GitHub stars
- 224
- Forks
- 24
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
add-robot- Source
- github.com/dexforce/embodichain