Expert guidance for developing with ROS-Plan - a declarative YAML-based ROS 2 node configuration, compilation, and runtime management system with launch file conversion tools.
Expert guidance for working with the ROS-Plan project - a comprehensive ROS 2 toolchain providing declarative plan format, plan compilation, runtime process management, and launch file analysis tools.
ROS-Plan is a comprehensive ROS 2 toolchain that provides:
1. **Declarative plan format** - YAML-based node configuration with socket/link abstraction
2. **Plan compiler** - Transforms plans into executable ROS 2 launch files
3. **Runtime system** - Process management with graceful shutdown, restart policies, and dynamic parameter updates
4. **Metadata extraction** - launch2dump tool for analyzing existing launch files
5. **Launch conversion** - launch2plan tool for converting ROS 2 launch files to plan format
The project consists of both Rust (core compiler and runtime) and Python (launch file integration) components.
**Current Phase**: Phase 12 (Launch-to-Plan Conversion) - In Progress
See `book/src/launch2plan.md` for complete design and progress tracking.
1. **ros-plan-format** - Data structures and parsing for ROS plan files (YAML format)
- Handles node definitions, links, sockets, parameters, QoS settings
- Key types: `Plan`, `Node`, `Link`, `NodeSocket`, `PlanSocket`
- Custom YAML tags: `!pub`, `!sub`, `!pubsub`, `!i64`, `!f64`, `!bool`, `!path`, `!expr`
2. **ros-plan-compiler** - Core compilation logic
- Main entry point: `Compiler::compile()`
- Evaluation, linking, program generation
- Lua integration for dynamic expressions
- Link resolution and validation
3. **ros-plan-runtime** - Process management and lifecycle
- Node spawning with ROS 2 arguments
- Graceful shutdown (SIGTERM → SIGKILL)
- Restart policies: Never, Always, OnFailure
- Dynamic parameter updates with program diffing
- Launch include tracking and reloading
- Status reporting (table and JSON formats)
- Event logging with circular buffer
4. **ros2plan** - CLI tool
- Commands: `compile`, `run` (with runtime)
- Usage: `ros2plan compile <plan-file> [args]`
5. **ros-utils** - ROS 2 integration utilities
- Package and executable resolution via `ros2` CLI
- Node command-line generation with remapping
- Extracts nodes, parameters, remappings, containers
- JSON/YAML output formats
- Uses UV for dependency management
- Discovers publishers, subscriptions, services, clients without middleware
- Uses rmw_introspect_cpp RMW implementation
- Requires workspace to be built and sourced
- Converts ROS 2 launch files to ROS-Plan YAML format
- Socket inference from introspection and remappings
- Conditional branch exploration with `when` clauses
- Automatic link generation from topic connections
- Argument type inference from default values
- Include handling with cycle detection
- Metadata tracking with TODO completion detection
- C++ RMW implementation for lightweight introspection
- Python wrapper for ROS 2 node introspection
- Built automatically via `make build` using colcon
- Required by launch2plan for node interface introspection
When working with this codebase, follow these guidelines:
**Build the project:**
```bash
make build
```
**Run tests frequently:**
```bash
make test
```
**Check code quality:**
```bash
make lint
```
**Run specific crate tests:**
```bash
cargo nextest run -p ros-plan-compiler --cargo-profile release-with-debug
```
**Value Types:**
```rust
// Use the Value enum from ros-plan-format
pub enum Value {
I64(i64),
F64(f64),
Bool(bool),
String(String),
Path(PathBuf),
Expr(String), // Lua expression
}
```
**Socket References in YAML:**
```yaml
link:
camera_image: !pubsub
src: ["camera/image"] # Node ID "camera", socket "image"
dst: ["detector/image"] # Node ID "detector", socket "image"
```
**When Clauses (Conditional Compilation):**
```yaml
node:
optional_node:
pkg: my_pkg
exec: my_node
when: "$(enable_feature)" # Lua expression
```
**Restart Policies:**
```rust
pub enum RestartPolicy {
Never,
Always { backoff: Duration },
OnFailure { max_retries: u32, backoff: Duration },
}
```
- 330 Rust tests (format, compiler, runtime, CLI, ros-utils)
- 110 Python tests (25 launch2dump + 9 ros2-introspect + 85 launch2plan)
**Install dependencies:**
```bash
cd python && uv sync
```
**Run launch2dump:**
```bash
cd python/launch2dump && uv run launch2dump <launch-file>
```
**Run ros2-introspect (requires workspace sourced):**
```bash
source install/setup.bash
cd python/ros2-introspect && uv run ros2-introspect <package> <executable>
```
**Run launch2plan (requires workspace sourced):**
```bash
source install/setup.bash
cd python/launch2plan && uv run launch2plan convert <launch-file>
```
**IMPORTANT**: Each line in a Makefile target runs in a separate shell. Environment sourcing must be on the same line as commands that need it.
**Correct:**
```makefile
. install/setup.sh && cd python/launch2plan && uv run pytest
```
**Incorrect:**
```makefile
. install/setup.sh && \
cd python/launch2plan && \
uv run pytest
```
Current implementation follows incremental phase-by-phase approach:
**Completed Phases:**
**Remaining Phases:**
**When implementing new phases:**
**Key Format Files:**
**Key Compiler Files:**
**Key Runtime Files:**
**Key Python Files:**
**Documentation:**
**Compile a plan file:**
```bash
cargo run --bin ros2plan -- compile examples/introduction.yaml
```
**Run with runtime:**
```bash
cargo run --bin ros2plan -- run examples/introduction.yaml
```
**Convert launch file to plan:**
```bash
source install/setup.bash
cd python/launch2plan && uv run launch2plan convert <launch-file>
```
**Check conversion status:**
```bash
cd python/launch2plan && uv run launch2plan status <plan-file>
```
Always ensure:
1. `make lint` passes (formatting + clippy with `-D warnings`)
2. `make test` passes (all 440 tests)
3. Documentation updated if behavior changes
4. Phase tracking updated in `book/src/launch2plan.md` for Phase 12 work
**Example Plan File:**
```yaml
node:
camera:
pkg: camera_driver
exec: camera_node
socket:
image: !pub
detector:
pkg: object_detector
exec: detector_node
socket:
image: !sub
link:
camera_image: !pubsub
type: sensor_msgs/msg/Image
src: ["camera/image"]
dst: ["detector/image"]
```
**Example Restart Policy:**
```yaml
node:
resilient_node:
pkg: my_pkg
exec: my_node
restart: !on_failure
max_retries: 3
backoff_secs: 5
```
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/ros-plan-ros-2-toolchain/raw