rosotacom-dev 2.5.dev51__tar.gz → 2.5.dev53__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.dev51 → rosotacom_dev-2.5.dev53}/.github/workflows/nightly-e2e.yml +1 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/PKG-INFO +26 -1
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/README.md +25 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/deployment-configuration.md +23 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/findings/README.md +3 -0
- rosotacom_dev-2.5.dev53/docs/findings/fastdds-datagram-cap-drops-large-samples.md +89 -0
- rosotacom_dev-2.5.dev53/docs/findings/graph-derived-types-block-a-non-graph-transport.md +79 -0
- rosotacom_dev-2.5.dev53/docs/findings/sender-rows-make-a-dead-link-look-loss-free.md +59 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/session-configuration.md +87 -3
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/benchmark.py +12 -2
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/cli.py +182 -42
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/cli_benchmark.py +80 -28
- rosotacom_dev-2.5.dev53/src/rosotacom/network_preflight.py +134 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/4_comp_occ_grid_zen/session-definition.yaml +3 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/6_sized_payload_zen/session-definition.yaml +3 -0
- rosotacom_dev-2.5.dev53/src/rosotacom/resources/ws/ota_configs/fastdds_easy_mode.xml.template +49 -0
- rosotacom_dev-2.5.dev53/src/rosotacom/resources/ws/ota_configs/fastdds_tuned.xml.template +154 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/base_bridge_relay.py +9 -2
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pub_sub_pair.py +19 -7
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/qos.py +24 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/session/content/base/session_plugin_base.yaml +21 -3
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/session/creation/generate_session_files.py +84 -7
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/transit.py +20 -2
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom_dev.egg-info/PKG-INFO +26 -1
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom_dev.egg-info/SOURCES.txt +10 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom_dev.egg-info/scm_file_list.json +10 -0
- rosotacom_dev-2.5.dev53/src/rosotacom_dev.egg-info/scm_version.json +8 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_markdown_links.py +15 -1
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_packaged_resources.py +2 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_security_maintenance_config.py +4 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/e2e/conftest.py +1 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/sessions/generate_rmw_matrix.py +7 -0
- rosotacom_dev-2.5.dev53/tests/sessions/rmw_matrix/1_heartbeat_fastdds-default/session-definition.yaml +22 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_benchmark.py +15 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_cli.py +19 -2
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_cli_benchmark.py +76 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_concurrency.py +25 -1
- rosotacom_dev-2.5.dev53/tests/unit/test_network_preflight.py +173 -0
- rosotacom_dev-2.5.dev53/tests/unit/test_ota_link_configs.py +288 -0
- rosotacom_dev-2.5.dev53/tests/unit/test_pub_sub_pair_types.py +144 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_relay_optional_parameters.py +1 -1
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_transit.py +26 -2
- rosotacom_dev-2.5.dev51/src/rosotacom_dev.egg-info/scm_version.json +0 -8
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.devcontainer/devcontainer.json.template +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.devcontainer/re_generate_devcontainer_json.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/CODEOWNERS +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/ISSUE_TEMPLATE/documentation-audit.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/ISSUE_TEMPLATE/implementation-cleanup.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/ISSUE_TEMPLATE/quality-workflow.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/ISSUE_TEMPLATE/redesign.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/ISSUE_TEMPLATE/release-process.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/ISSUE_TEMPLATE/repository-diagnosis.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/ISSUE_TEMPLATE/test-ci-audit.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/ISSUE_TEMPLATE/work-item.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/actions/setup-just/action.yml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/dependabot.yml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/workflows/benchmark-calibrate.yml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/workflows/benchmark-gate.yml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/workflows/dev-release.yml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/workflows/image-scan.yml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/workflows/pr-lightweight.yml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/workflows/pr-merge-gate.yml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/workflows/release.yml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.pre-commit-config.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/AGENTS.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/CONCURRENCY.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/CONTRIBUTING.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/DEVELOPMENT_PRINCIPLES.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/MANIFEST.in +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/budgets.jsonl +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/calibration/README.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/calibration/capacity-size-tight-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/calibration/probe-loss-gop-tight-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/calibration/probe-loss-nominal-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/calibration/probe-loss-tight-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/calibration/probe-loss-tight-fastdds.json +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/calibration/probe-loss-tight-zenoh.json +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/codecov.yml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/benchmark-ab.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/benchmark-bag-as-load.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/ci.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/ffmpeg-keyframes.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/findings/cyclone-spdp-discovery-bursts.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/findings/delay-alone-no-loss.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/findings/head-of-line-irregularity.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/findings/jitter-loss-bandwidth-latency.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/findings/keyframe-loss-kills-the-next-deltas.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/findings/lighter-message-loss.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/findings/oversubscription-queues-not-losses.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/findings/reorder-becomes-reader-loss.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/findings/repro/decode_chain_repro.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/findings/repro/reorder_drop_repro.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/findings/zero-loss-boundaries-18kb-20hz.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/forensics-report.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/geo-link-map.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/github-repository-settings.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/link-bandwidth.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/link-trace.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/owner-runbook.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/performance-bands.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/playbooks/README.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/quality-model.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/release-notes/TEMPLATE.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/release-notes/v2.1.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/release-notes/v2.2.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/release-notes/v2.3.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/release-notes/v2.4.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/release.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/rfcs/0001-expectation-driven-test-suite.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/rfcs/0002-expectation-concepts.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/rfcs/0003-metric-backbone.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/rfcs/0004-network-profiles.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/rfcs/0005-benchmark-genres-and-ci.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/rfcs/0006-dynamic-qos.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/rfcs/0007-regression-gate.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/rfcs/README.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/testing.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/work-items.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/install.sh +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/justfile +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/media/control_center.png +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/media/echo_test.png +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/media/forensics-report-example.png +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/media/host.png +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/media/vehicle.png +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/pyproject.toml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/requirements.txt +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/rosotacom.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/setup.cfg +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/__init__.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/__main__.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/anonymize.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/bag_ground_truth.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/benched_set.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/benchmark_delta.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/bundle_check.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/deployment.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/ffmpeg_packet.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/forensics.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/geomap.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/image_cache.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/netem_dist.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/network_profiles.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/network_shaper.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/plots.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/py.typed +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/benched-set.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/.gitignore +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/README.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/__init__.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/bags/8_drop_reference/metadata.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/deployment.example.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/dist/field-20260817.dist +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/profiles.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/rosotacom.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scenarios/2_native_chatter/scenario-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_a.sh +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_b.sh +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/wait_for_echo_topic.sh +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/foxglove.json +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/metadata.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/foxglove.json +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/metadata.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/10_restamp/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/11_trickle/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/12_content_integrity/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/13_link_latency/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/14_remote_assist_anonymized/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/15_remote_assist_anonymized_costmap/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/16_remote_assist_anonymized_camera/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/17_synthetic_camera_quality/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/1_heartbeat/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/1_heartbeat_status/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/2_native_chatter/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/3_comp_occ_grid/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/5_sized_payload/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/7_latched_static/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/8_drop/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/9_throttle/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/bench_1_1_capacity/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/bench_1_2_load_sweep/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/bench_1_3_ramp/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/bench_1_4_recovery/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/bench_1_5_camera/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ros2docker.json.example +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/.vscode/c_cpp_properties.json +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/.vscode/settings.json +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_easy_mode.xml.template +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_initial_peer_list.xml.template +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v2.xml.template +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v3.xml.template +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v4.xml.template +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v5.xml.template +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/create_zenoh_json5.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/cyclonedds_local_participants.xml.template +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/cyclonedds_minimal.xml.template +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/cyclonedds_tuned.xml.template +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/fastdds_unicast.xml.template +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/get_ota_xml.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/utils.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/zenoh.json5.template +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/.gitkeep +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_cpp/CMakeLists.txt +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_cpp/COLCON_IGNORE +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_cpp/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_cpp/package.xml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_cpp/src/hz_monitor.cpp +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_compressor.cpp +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_decompressor.cpp +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_msgs/CMakeLists.txt +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_msgs/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/CompressedData.msg +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/EchoHeartbeat.msg +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/OtaStamped.msg +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/SizedPayload.msg +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_msgs/package.xml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/__init__.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_in.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_out.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/ffmpeg_flags.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/heartbeat_echo.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/hz_monitor.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_bandwidth_reducer.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_pixel_capper.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/lanelet_saver.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/latch_relay.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/costmap_remapper.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/marker_remapper.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/speed_test.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/tf_remapper.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/traffic_monitor.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/wifi_network_analysis_1.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_bytes.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_trace.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/local_global_frame_bridge.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/localization_map_split_reduce_saver.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/msg_transform.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pair_management.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/playout_pacer.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/playout_pacer_core.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_in.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_out.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/restamp.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/sized_publisher.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency_core.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview_core.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/tf_map_to_cart_saver.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_monitor.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_resolution.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/trickle.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_compressor.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_decompressor.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_unwrapper.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_wrapper.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/package.xml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/resource/com_py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/setup.cfg +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/setup.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/test/test_copyright.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/test/test_flake8.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/test/test_pep257.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/session/content/network/up_connectivity.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/session/content/network/wifi_network_analysis_2.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/session/creation/anonymize_bag.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/session/creation/catmux_log_setup.sh +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/session/creation/create_session_yaml.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/session/creation/run_session.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/session/creation/run_session_in_external_terminal.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/session/creation/strip_ansi.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/status_eval.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/stream_stats.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/trace_profiles.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/video_quality.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom_dev.egg-info/dependency_links.txt +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom_dev.egg-info/entry_points.txt +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom_dev.egg-info/requires.txt +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom_dev.egg-info/top_level.txt +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/terminology.md +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_benched_set_registry.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_findings.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_ota_source_bundle.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_package_metadata.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_profile_covers_generated_commands.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_pytest_policy.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_readme_examples.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_session_configuration_doc.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_session_template_substitution.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_workflow_contracts.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/e2e/test_anonymize_e2e.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/e2e/test_benchmark_ab.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/e2e/test_benchmark_capacity.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/e2e/test_benchmark_replay.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/e2e/test_parallel_smoke.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/e2e/test_smoke.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/e2e/test_timeline_stepping.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/e2e/test_video_quality_e2e.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-local_zenoh-ros2dds-ota/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota-tuned/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/sessions/rmw_matrix/1_heartbeat_fastdds/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/sessions/rmw_matrix/1_heartbeat_zen-endpoints/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_anonymize.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_bag_ground_truth.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_benched_set.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_benchmark_delta.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_bundle_check.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_catmux_pane_logging.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_container_shaping.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_deployment.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_ffmpeg_flags.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_ffmpeg_packet.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_field_profiles.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_forensics.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_geomap.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_image_cache.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_link_bytes.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_link_trace.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_netem_dist.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_network_profiles.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_network_shaper.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_ota_unwrapper.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_ota_wrapper.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_ota_xml.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_playout_pacer.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_plots.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_qos_fallback_logging.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_session_pipeline.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_stage_latency.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_status_eval.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_status_overview.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_status_overview_observer.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_stream_stats.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_trace_profiles.py +0 -0
- {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/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.dev53
|
|
4
4
|
Summary: Host CLI for ROS OTA communication sessions.
|
|
5
5
|
Author: develNor
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -309,6 +309,24 @@ rosotacom start 1_heartbeat --identity b \
|
|
|
309
309
|
--peer-address a=10.0.0.10 --peer-address b=10.0.0.11
|
|
310
310
|
```
|
|
311
311
|
|
|
312
|
+
Before `start` stops a conflicting container, writes an instance, or builds an
|
|
313
|
+
image, it verifies that the selected identity's address belongs to this host and
|
|
314
|
+
that the route to the other peer selects that address as its source. A missing
|
|
315
|
+
VPN/data-plane interface or a route through the wrong network therefore fails
|
|
316
|
+
without disturbing a working session. Run the same check on its own with
|
|
317
|
+
`preflight`; deployments that require the other host to be online already can
|
|
318
|
+
also make three bounded ICMP probes mandatory:
|
|
319
|
+
|
|
320
|
+
```bash
|
|
321
|
+
rosotacom preflight 1_heartbeat --identity a \
|
|
322
|
+
--peer-address a=10.0.0.10 --peer-address b=10.0.0.11 \
|
|
323
|
+
--require-peer-reachable
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Peer reachability is opt-in because some valid networks block ICMP and peers may
|
|
327
|
+
be started in either order. `rosotacom start` accepts the same
|
|
328
|
+
`--require-peer-reachable` policy when a deployment does require it.
|
|
329
|
+
|
|
312
330
|
`rosotacom` reads the static session input and creates generated files under `session-instances/<date>/<session>_<timestamp>_<id>/config/`, including per-peer plugin/session specs, topic lists, optional QoS, and optional `domain_bridge.yaml`. Catmux pane output is logged under the same instance in `logs/<peer>/catmux/`.
|
|
313
331
|
|
|
314
332
|
What else a run leaves under `logs/<peer>/`, and which file to open first when a
|
|
@@ -580,6 +598,13 @@ the ssh client's own argv apart, and a transport that promises no more than
|
|
|
580
598
|
`-t` and `-o BatchMode=yes` are dropped rather than forwarded. They are options
|
|
581
599
|
of one client, and a transport that is not ssh never agreed to understand them.
|
|
582
600
|
|
|
601
|
+
The same four options — `--peer-checkout`, `--peer-exec`, `--install-mode`,
|
|
602
|
+
`--install-pin` — are on every `ota-benchmark` genre, not just `ota-smoke`. A
|
|
603
|
+
measurement is the last thing that should require a shell on the peer: the
|
|
604
|
+
whole point of a narrower transport is that the runs which touch a machine
|
|
605
|
+
repeatedly can go through it, and a benchmark touches it far more often than a
|
|
606
|
+
smoke test does.
|
|
607
|
+
|
|
583
608
|
### Live status / debugging overview
|
|
584
609
|
|
|
585
610
|
Enable a continuously-updated, per-topic pipeline overview by setting
|
|
@@ -264,6 +264,24 @@ rosotacom start 1_heartbeat --identity b \
|
|
|
264
264
|
--peer-address a=10.0.0.10 --peer-address b=10.0.0.11
|
|
265
265
|
```
|
|
266
266
|
|
|
267
|
+
Before `start` stops a conflicting container, writes an instance, or builds an
|
|
268
|
+
image, it verifies that the selected identity's address belongs to this host and
|
|
269
|
+
that the route to the other peer selects that address as its source. A missing
|
|
270
|
+
VPN/data-plane interface or a route through the wrong network therefore fails
|
|
271
|
+
without disturbing a working session. Run the same check on its own with
|
|
272
|
+
`preflight`; deployments that require the other host to be online already can
|
|
273
|
+
also make three bounded ICMP probes mandatory:
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
rosotacom preflight 1_heartbeat --identity a \
|
|
277
|
+
--peer-address a=10.0.0.10 --peer-address b=10.0.0.11 \
|
|
278
|
+
--require-peer-reachable
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Peer reachability is opt-in because some valid networks block ICMP and peers may
|
|
282
|
+
be started in either order. `rosotacom start` accepts the same
|
|
283
|
+
`--require-peer-reachable` policy when a deployment does require it.
|
|
284
|
+
|
|
267
285
|
`rosotacom` reads the static session input and creates generated files under `session-instances/<date>/<session>_<timestamp>_<id>/config/`, including per-peer plugin/session specs, topic lists, optional QoS, and optional `domain_bridge.yaml`. Catmux pane output is logged under the same instance in `logs/<peer>/catmux/`.
|
|
268
286
|
|
|
269
287
|
What else a run leaves under `logs/<peer>/`, and which file to open first when a
|
|
@@ -535,6 +553,13 @@ the ssh client's own argv apart, and a transport that promises no more than
|
|
|
535
553
|
`-t` and `-o BatchMode=yes` are dropped rather than forwarded. They are options
|
|
536
554
|
of one client, and a transport that is not ssh never agreed to understand them.
|
|
537
555
|
|
|
556
|
+
The same four options — `--peer-checkout`, `--peer-exec`, `--install-mode`,
|
|
557
|
+
`--install-pin` — are on every `ota-benchmark` genre, not just `ota-smoke`. A
|
|
558
|
+
measurement is the last thing that should require a shell on the peer: the
|
|
559
|
+
whole point of a narrower transport is that the runs which touch a machine
|
|
560
|
+
repeatedly can go through it, and a benchmark touches it far more often than a
|
|
561
|
+
smoke test does.
|
|
562
|
+
|
|
538
563
|
### Live status / debugging overview
|
|
539
564
|
|
|
540
565
|
Enable a continuously-updated, per-topic pipeline overview by setting
|
|
@@ -85,6 +85,29 @@ Precedence is explicit:
|
|
|
85
85
|
All logical peers must resolve to addresses before a session starts. Session
|
|
86
86
|
definitions do not accept physical addresses or SSH targets.
|
|
87
87
|
|
|
88
|
+
## Data-plane preflight
|
|
89
|
+
|
|
90
|
+
`rosotacom start` checks the resolved bindings against the host before it stops
|
|
91
|
+
or creates containers:
|
|
92
|
+
|
|
93
|
+
1. The selected identity's IPv4 address must be assigned locally.
|
|
94
|
+
2. `ip route get` for the other peer must select that same address as its
|
|
95
|
+
source.
|
|
96
|
+
|
|
97
|
+
This makes an absent VPN/interface, a wrong identity, and a route escaping over
|
|
98
|
+
another network startup errors instead of silent communication failures. Inspect
|
|
99
|
+
the result without starting anything:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
rosotacom preflight SESSION --identity PEER
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Add `--require-peer-reachable` to `preflight` or `start` when this deployment
|
|
106
|
+
also requires three bounded ICMP probes to succeed. Reachability is not the
|
|
107
|
+
global default: ICMP can be intentionally filtered, and valid peers can be
|
|
108
|
+
started in either order. Docker-isolated local smoke networks use their own
|
|
109
|
+
network lifecycle and bypass this host data-plane check.
|
|
110
|
+
|
|
88
111
|
## Project selection and completion
|
|
89
112
|
|
|
90
113
|
The nearest `rosotacom.yaml` is discovered upward from the current directory.
|
|
@@ -28,6 +28,9 @@ living verification hook.
|
|
|
28
28
|
|
|
29
29
|
## Findings
|
|
30
30
|
|
|
31
|
+
- [Sender-side transit rows made a dead link report zero loss](sender-rows-make-a-dead-link-look-loss-free.md) - `delivered = rows - lost` counted the sender's own `sent` rows as deliveries, so a topic the receiver never saw summarised as `delivered == expected` at 0.0% loss, with the publisher's timer reported as arrival spacing.
|
|
32
|
+
- [A bridge that learns types from the graph cannot use a transport that does not carry the graph](graph-derived-types-block-a-non-graph-transport.md) - over `zenoh_ros2dds` the payload topic never arrived in either run: the bridge routes a topic once a local reader exists and the reader waited for the bridge, leaving only `Pending=1` in a log.
|
|
33
|
+
- [A Fast DDS datagram cap stops every message larger than it](fastdds-datagram-cap-drops-large-samples.md) - copying CycloneDDS's 1200 B fragment size into the Fast DDS OTA profile makes every sample above the cap never arrive, at 1200 B and at 8192 B, sync and async — while the 84 B heartbeat keeps flowing at 10 Hz.
|
|
31
34
|
- [A lost keyframe silences exactly the next gop_size−2 deltas](keyframe-loss-kills-the-next-deltas.md) - libavcodec emits nothing for them, the last delta decodes with artifacts, the next keyframe restores clean decode; a lost delta never blocks decode — so the display hole is gop_size × frame period, deterministically.
|
|
32
35
|
- [Oversubscription queues — it does not lose until the queue itself dies](oversubscription-queues-not-losses.md) - 16% over an emulated cap climbed one-way delay 340 → 3250 ms across twelve bins with zero loss in every one; the losses arrived only when the queue died, all at once.
|
|
33
36
|
- [Best-effort reordering becomes reader-side loss, independent of history depth](reorder-becomes-reader-loss.md) - under pure delay jitter a Cyclone best-effort reader discards every overtaken sample (57% at 100 Hz under 50+-45 ms), delivery stays strictly monotonic, and depth 50 loses the same as depth 1.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# A Fast DDS Datagram Cap Stops Every Message Larger Than It
|
|
2
|
+
|
|
3
|
+
## Claim
|
|
4
|
+
|
|
5
|
+
Setting `<maxMessageSize>` on a Fast DDS UDPv4 transport to a value below a
|
|
6
|
+
sample's serialized size makes that sample **never arrive** through the OTA
|
|
7
|
+
pipeline — not "arrive fragmented", not "arrive with loss". Messages that fit
|
|
8
|
+
inside the cap keep flowing at full rate on the same link, which is what makes
|
|
9
|
+
this dangerous: an 84 B heartbeat crossing at 10 Hz with 0.0% loss is a link
|
|
10
|
+
that looks alive from every direction except the one that matters.
|
|
11
|
+
|
|
12
|
+
The obvious reason to set it is symmetry with CycloneDDS, whose OTA profile
|
|
13
|
+
carries this link at `FragmentSize`/`MaxMessageSize` 1200 B and works. The
|
|
14
|
+
symmetry does not transfer: on ROS 2 Kilted with Fast DDS 3.2.4 the cap is the
|
|
15
|
+
single knob that breaks the link, at 1200 B and at 8192 B, with a synchronous
|
|
16
|
+
writer and with an asynchronous one.
|
|
17
|
+
|
|
18
|
+
## Setup
|
|
19
|
+
|
|
20
|
+
- Host pair / topology: one host, the packaged local smoke rig — two
|
|
21
|
+
communication containers on their own Docker network, split ROS domains
|
|
22
|
+
(peer 50, peer 51, OTA 52) with the stock `domain_bridge` between them. The
|
|
23
|
+
same failure was first seen across two machines over a VPN; one host
|
|
24
|
+
reproduces it, so nothing private is needed.
|
|
25
|
+
- Session: a two-peer session with a `com_msgs/msg/SizedPayload` stream at
|
|
26
|
+
12000 B and 10 Hz on the loaded direction plus the echo heartbeat, OTA QoS
|
|
27
|
+
best_effort / depth 1 / lifespan 0.7 (the deployed shape).
|
|
28
|
+
- rosotacom SHA: measured at `6e4b748`; re-runs record theirs.
|
|
29
|
+
- Profile: none for the bisect — the failure needs no impairment, which is what
|
|
30
|
+
makes it attributable to the configuration rather than to the link.
|
|
31
|
+
- Seed policy: deterministic (no netem, no random load), `n=1` per variant; the
|
|
32
|
+
effect is present/absent, not a distribution.
|
|
33
|
+
|
|
34
|
+
## Evidence
|
|
35
|
+
|
|
36
|
+
Evidence grade: single-host reproduction on packaged material, one variant per
|
|
37
|
+
run, read from the receiving peer's own `status.txt`.
|
|
38
|
+
|
|
39
|
+
Each knob of the tuned profile was added to the working `fastdds_unicast.xml`
|
|
40
|
+
one at a time (2026-08-19):
|
|
41
|
+
|
|
42
|
+
| added to fastdds_unicast.xml | 12 kB stream at the receiver |
|
|
43
|
+
|---|---|
|
|
44
|
+
| interface allowlist (127.0.0.1 + OTA address) | FLOWING 10.0 Hz, 0.0% loss |
|
|
45
|
+
| loopback locators (default / metatraffic / initial peers) | FLOWING 10.0 Hz |
|
|
46
|
+
| `maxInitialPeersRange` 10 | FLOWING 10.0 Hz |
|
|
47
|
+
| discovery lease / announcement | FLOWING 10.0 Hz |
|
|
48
|
+
| socket buffer sizes (1 MB / 4 MB) | FLOWING 10.0 Hz |
|
|
49
|
+
| `non_blocking_send` | FLOWING 10.0 Hz |
|
|
50
|
+
| `publishMode` ASYNCHRONOUS | FLOWING, degraded: 9.3 Hz at 285 ms |
|
|
51
|
+
| **`maxMessageSize` 1200** | **IDLE — nothing delivered** |
|
|
52
|
+
| **`maxMessageSize` 8192** | **IDLE — nothing delivered** |
|
|
53
|
+
| **`maxMessageSize` 1200 + ASYNCHRONOUS** | **IDLE — nothing delivered** |
|
|
54
|
+
|
|
55
|
+
The heartbeat crossed at 10 Hz with 0.0% loss in every one of those runs,
|
|
56
|
+
including the three that delivered no payload at all.
|
|
57
|
+
|
|
58
|
+
Two nearby observations, both of which cost time before the bisect narrowed it:
|
|
59
|
+
|
|
60
|
+
- Two Fast DDS participants in two containers, with the capped profile and
|
|
61
|
+
nothing else running, DO exchange 12 kB and 38 kB samples (57–59 of 60). The
|
|
62
|
+
cap only breaks the full pipeline, where the sample crosses a domain bridge
|
|
63
|
+
and an OTA bridge, so an isolated transport probe will report the cap as
|
|
64
|
+
harmless.
|
|
65
|
+
- Asynchronous publication does not rescue it, which rules out the documented
|
|
66
|
+
"a synchronous writer cannot fragment" explanation as the whole story.
|
|
67
|
+
|
|
68
|
+
Verification: manual: run the packaged smoke for a session whose OTA side names
|
|
69
|
+
`fastdds_tuned.xml`, then again for one that adds `<maxMessageSize>1200` to it,
|
|
70
|
+
and read `logs/<receiver>/status/status.txt`; the payload stage is FLOWING in
|
|
71
|
+
the first and IDLE in the second while the heartbeat is FLOWING in both. The
|
|
72
|
+
shipped profiles are pinned against the cap by
|
|
73
|
+
`tests/unit/test_ota_link_configs.py::test_only_cyclone_caps_the_datagram_and_fast_dds_must_not`.
|
|
74
|
+
|
|
75
|
+
## Status
|
|
76
|
+
|
|
77
|
+
confirmed, 2026-08-19.
|
|
78
|
+
|
|
79
|
+
## Publication notes
|
|
80
|
+
|
|
81
|
+
This is why "the OTA middleware is a configuration choice" needs measuring
|
|
82
|
+
rather than reasoning: the two profiles that look like translations of each
|
|
83
|
+
other are not, and the failure mode of the wrong translation is a link that
|
|
84
|
+
passes a heartbeat check. Consequence for the transport comparison: Fast DDS
|
|
85
|
+
lets IP fragment a large sample here where CycloneDDS sends RTPS fragments, so
|
|
86
|
+
the two differ in what a lost packet costs and in what the tunnel has to
|
|
87
|
+
reassemble — the measured OpenVPN barrier on the operator's path is around
|
|
88
|
+
110 kB per message. Report Fast DDS numbers with that difference stated, not as
|
|
89
|
+
a like-for-like transport swap.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# A Bridge That Learns Types From The Graph Cannot Use A Transport That Does Not Carry The Graph
|
|
2
|
+
|
|
3
|
+
## Claim
|
|
4
|
+
|
|
5
|
+
`PubSubPair` resolved a stage's message type from
|
|
6
|
+
`get_topic_names_and_types()`, so it could only create its endpoints once
|
|
7
|
+
somebody else had created the matching one. On a DDS OTA link that is invisible
|
|
8
|
+
— the remote writer is in the same domain, so the graph knows it. Over the
|
|
9
|
+
zenoh DDS bridge (`rmw.ota: zenoh_ros2dds`) it is a deadlock: the bridge
|
|
10
|
+
creates a subscriber route for a topic only once a **local DDS reader** exists,
|
|
11
|
+
and the reader was waiting for the bridge to route a publisher into the graph.
|
|
12
|
+
Neither ever happens, the payload topic never arrives, and the only trace is one
|
|
13
|
+
word in a log line — `Initialized 1 pair(s). Pending=1`.
|
|
14
|
+
|
|
15
|
+
The heartbeat escapes it because the receiving peer's bridge sees the remote
|
|
16
|
+
liveliness token for it early enough to create the route before the reader is
|
|
17
|
+
needed; the wrapped payload topic does not. So the observable is again a link
|
|
18
|
+
that carries the small topic and silently drops the big one.
|
|
19
|
+
|
|
20
|
+
## Setup
|
|
21
|
+
|
|
22
|
+
- Host pair / topology: two machines over a VPN, `rmw.ota: zenoh_ros2dds`
|
|
23
|
+
(local cyclone), split ROS domains, one 12 kB `SizedPayload` stream at 10 Hz
|
|
24
|
+
plus the echo heartbeat.
|
|
25
|
+
- rosotacom SHA: observed at `6e4b748` (before the fix), fixed in `48d84dc`.
|
|
26
|
+
- Profile: the drive-derived loss process; the effect is not a loss effect and
|
|
27
|
+
reproduced identically in both runs under it.
|
|
28
|
+
- Seed policy: not applicable — present/absent, `n=2` runs, both failing the
|
|
29
|
+
same way.
|
|
30
|
+
|
|
31
|
+
## Evidence
|
|
32
|
+
|
|
33
|
+
Evidence grade: two live two-machine runs, read from the receiving peer's node
|
|
34
|
+
logs and from the zenoh bridge's own routing log.
|
|
35
|
+
|
|
36
|
+
Receiving peer, `bridge_in` (2026-08-19):
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
[PubSubPair] Created: sub='/ota/b/heartbeat_b' ...
|
|
40
|
+
[PubSubPair] Created: sub='/ota/b/cam_like/ota_stamped' ...
|
|
41
|
+
[PubSubPair] Initialized: sub='/ota/b/heartbeat_b' type='com_msgs/msg/EchoHeartbeat'
|
|
42
|
+
[bridge_in] Initialized 1 pair(s). Pending=1
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Receiving peer, `zenoh_bridge_ros2dds`, for the whole run:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
routes_mgr: Route Subscriber (Zenoh:ota/b/heartbeat_b -> ROS:/ota/b/heartbeat_b) created
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
— and no such line for `ota/b/cam_like/ota_stamped`, while the sending peer had
|
|
52
|
+
created its publisher route for exactly that key. Delivered payload messages in
|
|
53
|
+
both runs: 0 of ~810 sent.
|
|
54
|
+
|
|
55
|
+
The fix removes the dependency rather than the symptom: every session now writes
|
|
56
|
+
`<peer>/topic_types.yaml` (`<stage topic>: <message type>` for every stage that
|
|
57
|
+
peer takes part in, derived from the same pipeline description the status node
|
|
58
|
+
uses), the bridge and relay nodes read it, and the graph is consulted only for
|
|
59
|
+
what the file does not name.
|
|
60
|
+
|
|
61
|
+
Verification: `python -m pytest -q tests/unit/test_pub_sub_pair_types.py` — a
|
|
62
|
+
pair with a declared type creates its endpoints against an empty graph, a pair
|
|
63
|
+
without one still reads the graph, and a pair with neither stays pending.
|
|
64
|
+
`tests/unit/test_ota_link_configs.py::test_every_peer_gets_the_stage_types_its_bridges_need`
|
|
65
|
+
pins that the file is generated for every peer of every session.
|
|
66
|
+
|
|
67
|
+
## Status
|
|
68
|
+
|
|
69
|
+
confirmed, 2026-08-19.
|
|
70
|
+
|
|
71
|
+
## Publication notes
|
|
72
|
+
|
|
73
|
+
Worth stating in any "the transport is a configuration choice" claim: a
|
|
74
|
+
pipeline can depend on a transport property nobody wrote down — here, that the
|
|
75
|
+
transport propagates the ROS graph and not only the data. DDS does, the zenoh
|
|
76
|
+
DDS bridge does not, and the dependency only shows up as a topic that never
|
|
77
|
+
arrives. The general lesson is that a contract known at generation time should
|
|
78
|
+
be handed to the runtime rather than rediscovered from the runtime, which is
|
|
79
|
+
also what makes bring-up order-independent.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Sender-Side Transit Rows Made A Dead Link Report Zero Loss
|
|
2
|
+
|
|
3
|
+
## Claim
|
|
4
|
+
|
|
5
|
+
`summarize_transit_records` counted `delivered = rows − lost`. Sender-side
|
|
6
|
+
transit rows carry the status `sent` and are written whether or not anything
|
|
7
|
+
arrives, so a topic that the receiving peer never saw at all summarised as
|
|
8
|
+
`delivered == expected`, `loss_pct 0.0` — with the sender's own publication
|
|
9
|
+
cadence reported as the arrival spacing. The most dangerous shape a wrong number
|
|
10
|
+
can take: a link that delivered nothing scored better than one that delivered
|
|
11
|
+
96% of its messages.
|
|
12
|
+
|
|
13
|
+
Delivery is a receiver fact. Rows still `sent` after the join are `unconfirmed`;
|
|
14
|
+
`loss_pct` is `None` when no receiver accounted for the topic at all; and an
|
|
15
|
+
oracle reads that `None` as the worst case rather than as zero.
|
|
16
|
+
|
|
17
|
+
## Setup
|
|
18
|
+
|
|
19
|
+
- Host pair / topology: not a transport property — the summary is a pure
|
|
20
|
+
function of collected records, so the reproduction is a unit test over
|
|
21
|
+
synthetic rows. It was found on a two-machine run whose OTA transport
|
|
22
|
+
delivered nothing.
|
|
23
|
+
- rosotacom SHA: present up to `6e4b748`, fixed in `730ddf5`.
|
|
24
|
+
- Profile: none — the defect is in the accounting, not in the link.
|
|
25
|
+
- Seed policy: not applicable, deterministic.
|
|
26
|
+
|
|
27
|
+
## Evidence
|
|
28
|
+
|
|
29
|
+
Evidence grade: unit-level, deterministic, plus the live run that exposed it.
|
|
30
|
+
|
|
31
|
+
Live (2026-08-19, `rmw.ota: zenoh_ros2dds` over two machines): the sending peer
|
|
32
|
+
wrote 816 `outbound`/`sent` rows, the receiving peer wrote 5 rows and no
|
|
33
|
+
delivery at all. The run's `result.json` reported `delivered 807, expected 807,
|
|
34
|
+
loss_pct 0.0` for that topic, with inter-arrival p05/p95 of 102/104 ms — the
|
|
35
|
+
publisher's own timer, not an arrival distribution. The receiver's `status.txt`
|
|
36
|
+
for the same run said `ota_recv ABSENT/GRAPH pub=0` and `com_in IDLE`.
|
|
37
|
+
|
|
38
|
+
The window mattered as much as the number: this only became reachable when
|
|
39
|
+
sender-side transit rows landed (issue #294). Before that, a topic with no
|
|
40
|
+
receiver rows had no rows at all and simply did not appear.
|
|
41
|
+
|
|
42
|
+
Verification: `python -m pytest -q tests/unit/test_transit.py -k sender_rows`
|
|
43
|
+
— sender rows alone report `delivered 0`, `unconfirmed 3` and `loss_pct None`,
|
|
44
|
+
and a mixed set counts only the receiver's verdicts.
|
|
45
|
+
`tests/unit/test_benchmark.py::test_an_unknown_loss_figure_is_read_as_the_worst_case`
|
|
46
|
+
pins that an oracle does not pass on the `None`.
|
|
47
|
+
|
|
48
|
+
## Status
|
|
49
|
+
|
|
50
|
+
confirmed, 2026-08-19.
|
|
51
|
+
|
|
52
|
+
## Publication notes
|
|
53
|
+
|
|
54
|
+
A measurement pipeline that gains a second observer gains a way to be
|
|
55
|
+
confidently wrong: the new rows were real, the join was correct, and the
|
|
56
|
+
aggregate stopped meaning what its name said. Worth citing whenever a loss
|
|
57
|
+
figure is quoted from an automated run — state which side observed it. The
|
|
58
|
+
general rule the fix encodes: an aggregate over rows from two observers must say
|
|
59
|
+
which observer each row came from before it counts anything.
|
|
@@ -167,8 +167,49 @@ not override `RMW_IMPLEMENTATION` and relies on the ambient ROS 2 defaults — n
|
|
|
167
167
|
Per-side config blocks:
|
|
168
168
|
|
|
169
169
|
- DDS implementations (`cyclone`, `fastdds`) accept:
|
|
170
|
-
- `config: <template>` — template file under `ws/ota_configs/`
|
|
171
|
-
|
|
170
|
+
- `config: <template>` — template file under `ws/ota_configs/`
|
|
171
|
+
(`cyclonedds_tuned.xml`, `cyclonedds_minimal.xml`,
|
|
172
|
+
`cyclonedds_local_participants.xml`, `fastdds_tuned.xml`,
|
|
173
|
+
`fastdds_unicast.xml`, `fastdds_easy_mode.xml`).
|
|
174
|
+
- `easy_mode_ip: <string>` — resolved into a template's `#easy_mode_ip`
|
|
175
|
+
placeholder; defaults to the first resolved peer address. Only
|
|
176
|
+
`fastdds_easy_mode.xml` uses it.
|
|
177
|
+
|
|
178
|
+
`fastdds_easy_mode.xml` is the discovery alternative: Fast DDS 3.1 spawns or
|
|
179
|
+
reuses one Discovery Server per host and points the participant at the peer's
|
|
180
|
+
server too, so two hosts find each other with no multicast and no per-peer
|
|
181
|
+
locator list. It fails differently from `fastdds_tuned.xml` rather than
|
|
182
|
+
better — an explicit peer list cannot discover what it was not told about,
|
|
183
|
+
while easy mode depends on a server process being reachable on 11811 — which
|
|
184
|
+
is why both are packaged. Neither caps the datagram (see above); easy mode
|
|
185
|
+
expresses its transport settings as `<builtinTransports …>` attributes,
|
|
186
|
+
because replacing the transports outright would take its discovery path with
|
|
187
|
+
them.
|
|
188
|
+
|
|
189
|
+
**On the OTA side, omitting `config` is not "no configuration".** Each
|
|
190
|
+
implementation has a default template, and both defaults are the link-ready
|
|
191
|
+
one: `cyclone` → `cyclonedds_tuned.xml`, `fastdds` → `fastdds_tuned.xml`.
|
|
192
|
+
That is what makes `shared.rmw` an interchangeable choice — a session names a
|
|
193
|
+
middleware and gets unicast discovery with the OTA interface pinned either
|
|
194
|
+
way, rather than one middleware that survives a cellular tunnel and one that
|
|
195
|
+
has to be configured into surviving it. `fastdds_unicast.xml` is the earlier,
|
|
196
|
+
locator-only configuration, kept for a run that wants to measure the
|
|
197
|
+
difference.
|
|
198
|
+
|
|
199
|
+
The two defaults are **not** identical in what they put on the wire, and the
|
|
200
|
+
difference is deliberate. CycloneDDS fragments at the RTPS layer (1200 B);
|
|
201
|
+
Fast DDS hands a large sample to the kernel as one datagram and lets IP
|
|
202
|
+
fragment it. Writing the same cap into the Fast DDS profile is the obvious
|
|
203
|
+
move and it takes the link down: measured on the bench pair (2026-08-18/19,
|
|
204
|
+
ROS 2 Kilted, Fast DDS 3.2.4) a `maxMessageSize` below the sample size stops
|
|
205
|
+
the sample from ever arriving — at 1200 B and at 8192 B, synchronous writer
|
|
206
|
+
and asynchronous — while an 84 B heartbeat on the same link keeps flowing.
|
|
207
|
+
Plan the payload accordingly: the measured OpenVPN barrier on this path is
|
|
208
|
+
around 110 kB per message.
|
|
209
|
+
|
|
210
|
+
On the **local** side, omitting `config` really is no configuration: no
|
|
211
|
+
template is applied and no `CYCLONEDDS_URI` / `FASTDDS_DEFAULT_PROFILES_FILE`
|
|
212
|
+
is exported.
|
|
172
213
|
|
|
173
214
|
On the **local** side of a busy machine, set
|
|
174
215
|
`config: cyclonedds_local_participants.xml`. Cyclone allows 33 participants
|
|
@@ -179,10 +220,22 @@ Per-side config blocks:
|
|
|
179
220
|
interface and sets no peer list, because local discovery must keep working.
|
|
180
221
|
The OTA templates are not usable on the local side for exactly that reason.
|
|
181
222
|
- `zenoh_connect_endpoints` (native, OTA side only; `zenoh` is still accepted as a legacy OTA alias) accepts:
|
|
223
|
+
- `transport: tcp|udp` — the inter-host transport between the two routers.
|
|
224
|
+
Default `tcp`. On a lossy link TCP is the wrong choice for a best-effort
|
|
225
|
+
stream: one retransmit stalls everything queued behind it, which turns a
|
|
226
|
+
cellular dip into seconds of latency instead of one lost sample. The
|
|
227
|
+
listening router keeps `tcp/[::]:7447` whatever this is set to, because
|
|
228
|
+
every rmw_zenoh node on that host is a zenoh *client* of it over
|
|
229
|
+
`tcp/localhost:7447`.
|
|
182
230
|
- `main_peer: <peer_key>` — the peer whose zenoh router listens. Defaults to the first peer declared under `peers:`.
|
|
183
231
|
- `main_port: 7447` — listening port. Default `7447`.
|
|
184
232
|
- `zenoh_ros2dds` (bridge) accepts (OTA side only):
|
|
185
|
-
- `transport: udp|tcp` — default `
|
|
233
|
+
- `transport: udp|tcp` — default `tcp`, measured rather than assumed. On the
|
|
234
|
+
bench pair (2026-08-19, the 2026-08-17 drive's loss process, 12 kB at 10 Hz)
|
|
235
|
+
the UDP bridge delivered in one run of five and lost 66% of that one, while
|
|
236
|
+
the TCP bridge delivered in every run at ~1% loss with the lowest median
|
|
237
|
+
latency in the campaign. UDP stays available for a link where TCP's
|
|
238
|
+
head-of-line blocking costs more than its retransmission buys.
|
|
186
239
|
- `main_peer: <peer_key>` — defaults to the first peer.
|
|
187
240
|
- `main_port: 7447` — default `7447`.
|
|
188
241
|
|
|
@@ -227,6 +280,22 @@ topics to/from zenoh. The local graph still speaks DDS, so `rmw.local` must be
|
|
|
227
280
|
- `zen_pub_allow` / `zen_sub_allow` are derived from peer `com-name`s (`/ota/<com-name>/.*`).
|
|
228
281
|
- `zen_qos_pub` is derived from per-topic `zen_qos:` entries and baked into the generated `<peer>/plugin.yaml`.
|
|
229
282
|
|
|
283
|
+
#### Generated per peer: `topic_types.yaml`
|
|
284
|
+
|
|
285
|
+
Every session writes `<peer>/topic_types.yaml` — `<stage topic>: <message
|
|
286
|
+
type>` for every stage that peer takes part in — and the bridge and relay nodes
|
|
287
|
+
read it. It is generated whether or not `use_status_overview` is set, and is
|
|
288
|
+
derived from the same pipeline description the status node uses, so the two
|
|
289
|
+
cannot disagree about what a stage is called.
|
|
290
|
+
|
|
291
|
+
It exists because the alternative was the ROS graph, and the graph makes an
|
|
292
|
+
endpoint's creation depend on somebody else having created the matching one
|
|
293
|
+
first. Over a transport that carries data but not the graph — `rmw.ota:
|
|
294
|
+
zenoh_ros2dds`, where the bridge routes a topic only once a local DDS reader
|
|
295
|
+
exists — that is a deadlock, and a silent one: the receiving peer logs
|
|
296
|
+
`Initialized 1 pair(s). Pending=1` and the topic simply never arrives. The graph
|
|
297
|
+
is still consulted for anything the file does not name.
|
|
298
|
+
|
|
230
299
|
#### Domain bridging
|
|
231
300
|
|
|
232
301
|
If `shared.ota_domain_id` and `peer_settings.<peer>.domain_id` are both set and
|
|
@@ -421,6 +490,21 @@ Each entry is either:
|
|
|
421
490
|
- `expect` (optional mapping); `smoke_probe: false` keeps the topic in the
|
|
422
491
|
generated contract but excludes it from synthetic local-smoke probes
|
|
423
492
|
|
|
493
|
+
Two `expect` keys describe the *synthetic source* rather than the contract,
|
|
494
|
+
for the runs (local smoke, `ota-smoke`, OTA benchmark genres) that drive a
|
|
495
|
+
session with generated traffic instead of a replay:
|
|
496
|
+
|
|
497
|
+
- `smoke_native_hz` — publish the native topic at this rate instead of
|
|
498
|
+
deriving it from the `hz` bounds. Needed wherever the pipeline changes the
|
|
499
|
+
rate (`drop`, `throttle_hz`, `trickle_hz`), because the asserted rate is
|
|
500
|
+
the delivered one and the source has to run faster.
|
|
501
|
+
- `smoke_native_bytes` — the payload size for a
|
|
502
|
+
`com_msgs/msg/SizedPayload` topic (default 66000). The size belongs to the
|
|
503
|
+
load a session wants driven: comparing two OTA middlewares, or two
|
|
504
|
+
profiles, means holding the payload at a chosen size — a 38 kB camera
|
|
505
|
+
keyframe, say — rather than at whatever constant the driver carries. It is
|
|
506
|
+
also what the receiving side asserts, so both ends stay consistent.
|
|
507
|
+
|
|
424
508
|
In split-domain mode the generator must emit a standard ROS 2 `domain_bridge` YAML with explicit
|
|
425
509
|
message types for `/com/...` topics. For that reason, user-defined topic entries need `type:`.
|
|
426
510
|
The auto-generated heartbeat topic is the only exception because its type is known by the generator.
|
|
@@ -191,9 +191,19 @@ def oracle_passes(loss_pct: float, latency_ms: float | None, thresholds: OracleT
|
|
|
191
191
|
return loss_pct <= thresholds.max_loss_pct and latency_ms <= thresholds.max_latency_ms
|
|
192
192
|
|
|
193
193
|
|
|
194
|
+
def _oracle_loss_pct(value: Any) -> float:
|
|
195
|
+
"""A topic's loss for an oracle, with "unknown" read as the worst case.
|
|
196
|
+
|
|
197
|
+
`summarize_transit_records` reports `None` when no receiving peer accounted
|
|
198
|
+
for the topic at all. That is not zero loss; it is no evidence, and an
|
|
199
|
+
oracle that let it pass would turn a dead link into a green run.
|
|
200
|
+
"""
|
|
201
|
+
return 100.0 if value is None else float(value)
|
|
202
|
+
|
|
203
|
+
|
|
194
204
|
def oracle_passes_topic(topic_summary: dict[str, Any], thresholds: OracleThresholds) -> bool:
|
|
195
205
|
"""Apply the oracle to one topic of ``transit.summarize_transit_records`` output."""
|
|
196
|
-
loss_pct =
|
|
206
|
+
loss_pct = _oracle_loss_pct(topic_summary.get("loss_pct", 100.0))
|
|
197
207
|
latency = (topic_summary.get("ota_hop_ms") or {}).get(thresholds.latency_quantile)
|
|
198
208
|
return oracle_passes(loss_pct, None if latency is None else float(latency), thresholds)
|
|
199
209
|
|
|
@@ -323,7 +333,7 @@ def evaluate_bag_run(
|
|
|
323
333
|
lost = data.get("lost")
|
|
324
334
|
reordered = data.get("reordered")
|
|
325
335
|
run_expected = data.get("expected")
|
|
326
|
-
loss_pct =
|
|
336
|
+
loss_pct = _oracle_loss_pct(data.get("loss_pct", 100.0)) if data else 100.0
|
|
327
337
|
latency_p95 = (data.get("ota_hop_ms") or {}).get(quantile) if data else None
|
|
328
338
|
jitter_p95 = (data.get("jitter_ms") or {}).get("p95") if data else None
|
|
329
339
|
latency_val = None if latency_p95 is None else float(latency_p95)
|