Architecture
RobotDSL-Core is a Python compiler. It checks robot, world, task, and evaluation descriptions together, then generates native files for the user's robot environment. ROS, simulators, and Docker are execution or test dependencies, not compiler dependencies.
Repository layout
robotdsl-core/
├── pyproject.toml
├── src/mobiledsl/
│ ├── cli.py command-line entrypoint
│ ├── driver/ source loading, phase orchestration, output writing
│ ├── frontend/ grammar, parser, AST, source locations
│ ├── semantic/
│ │ ├── model/ vocabulary, resolved program, analysis facts; no AST dependency
│ │ ├── lower.py name resolution, type checking, AST normalization
│ │ └── analysis/ physical assembly, the world's places and regions, task use
│ ├── validation/ rules over analysis facts
│ ├── library/ component library loading
│ ├── support/ shared diagnostics and source-location types
│ └── targets/
│ ├── gazebo/ native models, physics, and simulated sensors
│ ├── mujoco/ the MuJoCo scene and the node that simulates it
│ ├── ros2/ ROS interfaces, control, launch, and runtime helpers
│ ├── nav2/ navigation providers and configuration
│ ├── mission/ the mission and evaluation data every runtime reads
│ ├── payload.py the runtime files every target copies
│ ├── ros_gz_nav2/ composition for Gazebo and cross-adapter checks
│ ├── ros_mujoco_nav2/ composition for MuJoCo
│ └── mjcf/ the robot alone, as one MJCF, for MuJoCo without ROS
├── tests/
│ ├── architecture/ import and installation boundaries
│ ├── driver/
│ ├── frontend/
│ ├── semantic/
│ ├── validation/
│ ├── library/ the loader's tests; fixtures/test_parts holds the parts only the tests use
│ └── targets/ native-tool and simulation tests
├── examples/
│ ├── demo/ the guide's demo program, which the tests also build on
│ └── library/ the parts of the guide's example robots and the objects of its world
├── docker/ the test images' build files
├── tools/ development utilities
└── docs/ this site (VitePress)Target packages own their binding, native-input adapters, typed output models, and emitters. ros_gz_nav2 owns Gazebo–ROS integration and composes the launch plan; Gazebo and Nav2 do not import each other. Changing simulators reuses robot and task semantics and autonomy adapters; composition checks interface compatibility. Runtime helpers live with their owning adapter and execute in the target environment. Compiler code never imports those helpers or ROS/simulator SDKs.
Compilation flow
program source library directories
│ │
▼ ▼
┌────────────┐ ┌────────────┐
│ parse │ frontend │ load │ library
└─────┬──────┘ └─────┬──────┘
│ syntax tree │ declarations
└────────────────┬───────────────┘
▼
┌────────────┐
│ lower │ semantic.lower
└─────┬──────┘
│ typed model
▼
┌────────────┐
│ analyze │ semantic.analysis
└─────┬──────┘
│ model and facts
▼
┌────────────┐
│ validate │ validation
└─────┬──────┘
│ validated model and facts
▼
┌────────────┐
│ bind │ targets
│ render │
└─────┬──────┘
│ exact file bytes
▼
┌────────────┐
│ write │ driver
└────────────┘Lowering resolves names, checks types, fills in the defaults the vocabulary states, and normalizes the syntax tree. Analysis derives facts such as geometry, mass, connectivity, where each world name is and what each entity covers, and action dataflow. Validation judges those facts without recomputing them or changing the model, and a target reads them rather than interpreting the program again: the map, the mission and the evaluator each read the world on their own once, and disagreed. Missing required facts produce diagnostics; optional unknowns remain visible. Validated values are immutable and retain their source locations.
The target binds actions and requirements to selected implementations. It checks unsupported operations and cross-file references before producing exact output bytes. The driver writes them only after planning succeeds and protects input files and unrelated output contents.
Dependency direction
Each compiler package imports only the packages in its row, plus support, which holds diagnostics and source locations.
| Package | Imports |
|---|---|
cli | driver |
driver | every package below |
semantic.lower | frontend, library, semantic.model |
semantic.analysis | semantic.model |
validation | semantic.model |
targets | semantic.model |
frontend, library, semantic.model | nothing |
Inside targets, the simulator adapters (gazebo, mujoco) and the autonomy adapters (ros2, nav2) never import each other; a composing target (ros_gz_nav2, ros_mujoco_nav2, mjcf) imports the ones it needs. The robot description is built by the Gazebo adapter and reused by the MuJoCo target without Gazebo's blocks; the mjcf target writes it into an MJCF with the MuJoCo target's contacts and actuators. targets/mission (the mission and evaluation data every runtime reads) and targets/payload (the runtime files every target copies) are shared by the composing targets and imported by no adapter.
Lowering consumes the AST and already-loaded library declarations; the resolved model and its analyses do not depend on the parser. Frontend, semantic, and validation code do not import targets or perform file I/O. The driver loads source files and calls library loaders. Runtime helpers consume emitted data, not compiler models. URDF elements, plugins, topic names, and contact approximations belong in targets. Native-input adapters retain original files alongside their semantic projection.
Tests enforce import boundaries, compilation without ROS or simulator packages, and execution of generated output without the compiler checkout or installation.
Libraries and surrounding projects
Component and scene libraries are ordinary directories supplied explicitly at compile time. They contain declarations and local assets; they have no install step, package store, or hidden default location.
Acquisition, CAD conversion, image reconstruction, calibration, and policy training belong to external preparation tools. Original assets and official webpages stay with library source material. The experiment project owns cases, repetitions, acceptance thresholds, and aggregate scores.
Generated output
Typed target models supply native consumers from the same resolved facts:
- Robot/world descriptions and their assets.
- Controller, perception, and navigation configuration.
- Executable task bindings, observation settings, and a launch entrypoint.
- Diagnostics and optional inspection views, separate from execution inputs.
Each executable responsibility has one authoritative representation. Runtime-facing formats are defined separately from internal compiler models. Shared values in different native formats are derived consistently. Output contains its required resources or explicitly binds resources supplied by the user's environment; it does not depend on the compiler checkout. Runtime logs and results stay outside the output.
Simulator and autonomy bindings are separate concerns. A new target implements the same semantic contracts and verifies actuation, sensors, timing, reset, and observations. Compilation checks the declared configuration; startup and execution establish whether the robot actually works.
See Language for semantics and Developer onboarding for the development workflow.
Design references
| Reference | Principle used here |
|---|---|
| rustc | Separate syntax, semantic representations, analysis, and code generation. |
| rust-analyzer | Isolate semantic analysis from I/O and internal models from external formats. |
| TypeSpec | Emit different formats from one checked semantic model. |
| MLIR | Verify the model after every transformation stage; each stage receives valid input. |
| Scenic | Give simulator adapters explicit action and observation boundaries; one scenario language runs on CARLA, Webots, and other simulators. |
| Menagerie | Require documentation, a license, and a changelog next to every library asset, and test for them. |
These are design references; none is a compiler dependency.