This directory contains scripts for generating and distributing topology-specific execution artifacts, starting REST servers on all Hosts, and operating the Zenoh router.
| Script | Description |
|---|---|
generate_exec_scripts.py |
Generates execution scripts and Compose files from a topology JSON file |
distribute_exec_scripts.sh |
Distributes generated scripts to each host via SCP |
manage_rest_servers.sh |
Manages remote_hosts_scripts/rest_server.py on all Hosts via SSH from the Manager |
system_perf/check_clock_skew_rest.py |
Estimates per-host clock skew via REST four-timestamp probes and saves CSV reports |
system_perf/check_chrony_manager_sync.py |
Checks whether Hosts are synchronized to Manager NTP source and reports likely chrony misconfigurations |
system_perf/README.md |
Usage and output details for system-performance checks |
For usage of each script, see the Usage in Details section in the top-level README.
This section describes the files automatically generated by generate_exec_scripts.py.
| File | Purpose |
|---|---|
<host_name>_exec_docker.sh |
Wrapper script that launches the host-specific Compose file with automatic UID/GID handling |
<host_name>_exec_native.sh |
Wrapper script that runs <host_name>.launch.py directly via ros2 launch on the host (native execution mode) |
<host_name>_compose.yaml |
Host-specific Compose definition for real multi-host deployment |
<host_name>.launch.py |
ROS 2 launch file executed via ros2 launch (used by both Docker and native modes) |
local_exec.sh |
Wrapper script for launching all services with local_compose.yaml on a single machine |
local_compose.yaml |
Compose definition that launches all services on the local development machine |
zenohd_compose.yaml |
Standalone Compose file for starting the Zenoh router container in Docker execution mode |
metadata.txt |
Metadata for the generated topology directory, including input JSON and topology statistics |
metadata.txt is generated at <ws-dir>/<topology-name>/metadata.txt and records the following categories of information.
1. general info
command: Full command line used to run the generatortimestamp: Script execution time inYYYY-MM-DD_hh-mm-ssformatjson: Input JSON file namejson_path: Input JSON file pathws_dir: Output base directorytopology_dir: Generated topology directory name
2. test config
qos_mode:singlefor object input,sweepfor array inputqos_case_count: Number of QoS casesqos_json: Normalized QoS case listqos_history/qos_depth/qos_reliability: Default QoS settings, taken from the first QoS case
3. topology stats
host_count/node_count: Number of hosts and nodespublisher_count/subscriber_count/intermediate_count: Node counts by role (intermediatemeans a node that has bothpublishersandsubscribers)topic_count: Number of unique topicshosts: Host name list, for examplehost1, host2publishers/subscribers/intermediates: Node name lists grouped by roletopics: Topic names in alphabetical ordertopic_runtime_json: Per-topic runtime config used for analysis (payload_size,period_ms,publisher_count)
Generated <host_name>_exec_docker.sh, <host_name>_exec_native.sh, and local_exec.sh scripts support the runtime options below.
--rmw is required and selects middleware at runtime.
--eval-time is applied to every launched node (Publisher / Subscriber / Intermediate).
payload_size and period_ms must be specified in each nodes[].publishers[] entry in the topology JSON, and those values are passed directly to Publisher / Intermediate nodes.
--trial-idx is available only on <host_name>_exec_docker.sh, <host_name>_exec_native.sh, and local_exec.sh.
QoS settings are applied at runtime. If the topology JSON defines qos as an array,
the generated files use the first QoS case as their default, and the future sweep
runner should pass the current case via --qos-* options or QOS_* environment
variables.
For the JSON schema, see topology_example/README.md.
| Option | Short | Description | Default |
|---|---|---|---|
--rmw |
-m |
RMW implementation (fastdds, cyclonedds, zenoh) |
required |
--eval-time |
-t |
Evaluation time in seconds | 60 |
--trial-idx |
-i |
Trial index for local execution | 1 |
--qos-case-idx |
— | QoS sweep case index | unset |
--qos-history |
— | QoS history (KEEP_LAST, KEEP_ALL) |
first QoS case |
--qos-depth |
— | QoS depth, used only with KEEP_LAST |
first QoS case |
--qos-reliability |
— | QoS reliability (RELIABLE, BEST_EFFORT) |
first QoS case |
The generated launch files also read these environment variables:
| Environment variable | Description |
|---|---|
QOS_CASE_INDEX |
Optional QoS sweep case index |
QOS_HISTORY |
QoS history passed to node --qos-history |
QOS_DEPTH |
QoS depth passed to node --qos-depth |
QOS_RELIABILITY |
QoS reliability passed to node --qos-reliability |
Each node launched from <host_name>_exec_docker.sh, <host_name>_exec_native.sh, or local_exec.sh receives a --log-dir under results/YYYY-MM-DD_hh-mm-ss-<rmw>/raw_logs/trial<trial_idx>/ inside the generated topology directory. results/latest-<rmw> is updated as a symbolic link to the active run directory.
Example: performance_ws/simple/results/latest-fastdds/raw_logs/trial1/
distribute_exec_scripts.sh copies the host-specific execution files from <ws-dir>/<topology>/exec_scripts/ to each remote Host listed in metadata.txt.
It distributes the following files for each <host_name>:
<host_name>.launch.py<host_name>_exec_docker.sh<host_name>_exec_native.sh<host_name>_compose.yamlzenohd_compose.yamlmetadata.txt
This script is mainly useful when you want to perform distribution manually before running the benchmark, or when you want to refresh remote files without starting a full test run. For normal docker and native benchmark runs, performance_test.py runs this distribution step automatically.
./manager_scripts/distribute_exec_scripts.sh \
<topology> \
[--ws-dir|-w <dir>] \
[--remote-repo-base|-b <dir>] \
[--ssh-user|-u <user>]| Argument | Short | Description | Default |
|---|---|---|---|
<topology> |
— | Topology directory under ws-dir |
required |
--ws-dir |
-w |
Workspace directory that contains generated topologies | performance_ws |
--remote-repo-base |
-b |
Remote repository base directory on each Host | /home/ubuntu/ros2-perf-multihost |
--ssh-user |
-u |
SSH user for all Hosts | ubuntu |
Example:
./manager_scripts/distribute_exec_scripts.sh \
simple \
--remote-repo-base /home/ubuntu/ros2-perf-multihostmanage_rest_servers.sh manages remote_hosts_scripts/rest_server.py on all target Hosts from the Manager machine.
It resolves host names from <ws-dir>/<topology>/metadata.txt.
start launches REST servers in the background over SSH and waits until each server port is reachable.
If command execution or readiness check fails on any Host, the script exits with a non-zero status.
Runtime log files created by this script are stored on each Host under:
<remote-repo-base>/<ws-dir>/<topology>/runtime_logs/rest_server.log
The logs subcommand reads rest_server.log.
start / stop / status operate on the process listening on fixed REST port 5000 (no PID file management).
./manager_scripts/manage_rest_servers.sh \
<command> \
<topology> \
[--ws-dir|-w <dir>] \
[--remote-repo-base|-b <dir>] \
[--ssh-user|-u <user>] \
[--force|-f] \
[--wait-retries <n>] \
[--wait-interval <sec>]Commands:
start: start REST servers on all Hosts and wait until each Host is readystop: stop REST servers on all Hosts using port5000restart: stop and then start REST servers on all Hostsstatus: show per-Host state based on port5000wait: wait until all Hosts expose the REST portmonitor: periodically run status checkslogs: show REST server logs from all Hosts
| Argument | Short | Description | Default |
|---|---|---|---|
<command> |
— | One of start, stop, restart, status, wait, monitor, logs |
required |
<topology> |
— | Topology directory under ws-dir |
required |
--ws-dir |
-w |
Workspace directory that contains generated topologies | performance_ws |
--remote-repo-base |
-b |
Remote repository base directory on each Host | /home/ubuntu/ros2-perf-multihost |
--ssh-user |
-u |
SSH user for all Hosts | ubuntu |
--force |
-f |
Skip confirmation prompts for process termination | off |
--wait-retries |
— | Number of readiness checks per Host | 30 |
--wait-interval |
— | Seconds between readiness checks | 2 |
--monitor-interval |
— | Seconds between monitor samples | 5 |
--monitor-count |
— | Number of monitor samples (0 means infinite) |
0 |
--log-lines |
— | Number of lines to show for logs |
100 |
--follow |
— | Follow logs continuously (logs command) |
off |
Example:
./manager_scripts/manage_rest_servers.sh \
start \
simple \
--remote-repo-base /home/ubuntu/ros2-perf-multihost
./manager_scripts/manage_rest_servers.sh restart simple
./manager_scripts/manage_rest_servers.sh status simple
./manager_scripts/manage_rest_servers.sh monitor simple --monitor-interval 2 --monitor-count 10
./manager_scripts/manage_rest_servers.sh logs simple --log-lines 200
./manager_scripts/manage_rest_servers.sh logs simple --follow
./manager_scripts/manage_rest_servers.sh stop simpleSystem performance check tools are organized under manager_scripts/system_perf/.
- Detailed usage for
check_clock_skew_rest.pyandcheck_chrony_manager_sync.py: