Audience

Verification level

Configuration only. The real door URDF is resolved, joint declarations are validated, and an ExecutionPlan is produced. No backend is started and no door motion is claimed.

Files

  • run.yaml creates a door instance with one initial hinge angle.
  • main.py inspects joint names, units, groups, and initial state.
  • Articulation manifest packages the model and its portable joint vocabulary.

Component manifest, line by line

yaml
schema: fastsim-component/1
id: articulation://fastsim/component-demo-door # Reusable articulation identity.
version: 1.0.0
kind: articulation                             # It is jointed, but not a robot.
semantics:
  joints: [door_hinge]                         # Stable authored joint names.
  links: [frame, door_panel]                   # Stable authored link names.
  joint_units:
    door_hinge: rad                            # Commands/state use radians.
  groups:
    door: [door_hinge]                         # Named control-resource group.
variants:
  pybullet:
    resources:
      model:
        uri: ../../_shared/assets/door.urdf     # Asset relative to the manifest.
        format: model/vnd.urdf+xml
        role: simulation

semantics is the portable vocabulary used by upper layers. Backend-native names and files may differ between variants, but a consumer can keep addressing door_hinge and group door.

To author another articulation, list every controllable joint, its unit, relevant links, and useful groups. An articulation is not automatically a robot; use kind: robot only when the component really represents a robot actor.

run.yaml, line by line

yaml
schema: fastsim/2
name: articulation-component
backend: pybullet                         # Select the URDF variant.

runtime:
  physics_hz: 60
  control_hz: 30
  seed: 103

scenario:
  scene:
    articulations:                        # Correct group for non-robot jointed assets.
      cabinet_door:                       # Local entity alias.
        use: articulation://fastsim/component-demo-door
        pose:
          xyz_m: [0.60, 0.0, 0.0]       # Root position in world metres.
          quat_xyzw: [0.0, 0.0, 0.0, 1.0]
        initial_state:
          joints:
            door_hinge: 0.35             # Initial angle in declared radians.

The compiler checks that door_hinge exists in the selected component semantics. A typo is rejected before a simulator is launched.

What main.py proves

The program uses load_project, compiles the sibling Run, and asserts that:

  • the resolved kind is articulation;
  • door_hinge and its rad unit survive resolution;
  • group door expands to the intended joint;
  • the authored initial value reaches articulations.cabinet_door.

Run it

bash
cd demo/components/03_articulation_component
fastsim config validate run.yaml --json
fastsim config expand run.yaml
fastsim config explain run.yaml scenario.scene.articulations.cabinet_door.initial_state.joints.door_hinge
fastsim config lock run.yaml --output run.lock.yaml
fastsim config verify-lock run.lock.yaml --json
python main.py

Expected output

text
Entity: articulations.cabinet_door
Kind: articulation
Joints: ('door_hinge',)
Control group 'door': ('door_hinge',)
Initial door_hinge: 0.35 rad

Common errors

  • Placing the door under objects: loses the intended kind contract and is rejected.
  • Initial joint keys must match manifest semantics exactly.
  • Declare angle units explicitly; do not make consumers guess degrees versus radians.
  • A group may contain only joints declared by the selected component semantics.
  • This compile-only example does not prove actuator tuning or collision behavior.

Next

Previous: object component · Next: robot component