You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# Scalability Evaluation Method for ROS 2 Distributed Communication
1
+
# ros2-perf-multihost
2
2
3
-
For the nested workspace that contains the ROS 2 node implementations used in this repository, see [ros2_node_impl_ws/README.md](./ros2_node_impl_ws/README.md).
3
+
**Automated Coordination Framework for Objective Architecture Evaluation in Distributed Systems**
4
4
5
-
## Generating Execution Scripts with a Shared Docker Image
5
+
The "RMW Cambrian Explosion" in ROS 2 ecosystem following Zenoh’s integration presents developers with complex middleware choices and architectural challenges.
6
+
Selecting the optimal RMW and system configuration requires empirical data from actual physical hardware.
6
7
7
-
Instead of generating and building a Dockerfile for each topology, this repository reuses a single shared Docker image and generates only topology-specific execution scripts and Compose definitions.
8
+
**ros2-perf-multihost** is an open-source framework for objectively evaluating the performance and architecture of ROS 2 systems in distributed environments on physical devices.
9
+
It coordinates evaluation pipelines across multiple physical devices, and enables developers to quantify how node placement and network configurations impact overall stability.
10
+
Our purpose is to provide a "scientific scale" for optimizing distributed system design across edge devices and servers with real-world networks, empowering data-driven decisions for large-scale robotic systems.
8
11
9
-
### Generate Execution Scripts
12
+
##Overview
10
13
11
-
Generate execution scripts (`host*_exec.sh`, `host*_run.sh`) and Docker Compose files from a JSON topology file.
-**Manager-Host Coordination**: Deploy nodes in bulk to multiple target Hosts (Raspberry Pi, Jetson, servers, etc.) via REST API and remotely manage their lifecycle from a central Manager.
17
+
-**Flexible Topology Configuration**: Define node relationships and QoS settings to the host assignments declaratively via JSON. Iterate complex topologies for multiple RMWs efficiently.
18
+
-**RMW Neutrality**: Evaluate multiple RMW implementations (FastDDS, CycloneDDS, Zenoh) while using QoS and topology definitions for cross-RMW comparisons.
19
+
-**Dual Execution Modes**: Support both Docker containerized and native ROS 2 environments for seamless evaluation across development as production-like setups.
20
+
-**Precision Telemetry & Monitoring**: Record CPU and memory load on each host with trial-aligned timestamps, enabling time-correlated analysis with end-to-end communication metrics.
17
21
18
-
### Options Supported by Generated Scripts
22
+
### 🏗 Architecture
19
23
20
-
Generated `host*_run.sh` and `local_run.sh` scripts support the runtime options below. `--eval-time` is applied to every launched node (Publisher / Subscriber / Intermediate). `payload_size` and `period_ms` must be specified in each Publisher / Intermediate topic entry in the topology JSON, and those values are passed directly to Publisher / Intermediate nodes. `--trial-idx` is available only on `host*_run.sh` and `local_run.sh`. For the JSON schema, see [topology_example/README.md](./topology_example/README.md).
24
+
This framework employs a two-tier architecture:
21
25
22
-
| Option | Short | Description | Default |
23
-
|---|---|---|---|
24
-
| --eval-time | -t | Evaluation time in seconds | 60 |
25
-
| --trial-idx | -r | Trial index for local execution | 1 |
26
+
-**Manager**: Generates topology-specific scripts, coordinates execution across hosts via REST API, collects logs, and aggregates results.
27
+
-**Hosts**: Operate a lightweight REST server to receive execution commands and launch ROS 2 nodes in either Docker containers or native environments.
28
+
29
+
The workflow proceeds as follows:
30
+
31
+
1.**Topology Definition**: Users define node placement, topic relationships, and QoS configuration in a topology JSON file.
32
+
2.**Coordination**: The Manager generates execution scripts for the selected RMW and distributes them to each Host for execution.
33
+
3.**Execution**: All hosts begin operation tests simultaneously while collecting system metrics in the background.
34
+
4.**Data Aggregation**: After experiment completion, the Manager collates logs from all hosts and outputs analysis-ready CSV files.
35
+
36
+
### Observable Metrics 📊
37
+
38
+
The default pipeline correlates communication performance with host-level resource utilization:
39
+
40
+
| Category | Metrics | Per |
41
+
| :-- | :-- | :-- |
42
+
|**Communication**| End-to-end latency and message loss count | Per-trial |
43
+
|**Throughput**| Aggregated throughput estimated from publish period, publisher count, payload size, and observed loss | Per-trial |
44
+
|**Host Resource Usage**| CPU and memory usage, load average, and swap usage summary | Per-host / Per-trial |
26
45
27
-
#### Examples
46
+
## Getting Started
47
+
48
+
### Prerequisites
49
+
50
+
Prepare the repository root on the manager host first.
`--eval-time` is applied to all nodes launched through `*_run.sh` or `local_run.sh`. `payload_size` and `period_ms` are read from each Publisher/Intermediate entry in the topology JSON.
70
+
### Quick Start: Local Verification
41
71
42
-
### Pull the Shared Docker Image
72
+
Instead of generating and building a Dockerfile for each topology, this repository reuses a single shared Docker image and generates only topology-specific execution scripts and Compose definitions.
Use the published GitHub Packages image [`ghcr.io/hal-lab-u-tokyo/ros2-perf-multihost:latest`](https://github.com/hal-lab-u-tokyo/ros2-perf-multihost/pkgs/container/ros2-perf-multihost). Generated `local_compose.yaml` and `host{N}_compose.yaml` files also reference the same image. For image build and push steps, see `docker/README.md`.
49
81
50
-
### Generate Scripts from the Project Root
82
+
2. Generate execution scripts from a topology JSON file.
`local_run.sh` automatically sets `LOCAL_UID=$(id -u)` and `LOCAL_GID=$(id -g)` before running `docker compose`, which helps avoid root-owned files on bind mounts.
95
+
96
+
When using Zenoh, the script starts the Zenoh router first, then launches the host services, and stops the router automatically afterward.
97
+
98
+
### Generate Execution Scripts
99
+
100
+
Generate execution scripts (`host*_exec.sh`, `host*_run.sh`) and Docker Compose files from a JSON topology file.
Each node launched from `host{N}_run.sh` or `local_run.sh` receives a `--log_dir` under `results/YYYY-MM-DD_hh-mm-ss/exec_logs/trial<trial_idx>/` inside the generated run directory. `results/latest` is updated as a symbolic link to the active run directory. Example: `performance_ws/latest/results/2026-04-26_13-21-45/exec_logs/trial1/`.
107
157
108
-
### Local Verification with Docker
158
+
#### Runtime Options Supported by Generated Scripts
159
+
160
+
Generated `host*_run.sh` and `local_run.sh` scripts support the runtime options below. `--eval-time` is applied to every launched node (Publisher / Subscriber / Intermediate). `payload_size` and `period_ms` must be specified in each Publisher / Intermediate topic entry in the topology JSON, and those values are passed directly to Publisher / Intermediate nodes. `--trial-idx` is available only on `host*_run.sh` and `local_run.sh`. For the JSON schema, see [topology_example/README.md](./topology_example/README.md).
161
+
162
+
| Option | Short | Description | Default |
163
+
|---|---|---|---|
164
+
| --eval-time | -t | Evaluation time in seconds | 60 |
165
+
| --trial-idx | -r | Trial index for local execution | 1 |
166
+
167
+
Examples:
168
+
169
+
```bash
170
+
# Use default values
171
+
./host1_exec.sh
172
+
173
+
# Override eval-time
174
+
./host1_run.sh --eval-time 60
175
+
176
+
# Short options
177
+
./host1_run.sh -t 60
178
+
```
179
+
180
+
`--eval-time` is applied to all nodes launched through `*_run.sh` or `local_run.sh`. `payload_size` and `period_ms` are read from each Publisher/Intermediate entry in the topology JSON.
181
+
182
+
### Run with Docker
183
+
184
+
Use Docker when you want a containerized execution environment.
`local_run.sh` automatically sets `LOCAL_UID=$(id -u)` and `LOCAL_GID=$(id -g)` before running `docker compose`, which helps avoid root-owned files on bind mounts.
190
+
For multi-host execution, run the host-specific wrapper on each target host.
115
191
116
-
When using Zenoh, the script starts the Zenoh router first, then launches the host services, and stops the router automatically afterward.
## REST Server and Automated Performance Evaluation
239
+
### Automated Benchmark via REST
166
240
167
241
In a multi-host setup, each Raspberry Pi runs a REST server implemented by `rest_server.py`. A controller script sends requests to those servers to automate benchmark execution.
168
242
169
-
Install the required Python packages with apt before starting the REST workflow.
SSH into each host and launch `remote_hosts_scripts/rest_server.py` directly.
@@ -203,10 +270,62 @@ Main arguments:
203
270
-`--scenario`: Scenario directory to use (default: `latest`)
204
271
-`--eval-time`: Override evaluation time; if omitted, the default from `*_run.sh` or `*_exec.sh` is used
205
272
206
-
`performance_test.py` launches node groups via REST for each trial, then collects logs from each host with `scp`. On prepare, the manager creates `<ws-dir>/<scenario>/results/<session_timestamp>/` and updates `<ws-dir>/<scenario>/results/latest` to point to it. Trial logs are collected under `<ws-dir>/<scenario>/results/latest/logs/trial<N>/`, and aggregated outputs (for example `total_latency.csv`, `throughput.csv`, `host_trials_usage.csv`, `host_usage_summary.csv`) are written under `<ws-dir>/<scenario>/results/latest/csv/`.
207
-
208
273
When using Zenoh as the RMW, start the router on the manager host before running the benchmark.
`performance_test.py` launches node groups via REST for each trial, then collects logs from each host with `scp`.
282
+
283
+
On prepare, the manager creates `<ws-dir>/<scenario>/results/<session_timestamp>/` and updates `<ws-dir>/<scenario>/results/latest` to point to it.
284
+
285
+
- Trial logs are collected under `<ws-dir>/<scenario>/results/latest/logs/trial<N>/`.
286
+
- Aggregated outputs such as `total_latency.csv`, `throughput.csv`, `host_trials_usage.csv`, and `host_usage_summary.csv` are written under `<ws-dir>/<scenario>/results/latest/csv/`.
287
+
288
+
## Directory Structure
289
+
290
+
The main directories and their roles are as follows:
291
+
292
+
| Directory | Role |
293
+
|---|---|
294
+
|`manager_scripts/`| Generates topology-specific execution artifacts and provides helper scripts for distribution and router operation. |
295
+
|`remote_hosts_scripts/`| Runs on each host (REST server, remote start orchestration, and host metrics collection). |
296
+
|`performance_test/`| Executes trial automation, log collection, and CSV aggregation/analysis. |
297
+
|`performance_ws/`| Stores generated scenarios, execution scripts, and run results. |
298
+
|`topology_example/`| Provides example topology JSON files and schema guidance. |
299
+
|`ros2_node_impl_ws/`| ROS 2 node implementation workspace used by generated execution scripts. |
300
+
|`docker/`| Shared Docker image definition and compose-related assets. |
301
+
302
+
## Related Documents
303
+
304
+
For detailed usage in subdomains, see the following documents:
305
+
306
+
-[docker/README.md](./docker/README.md): Docker image build/push details and container workflow notes.
307
+
-[topology_example/README.md](./topology_example/README.md): Topology JSON format and modeling guidance.
308
+
-[ros2_node_impl_ws/README.md](./ros2_node_impl_ws/README.md): ROS 2 node workspace usage and build instructions.
309
+
310
+
## Troubleshooting
311
+
312
+
Common issues and fixes:
313
+
314
+
-`python3 manager_scripts/generate_exec_scripts.py ...` fails because output exists: rerun with `--force` or remove the existing scenario directory under `performance_ws/`.
315
+
-`distribute_exec_scripts.sh` fails with SSH/SCP errors: verify hostnames, SSH keys, and that repository paths are identical across hosts.
316
+
- REST benchmark does not start remote execution: ensure `python3 remote_hosts_scripts/rest_server.py` is running on every target host before calling `performance_test.py`.
317
+
- Docker mode fails on remote hosts: pull `ghcr.io/hal-lab-u-tokyo/ros2-perf-multihost:latest` and confirm Docker permissions on each host.
318
+
- Native mode cannot find workspace paths: set `ROS2_PERF_WS` to the project root before running `host*_exec.sh`.
319
+
- Expected CSV outputs are missing: check `<ws-dir>/<scenario>/results/latest/logs/trial<N>/` for trial logs and inspect script stderr for analyzer failures.
320
+
321
+
## Contributing and License
322
+
323
+
Contributions are welcome. Please open an issue to discuss bugs, feature requests, or design changes before large modifications.
324
+
325
+
When submitting a pull request:
326
+
327
+
- Keep changes scoped and include a clear rationale.
328
+
- Update documentation for user-facing behavior changes.
329
+
- Include reproduction steps for bug fixes and benchmark-related changes.
330
+
331
+
This project is licensed under the terms in [LICENSE](./LICENSE).
0 commit comments