rosotacom-dev 2.5.dev15__tar.gz → 2.5.dev17__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/PKG-INFO +21 -1
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/README.md +20 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/rfcs/0002-expectation-concepts.md +18 -0
- rosotacom_dev-2.5.dev17/src/rosotacom/benchmark_delta.py +279 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/cli_benchmark.py +62 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview.py +12 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview_core.py +11 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom_dev.egg-info/PKG-INFO +21 -1
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom_dev.egg-info/SOURCES.txt +2 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom_dev.egg-info/scm_file_list.json +2 -0
- rosotacom_dev-2.5.dev17/src/rosotacom_dev.egg-info/scm_version.json +8 -0
- rosotacom_dev-2.5.dev17/tests/unit/test_benchmark_delta.py +172 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_status_overview.py +48 -0
- rosotacom_dev-2.5.dev15/src/rosotacom_dev.egg-info/scm_version.json +0 -8
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/.devcontainer/devcontainer.json.template +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/.devcontainer/re_generate_devcontainer_json.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/.github/CODEOWNERS +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/.github/ISSUE_TEMPLATE/documentation-audit.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/.github/ISSUE_TEMPLATE/implementation-cleanup.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/.github/ISSUE_TEMPLATE/quality-workflow.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/.github/ISSUE_TEMPLATE/redesign.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/.github/ISSUE_TEMPLATE/release-process.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/.github/ISSUE_TEMPLATE/repository-diagnosis.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/.github/ISSUE_TEMPLATE/test-ci-audit.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/.github/ISSUE_TEMPLATE/work-item.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/.github/dependabot.yml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/.github/workflows/benchmark-calibrate.yml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/.github/workflows/benchmark-gate.yml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/.github/workflows/dev-release.yml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/.github/workflows/image-scan.yml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/.github/workflows/nightly-e2e.yml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/.github/workflows/pr-lightweight.yml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/.github/workflows/pr-merge-gate.yml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/.github/workflows/release.yml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/.pre-commit-config.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/AGENTS.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/CONCURRENCY.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/CONTRIBUTING.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/DEVELOPMENT_PRINCIPLES.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/MANIFEST.in +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/budgets.jsonl +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/calibration/README.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/calibration/capacity-size-tight-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/calibration/probe-loss-gop-tight-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/calibration/probe-loss-nominal-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/calibration/probe-loss-tight-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/calibration/probe-loss-tight-fastdds.json +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/calibration/probe-loss-tight-zenoh.json +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/codecov.yml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/deployment-configuration.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/benchmark-ab.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/benchmark-bag-as-load.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/ci.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/ffmpeg-keyframes.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/findings/README.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/findings/cyclone-spdp-discovery-bursts.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/findings/delay-alone-no-loss.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/findings/head-of-line-irregularity.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/findings/jitter-loss-bandwidth-latency.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/findings/lighter-message-loss.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/findings/zero-loss-boundaries-18kb-20hz.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/forensics-report.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/geo-link-map.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/github-repository-settings.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/link-trace.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/owner-runbook.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/performance-bands.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/playbooks/README.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/quality-model.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/release-notes/TEMPLATE.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/release-notes/v2.1.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/release-notes/v2.2.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/release-notes/v2.3.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/release-notes/v2.4.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/release.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/rfcs/0001-expectation-driven-test-suite.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/rfcs/0003-metric-backbone.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/rfcs/0004-network-profiles.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/rfcs/0005-benchmark-genres-and-ci.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/rfcs/0006-dynamic-qos.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/rfcs/0007-regression-gate.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/rfcs/README.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/testing.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/docs/work-items.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/install.sh +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/justfile +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/media/control_center.png +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/media/echo_test.png +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/media/forensics-report-example.png +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/media/host.png +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/media/vehicle.png +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/pyproject.toml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/requirements.txt +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/rosotacom.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/run_session_in_container.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/session-configuration.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/setup.cfg +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/__init__.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/__main__.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/anonymize.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/bag_ground_truth.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/benched_set.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/benchmark.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/bundle_check.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/cli.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/deployment.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/ffmpeg_packet.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/forensics.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/geomap.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/network_profiles.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/network_shaper.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/plots.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/py.typed +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/benched-set.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/.gitignore +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/README.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/__init__.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/bags/8_drop_reference/metadata.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/deployment.example.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/profiles.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/rosotacom.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scenarios/2_native_chatter/scenario-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_a.sh +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_b.sh +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/wait_for_echo_topic.sh +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/foxglove.json +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/metadata.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/foxglove.json +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/metadata.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/sessions/10_restamp/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/sessions/11_trickle/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/sessions/12_content_integrity/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/sessions/13_link_latency/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/sessions/14_remote_assist_anonymized/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/sessions/15_remote_assist_anonymized_costmap/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/sessions/16_remote_assist_anonymized_camera/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/sessions/17_synthetic_camera_quality/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/sessions/1_heartbeat/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/sessions/1_heartbeat_status/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/sessions/2_native_chatter/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/sessions/3_comp_occ_grid/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/sessions/4_comp_occ_grid_zen/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/sessions/5_sized_payload/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/sessions/6_sized_payload_zen/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/sessions/7_latched_static/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/sessions/8_drop/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/sessions/9_throttle/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/sessions/bench_1_1_capacity/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/sessions/bench_1_2_load_sweep/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/sessions/bench_1_3_ramp/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/sessions/bench_1_4_recovery/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/examples/sessions/bench_1_5_camera/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ros2docker.json.example +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/.vscode/c_cpp_properties.json +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/.vscode/settings.json +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_easy_mode.xml.template +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_initial_peer_list.xml.template +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v2.xml.template +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v3.xml.template +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v4.xml.template +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v5.xml.template +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ota_configs/create_zenoh_json5.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ota_configs/cyclonedds_minimal.xml.template +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ota_configs/cyclonedds_tuned.xml.template +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ota_configs/fastdds_unicast.xml.template +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ota_configs/get_ota_xml.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ota_configs/utils.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ota_configs/zenoh.json5.template +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/.gitkeep +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_cpp/CMakeLists.txt +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_cpp/COLCON_IGNORE +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_cpp/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_cpp/package.xml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_cpp/src/hz_monitor.cpp +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_compressor.cpp +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_decompressor.cpp +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_msgs/CMakeLists.txt +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_msgs/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/CompressedData.msg +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/EchoHeartbeat.msg +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/OtaStamped.msg +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/SizedPayload.msg +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_msgs/package.xml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/__init__.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/base_bridge_relay.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_in.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_out.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/heartbeat_echo.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/hz_monitor.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_bandwidth_reducer.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_pixel_capper.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/lanelet_saver.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/latch_relay.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/costmap_remapper.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/marker_remapper.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/speed_test.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/tf_remapper.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/traffic_monitor.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/wifi_network_analysis_1.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_bytes.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_trace.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/local_global_frame_bridge.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/localization_map_split_reduce_saver.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/msg_transform.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pair_management.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pub_sub_pair.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/qos.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_in.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_out.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/restamp.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/sized_publisher.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency_core.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/tf_map_to_cart_saver.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_monitor.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_resolution.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/trickle.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_compressor.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_decompressor.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_unwrapper.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_wrapper.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/package.xml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/resource/com_py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/setup.cfg +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/setup.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/test/test_copyright.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/test/test_flake8.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/ros2src/com_py/test/test_pep257.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/session/content/base/session_plugin_base.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/session/content/network/up_connectivity.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/session/content/network/wifi_network_analysis_2.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/session/creation/anonymize_bag.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/session/creation/catmux_log_setup.sh +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/session/creation/create_session_yaml.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/session/creation/generate_session_files.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/session/creation/run_session.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/session/creation/run_session_in_external_terminal.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/resources/ws/session/creation/strip_ansi.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/status_eval.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/stream_stats.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/trace_profiles.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/transit.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom/video_quality.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom_dev.egg-info/dependency_links.txt +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom_dev.egg-info/entry_points.txt +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom_dev.egg-info/requires.txt +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom_dev.egg-info/top_level.txt +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/stop_session_in_container.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/terminology.md +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/contract/test_benched_set_registry.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/contract/test_findings.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/contract/test_markdown_links.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/contract/test_ota_source_bundle.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/contract/test_package_metadata.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/contract/test_packaged_resources.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/contract/test_profile_covers_generated_commands.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/contract/test_pytest_policy.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/contract/test_readme_examples.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/contract/test_security_maintenance_config.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/contract/test_session_configuration_doc.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/contract/test_workflow_contracts.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/e2e/conftest.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/e2e/test_anonymize_e2e.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/e2e/test_benchmark_ab.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/e2e/test_benchmark_capacity.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/e2e/test_benchmark_replay.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/e2e/test_parallel_smoke.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/e2e/test_smoke.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/e2e/test_timeline_stepping.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/e2e/test_video_quality_e2e.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/sessions/generate_rmw_matrix.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-local_zenoh-ros2dds-ota/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota-tuned/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/sessions/rmw_matrix/1_heartbeat_fastdds/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/sessions/rmw_matrix/1_heartbeat_zen-endpoints/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_anonymize.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_bag_ground_truth.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_benched_set.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_benchmark.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_bundle_check.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_cli.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_cli_benchmark.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_concurrency.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_deployment.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_ffmpeg_packet.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_forensics.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_geomap.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_link_bytes.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_link_trace.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_network_profiles.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_network_shaper.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_ota_xml.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_plots.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_stage_latency.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_status_eval.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_stream_stats.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_trace_profiles.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_transit.py +0 -0
- {rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/tests/unit/test_video_quality.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rosotacom-dev
|
|
3
|
-
Version: 2.5.
|
|
3
|
+
Version: 2.5.dev17
|
|
4
4
|
Summary: Host CLI for ROS OTA communication sessions.
|
|
5
5
|
Author: develNor
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -778,6 +778,26 @@ performance bands in `budgets.jsonl` via `rosotacom benchmark compare`, and
|
|
|
778
778
|
bands move only through `rosotacom benchmark ratchet` — see
|
|
779
779
|
[docs/performance-bands.md](docs/performance-bands.md) for the band schema,
|
|
780
780
|
verdicts, and the ratchet workflow (RFC 0007).
|
|
781
|
+
|
|
782
|
+
Two result sets taken in **different environments** — emulated versus a real
|
|
783
|
+
link, or shaped versus unshaped — are compared with `rosotacom benchmark delta`:
|
|
784
|
+
|
|
785
|
+
```bash
|
|
786
|
+
rosotacom benchmark delta emulated/ ota/ \
|
|
787
|
+
--label-reference emulated --label-measured ota \
|
|
788
|
+
--out delta.json --markdown delta.md
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
It pairs runs on genre, profile, RMW and session name, so a row that ran in one
|
|
792
|
+
environment and not the other is reported as unmatched rather than silently
|
|
793
|
+
dropped — "it got faster" and "it did not run" must not look the same. Every
|
|
794
|
+
report is labelled `monitor_only` and carries each side's command and profile
|
|
795
|
+
file, so a table pasted into a paper or an issue can be traced back without the
|
|
796
|
+
directory it came from.
|
|
797
|
+
|
|
798
|
+
It exits 0 whatever the numbers say, and non-zero only when the two sets share
|
|
799
|
+
no rows at all — a delta is an observation to explain, and an exit code would
|
|
800
|
+
turn "explain this" into "re-run until it is quiet".
|
|
781
801
|
For live benchmark probes, `--duration` is the shaped publish window; after that
|
|
782
802
|
rosotacom stops synthetic publishers and waits `--drain-s` seconds before
|
|
783
803
|
tearing down shaping, so delayed in-flight messages are not miscounted as loss.
|
|
@@ -733,6 +733,26 @@ performance bands in `budgets.jsonl` via `rosotacom benchmark compare`, and
|
|
|
733
733
|
bands move only through `rosotacom benchmark ratchet` — see
|
|
734
734
|
[docs/performance-bands.md](docs/performance-bands.md) for the band schema,
|
|
735
735
|
verdicts, and the ratchet workflow (RFC 0007).
|
|
736
|
+
|
|
737
|
+
Two result sets taken in **different environments** — emulated versus a real
|
|
738
|
+
link, or shaped versus unshaped — are compared with `rosotacom benchmark delta`:
|
|
739
|
+
|
|
740
|
+
```bash
|
|
741
|
+
rosotacom benchmark delta emulated/ ota/ \
|
|
742
|
+
--label-reference emulated --label-measured ota \
|
|
743
|
+
--out delta.json --markdown delta.md
|
|
744
|
+
```
|
|
745
|
+
|
|
746
|
+
It pairs runs on genre, profile, RMW and session name, so a row that ran in one
|
|
747
|
+
environment and not the other is reported as unmatched rather than silently
|
|
748
|
+
dropped — "it got faster" and "it did not run" must not look the same. Every
|
|
749
|
+
report is labelled `monitor_only` and carries each side's command and profile
|
|
750
|
+
file, so a table pasted into a paper or an issue can be traced back without the
|
|
751
|
+
directory it came from.
|
|
752
|
+
|
|
753
|
+
It exits 0 whatever the numbers say, and non-zero only when the two sets share
|
|
754
|
+
no rows at all — a delta is an observation to explain, and an exit code would
|
|
755
|
+
turn "explain this" into "re-run until it is quiet".
|
|
736
756
|
For live benchmark probes, `--duration` is the shaped publish window; after that
|
|
737
757
|
rosotacom stops synthetic publishers and waits `--drain-s` seconds before
|
|
738
758
|
tearing down shaping, so delayed in-flight messages are not miscounted as loss.
|
|
@@ -290,6 +290,24 @@ once `optional` are all fixed:
|
|
|
290
290
|
end-to-end by remote_assist (`/tf` local→global, `/move_base_free/goal`
|
|
291
291
|
global→local, both delivered to `native_in`); ffmpeg video is n/a -- there is no
|
|
292
292
|
video/ffmpeg feature anywhere in the codebase, so there is nothing to test.
|
|
293
|
+
- [x] The third latched "not delivering" state is named (issue #231, Option A).
|
|
294
|
+
A latched topic that has a publisher but holds no value now reads distinctly
|
|
295
|
+
("has a publisher but holds no retained latched value") from "no publisher"
|
|
296
|
+
and "stopped", so a broken/empty latch is no longer indistinguishable from a
|
|
297
|
+
silent producer (`classify_stage` carries a `latched` flag; `_stage_diagnosis`
|
|
298
|
+
names it). The transient_local read Option A asks for was **not** forced per
|
|
299
|
+
declared role: a first attempt did (`collect_latched_stage_topics` ->
|
|
300
|
+
forced QoS) and broke `e2e-remote-assist`, because a latched topic's *native
|
|
301
|
+
source* stage is published VOLATILE (the ROS 1 bridge offers no durability)
|
|
302
|
+
and a TRANSIENT_LOCAL reader is incompatible with a VOLATILE writer -- it
|
|
303
|
+
received nothing and reported a false STALLED. The correct, per-stage form
|
|
304
|
+
is the existing publisher-matched `_observation_qos`, which already requests
|
|
305
|
+
transient_local on the delivered stages that offer it (com_in/app_in); that
|
|
306
|
+
matched subscription is observable on the graph (it raises the subscriber
|
|
307
|
+
count). Validation:
|
|
308
|
+
`tests/unit/test_status_overview.py::test_observation_qos_does_not_force_transient_local_for_latched_roles`,
|
|
309
|
+
`::test_stage_diagnosis_names_the_three_latched_states`,
|
|
310
|
+
`::test_classify_stage_marks_latched_role`.
|
|
293
311
|
|
|
294
312
|
### Replay-only (ground-truth) assertions — from "Live vs replay" above
|
|
295
313
|
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
"""Compare two benchmark result sets taken in different environments.
|
|
2
|
+
|
|
3
|
+
The local emulated lanes encode most of the performance truth cheaply and
|
|
4
|
+
deterministically. What they cannot show is **which effects exist only on the
|
|
5
|
+
real link** — cellular variability, VPN/MTU quirks, radio behaviour, real
|
|
6
|
+
cross-traffic — and which are emulation artifacts. Real links stay monitor-only
|
|
7
|
+
by the determinism rule, so the missing piece was never another measurement: it
|
|
8
|
+
was the *comparison* between two sets of the same rows.
|
|
9
|
+
|
|
10
|
+
This is that comparison. It reads two directories (or lists) of `result.json`
|
|
11
|
+
runs, pairs them by what makes a row a row, and reports per-row, per-metric
|
|
12
|
+
deltas as JSON plus a short Markdown summary.
|
|
13
|
+
|
|
14
|
+
Three properties are deliberate, because it is easy to produce numbers that lie:
|
|
15
|
+
|
|
16
|
+
* **Pairing is explicit and refuses to guess.** Rows are matched on genre,
|
|
17
|
+
profile, RMW and session name. A row present on one side only is reported as
|
|
18
|
+
unmatched rather than silently dropped, because "it got faster" and "it did
|
|
19
|
+
not run" must not look the same.
|
|
20
|
+
* **Every report says it is correlational.** The two sets differ in the
|
|
21
|
+
environment *and* in everything the environment drags along; a delta is an
|
|
22
|
+
observation, never a verdict. `monitor_only: true` is in the JSON and the
|
|
23
|
+
first line of the Markdown.
|
|
24
|
+
* **It is self-describing.** Each side carries its rosotacom SHA, profile file,
|
|
25
|
+
and the command that produced it, so a report pasted into a paper or an issue
|
|
26
|
+
can be traced back without the directory it came from.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
from __future__ import annotations
|
|
30
|
+
|
|
31
|
+
import json
|
|
32
|
+
from dataclasses import dataclass, field
|
|
33
|
+
from pathlib import Path
|
|
34
|
+
from typing import Any
|
|
35
|
+
|
|
36
|
+
SCHEMA_VERSION = 1
|
|
37
|
+
|
|
38
|
+
#: Numeric leaves under `result` that are worth comparing across environments.
|
|
39
|
+
#: A deny-list rather than an allow-list would drag in ids and counts whose
|
|
40
|
+
#: "delta" means nothing.
|
|
41
|
+
INTERESTING_SUFFIXES = (
|
|
42
|
+
"capacity",
|
|
43
|
+
"latency_ms",
|
|
44
|
+
"latency_p95_ms",
|
|
45
|
+
"loss_pct",
|
|
46
|
+
"rate_hz",
|
|
47
|
+
"mean_payload_bytes",
|
|
48
|
+
"offered_bandwidth_bps",
|
|
49
|
+
"jitter_ms",
|
|
50
|
+
"throughput_bps",
|
|
51
|
+
"delivered",
|
|
52
|
+
"received",
|
|
53
|
+
"published",
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@dataclass(frozen=True)
|
|
58
|
+
class RowKey:
|
|
59
|
+
"""What makes two runs the same row in different environments."""
|
|
60
|
+
|
|
61
|
+
genre: str
|
|
62
|
+
profile: str
|
|
63
|
+
rmw: str
|
|
64
|
+
session: str
|
|
65
|
+
|
|
66
|
+
def label(self) -> str:
|
|
67
|
+
return f"{self.genre}/{self.profile}/{self.rmw}/{self.session}"
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@dataclass
|
|
71
|
+
class Run:
|
|
72
|
+
key: RowKey
|
|
73
|
+
metrics: dict[str, float]
|
|
74
|
+
provenance: dict[str, Any] = field(default_factory=dict)
|
|
75
|
+
path: str = ""
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _flatten_numbers(value: Any, prefix: str = "") -> dict[str, float]:
|
|
79
|
+
out: dict[str, float] = {}
|
|
80
|
+
if isinstance(value, dict):
|
|
81
|
+
for key, child in value.items():
|
|
82
|
+
out.update(_flatten_numbers(child, f"{prefix}.{key}" if prefix else str(key)))
|
|
83
|
+
elif isinstance(value, bool):
|
|
84
|
+
# Explicitly before the numeric branch: bool is an int in Python, and a
|
|
85
|
+
# "delta" between True and False is a category error dressed as -1.
|
|
86
|
+
return {}
|
|
87
|
+
elif isinstance(value, (int, float)):
|
|
88
|
+
return {prefix: float(value)}
|
|
89
|
+
return out
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def interesting_metrics(result: Any) -> dict[str, float]:
|
|
93
|
+
numbers = _flatten_numbers(result)
|
|
94
|
+
return {
|
|
95
|
+
name: value
|
|
96
|
+
for name, value in numbers.items()
|
|
97
|
+
if any(name == suffix or name.endswith("." + suffix) for suffix in INTERESTING_SUFFIXES)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def load_run(path: Path) -> Run | None:
|
|
102
|
+
"""Read one `result.json`. Returns None when it is not one."""
|
|
103
|
+
try:
|
|
104
|
+
data = json.loads(path.read_text(encoding="utf-8"))
|
|
105
|
+
except (OSError, json.JSONDecodeError):
|
|
106
|
+
return None
|
|
107
|
+
if not isinstance(data, dict) or "genre" not in data:
|
|
108
|
+
return None
|
|
109
|
+
|
|
110
|
+
context = data.get("context") or {}
|
|
111
|
+
session = context.get("session") or {}
|
|
112
|
+
profile = context.get("profile") or {}
|
|
113
|
+
rmw = context.get("rmw") or {}
|
|
114
|
+
|
|
115
|
+
key = RowKey(
|
|
116
|
+
genre=str(data.get("genre") or ""),
|
|
117
|
+
profile=str(profile.get("name") or (data.get("configuration") or {}).get("profile") or ""),
|
|
118
|
+
rmw=str(rmw.get("requested") or session.get("rmw") or ""),
|
|
119
|
+
session=str(session.get("name") or ""),
|
|
120
|
+
)
|
|
121
|
+
return Run(
|
|
122
|
+
key=key,
|
|
123
|
+
metrics=interesting_metrics(data.get("result")),
|
|
124
|
+
provenance={
|
|
125
|
+
"created_at": data.get("created_at"),
|
|
126
|
+
"command": context.get("command"),
|
|
127
|
+
"profiles_file": (context.get("paths") or {}).get("profiles_file"),
|
|
128
|
+
"rosotacom_sha": (context.get("versions") or {}).get("rosotacom_sha"),
|
|
129
|
+
"verdict": (data.get("verdict") or {}).get("status"),
|
|
130
|
+
},
|
|
131
|
+
path=str(path),
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def collect(paths: list[Path]) -> dict[RowKey, Run]:
|
|
136
|
+
"""Every `result.json` under the given files or directories, by row."""
|
|
137
|
+
found: dict[RowKey, Run] = {}
|
|
138
|
+
for path in paths:
|
|
139
|
+
candidates = [path] if path.is_file() else sorted(path.rglob("result.json"))
|
|
140
|
+
for candidate in candidates:
|
|
141
|
+
run = load_run(candidate)
|
|
142
|
+
if run is None:
|
|
143
|
+
continue
|
|
144
|
+
# Last one wins, and it is the newest by directory ordering — a
|
|
145
|
+
# re-run of a row supersedes it rather than doubling it.
|
|
146
|
+
found[run.key] = run
|
|
147
|
+
return found
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def compare(
|
|
151
|
+
reference: dict[RowKey, Run],
|
|
152
|
+
measured: dict[RowKey, Run],
|
|
153
|
+
*,
|
|
154
|
+
label_reference: str,
|
|
155
|
+
label_measured: str,
|
|
156
|
+
) -> dict[str, Any]:
|
|
157
|
+
rows: list[dict[str, Any]] = []
|
|
158
|
+
for key in sorted(set(reference) & set(measured), key=lambda k: k.label()):
|
|
159
|
+
a, b = reference[key], measured[key]
|
|
160
|
+
metrics = []
|
|
161
|
+
for name in sorted(set(a.metrics) | set(b.metrics)):
|
|
162
|
+
left = a.metrics.get(name)
|
|
163
|
+
right = b.metrics.get(name)
|
|
164
|
+
if left is None or right is None:
|
|
165
|
+
metrics.append(
|
|
166
|
+
{
|
|
167
|
+
"metric": name,
|
|
168
|
+
label_reference: left,
|
|
169
|
+
label_measured: right,
|
|
170
|
+
"delta": None,
|
|
171
|
+
"relative": None,
|
|
172
|
+
"note": "present on one side only",
|
|
173
|
+
}
|
|
174
|
+
)
|
|
175
|
+
continue
|
|
176
|
+
delta = right - left
|
|
177
|
+
metrics.append(
|
|
178
|
+
{
|
|
179
|
+
"metric": name,
|
|
180
|
+
label_reference: left,
|
|
181
|
+
label_measured: right,
|
|
182
|
+
"delta": delta,
|
|
183
|
+
"relative": (delta / left) if left else None,
|
|
184
|
+
}
|
|
185
|
+
)
|
|
186
|
+
rows.append(
|
|
187
|
+
{
|
|
188
|
+
"row": key.label(),
|
|
189
|
+
"genre": key.genre,
|
|
190
|
+
"profile": key.profile,
|
|
191
|
+
"rmw": key.rmw,
|
|
192
|
+
"session": key.session,
|
|
193
|
+
"metrics": metrics,
|
|
194
|
+
"provenance": {label_reference: a.provenance, label_measured: b.provenance},
|
|
195
|
+
}
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
return {
|
|
199
|
+
"schema_version": SCHEMA_VERSION,
|
|
200
|
+
# First key, and repeated in the Markdown: a delta between two
|
|
201
|
+
# environments is correlational. The two sets differ in the environment
|
|
202
|
+
# and in everything it drags along.
|
|
203
|
+
"monitor_only": True,
|
|
204
|
+
"labels": {"reference": label_reference, "measured": label_measured},
|
|
205
|
+
"rows": rows,
|
|
206
|
+
"unmatched": {
|
|
207
|
+
label_reference: sorted(k.label() for k in set(reference) - set(measured)),
|
|
208
|
+
label_measured: sorted(k.label() for k in set(measured) - set(reference)),
|
|
209
|
+
},
|
|
210
|
+
"counts": {
|
|
211
|
+
"matched": len(rows),
|
|
212
|
+
f"only_{label_reference}": len(set(reference) - set(measured)),
|
|
213
|
+
f"only_{label_measured}": len(set(measured) - set(reference)),
|
|
214
|
+
},
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def render_markdown(report: dict[str, Any]) -> str:
|
|
219
|
+
ref = report["labels"]["reference"]
|
|
220
|
+
mea = report["labels"]["measured"]
|
|
221
|
+
lines = [
|
|
222
|
+
f"# Benchmark delta: {ref} vs {mea}",
|
|
223
|
+
"",
|
|
224
|
+
"**Monitor-only and correlational.** The two sets differ in the environment "
|
|
225
|
+
"and in everything the environment drags along; a delta here is an "
|
|
226
|
+
"observation to explain, never a verdict and never a gate.",
|
|
227
|
+
"",
|
|
228
|
+
f"{report['counts']['matched']} row(s) matched, "
|
|
229
|
+
f"{report['counts'][f'only_{ref}']} only in {ref}, "
|
|
230
|
+
f"{report['counts'][f'only_{mea}']} only in {mea}.",
|
|
231
|
+
"",
|
|
232
|
+
]
|
|
233
|
+
|
|
234
|
+
for row in report["rows"]:
|
|
235
|
+
lines.append(f"## `{row['row']}`")
|
|
236
|
+
lines.append("")
|
|
237
|
+
lines.append(f"| metric | {ref} | {mea} | Δ | Δ% |")
|
|
238
|
+
lines.append("|---|---:|---:|---:|---:|")
|
|
239
|
+
for metric in row["metrics"]:
|
|
240
|
+
left = metric[ref]
|
|
241
|
+
right = metric[mea]
|
|
242
|
+
delta = metric["delta"]
|
|
243
|
+
relative = metric["relative"]
|
|
244
|
+
lines.append(
|
|
245
|
+
f"| `{metric['metric']}` | {_fmt(left)} | {_fmt(right)} | {_fmt(delta, sign=True)} | {_pct(relative)} |"
|
|
246
|
+
)
|
|
247
|
+
lines.append("")
|
|
248
|
+
for side in (ref, mea):
|
|
249
|
+
provenance = row["provenance"][side]
|
|
250
|
+
command = provenance.get("command") or "-"
|
|
251
|
+
lines.append(f"- {side}: `{command}`")
|
|
252
|
+
lines.append("")
|
|
253
|
+
|
|
254
|
+
for side in (ref, mea):
|
|
255
|
+
missing = report["unmatched"][side]
|
|
256
|
+
if missing:
|
|
257
|
+
lines.append(f"## Only in {side}")
|
|
258
|
+
lines.append("")
|
|
259
|
+
lines.extend(f"- `{name}`" for name in missing)
|
|
260
|
+
lines.append("")
|
|
261
|
+
lines.append(
|
|
262
|
+
"A row on one side only is not a delta. It ran in one environment "
|
|
263
|
+
"and not the other, and treating that as an improvement is the "
|
|
264
|
+
"commonest way this kind of report lies."
|
|
265
|
+
)
|
|
266
|
+
lines.append("")
|
|
267
|
+
|
|
268
|
+
return "\n".join(lines)
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def _fmt(value: float | None, *, sign: bool = False) -> str:
|
|
272
|
+
if value is None:
|
|
273
|
+
return "—"
|
|
274
|
+
formatted = f"{value:+.4g}" if sign else f"{value:.4g}"
|
|
275
|
+
return formatted
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def _pct(value: float | None) -> str:
|
|
279
|
+
return "—" if value is None else f"{value * 100:+.1f}%"
|
|
@@ -4843,6 +4843,56 @@ def _parse_values(raw: str) -> list[float]:
|
|
|
4843
4843
|
# --------------------------------------------------------------------------- #
|
|
4844
4844
|
|
|
4845
4845
|
|
|
4846
|
+
def benchmark_delta(args: argparse.Namespace) -> int:
|
|
4847
|
+
"""`rosotacom benchmark delta` — the cross-environment comparison.
|
|
4848
|
+
|
|
4849
|
+
Exits 0 whenever the comparison itself succeeded, including when rows are
|
|
4850
|
+
unmatched or every metric moved. This is monitor-only by construction
|
|
4851
|
+
(`benchmark_delta.compare` puts `monitor_only: true` first in the report):
|
|
4852
|
+
the number is the deliverable, and an exit code would turn "explain this"
|
|
4853
|
+
into "re-run until it is quiet".
|
|
4854
|
+
|
|
4855
|
+
It exits non-zero for the one thing that is a failure — no rows in common,
|
|
4856
|
+
which means the two sides were not the same rows and the report would be
|
|
4857
|
+
an empty table with a confident heading.
|
|
4858
|
+
"""
|
|
4859
|
+
from . import benchmark_delta as delta_module
|
|
4860
|
+
|
|
4861
|
+
reference = delta_module.collect([Path(args.reference)])
|
|
4862
|
+
measured = delta_module.collect([Path(args.measured)])
|
|
4863
|
+
report = delta_module.compare(
|
|
4864
|
+
reference,
|
|
4865
|
+
measured,
|
|
4866
|
+
label_reference=args.label_reference,
|
|
4867
|
+
label_measured=args.label_measured,
|
|
4868
|
+
)
|
|
4869
|
+
|
|
4870
|
+
if args.out:
|
|
4871
|
+
Path(args.out).write_text(json.dumps(report, indent=2) + "\n", encoding="utf-8")
|
|
4872
|
+
markdown = delta_module.render_markdown(report)
|
|
4873
|
+
if args.markdown:
|
|
4874
|
+
Path(args.markdown).write_text(markdown, encoding="utf-8")
|
|
4875
|
+
else:
|
|
4876
|
+
print(markdown)
|
|
4877
|
+
|
|
4878
|
+
counts = report["counts"]
|
|
4879
|
+
print(
|
|
4880
|
+
f"BENCHMARK DELTA: {counts['matched']} row(s) matched, "
|
|
4881
|
+
f"{counts[f'only_{args.label_reference}']} only in {args.label_reference}, "
|
|
4882
|
+
f"{counts[f'only_{args.label_measured}']} only in {args.label_measured} "
|
|
4883
|
+
"(monitor-only)"
|
|
4884
|
+
)
|
|
4885
|
+
if not report["rows"]:
|
|
4886
|
+
print(
|
|
4887
|
+
"rosotacom: error: the two sets share no rows, so there is nothing to "
|
|
4888
|
+
"compare. Check that both sides ran the same registry rows under the "
|
|
4889
|
+
"same profile and RMW.",
|
|
4890
|
+
file=sys.stderr,
|
|
4891
|
+
)
|
|
4892
|
+
return 1
|
|
4893
|
+
return 0
|
|
4894
|
+
|
|
4895
|
+
|
|
4846
4896
|
def _add_benchmark_common_args(parser: argparse.ArgumentParser, *, ota_benchmark: bool = False) -> None:
|
|
4847
4897
|
from .cli import (
|
|
4848
4898
|
OTA_DEFAULT_SUDO_MODE,
|
|
@@ -8068,6 +8118,18 @@ def _register_benchmark_band_parsers(benchmark_subparsers: Any) -> None:
|
|
|
8068
8118
|
)
|
|
8069
8119
|
compare_parser.set_defaults(func=benchmark_compare)
|
|
8070
8120
|
|
|
8121
|
+
delta_parser = benchmark_subparsers.add_parser(
|
|
8122
|
+
"delta",
|
|
8123
|
+
help="Compare two result.json sets taken in different environments (monitor-only).",
|
|
8124
|
+
)
|
|
8125
|
+
delta_parser.add_argument("reference", help="Directory or result.json for the reference environment.")
|
|
8126
|
+
delta_parser.add_argument("measured", help="Directory or result.json for the measured environment.")
|
|
8127
|
+
delta_parser.add_argument("--label-reference", default="emulated", help="Name for the reference side.")
|
|
8128
|
+
delta_parser.add_argument("--label-measured", default="ota", help="Name for the measured side.")
|
|
8129
|
+
delta_parser.add_argument("--out", default=None, help="Write the JSON report here.")
|
|
8130
|
+
delta_parser.add_argument("--markdown", default=None, help="Write the Markdown summary here.")
|
|
8131
|
+
delta_parser.set_defaults(func=benchmark_delta)
|
|
8132
|
+
|
|
8071
8133
|
ratchet_parser = benchmark_subparsers.add_parser(
|
|
8072
8134
|
"ratchet",
|
|
8073
8135
|
help="Rewrite committed bands from result.json run(s) — bands are never hand-edited.",
|
|
@@ -161,6 +161,18 @@ class StageObserver(Node):
|
|
|
161
161
|
value. Adopting the publisher's offered durability/reliability (request ==
|
|
162
162
|
offered) is always compatible and replays the durable history. Falls back
|
|
163
163
|
to best-effort/volatile when no publisher QoS is available.
|
|
164
|
+
|
|
165
|
+
Adopting the *publisher's* offered durability (rather than forcing
|
|
166
|
+
TRANSIENT_LOCAL for every stage of a declared latched topic) is
|
|
167
|
+
deliberate: a latched topic's own source stage -- the vehicle's native
|
|
168
|
+
publish -- is VOLATILE (the ROS 1 bridge offers no durability), and a
|
|
169
|
+
TRANSIENT_LOCAL reader is incompatible with a VOLATILE writer and would
|
|
170
|
+
receive nothing, turning a healthy native stage into a false STALLED.
|
|
171
|
+
Only the delivered stages (com_in/app_in) offer TRANSIENT_LOCAL, and the
|
|
172
|
+
per-publisher match already requests it there -- which is the
|
|
173
|
+
"subscribe transient_local on latched roles" of issue #231, made
|
|
174
|
+
per-stage-correct. The matched subscription is observable on the graph
|
|
175
|
+
(it raises the topic's subscriber count).
|
|
164
176
|
"""
|
|
165
177
|
durability = DurabilityPolicy.VOLATILE
|
|
166
178
|
reliability = ReliabilityPolicy.BEST_EFFORT
|
|
@@ -497,6 +497,7 @@ class StatusAggregator:
|
|
|
497
497
|
"quality_reason": None,
|
|
498
498
|
"observation": "graph" if obs is not None and obs.graph_only else "payload",
|
|
499
499
|
"inferred_from": None,
|
|
500
|
+
"latched": str((expect or {}).get("mode", "")).strip().lower() == "latched",
|
|
500
501
|
}
|
|
501
502
|
if obs is None:
|
|
502
503
|
return result
|
|
@@ -744,6 +745,16 @@ class StatusAggregator:
|
|
|
744
745
|
f"{topic} has a publisher; payload is intentionally not "
|
|
745
746
|
"subscribed and adjacent local flow is not observed"
|
|
746
747
|
)
|
|
748
|
+
if stage_result.get("latched"):
|
|
749
|
+
# The third state issue #231 names: distinct from "no publisher"
|
|
750
|
+
# (ABSENT) and "stopped" (STALE). The observation subscribes
|
|
751
|
+
# transient_local for latched roles, so a value published before
|
|
752
|
+
# it matched would have been replayed; holding none means nothing
|
|
753
|
+
# was ever latched (empty/broken latch), not a late-joining reader.
|
|
754
|
+
return (
|
|
755
|
+
f"{topic} has a publisher but holds no retained latched "
|
|
756
|
+
"value (nothing was latched, or the latch was lost)"
|
|
757
|
+
)
|
|
747
758
|
return f"{topic} has a publisher but no messages observed yet"
|
|
748
759
|
if st == STALE:
|
|
749
760
|
return f"{topic} stopped receiving messages"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rosotacom-dev
|
|
3
|
-
Version: 2.5.
|
|
3
|
+
Version: 2.5.dev17
|
|
4
4
|
Summary: Host CLI for ROS OTA communication sessions.
|
|
5
5
|
Author: develNor
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -778,6 +778,26 @@ performance bands in `budgets.jsonl` via `rosotacom benchmark compare`, and
|
|
|
778
778
|
bands move only through `rosotacom benchmark ratchet` — see
|
|
779
779
|
[docs/performance-bands.md](docs/performance-bands.md) for the band schema,
|
|
780
780
|
verdicts, and the ratchet workflow (RFC 0007).
|
|
781
|
+
|
|
782
|
+
Two result sets taken in **different environments** — emulated versus a real
|
|
783
|
+
link, or shaped versus unshaped — are compared with `rosotacom benchmark delta`:
|
|
784
|
+
|
|
785
|
+
```bash
|
|
786
|
+
rosotacom benchmark delta emulated/ ota/ \
|
|
787
|
+
--label-reference emulated --label-measured ota \
|
|
788
|
+
--out delta.json --markdown delta.md
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
It pairs runs on genre, profile, RMW and session name, so a row that ran in one
|
|
792
|
+
environment and not the other is reported as unmatched rather than silently
|
|
793
|
+
dropped — "it got faster" and "it did not run" must not look the same. Every
|
|
794
|
+
report is labelled `monitor_only` and carries each side's command and profile
|
|
795
|
+
file, so a table pasted into a paper or an issue can be traced back without the
|
|
796
|
+
directory it came from.
|
|
797
|
+
|
|
798
|
+
It exits 0 whatever the numbers say, and non-zero only when the two sets share
|
|
799
|
+
no rows at all — a delta is an observation to explain, and an exit code would
|
|
800
|
+
turn "explain this" into "re-run until it is quiet".
|
|
781
801
|
For live benchmark probes, `--duration` is the shaped publish window; after that
|
|
782
802
|
rosotacom stops synthetic publishers and waits `--drain-s` seconds before
|
|
783
803
|
tearing down shaping, so delayed in-flight messages are not miscounted as loss.
|
|
@@ -92,6 +92,7 @@ src/rosotacom/anonymize.py
|
|
|
92
92
|
src/rosotacom/bag_ground_truth.py
|
|
93
93
|
src/rosotacom/benched_set.py
|
|
94
94
|
src/rosotacom/benchmark.py
|
|
95
|
+
src/rosotacom/benchmark_delta.py
|
|
95
96
|
src/rosotacom/bundle_check.py
|
|
96
97
|
src/rosotacom/cli.py
|
|
97
98
|
src/rosotacom/cli_benchmark.py
|
|
@@ -314,6 +315,7 @@ tests/unit/test_anonymize.py
|
|
|
314
315
|
tests/unit/test_bag_ground_truth.py
|
|
315
316
|
tests/unit/test_benched_set.py
|
|
316
317
|
tests/unit/test_benchmark.py
|
|
318
|
+
tests/unit/test_benchmark_delta.py
|
|
317
319
|
tests/unit/test_bundle_check.py
|
|
318
320
|
tests/unit/test_cli.py
|
|
319
321
|
tests/unit/test_cli_benchmark.py
|
{rosotacom_dev-2.5.dev15 → rosotacom_dev-2.5.dev17}/src/rosotacom_dev.egg-info/scm_file_list.json
RENAMED
|
@@ -93,6 +93,7 @@
|
|
|
93
93
|
"src/rosotacom/bag_ground_truth.py",
|
|
94
94
|
"src/rosotacom/benched_set.py",
|
|
95
95
|
"src/rosotacom/benchmark.py",
|
|
96
|
+
"src/rosotacom/benchmark_delta.py",
|
|
96
97
|
"src/rosotacom/bundle_check.py",
|
|
97
98
|
"src/rosotacom/cli.py",
|
|
98
99
|
"src/rosotacom/cli_benchmark.py",
|
|
@@ -309,6 +310,7 @@
|
|
|
309
310
|
"tests/unit/test_bag_ground_truth.py",
|
|
310
311
|
"tests/unit/test_benched_set.py",
|
|
311
312
|
"tests/unit/test_benchmark.py",
|
|
313
|
+
"tests/unit/test_benchmark_delta.py",
|
|
312
314
|
"tests/unit/test_bundle_check.py",
|
|
313
315
|
"tests/unit/test_cli.py",
|
|
314
316
|
"tests/unit/test_cli_benchmark.py",
|