Skip to main content

play_launch

Resolve, run, and analyze ROS 2 launch executions with resource monitoring and interactive management.

Watch the demo

Upgrading? CHANGELOG.md lists the breaking changes — 0.9.0 has several, and a few of them change behaviour rather than erroring.

Installation

Requires Ubuntu 22.04+ with ROS 2 (Humble, Jazzy, Kilted, Lyrical or Rolling), Python 3.10+, and:

sudo apt install libz3-dev
sudo apt install ros-${ROS_DISTRO}-rclcpp-components ros-${ROS_DISTRO}-class-loader

Install from PyPI:

pip install play_launch

One wheel serves every supported ROS distribution that shares your Python (Humble on 3.10; Jazzy and Kilted on 3.12; Lyrical and Rolling on 3.14), for x86_64 and aarch64. It uses the distribution you sourced (ROS_DISTRO), or the only one under /opt/ros when nothing is sourced; PLAY_LAUNCH_ROS_DISTRO overrides both, and python3 -m play_launch.payload says which one it picked and why. On Ubuntu 24.04 and later add --break-system-packages (or use a virtual environment with --system-site-packages, so ROS's Python packages stay visible).

This installs the play_launch command, which carries the whole surface: launch, run, up, resolve, dump, check, plot, contract, context, setcap, verify, measure.

Optional: grant the helper binaries the capabilities they need for per-process I/O monitoring and non-root RT scheduling (requires sudo):

play_launch setcap

This enables per-process I/O monitoring and non-root RT scheduling (--sched): play_launch setcap grants CAP_SYS_PTRACE to the I/O helper and CAP_SYS_NICE to the RT helper — both are small ROS-free binaries. The main play_launch binary is never given a file capability — that would put it in secure-execution mode and stop it finding its ROS libraries.

See the Real-Time Scheduling Guide for the scheduling spec format and how it maps onto processes, threads, and the kernel.

Quick Start

Launch any ROS 2 package with monitoring and Web UI enabled by default:

play_launch launch demo_nodes_cpp topics/talker_listener.launch.py

Access Web UI at http://127.0.0.1:8080 for real-time node management and log streaming.

The Rust parser is used by default for speed. For maximum compatibility, use --parser python.

Usage

Launch Files

Replace ros2 launch with play_launch launch:

play_launch launch <package> <launch_file> [arguments...]

Single Nodes

Replace ros2 run with play_launch run:

play_launch run <package> <executable> [arguments...]

Two-Step Workflow

Resolve once, bring the system up as often as you like:

# Resolve once — writes system_model.yaml
play_launch dump launch <package> <launch_file> [arguments...]

# Bring it up, as often as you like
play_launch up system_model.yaml

up takes the model path positionally or as --model <path>; it is required either way, since the model is the only thing up spawns from.

Checking Contracts

check parses a launch file and checks the contracts shipped beside it (<stem>.contract.yaml). It needs no ROS graph and is meant for CI:

play_launch check my_pkg bringup.launch.xml               # 0 clean, 1 errors, 3 a contract refused
play_launch check bringup.launch.xml --expect ladder-rung-budget   # a negative test
play_launch check bringup.launch.xml --explain --width 100         # the fault-reaction table, wrapped
play_launch --version   # play_launch 0.13.0 (v0.13.0-9-gabc1234, rlm v0.1.47)

Exit status 3 means a contract file did not parse (error[manifest-parse]), so it was not checked at all; the refusal names the checker's version and the grammar (rlm tag) it reads. Through a pipe the output is ASCII without colour (NO_COLOR is honoured on a terminal too). Exit codes, --expect, the JSON report and the --explain table: Checking contracts in CI.

Features

All features enabled by default:

  • Resource monitoring: CPU, memory, I/O, GPU (2s interval)
  • Diagnostic monitoring: the /diagnostics topic (add more via diagnostics.topics)
  • Web UI: Interactive management at http://127.0.0.1:8080
  • Observable containers: Composable nodes share their container's process, as under ros2 launch, with ComponentEvent load reporting (default; --container-mode isolated fork+execs each composable instead)

Disable Features

Disable specific features:

play_launch launch <package> <launch_file> --disable-monitoring
play_launch launch <package> <launch_file> --disable-diagnostics
play_launch launch <package> <launch_file> --disable-web-ui
play_launch launch <package> <launch_file> --disable-all

Container Mode

Control how composable nodes are managed (default: observable):

# Observable: ComponentEvent publishing, shared process -- as `ros2 launch` runs it (default)
play_launch launch <pkg> <file> --container-mode observable

# Isolated: fork+exec per-node process isolation (a crash takes down one node)
play_launch launch <pkg> <file> --container-mode isolated

# Stock: use original container from launch file, no override
play_launch launch <pkg> <file> --container-mode stock

Adjust Monitoring

Change sampling interval (default: 2000ms):

play_launch launch <package> <launch_file> --monitor-interval-ms 500

Configure Web UI

Change address or port (default: 127.0.0.1:8080):

play_launch launch <package> <launch_file> --web-addr 0.0.0.0:8080

Configuration File

Use YAML for advanced control:

# config.yaml
monitoring:
  enabled: true
  sample_interval_ms: 2000

processes:
  - node_pattern: "NODE 'rclcpp_components/component_container*"
    cpu_affinity: [0, 1]
    nice: 5

Apply configuration:

play_launch launch <package> <launch_file> --config config.yaml
play_launch up system_model.yaml --config config.yaml

Visualization

Generate interactive plots from monitoring data:

# Plot latest execution
play_launch plot

# Plot specific log directory
play_launch plot --log-dir play_log/2025-10-28_16-17-56

# Plot specific metrics
play_launch plot --metrics cpu --metrics memory

# List available metrics
play_launch plot --list-metrics

Output saved to play_log/<timestamp>/plot/:

  • cpu_timeline.html - CPU usage over time
  • memory_timeline.html - Memory usage over time
  • io_timeline.html - I/O read/write rates
  • cpu_distribution.html - CPU distribution box plot
  • memory_distribution.html - Memory distribution box plot
  • statistics.txt - Top 10 rankings for all metrics

Web UI Features

  • Node management: Start/Stop/Restart individual or all nodes
  • Container controls: Load/Unload composable nodes
  • Real-time logs: Stream stdout/stderr with log level coloring and filtering
  • Diagnostics panel: View /diagnostics messages with level filtering
  • Status monitoring: Color-coded node states
  • Auto-restart: Per-node automatic restart configuration
  • Search & filter: Find nodes in large deployments

Output Structure

play_log/<timestamp>/
├── node/<node_name>/
│   ├── metadata.json
│   ├── metrics.csv       # Resource metrics (when enabled)
│   ├── out/err           # Process logs (the live process)
│   ├── pid/status/cmdline
│   ├── out.N/err.N       # Earlier processes of a respawned member, N = 1, 2, ...
│   ├── pid.N/status.N    #   in start order (the plain names are the newest)
│   └── params_files/     # ROS parameter files
├── load_node/<name>/
│   └── out/err           # Per-composable-node logs (isolated mode)
├── system_stats.csv      # System-wide metrics
├── diagnostics.csv       # Diagnostic messages (when enabled)
└── plot/                 # Generated visualizations

Command Reference

# Launch (all features enabled by default)
play_launch launch <package> <launch_file> [args...]
play_launch run <package> <executable> [args...]

# Dump and up (dump emits the SystemModel by default — one artifact)
play_launch dump launch <package> <launch_file> [args...]
play_launch up system_model.yaml            # or: play_launch up --model system_model.yaml

# Parser selection (Rust is default)
play_launch launch <pkg> <file> --parser rust     # Default, fast
play_launch launch <pkg> <file> --parser python   # Maximum compatibility

# Container mode
play_launch launch <pkg> <file> --container-mode observable  # Default
play_launch launch <pkg> <file> --container-mode isolated
play_launch launch <pkg> <file> --container-mode stock

# Disable features
play_launch launch <pkg> <file> --disable-monitoring
play_launch launch <pkg> <file> --disable-diagnostics
play_launch launch <pkg> <file> --disable-web-ui
play_launch launch <pkg> <file> --disable-all
play_launch launch <pkg> <file> --disable-respawn

# Reload a composable node whose process crashed (default: off)
play_launch launch <pkg> <file> --composable-respawn on-crash  # always
play_launch launch <pkg> <file> --composable-respawn inherit   # only under a respawn="true" container

# Enable only specific features
play_launch launch <pkg> <file> --enable monitoring
play_launch launch <pkg> <file> --enable web-ui --enable diagnostics

# Adjust settings
play_launch launch <pkg> <file> --monitor-interval-ms 500
play_launch launch <pkg> <file> --web-addr 0.0.0.0:8080
play_launch launch <pkg> <file> --config config.yaml

# Logging
play_launch launch <pkg> <file> --verbose              # Enable INFO level
RUST_LOG=play_launch=debug play_launch launch <pkg> <file>  # DEBUG level

# Contracts
play_launch check <pkg> <file> [args...]           # exit 0 / 1 errors / 3 refused
play_launch check <pkg> <file> --expect <rule-id>  # pass only on exactly these errors
play_launch check <pkg> <file> --format json       # diagnostics as JSON on stdout
play_launch check <pkg> <file> --explain --ascii --width 120

# Visualization
play_launch plot
play_launch plot --log-dir <dir>
play_launch plot --metrics cpu --metrics memory --metrics io --metrics gpu
play_launch plot --list-metrics

Development

Prerequisites

  • ROS 2 (Humble on Ubuntu 22.04; Jazzy or Kilted on 24.04; Lyrical or Rolling on 26.04), sourced: the build targets $ROS_DISTRO
  • libclang (libclang-dev): rcl_interception_sys generates its bindings from the ROS headers
  • Rust toolchain (stable)
  • Python 3.10+
  • just command runner
  • cargo-nextest test runner
  • uv Python package manager

Install Dependencies

just install-deps

This installs colcon-cargo-ros2 and runs rosdep install for all ROS dependencies.

Build

just build          # Full build: colcon + interception .so + wheel
just build-cpp      # C++ only (msgs + container)
just build-rust     # Rust only (assumes C++ install/ exists)
just build-wheel    # Bundle + wheel only (no colcon rebuild)

Optional: grant the I/O helper its monitoring capability and the RT helper its scheduling capability (requires sudo). After this, RT scheduling (--sched) works without root:

play_launch setcap

Re-run it after every rebuild or upgrade. A file capability is bound to the exact contents of a binary, so replacing that binary drops it — deliberately, since carrying privilege across a change would grant it to code nobody vetted. play_launch says so when it happens, naming the grant it is replacing rather than telling you to run a command you already ran.

(A just setcap recipe also exists. It is a DEVELOPER convenience that avoids the password prompt via a throwaway container, it needs a source checkout, and it does not work under rootless Docker. play_launch setcap is the supported path.)

Run

just run launch <package> <launch_file> [arguments...]
just run run <package> <executable> [arguments...]

Test

just test               # Parser unit + fast integration (~3s)
just test-all           # Parser unit + all integration (~30s)
just test-unit          # Parser unit tests only
just test-integration   # All integration tests
just test-autoware      # Autoware integration tests

Code Quality

just check      # clippy + rustfmt + ruff + cpplint + clang-format
just format     # Auto-format Rust + Python + C++
just quality    # Format then check

Install Wheel Locally

just install-wheel

License

MIT License. See LICENSE.txt.

Metadata

Release files for play-launch 0.20.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for play-launch 0.20.0
File Actions
play_launch-0.20.0-cp314-none-manylinux_2_43_x86_64.whl CPython 3.14 none Linux glibc 2.43+ x86-64 Details for play_launch-0.20.0-cp314-none-manylinux_2_43_x86_64.whl
play_launch-0.20.0-cp314-none-manylinux_2_43_aarch64.whl CPython 3.14 none Linux glibc 2.43+ ARM64 Details for play_launch-0.20.0-cp314-none-manylinux_2_43_aarch64.whl
play_launch-0.20.0-cp312-none-manylinux_2_39_x86_64.whl CPython 3.12 none Linux glibc 2.39+ x86-64 Details for play_launch-0.20.0-cp312-none-manylinux_2_39_x86_64.whl
play_launch-0.20.0-cp312-none-manylinux_2_39_aarch64.whl CPython 3.12 none Linux glibc 2.39+ ARM64 Details for play_launch-0.20.0-cp312-none-manylinux_2_39_aarch64.whl
play_launch-0.20.0-cp310-none-manylinux_2_35_x86_64.whl CPython 3.10 none Linux glibc 2.35+ x86-64 Details for play_launch-0.20.0-cp310-none-manylinux_2_35_x86_64.whl
play_launch-0.20.0-cp310-none-manylinux_2_35_aarch64.whl CPython 3.10 none Linux glibc 2.35+ ARM64 Details for play_launch-0.20.0-cp310-none-manylinux_2_35_aarch64.whl

Total release size: 220.8 MB

Release files / play_launch-0.20.0-cp314-none-manylinux_2_43_x86_64.whl

Download URL play_launch-0.20.0-cp314-none-manylinux_2_43_x86_64.whl
Size 47.7 MB
Tags CPython 3.14 Linux glibc 2.43+ x86-64
SHA-256 checksum
How to use checksums
96ce6520f8af1f36ead4ef3fd0b4c57d65a105315e3171f79948fa1b4757fb4d
BLAKE2b-256 checksum
How to use checksums
25928890f3b2dbc5340154e0812a1d4fe82583ebe5d65af0c926ec8e5b96582f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Release files / play_launch-0.20.0-cp314-none-manylinux_2_43_aarch64.whl

Download URL play_launch-0.20.0-cp314-none-manylinux_2_43_aarch64.whl
Size 43.6 MB
Tags CPython 3.14 Linux glibc 2.43+ ARM64
SHA-256 checksum
How to use checksums
8cb7dd3be3caf8a6979d59f6eb3e81908fa6790c6df898b481d889684185acc0
BLAKE2b-256 checksum
How to use checksums
e7c1362babe645570b31271268ddd6fa81eae655177768a985b281c100b8a3bd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Release files / play_launch-0.20.0-cp312-none-manylinux_2_39_x86_64.whl

Download URL play_launch-0.20.0-cp312-none-manylinux_2_39_x86_64.whl
Size 44.9 MB
Tags CPython 3.12 Linux glibc 2.39+ x86-64
SHA-256 checksum
How to use checksums
5d86d7352d314cfbd14a62da455296ff3ad4fac5caf1e650c1b658c970369cac
BLAKE2b-256 checksum
How to use checksums
5b58e6368edff21b6136f1f73235e986ac5b33edfe9b84e5ab3a33d0ee14c576
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Release files / play_launch-0.20.0-cp312-none-manylinux_2_39_aarch64.whl

Download URL play_launch-0.20.0-cp312-none-manylinux_2_39_aarch64.whl
Size 41.5 MB
Tags CPython 3.12 Linux glibc 2.39+ ARM64
SHA-256 checksum
How to use checksums
fe0d246f77cc4e6a958f80bec5162eebd8f2f3581f8a9dfd6ba13e1251fbd66a
BLAKE2b-256 checksum
How to use checksums
87ec9b38155f276da10f67c51840242bf922284bda96deb6f15ce39480a0be6a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Release files / play_launch-0.20.0-cp310-none-manylinux_2_35_x86_64.whl

Download URL play_launch-0.20.0-cp310-none-manylinux_2_35_x86_64.whl
Size 22.4 MB
Tags CPython 3.10 Linux glibc 2.35+ x86-64
SHA-256 checksum
How to use checksums
d6825b9ca2c1db689228a035b8b895a084b92ec90070e7ebfbd4ac999f9bbd99
BLAKE2b-256 checksum
How to use checksums
272d9f3d1a70246a18624111479097991d7ccc7e77637b94dcf45e8bec8b8bc2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Release files / play_launch-0.20.0-cp310-none-manylinux_2_35_aarch64.whl

Download URL play_launch-0.20.0-cp310-none-manylinux_2_35_aarch64.whl
Size 20.6 MB
Tags CPython 3.10 Linux glibc 2.35+ ARM64
SHA-256 checksum
How to use checksums
df6c34d13f690e1a31ddbff74e1ce25ebd6aee5cff4d7824d4d635daa9cddd4c
BLAKE2b-256 checksum
How to use checksums
f5e7c25a339d13f83742b238350d6ce5ef119315d4ea797f65695bca55f52841
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Security for play-launch 0.20.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 6 files in this release have been uploaded with provenance metadata.

Select from 6 files

Attestation for play_launch-0.20.0-cp314-none-manylinux_2_43_x86_64.whl

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.20.0 This release

6 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page