rosotacom-dev 2.5.dev65__tar.gz → 2.5.dev67__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.dev65 → rosotacom_dev-2.5.dev67}/PKG-INFO +8 -1
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/README.md +7 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/findings/README.md +1 -0
- rosotacom_dev-2.5.dev67/docs/findings/one-domain-two-cyclone-configs-stop-interoperating.md +94 -0
- rosotacom_dev-2.5.dev67/docs/ota-pcap.md +134 -0
- rosotacom_dev-2.5.dev67/src/rosotacom/resources/ws/ota_configs/cyclonedds_scoped.xml.template +87 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ota_configs/get_ota_xml.py +75 -30
- rosotacom_dev-2.5.dev67/src/rosotacom/resources/ws/ros2src/com_py/com_py/ota_pcap.py +402 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview.py +93 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/session/content/base/session_plugin_base.yaml +16 -4
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/session/creation/generate_session_files.py +45 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom_dev.egg-info/PKG-INFO +8 -1
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom_dev.egg-info/SOURCES.txt +5 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom_dev.egg-info/scm_file_list.json +5 -0
- rosotacom_dev-2.5.dev67/src/rosotacom_dev.egg-info/scm_version.json +8 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/contract/test_generated_topics_have_a_producer.py +3 -1
- rosotacom_dev-2.5.dev67/tests/unit/test_ota_pcap.py +308 -0
- rosotacom_dev-2.5.dev67/tests/unit/test_ota_xml.py +134 -0
- rosotacom_dev-2.5.dev65/src/rosotacom_dev.egg-info/scm_version.json +0 -8
- rosotacom_dev-2.5.dev65/tests/unit/test_ota_xml.py +0 -70
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/.devcontainer/devcontainer.json.template +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/.devcontainer/re_generate_devcontainer_json.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/.github/CODEOWNERS +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/.github/ISSUE_TEMPLATE/documentation-audit.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/.github/ISSUE_TEMPLATE/implementation-cleanup.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/.github/ISSUE_TEMPLATE/quality-workflow.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/.github/ISSUE_TEMPLATE/redesign.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/.github/ISSUE_TEMPLATE/release-process.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/.github/ISSUE_TEMPLATE/repository-diagnosis.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/.github/ISSUE_TEMPLATE/test-ci-audit.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/.github/ISSUE_TEMPLATE/work-item.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/.github/actions/setup-just/action.yml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/.github/dependabot.yml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/.github/workflows/benchmark-calibrate.yml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/.github/workflows/benchmark-gate.yml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/.github/workflows/dev-release.yml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/.github/workflows/image-scan.yml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/.github/workflows/nightly-e2e.yml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/.github/workflows/pr-lightweight.yml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/.github/workflows/pr-merge-gate.yml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/.github/workflows/release.yml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/.pre-commit-config.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/AGENTS.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/CONCURRENCY.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/CONTRIBUTING.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/DEVELOPMENT_PRINCIPLES.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/MANIFEST.in +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/budgets.jsonl +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/calibration/README.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/calibration/capacity-size-tight-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/calibration/probe-loss-gop-tight-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/calibration/probe-loss-nominal-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/calibration/probe-loss-tight-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/calibration/probe-loss-tight-fastdds.json +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/calibration/probe-loss-tight-zenoh.json +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/codecov.yml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/deployment-configuration.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/benchmark-ab.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/benchmark-bag-as-load.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/ci.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/ffmpeg-keyframes.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/findings/a-transport-element-doubles-every-fastdds-sample.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/findings/cyclone-fragment-equal-to-max-drops-fragmented-samples.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/findings/cyclone-spdp-discovery-bursts.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/findings/delay-alone-no-loss.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/findings/fastdds-datagram-cap-drops-large-samples.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/findings/graph-derived-types-block-a-non-graph-transport.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/findings/head-of-line-irregularity.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/findings/jitter-loss-bandwidth-latency.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/findings/keyframe-loss-kills-the-next-deltas.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/findings/lifespan-is-enforced-by-one-reader-and-not-the-other.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/findings/lighter-message-loss.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/findings/oversubscription-queues-not-losses.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/findings/reorder-becomes-reader-loss.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/findings/repro/decode_chain_repro.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/findings/repro/reorder_drop_repro.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/findings/sender-rows-make-a-dead-link-look-loss-free.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/findings/zero-loss-boundaries-18kb-20hz.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/forensics-report.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/geo-link-map.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/github-repository-settings.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/link-bandwidth.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/link-trace.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/owner-runbook.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/performance-bands.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/playbooks/README.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/quality-model.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/release-notes/TEMPLATE.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/release-notes/v2.1.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/release-notes/v2.2.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/release-notes/v2.3.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/release-notes/v2.4.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/release.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/rfcs/0001-expectation-driven-test-suite.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/rfcs/0002-expectation-concepts.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/rfcs/0003-metric-backbone.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/rfcs/0004-network-profiles.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/rfcs/0005-benchmark-genres-and-ci.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/rfcs/0006-dynamic-qos.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/rfcs/0007-regression-gate.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/rfcs/README.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/testing.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/docs/work-items.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/install.sh +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/justfile +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/media/control_center.png +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/media/echo_test.png +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/media/forensics-report-example.png +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/media/host.png +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/media/vehicle.png +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/pyproject.toml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/requirements.txt +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/rosotacom.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/session-configuration.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/setup.cfg +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/__init__.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/__main__.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/anonymize.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/bag_ground_truth.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/benched_set.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/benchmark.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/benchmark_delta.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/bundle_check.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/cli.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/cli_benchmark.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/deployment.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/ffmpeg_packet.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/forensics.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/geomap.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/image_cache.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/netem_dist.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/network_preflight.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/network_profiles.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/network_shaper.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/plots.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/py.typed +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/benched-set.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/.gitignore +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/README.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/__init__.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/bags/8_drop_reference/metadata.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/deployment.example.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/dist/field-20260817.dist +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/profiles.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/ros2docker.lyrical.json +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/rosotacom.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scenarios/2_native_chatter/scenario-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_a.sh +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_b.sh +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/external.lyrical.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/wait_for_echo_topic.sh +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/external.lyrical.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/foxglove.json +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/metadata.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/foxglove.json +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/metadata.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/sessions/10_restamp/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/sessions/11_trickle/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/sessions/12_content_integrity/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/sessions/13_link_latency/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/sessions/14_remote_assist_anonymized/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/sessions/15_remote_assist_anonymized_costmap/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/sessions/16_remote_assist_anonymized_camera/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/sessions/17_synthetic_camera_quality/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/sessions/1_heartbeat/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/sessions/1_heartbeat_status/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/sessions/2_native_chatter/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/sessions/3_comp_occ_grid/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/sessions/4_comp_occ_grid_zen/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/sessions/5_sized_payload/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/sessions/6_sized_payload_zen/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/sessions/7_latched_static/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/sessions/8_drop/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/sessions/9_throttle/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/sessions/bench_1_1_capacity/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/sessions/bench_1_2_load_sweep/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/sessions/bench_1_3_ramp/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/sessions/bench_1_4_recovery/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/examples/sessions/bench_1_5_camera/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ros2docker.json.example +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ros2docker.lyrical.json.example +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/.vscode/c_cpp_properties.json +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/.vscode/settings.json +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_easy_mode.xml.template +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_initial_peer_list.xml.template +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v2.xml.template +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v3.xml.template +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v4.xml.template +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v5.xml.template +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ota_configs/create_zenoh_json5.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ota_configs/cyclonedds_local_participants.xml.template +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ota_configs/cyclonedds_minimal.xml.template +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ota_configs/cyclonedds_tuned.xml.template +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ota_configs/fastdds_easy_mode.xml.template +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ota_configs/fastdds_local.xml.template +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ota_configs/fastdds_tuned.xml.template +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ota_configs/fastdds_unicast.xml.template +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ota_configs/utils.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ota_configs/zenoh.json5.template +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/.gitkeep +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_cpp/CMakeLists.txt +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_cpp/COLCON_IGNORE +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_cpp/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_cpp/package.xml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_cpp/src/hz_monitor.cpp +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_compressor.cpp +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_decompressor.cpp +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_msgs/CMakeLists.txt +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_msgs/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/CompressedData.msg +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/EchoHeartbeat.msg +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/OtaStamped.msg +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/SizedPayload.msg +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_msgs/package.xml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/__init__.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/base_bridge_relay.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_in.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_out.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/ffmpeg_flags.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/heartbeat_echo.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/hz_monitor.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_bandwidth_reducer.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_pixel_capper.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/lanelet_saver.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/latch_relay.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/costmap_remapper.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/marker_remapper.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/speed_test.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/tf_remapper.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/traffic_monitor.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/wifi_network_analysis_1.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_bytes.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_trace.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/local_global_frame_bridge.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/localization_map_split_reduce_saver.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/msg_transform.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pair_management.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/playout_pacer.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/playout_pacer_core.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pub_sub_pair.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/qos.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_in.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_out.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/restamp.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/sized_publisher.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency_core.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview_core.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/tf_map_to_cart_saver.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_monitor.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_resolution.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/trickle.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_compressor.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_decompressor.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_unwrapper.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_wrapper.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/package.xml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/resource/com_py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/setup.cfg +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/setup.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/test/test_copyright.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/test/test_flake8.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/ros2src/com_py/test/test_pep257.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/session/content/network/up_connectivity.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/session/content/network/wifi_network_analysis_2.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/session/creation/anonymize_bag.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/session/creation/catmux_log_setup.sh +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/session/creation/create_session_yaml.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/session/creation/run_session.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/session/creation/run_session_in_external_terminal.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/resources/ws/session/creation/strip_ansi.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/status_eval.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/stream_stats.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/trace_profiles.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/transit.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom/video_quality.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom_dev.egg-info/dependency_links.txt +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom_dev.egg-info/entry_points.txt +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom_dev.egg-info/requires.txt +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/src/rosotacom_dev.egg-info/top_level.txt +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/terminology.md +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/contract/test_benched_set_registry.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/contract/test_findings.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/contract/test_lyrical_runtime_compat.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/contract/test_markdown_links.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/contract/test_ota_source_bundle.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/contract/test_package_metadata.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/contract/test_packaged_resources.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/contract/test_profile_covers_generated_commands.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/contract/test_pytest_policy.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/contract/test_readme_examples.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/contract/test_security_maintenance_config.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/contract/test_session_configuration_doc.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/contract/test_session_template_substitution.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/contract/test_workflow_contracts.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/e2e/conftest.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/e2e/test_anonymize_e2e.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/e2e/test_benchmark_ab.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/e2e/test_benchmark_capacity.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/e2e/test_benchmark_replay.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/e2e/test_parallel_smoke.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/e2e/test_smoke.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/e2e/test_timeline_stepping.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/e2e/test_video_quality_e2e.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/sessions/generate_rmw_matrix.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-local_zenoh-ros2dds-ota/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota-tuned/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/sessions/rmw_matrix/1_heartbeat_fastdds/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/sessions/rmw_matrix/1_heartbeat_fastdds-default/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/sessions/rmw_matrix/1_heartbeat_zen-endpoints/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_anonymize.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_bag_ground_truth.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_benched_set.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_benchmark.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_benchmark_delta.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_bundle_check.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_catmux_pane_logging.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_cli.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_cli_benchmark.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_concurrency.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_container_shaping.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_deployment.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_ffmpeg_flags.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_ffmpeg_packet.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_field_profiles.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_forensics.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_geomap.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_image_cache.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_link_bytes.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_link_trace.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_netem_dist.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_network_preflight.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_network_profiles.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_network_shaper.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_ota_link_configs.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_ota_unwrapper.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_ota_wrapper.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_playout_pacer.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_plots.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_pub_sub_pair_types.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_qos_fallback_logging.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_relay_optional_parameters.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_ros_node_entity_ownership.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_session_pipeline.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_stage_latency.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_status_eval.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_status_overview.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_status_overview_observer.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_stream_stats.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_trace_profiles.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/tests/unit/test_transit.py +0 -0
- {rosotacom_dev-2.5.dev65 → rosotacom_dev-2.5.dev67}/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.dev67
|
|
4
4
|
Summary: Host CLI for ROS OTA communication sessions.
|
|
5
5
|
Author: develNor
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -684,6 +684,13 @@ the [link trace recorder](docs/link-trace.md). It writes
|
|
|
684
684
|
`link_trace.jsonl` under the same status directory with `/proc/net/dev` counter
|
|
685
685
|
deltas, echo-heartbeat RTT/loss provenance, and an optional modem-metrics hook.
|
|
686
686
|
|
|
687
|
+
Those counters localise loss to a *direction* and no further. When the question
|
|
688
|
+
is which fragment was lost, whether a retransmit followed, or how one sample's
|
|
689
|
+
sub-messages were spaced, enable the [header-only OTA capture](docs/ota-pcap.md)
|
|
690
|
+
next to them — `shared.ota_pcap.enabled`, off by default, roughly 1 % of payload
|
|
691
|
+
volume, and every packet labelled uplink or downlink. It needs no capability,
|
|
692
|
+
no image change and no extra container.
|
|
693
|
+
|
|
687
694
|
Convert a recorded link trace into a profiles-file entry when you want to replay
|
|
688
695
|
the same drive conditions in a repeatable benchmark:
|
|
689
696
|
|
|
@@ -639,6 +639,13 @@ the [link trace recorder](docs/link-trace.md). It writes
|
|
|
639
639
|
`link_trace.jsonl` under the same status directory with `/proc/net/dev` counter
|
|
640
640
|
deltas, echo-heartbeat RTT/loss provenance, and an optional modem-metrics hook.
|
|
641
641
|
|
|
642
|
+
Those counters localise loss to a *direction* and no further. When the question
|
|
643
|
+
is which fragment was lost, whether a retransmit followed, or how one sample's
|
|
644
|
+
sub-messages were spaced, enable the [header-only OTA capture](docs/ota-pcap.md)
|
|
645
|
+
next to them — `shared.ota_pcap.enabled`, off by default, roughly 1 % of payload
|
|
646
|
+
volume, and every packet labelled uplink or downlink. It needs no capability,
|
|
647
|
+
no image change and no extra container.
|
|
648
|
+
|
|
642
649
|
Convert a recorded link trace into a profiles-file entry when you want to replay
|
|
643
650
|
the same drive conditions in a repeatable benchmark:
|
|
644
651
|
|
|
@@ -32,6 +32,7 @@ living verification hook.
|
|
|
32
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
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.
|
|
34
34
|
- [A fragment sized exactly like the datagram cap stops every fragmented sample](cyclone-fragment-equal-to-max-drops-fragmented-samples.md) - CycloneDDS 11.0.1 delivers nothing above one fragment when `FragmentSize` equals `MaxMessageSize`, where 0.10.5 delivers everything on the identical profile; a 40 B string still crosses, and discovery, endpoint announcement and proxy-writer matching all succeed while no sample arrives.
|
|
35
|
+
- [Two CycloneDDS configurations on one domain stop interoperating](one-domain-two-cyclone-configs-stop-interoperating.md) - on 11.0.1 a publisher and a subscriber on the same host and domain deliver nothing when one carries the local profile and the other the OTA profile, where 0.10.5 delivers in all four combinations; discovery, endpoint announcement and matching all succeed while no sample moves.
|
|
35
36
|
- [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.
|
|
36
37
|
- [Any transport element in a Fast DDS profile doubles every sample on the wire](a-transport-element-doubles-every-fastdds-sample.md) - 366 datagrams for 180 samples against 183 without it; `<builtinTransports>DEFAULT` is a no-op selection and doubles too, so the trigger is the element's presence — removing it takes the shipped OTA profile from 2.10x the payload to 1.04x at identical delivery.
|
|
37
38
|
- [Lifespan is enforced by one DDS reader and not the other](lifespan-is-enforced-by-one-reader-and-not-the-other.md) - under the same 20% oversubscription both stacks queue alike (472 and 433 delivered at ~1.1-1.2 s); with `lifespan: 0.7` CycloneDDS is unchanged and delivers 9.1% inside the bound, while Fast DDS drops to 4 delivered and never exceeds 570 ms — the policy decides shown-vs-suppressed, not how long the wait is.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Two CycloneDDS Configurations on One Domain Stop Interoperating
|
|
2
|
+
|
|
3
|
+
## Claim
|
|
4
|
+
|
|
5
|
+
On CycloneDDS 11.0.1 two participants on the **same host and the same domain**
|
|
6
|
+
exchange no data when they are given different configurations. On 0.10.5 they
|
|
7
|
+
do. Discovery is unaffected in the failing combination — the topic appears in
|
|
8
|
+
`ros2 topic list`, both sides announce their endpoints, the reader builds its
|
|
9
|
+
proxy writers — and no sample is delivered.
|
|
10
|
+
|
|
11
|
+
This is what a session relies on without saying so. A peer renders two whole
|
|
12
|
+
configurations, a local one and an OTA one, and exports `CYCLONEDDS_URI` twice,
|
|
13
|
+
so the second replaces the first: processes started after it view the *local*
|
|
14
|
+
domain through the *OTA* profile while the relay and the application containers
|
|
15
|
+
view it through the local one. Under 0.10.5 that mixture worked. Under 11.0.1
|
|
16
|
+
the bridge subscribes on the local domain, receives nothing, forwards nothing
|
|
17
|
+
into the OTA domain, and the far peer receives nothing — with every stage
|
|
18
|
+
reporting itself healthy.
|
|
19
|
+
|
|
20
|
+
## Setup
|
|
21
|
+
|
|
22
|
+
- Host pair / topology: for the effect itself, one host is enough — two
|
|
23
|
+
containers from the same communication image, `--network host`, one ROS
|
|
24
|
+
domain, one publisher and one subscriber. The session it was found in runs
|
|
25
|
+
across two hosts joined by a point-to-point VPN.
|
|
26
|
+
- Session: none for the isolated measurement; a `std_msgs/msg/String` at 2 Hz
|
|
27
|
+
and `ros2 topic echo … --once`. The two configurations are the ones a session
|
|
28
|
+
renders: `cyclonedds_local_participants.xml` and `cyclonedds_tuned.xml`.
|
|
29
|
+
- rosotacom SHA: measured on the packaged 2.5.dev61 images; re-runs record
|
|
30
|
+
theirs.
|
|
31
|
+
- Profile: none — no impairment; the effect needs none.
|
|
32
|
+
- Seed policy: deterministic (no netem, no random load), `n=1` per cell; the
|
|
33
|
+
effect is present/absent, not a distribution.
|
|
34
|
+
- Stacks: `ros-kilted-cyclonedds` 0.10.5-2noble against
|
|
35
|
+
`ros-lyrical-cyclonedds` 11.0.1-4resolute.
|
|
36
|
+
|
|
37
|
+
## Evidence
|
|
38
|
+
|
|
39
|
+
| publisher / subscriber | 0.10.5 | 11.0.1 |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| local / local | 12 B | 12 B |
|
|
42
|
+
| local / **ota** | 12 B | **0** |
|
|
43
|
+
| **ota** / local | 12 B | **0** |
|
|
44
|
+
| ota / ota | 12 B | 12 B |
|
|
45
|
+
|
|
46
|
+
Inside a failing session, one topic the relay publishes on the local domain:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
/com/out/<peer>/can/twist/max10hz/ota_stamped, domain 47
|
|
50
|
+
subscriber with local_dds.xml : 512 B received
|
|
51
|
+
subscriber with ota_dds.xml : 0 B
|
|
52
|
+
domain 47 seen through local_dds.xml : 103 topics
|
|
53
|
+
domain 47 seen through ota_dds.xml : 29 topics
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Ruled out on the way to it, each measured with the real images on the same
|
|
57
|
+
hosts: cross-host delivery, same-host delivery under one profile,
|
|
58
|
+
`com_msgs/msg/OtaStamped`, the container's IPC namespace, `domain_bridge`
|
|
59
|
+
itself (minimal config, the session's full 27-topic config, with and without the
|
|
60
|
+
OTA profile, with and without `ROS_DOMAIN_ID` set), participant count (0, 6 and
|
|
61
|
+
12 extra participants), and adding the local profile's
|
|
62
|
+
`ParticipantIndex`/`MaxAutoParticipantIndex` to the OTA profile.
|
|
63
|
+
|
|
64
|
+
Verification: automated:
|
|
65
|
+
`pytest tests/unit/test_ota_xml.py::test_shipped_scoped_template_carries_both_domains_and_only_ota_restrictions`
|
|
66
|
+
holds the shape of the configuration that avoids the mixture — OTA restrictions
|
|
67
|
+
scoped to the OTA domain, the local domain left with default discovery. Manual,
|
|
68
|
+
for the effect itself: two containers on one host and one domain, one publisher
|
|
69
|
+
and one subscriber, each given one of the two rendered profiles, all four
|
|
70
|
+
combinations.
|
|
71
|
+
|
|
72
|
+
## Status
|
|
73
|
+
|
|
74
|
+
confirmed, 2026-08-20.
|
|
75
|
+
|
|
76
|
+
Addressed by `cyclonedds_scoped.xml.template`, which carries both domains in one
|
|
77
|
+
file with each section scoped by `Domain Id`, so one configuration can be shared
|
|
78
|
+
by every process on the host. It is an additional template: the two-file
|
|
79
|
+
arrangement is unchanged, and a session that does not name the new one behaves
|
|
80
|
+
exactly as before.
|
|
81
|
+
|
|
82
|
+
## Publication notes
|
|
83
|
+
|
|
84
|
+
The reportable part is not "a DDS version changed". It is that a configuration
|
|
85
|
+
which was *never* uniform became load-bearing without anybody choosing it: the
|
|
86
|
+
mixture had been there all along and was harmless, so nothing recorded it as a
|
|
87
|
+
property of the deployment. A measurement stack should state, beside the
|
|
88
|
+
middleware version, whether every process on a domain was configured
|
|
89
|
+
identically — because on one side of that version boundary the answer does not
|
|
90
|
+
matter and on the other it decides whether any data moves.
|
|
91
|
+
|
|
92
|
+
Second, it is another instance of the same trap as the datagram cap: a link that
|
|
93
|
+
passes discovery, endpoint matching and a heartbeat check while carrying
|
|
94
|
+
nothing. Neither check tests what the payload uses.
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Header-Only OTA Capture
|
|
2
|
+
|
|
3
|
+
A passive, header-only packet capture of the OTA link, written beside the
|
|
4
|
+
[link trace](link-trace.md) by the same node:
|
|
5
|
+
|
|
6
|
+
```text
|
|
7
|
+
session-instances/.../logs/<peer>/status/ota.pcap
|
|
8
|
+
session-instances/.../logs/<peer>/status/ota.json
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Enable it in a session definition:
|
|
12
|
+
|
|
13
|
+
```yaml
|
|
14
|
+
shared:
|
|
15
|
+
use_status_overview: true
|
|
16
|
+
ota_pcap:
|
|
17
|
+
enabled: true
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Everything else is optional:
|
|
21
|
+
|
|
22
|
+
```yaml
|
|
23
|
+
ota_pcap:
|
|
24
|
+
enabled: true
|
|
25
|
+
snaplen: 96 # bytes kept per packet; headers, no payload
|
|
26
|
+
max_mb: 2000 # ceiling for one capture file
|
|
27
|
+
peer_filter: true # keep only packets to or from the remote peer
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Off by default, and off is exactly the session that existed before: a
|
|
31
|
+
definition without the block renders the same peer files it always did, which
|
|
32
|
+
a test asserts by rendering both and diffing them.
|
|
33
|
+
|
|
34
|
+
## What it answers that the link trace cannot
|
|
35
|
+
|
|
36
|
+
`link_trace.jsonl` counts `/proc/net/dev` bytes per direction once a second.
|
|
37
|
+
That localises loss to a **direction** and no further. It cannot say which
|
|
38
|
+
fragment of which sample was lost, whether a retransmit followed, or how one
|
|
39
|
+
sample's sub-messages were spaced on the wire.
|
|
40
|
+
|
|
41
|
+
The capture answers those, at roughly 1 % of payload volume. Use the two
|
|
42
|
+
together: the trace is the cheap continuous record, the capture is what you
|
|
43
|
+
turn on for a measurement run.
|
|
44
|
+
|
|
45
|
+
## What the file is
|
|
46
|
+
|
|
47
|
+
`LINKTYPE_LINUX_SLL` (113), microsecond `pcap`, snaplen 96 by default. Every
|
|
48
|
+
reader takes it — Wireshark, `tshark`, `scapy`, `capinfos`.
|
|
49
|
+
|
|
50
|
+
The link type is the important choice. The capture uses a `SOCK_DGRAM` packet
|
|
51
|
+
socket, so one code path works on both link types the fleet has: a VPN `tun`
|
|
52
|
+
device is layer 3 and has no link-layer header at all, while a control-centre
|
|
53
|
+
LAN port is Ethernet. The kernel hands `SOCK_DGRAM` the network-layer packet
|
|
54
|
+
either way, plus the `sockaddr_ll` that `LINKTYPE_LINUX_SLL` is defined over.
|
|
55
|
+
|
|
56
|
+
That pseudo-header carries the field the analysis is for:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# uplink (this host sent it) against downlink, per packet
|
|
60
|
+
tshark -r ota.pcap -T fields -e sll.pkttype | sort | uniq -c
|
|
61
|
+
# 4 = PACKET_OUTGOING, 0 = PACKET_HOST
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
A `LINKTYPE_RAW` capture would have thrown that away.
|
|
65
|
+
|
|
66
|
+
Timestamps come from the kernel (`SO_TIMESTAMPNS`), not from the moment python
|
|
67
|
+
reached the packet.
|
|
68
|
+
|
|
69
|
+
## The sidecar, and the number that matters
|
|
70
|
+
|
|
71
|
+
`ota.json` is written when the capture stops:
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"interface": "tun0",
|
|
76
|
+
"snaplen": 96,
|
|
77
|
+
"linktype": "LINKTYPE_LINUX_SLL",
|
|
78
|
+
"filter": "udp and host 10.254.0.37",
|
|
79
|
+
"promiscuous": false,
|
|
80
|
+
"packets": 2434,
|
|
81
|
+
"bytes": 272498,
|
|
82
|
+
"kernel_drops": 0,
|
|
83
|
+
"kernel_seen": 4638,
|
|
84
|
+
"first_timestamp": 1787297717.008177,
|
|
85
|
+
"last_timestamp": 1787297733.10892,
|
|
86
|
+
"stopped_because": "signal"
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**`kernel_drops` is a gap in the file, not on the link.** A capture that fell
|
|
91
|
+
behind looks exactly like radio loss to anyone reading the pcap months later,
|
|
92
|
+
so subtract it before reading any loss out of the capture. Zero is the normal
|
|
93
|
+
result on a link of a few Mbit/s; a non-zero value means this process, not the
|
|
94
|
+
radio.
|
|
95
|
+
|
|
96
|
+
## Which interface, and the refusal that matters
|
|
97
|
+
|
|
98
|
+
The interface is not configured. It is resolved from the peer's own OTA
|
|
99
|
+
address by `com_py.link_bytes.resolve_link_interface` — the same resolution the
|
|
100
|
+
status snapshot's `link` block uses, including its refusal to report a loopback
|
|
101
|
+
interface for a non-loopback address. That refusal is issue #267: sampling `lo`
|
|
102
|
+
on a machine that also runs an `-a` recorder reads about 28 Gbit/s next to a
|
|
103
|
+
6 Mbit/s link, and it survived a field session and an offline analysis before
|
|
104
|
+
anyone doubted the number. A capture on the wrong device would be the same
|
|
105
|
+
mistake in a bigger file.
|
|
106
|
+
|
|
107
|
+
If no interface resolves, the capture is skipped with a warning and the session
|
|
108
|
+
runs on. `shared.ota_pcap.enabled` therefore requires
|
|
109
|
+
`shared.use_status_overview: true`, which is where that resolution lives.
|
|
110
|
+
|
|
111
|
+
## Privilege, containers, and what the option costs
|
|
112
|
+
|
|
113
|
+
Nothing is added. The communication container already runs as root with
|
|
114
|
+
`CAP_NET_RAW` in docker's default set, so the capture needs no `--cap-add`, no
|
|
115
|
+
image change, no rebuild and no extra container in `docker ps`.
|
|
116
|
+
|
|
117
|
+
`CAP_NET_ADMIN` is *not* taken and is not needed: it buys promiscuous mode,
|
|
118
|
+
which this capture deliberately does not use. Everything of interest is
|
|
119
|
+
addressed to or from this host, and promiscuous mode on a control-centre LAN
|
|
120
|
+
port would collect other people's traffic.
|
|
121
|
+
|
|
122
|
+
The capture runs as a separate process rather than inside the status node's
|
|
123
|
+
thread, so a capture that misbehaves cannot reach the snapshot an operator is
|
|
124
|
+
watching. It is stopped with `SIGINT` and waited for, because that is what
|
|
125
|
+
writes the sidecar JSON.
|
|
126
|
+
|
|
127
|
+
## Cost
|
|
128
|
+
|
|
129
|
+
Header-only at 96 bytes: about 6 MB per minute at 500 packets/s, so a two-hour
|
|
130
|
+
run is well under a gigabyte. `max_mb` bounds a mistake — a capture pointed at
|
|
131
|
+
a busy LAN port — rather than shaping a run; when it is reached the capture
|
|
132
|
+
stops and says so in `stopped_because`.
|
|
133
|
+
|
|
134
|
+
Nothing is transmitted, so the capture costs no link capacity.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!--
|
|
3
|
+
One CycloneDDS configuration for both of a peer's domains, each section scoped
|
|
4
|
+
to the domain it belongs to.
|
|
5
|
+
|
|
6
|
+
Set it as `shared.rmw.ota.cyclone.config` and leave the local one unset: this
|
|
7
|
+
file already carries the local domain's section, so nothing has to overwrite
|
|
8
|
+
anything.
|
|
9
|
+
|
|
10
|
+
Why it exists. The two-file arrangement renders a local profile and an OTA
|
|
11
|
+
profile and exports CYCLONEDDS_URI twice, so the second replaces the first and
|
|
12
|
+
every process started after it views the *local* domain through the *OTA*
|
|
13
|
+
profile. On CycloneDDS 0.10.5 that was survivable: participants configured
|
|
14
|
+
differently on one host and one domain still exchanged data. On 11.0.1 they do
|
|
15
|
+
not — they discover each other, announce their endpoints, match, and deliver
|
|
16
|
+
nothing. Measured on one host, one domain, a publisher and a subscriber:
|
|
17
|
+
|
|
18
|
+
publisher / subscriber 0.10.5 11.0.1
|
|
19
|
+
local / local 12 B 12 B
|
|
20
|
+
local / ota 12 B 0
|
|
21
|
+
ota / local 12 B 0
|
|
22
|
+
ota / ota 12 B 12 B
|
|
23
|
+
|
|
24
|
+
A session whose relay publishes under one profile and whose bridge subscribes
|
|
25
|
+
under the other therefore hands nothing from the local domain into the OTA
|
|
26
|
+
domain, and the link carries nothing while every stage looks healthy
|
|
27
|
+
(docs/findings/one-domain-two-cyclone-configs-stop-interoperating.md).
|
|
28
|
+
|
|
29
|
+
Scoping fixes the cause rather than the symptom: the OTA settings apply to the
|
|
30
|
+
OTA domain, the local domain keeps default discovery with room for many
|
|
31
|
+
participants, and one file can be shared by every process on the host.
|
|
32
|
+
|
|
33
|
+
The two-file arrangement stays exactly as it was — this is an additional
|
|
34
|
+
template, not a replacement, and a session that does not name it is unchanged.
|
|
35
|
+
-->
|
|
36
|
+
<CycloneDDS xmlns="https://cdds.io/config">
|
|
37
|
+
<!--
|
|
38
|
+
The OTA domain: interface-pinned, unicast-only, with the datagram caps the
|
|
39
|
+
provisioned link is sized for. Identical to cyclonedds_tuned.xml except that
|
|
40
|
+
it says which domain it is for.
|
|
41
|
+
-->
|
|
42
|
+
<Domain Id="#ota_domain">
|
|
43
|
+
<General>
|
|
44
|
+
<AllowMulticast>false</AllowMulticast>
|
|
45
|
+
<Interfaces>
|
|
46
|
+
<NetworkInterface address="#host_ip"/>
|
|
47
|
+
</Interfaces>
|
|
48
|
+
<MulticastRecvNetworkInterfaceAddresses>none</MulticastRecvNetworkInterfaceAddresses>
|
|
49
|
+
<!-- Strictly below MaxMessageSize; see cyclonedds_tuned.xml for what
|
|
50
|
+
making them equal cost. -->
|
|
51
|
+
<FragmentSize>1024B</FragmentSize>
|
|
52
|
+
<MaxMessageSize>1200B</MaxMessageSize>
|
|
53
|
+
<MaxRexmitMessageSize>1200B</MaxRexmitMessageSize>
|
|
54
|
+
</General>
|
|
55
|
+
|
|
56
|
+
<Discovery>
|
|
57
|
+
<Peers>
|
|
58
|
+
<!--peer-block--><Peer Address="#peer"/><!--/peer-block-->
|
|
59
|
+
</Peers>
|
|
60
|
+
<EnableTopicDiscoveryEndpoints>false</EnableTopicDiscoveryEndpoints>
|
|
61
|
+
<LeaseDuration>60s</LeaseDuration>
|
|
62
|
+
<SPDPInterval>#spdp_interval</SPDPInterval>
|
|
63
|
+
</Discovery>
|
|
64
|
+
|
|
65
|
+
<Internal>
|
|
66
|
+
<SquashParticipants>true</SquashParticipants>
|
|
67
|
+
</Internal>
|
|
68
|
+
|
|
69
|
+
<Tracing>
|
|
70
|
+
<Verbosity>config</Verbosity>
|
|
71
|
+
<OutputFile>/tmp/cyclonedds.log</OutputFile>
|
|
72
|
+
</Tracing>
|
|
73
|
+
</Domain>
|
|
74
|
+
|
|
75
|
+
<!--
|
|
76
|
+
The local domain: default discovery, more participants. It pins no interface,
|
|
77
|
+
disables no multicast and sets no peer list, because intra-host discovery has
|
|
78
|
+
to keep working — the same reasoning as cyclonedds_local_participants.xml,
|
|
79
|
+
including why 119 and not higher.
|
|
80
|
+
-->
|
|
81
|
+
<Domain Id="#local_domain">
|
|
82
|
+
<Discovery>
|
|
83
|
+
<ParticipantIndex>auto</ParticipantIndex>
|
|
84
|
+
<MaxAutoParticipantIndex>119</MaxAutoParticipantIndex>
|
|
85
|
+
</Discovery>
|
|
86
|
+
</Domain>
|
|
87
|
+
</CycloneDDS>
|
|
@@ -15,8 +15,20 @@ import re
|
|
|
15
15
|
import sys
|
|
16
16
|
import tempfile
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
KNOWN_PLACEHOLDERS = {
|
|
19
|
+
"#host_ip",
|
|
20
|
+
"#peer",
|
|
21
|
+
"#easy_mode_ip",
|
|
22
|
+
"#spdp_interval",
|
|
23
|
+
#: A template that scopes its settings to one ROS domain resolves these.
|
|
24
|
+
#: Cyclone applies a <Domain> section to the domain its Id names, so a
|
|
25
|
+
#: single configuration can hold the OTA settings for the OTA domain and
|
|
26
|
+
#: leave the local domain alone — which is what lets every process on a
|
|
27
|
+
#: host share one configuration instead of half of them carrying the OTA
|
|
28
|
+
#: profile and half the local one.
|
|
29
|
+
"#local_domain",
|
|
30
|
+
"#ota_domain",
|
|
31
|
+
}
|
|
20
32
|
PLACEHOLDER_PATTERN = re.compile(r"#[A-Za-z_][A-Za-z0-9_]*")
|
|
21
33
|
DEFAULT_SPDP_INTERVAL = "30s"
|
|
22
34
|
|
|
@@ -48,6 +60,19 @@ def _resolved_address(value: str, label: str) -> str:
|
|
|
48
60
|
return address
|
|
49
61
|
|
|
50
62
|
|
|
63
|
+
def _resolved_domain(value: str, label: str) -> str:
|
|
64
|
+
"""A ROS domain id, validated rather than pasted into the XML.
|
|
65
|
+
|
|
66
|
+
An unusable Id is worse than a missing one: Cyclone keeps a <Domain>
|
|
67
|
+
section it cannot match to any domain, so the settings vanish without a
|
|
68
|
+
word and the link comes up on defaults.
|
|
69
|
+
"""
|
|
70
|
+
domain = str(value).strip()
|
|
71
|
+
if not domain.isdigit() or not 0 <= int(domain) <= 232:
|
|
72
|
+
raise ValueError(f"{label} must be a ROS domain id between 0 and 232, got {value!r}.")
|
|
73
|
+
return str(int(domain))
|
|
74
|
+
|
|
75
|
+
|
|
51
76
|
def _resolved_spdp_interval(value: str) -> str:
|
|
52
77
|
interval = value.strip().lower()
|
|
53
78
|
if not interval:
|
|
@@ -99,9 +124,7 @@ def _expand_peer_block(content: str, peer_ips: list) -> str:
|
|
|
99
124
|
|
|
100
125
|
has_markers = PEER_BLOCK_OPEN in content
|
|
101
126
|
if has_markers and (PEER_BLOCK_CLOSE not in content):
|
|
102
|
-
raise RuntimeError(
|
|
103
|
-
f"Template has '{PEER_BLOCK_OPEN}' without matching '{PEER_BLOCK_CLOSE}'."
|
|
104
|
-
)
|
|
127
|
+
raise RuntimeError(f"Template has '{PEER_BLOCK_OPEN}' without matching '{PEER_BLOCK_CLOSE}'.")
|
|
105
128
|
|
|
106
129
|
if len(peer_ips) == 1 and not has_markers:
|
|
107
130
|
return content.replace("#peer", peer_ips[0])
|
|
@@ -116,9 +139,7 @@ def _expand_peer_block(content: str, peer_ips: list) -> str:
|
|
|
116
139
|
|
|
117
140
|
matches = list(PEER_BLOCK_PATTERN.finditer(content))
|
|
118
141
|
if len(matches) != 1:
|
|
119
|
-
raise RuntimeError(
|
|
120
|
-
f"Template must contain exactly one peer-block region; found {len(matches)}."
|
|
121
|
-
)
|
|
142
|
+
raise RuntimeError(f"Template must contain exactly one peer-block region; found {len(matches)}.")
|
|
122
143
|
m = matches[0]
|
|
123
144
|
block = m.group(1)
|
|
124
145
|
if "#peer" not in block:
|
|
@@ -128,11 +149,11 @@ def _expand_peer_block(content: str, peer_ips: list) -> str:
|
|
|
128
149
|
|
|
129
150
|
# Preserve the indentation of the marker line so duplicated blocks align.
|
|
130
151
|
line_start = content.rfind("\n", 0, m.start()) + 1
|
|
131
|
-
indent = content[line_start:m.start()]
|
|
152
|
+
indent = content[line_start : m.start()]
|
|
132
153
|
sep = ("\n" + indent) if not indent.strip() else ""
|
|
133
154
|
|
|
134
155
|
rendered = sep.join(block.replace("#peer", ip) for ip in peer_ips)
|
|
135
|
-
return content[:m.start()] + rendered + content[m.end():]
|
|
156
|
+
return content[: m.start()] + rendered + content[m.end() :]
|
|
136
157
|
|
|
137
158
|
|
|
138
159
|
def main(
|
|
@@ -141,12 +162,14 @@ def main(
|
|
|
141
162
|
peer: str = None,
|
|
142
163
|
easy_mode_ip: str = None,
|
|
143
164
|
spdp_interval: str = DEFAULT_SPDP_INTERVAL,
|
|
165
|
+
local_domain: str = None,
|
|
166
|
+
ota_domain: str = None,
|
|
144
167
|
) -> str:
|
|
145
168
|
path = _template_path(config)
|
|
146
169
|
if not os.path.exists(path):
|
|
147
170
|
raise FileNotFoundError(f"Template not found: {path}")
|
|
148
171
|
|
|
149
|
-
with open(path,
|
|
172
|
+
with open(path, encoding="utf-8") as f:
|
|
150
173
|
content = f.read()
|
|
151
174
|
|
|
152
175
|
found = set(PLACEHOLDER_PATTERN.findall(content))
|
|
@@ -159,9 +182,7 @@ def main(
|
|
|
159
182
|
|
|
160
183
|
if "#host_ip" in found:
|
|
161
184
|
if not host_ip:
|
|
162
|
-
raise RuntimeError(
|
|
163
|
-
f"Template '{os.path.basename(path)}' uses #host_ip but --host-ip was not provided."
|
|
164
|
-
)
|
|
185
|
+
raise RuntimeError(f"Template '{os.path.basename(path)}' uses #host_ip but --host-ip was not provided.")
|
|
165
186
|
content = content.replace("#host_ip", _resolved_address(host_ip, "Host IP"))
|
|
166
187
|
|
|
167
188
|
if "#easy_mode_ip" in found:
|
|
@@ -169,45 +190,60 @@ def main(
|
|
|
169
190
|
raise RuntimeError(
|
|
170
191
|
f"Template '{os.path.basename(path)}' uses #easy_mode_ip but --easy-mode-ip was not provided."
|
|
171
192
|
)
|
|
172
|
-
content = content.replace(
|
|
173
|
-
"#easy_mode_ip", _resolved_address(easy_mode_ip, "Easy Mode IP")
|
|
174
|
-
)
|
|
193
|
+
content = content.replace("#easy_mode_ip", _resolved_address(easy_mode_ip, "Easy Mode IP"))
|
|
175
194
|
|
|
176
195
|
if "#spdp_interval" in found:
|
|
177
196
|
content = content.replace("#spdp_interval", _resolved_spdp_interval(spdp_interval))
|
|
178
197
|
|
|
198
|
+
for placeholder, value, option in (
|
|
199
|
+
("#local_domain", local_domain, "--local-domain"),
|
|
200
|
+
("#ota_domain", ota_domain, "--ota-domain"),
|
|
201
|
+
):
|
|
202
|
+
if placeholder in found:
|
|
203
|
+
if value is None or not str(value).strip():
|
|
204
|
+
raise RuntimeError(
|
|
205
|
+
f"Template '{os.path.basename(path)}' uses {placeholder} but {option} was not provided."
|
|
206
|
+
)
|
|
207
|
+
content = content.replace(placeholder, _resolved_domain(value, placeholder))
|
|
208
|
+
|
|
179
209
|
if "#peer" in found:
|
|
180
210
|
if not peer:
|
|
181
|
-
raise RuntimeError(
|
|
182
|
-
f"Template '{os.path.basename(path)}' uses #peer but --peer was not provided."
|
|
183
|
-
)
|
|
211
|
+
raise RuntimeError(f"Template '{os.path.basename(path)}' uses #peer but --peer was not provided.")
|
|
184
212
|
content = _expand_peer_block(content, _resolve_peer_ips(peer))
|
|
185
213
|
|
|
186
214
|
return content
|
|
187
215
|
|
|
188
216
|
|
|
189
217
|
if __name__ == "__main__":
|
|
190
|
-
parser = argparse.ArgumentParser(
|
|
191
|
-
description="Resolve placeholders in an OTA DDS XML template."
|
|
192
|
-
)
|
|
218
|
+
parser = argparse.ArgumentParser(description="Resolve placeholders in an OTA DDS XML template.")
|
|
193
219
|
parser.add_argument(
|
|
194
|
-
"-c",
|
|
220
|
+
"-c",
|
|
221
|
+
"--config",
|
|
222
|
+
required=True,
|
|
195
223
|
help="Template name (e.g. fastdds_v1.xml, cyclonedds.xml, fastdds_easy_mode.xml).",
|
|
196
224
|
)
|
|
197
225
|
parser.add_argument(
|
|
198
|
-
"-i",
|
|
226
|
+
"-i",
|
|
227
|
+
"--host-ip",
|
|
228
|
+
dest="host_ip",
|
|
199
229
|
help="Resolved local host address (#host_ip).",
|
|
200
230
|
)
|
|
201
231
|
parser.add_argument(
|
|
202
|
-
"-p",
|
|
232
|
+
"-p",
|
|
233
|
+
"--peer",
|
|
234
|
+
dest="peer",
|
|
203
235
|
help="Resolved peer address, or comma-separated addresses (#peer).",
|
|
204
236
|
)
|
|
205
237
|
parser.add_argument(
|
|
206
|
-
"-e",
|
|
238
|
+
"-e",
|
|
239
|
+
"--easy-mode-ip",
|
|
240
|
+
dest="easy_mode_ip",
|
|
207
241
|
help="Resolved Fast DDS Easy Mode address (#easy_mode_ip).",
|
|
208
242
|
)
|
|
209
243
|
parser.add_argument(
|
|
210
|
-
"-o",
|
|
244
|
+
"-o",
|
|
245
|
+
"--output",
|
|
246
|
+
dest="output",
|
|
211
247
|
help=(
|
|
212
248
|
"Write the rendered XML to this path, atomically. Prefer this over a shell "
|
|
213
249
|
"redirect: `> file` truncates the target before this script runs, so a "
|
|
@@ -216,6 +252,16 @@ if __name__ == "__main__":
|
|
|
216
252
|
"comes up carrying nothing."
|
|
217
253
|
),
|
|
218
254
|
)
|
|
255
|
+
parser.add_argument(
|
|
256
|
+
"--local-domain",
|
|
257
|
+
dest="local_domain",
|
|
258
|
+
help="Local ROS domain id, for a template that scopes a section to it (#local_domain).",
|
|
259
|
+
)
|
|
260
|
+
parser.add_argument(
|
|
261
|
+
"--ota-domain",
|
|
262
|
+
dest="ota_domain",
|
|
263
|
+
help="OTA ROS domain id, for a template that scopes a section to it (#ota_domain).",
|
|
264
|
+
)
|
|
219
265
|
parser.add_argument(
|
|
220
266
|
"--spdp-interval",
|
|
221
267
|
dest="spdp_interval",
|
|
@@ -224,8 +270,7 @@ if __name__ == "__main__":
|
|
|
224
270
|
)
|
|
225
271
|
args = parser.parse_args()
|
|
226
272
|
output = args.output
|
|
227
|
-
rendered = main(**{k: v for k, v in vars(args).items()
|
|
228
|
-
if v is not None and k != "output"})
|
|
273
|
+
rendered = main(**{k: v for k, v in vars(args).items() if v is not None and k != "output"})
|
|
229
274
|
if not output:
|
|
230
275
|
print(rendered)
|
|
231
276
|
raise SystemExit(0)
|