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.
Files changed (378) hide show
  1. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/workflows/nightly-e2e.yml +1 -0
  2. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/PKG-INFO +26 -1
  3. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/README.md +25 -0
  4. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/deployment-configuration.md +23 -0
  5. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/findings/README.md +3 -0
  6. rosotacom_dev-2.5.dev53/docs/findings/fastdds-datagram-cap-drops-large-samples.md +89 -0
  7. rosotacom_dev-2.5.dev53/docs/findings/graph-derived-types-block-a-non-graph-transport.md +79 -0
  8. rosotacom_dev-2.5.dev53/docs/findings/sender-rows-make-a-dead-link-look-loss-free.md +59 -0
  9. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/session-configuration.md +87 -3
  10. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/benchmark.py +12 -2
  11. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/cli.py +182 -42
  12. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/cli_benchmark.py +80 -28
  13. rosotacom_dev-2.5.dev53/src/rosotacom/network_preflight.py +134 -0
  14. {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
  15. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/6_sized_payload_zen/session-definition.yaml +3 -0
  16. rosotacom_dev-2.5.dev53/src/rosotacom/resources/ws/ota_configs/fastdds_easy_mode.xml.template +49 -0
  17. rosotacom_dev-2.5.dev53/src/rosotacom/resources/ws/ota_configs/fastdds_tuned.xml.template +154 -0
  18. {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
  19. {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
  20. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/qos.py +24 -0
  21. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/session/content/base/session_plugin_base.yaml +21 -3
  22. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/session/creation/generate_session_files.py +84 -7
  23. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/transit.py +20 -2
  24. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom_dev.egg-info/PKG-INFO +26 -1
  25. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom_dev.egg-info/SOURCES.txt +10 -0
  26. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom_dev.egg-info/scm_file_list.json +10 -0
  27. rosotacom_dev-2.5.dev53/src/rosotacom_dev.egg-info/scm_version.json +8 -0
  28. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_markdown_links.py +15 -1
  29. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_packaged_resources.py +2 -0
  30. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_security_maintenance_config.py +4 -0
  31. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/e2e/conftest.py +1 -0
  32. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/sessions/generate_rmw_matrix.py +7 -0
  33. rosotacom_dev-2.5.dev53/tests/sessions/rmw_matrix/1_heartbeat_fastdds-default/session-definition.yaml +22 -0
  34. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_benchmark.py +15 -0
  35. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_cli.py +19 -2
  36. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_cli_benchmark.py +76 -0
  37. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_concurrency.py +25 -1
  38. rosotacom_dev-2.5.dev53/tests/unit/test_network_preflight.py +173 -0
  39. rosotacom_dev-2.5.dev53/tests/unit/test_ota_link_configs.py +288 -0
  40. rosotacom_dev-2.5.dev53/tests/unit/test_pub_sub_pair_types.py +144 -0
  41. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_relay_optional_parameters.py +1 -1
  42. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_transit.py +26 -2
  43. rosotacom_dev-2.5.dev51/src/rosotacom_dev.egg-info/scm_version.json +0 -8
  44. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.devcontainer/devcontainer.json.template +0 -0
  45. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.devcontainer/re_generate_devcontainer_json.py +0 -0
  46. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/CODEOWNERS +0 -0
  47. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/ISSUE_TEMPLATE/documentation-audit.md +0 -0
  48. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/ISSUE_TEMPLATE/implementation-cleanup.md +0 -0
  49. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/ISSUE_TEMPLATE/quality-workflow.md +0 -0
  50. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/ISSUE_TEMPLATE/redesign.md +0 -0
  51. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/ISSUE_TEMPLATE/release-process.md +0 -0
  52. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/ISSUE_TEMPLATE/repository-diagnosis.md +0 -0
  53. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/ISSUE_TEMPLATE/test-ci-audit.md +0 -0
  54. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/ISSUE_TEMPLATE/work-item.md +0 -0
  55. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  56. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/actions/setup-just/action.yml +0 -0
  57. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/dependabot.yml +0 -0
  58. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/workflows/benchmark-calibrate.yml +0 -0
  59. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/workflows/benchmark-gate.yml +0 -0
  60. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/workflows/dev-release.yml +0 -0
  61. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/workflows/image-scan.yml +0 -0
  62. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/workflows/pr-lightweight.yml +0 -0
  63. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/workflows/pr-merge-gate.yml +0 -0
  64. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.github/workflows/release.yml +0 -0
  65. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/.pre-commit-config.yaml +0 -0
  66. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/AGENTS.md +0 -0
  67. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/CONCURRENCY.md +0 -0
  68. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/CONTRIBUTING.md +0 -0
  69. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/DEVELOPMENT_PRINCIPLES.md +0 -0
  70. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/LICENSE.txt +0 -0
  71. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/MANIFEST.in +0 -0
  72. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/budgets.jsonl +0 -0
  73. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/calibration/README.md +0 -0
  74. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/calibration/capacity-size-tight-cyclone.json +0 -0
  75. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/calibration/probe-loss-gop-tight-cyclone.json +0 -0
  76. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/calibration/probe-loss-nominal-cyclone.json +0 -0
  77. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/calibration/probe-loss-tight-cyclone.json +0 -0
  78. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/calibration/probe-loss-tight-fastdds.json +0 -0
  79. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/calibration/probe-loss-tight-zenoh.json +0 -0
  80. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/codecov.yml +0 -0
  81. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/benchmark-ab.md +0 -0
  82. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/benchmark-bag-as-load.md +0 -0
  83. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/ci.md +0 -0
  84. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/ffmpeg-keyframes.md +0 -0
  85. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/findings/cyclone-spdp-discovery-bursts.md +0 -0
  86. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/findings/delay-alone-no-loss.md +0 -0
  87. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/findings/head-of-line-irregularity.md +0 -0
  88. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/findings/jitter-loss-bandwidth-latency.md +0 -0
  89. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/findings/keyframe-loss-kills-the-next-deltas.md +0 -0
  90. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/findings/lighter-message-loss.md +0 -0
  91. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/findings/oversubscription-queues-not-losses.md +0 -0
  92. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/findings/reorder-becomes-reader-loss.md +0 -0
  93. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/findings/repro/decode_chain_repro.py +0 -0
  94. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/findings/repro/reorder_drop_repro.py +0 -0
  95. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/findings/zero-loss-boundaries-18kb-20hz.md +0 -0
  96. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/forensics-report.md +0 -0
  97. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/geo-link-map.md +0 -0
  98. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/github-repository-settings.md +0 -0
  99. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/link-bandwidth.md +0 -0
  100. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/link-trace.md +0 -0
  101. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/owner-runbook.md +0 -0
  102. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/performance-bands.md +0 -0
  103. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/playbooks/README.md +0 -0
  104. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/quality-model.md +0 -0
  105. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/release-notes/TEMPLATE.md +0 -0
  106. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/release-notes/v2.1.md +0 -0
  107. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/release-notes/v2.2.md +0 -0
  108. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/release-notes/v2.3.md +0 -0
  109. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/release-notes/v2.4.md +0 -0
  110. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/release.md +0 -0
  111. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/rfcs/0001-expectation-driven-test-suite.md +0 -0
  112. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/rfcs/0002-expectation-concepts.md +0 -0
  113. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/rfcs/0003-metric-backbone.md +0 -0
  114. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/rfcs/0004-network-profiles.md +0 -0
  115. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/rfcs/0005-benchmark-genres-and-ci.md +0 -0
  116. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/rfcs/0006-dynamic-qos.md +0 -0
  117. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/rfcs/0007-regression-gate.md +0 -0
  118. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/rfcs/README.md +0 -0
  119. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/testing.md +0 -0
  120. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/docs/work-items.md +0 -0
  121. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/install.sh +0 -0
  122. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/justfile +0 -0
  123. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/media/control_center.png +0 -0
  124. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/media/echo_test.png +0 -0
  125. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/media/forensics-report-example.png +0 -0
  126. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/media/host.png +0 -0
  127. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/media/vehicle.png +0 -0
  128. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/pyproject.toml +0 -0
  129. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/requirements.txt +0 -0
  130. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/rosotacom.yaml +0 -0
  131. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/setup.cfg +0 -0
  132. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/__init__.py +0 -0
  133. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/__main__.py +0 -0
  134. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/anonymize.py +0 -0
  135. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/bag_ground_truth.py +0 -0
  136. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/benched_set.py +0 -0
  137. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/benchmark_delta.py +0 -0
  138. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/bundle_check.py +0 -0
  139. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/deployment.py +0 -0
  140. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/ffmpeg_packet.py +0 -0
  141. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/forensics.py +0 -0
  142. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/geomap.py +0 -0
  143. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/image_cache.py +0 -0
  144. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/netem_dist.py +0 -0
  145. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/network_profiles.py +0 -0
  146. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/network_shaper.py +0 -0
  147. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/plots.py +0 -0
  148. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/py.typed +0 -0
  149. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/benched-set.yaml +0 -0
  150. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/.gitignore +0 -0
  151. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/README.md +0 -0
  152. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/__init__.py +0 -0
  153. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/bags/8_drop_reference/metadata.yaml +0 -0
  154. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/deployment.example.yaml +0 -0
  155. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/dist/field-20260817.dist +0 -0
  156. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/profiles.yaml +0 -0
  157. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/ros2docker.json +0 -0
  158. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/rosotacom.yaml +0 -0
  159. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scenarios/2_native_chatter/scenario-definition.yaml +0 -0
  160. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_a.sh +0 -0
  161. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_b.sh +0 -0
  162. {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
  163. {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
  164. {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
  165. {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
  166. {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
  167. {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
  168. {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
  169. {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
  170. {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
  171. {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
  172. {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
  173. {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
  174. {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
  175. {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
  176. {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
  177. {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
  178. {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
  179. {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
  180. {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
  181. {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
  182. {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
  183. {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
  184. {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
  185. {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
  186. {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
  187. {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
  188. {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
  189. {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
  190. {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
  191. {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
  192. {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
  193. {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
  194. {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
  195. {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
  196. {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
  197. {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
  198. {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
  199. {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
  200. {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
  201. {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
  202. {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
  203. {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
  204. {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
  205. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/10_restamp/session-definition.yaml +0 -0
  206. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/11_trickle/session-definition.yaml +0 -0
  207. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/12_content_integrity/session-definition.yaml +0 -0
  208. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/13_link_latency/session-definition.yaml +0 -0
  209. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/14_remote_assist_anonymized/session-definition.yaml +0 -0
  210. {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
  211. {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
  212. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/17_synthetic_camera_quality/session-definition.yaml +0 -0
  213. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/1_heartbeat/session-definition.yaml +0 -0
  214. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/1_heartbeat_status/session-definition.yaml +0 -0
  215. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/2_native_chatter/session-definition.yaml +0 -0
  216. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/3_comp_occ_grid/session-definition.yaml +0 -0
  217. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/5_sized_payload/session-definition.yaml +0 -0
  218. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/7_latched_static/session-definition.yaml +0 -0
  219. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/8_drop/session-definition.yaml +0 -0
  220. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/9_throttle/session-definition.yaml +0 -0
  221. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/bench_1_1_capacity/session-definition.yaml +0 -0
  222. {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
  223. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/bench_1_3_ramp/session-definition.yaml +0 -0
  224. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/bench_1_4_recovery/session-definition.yaml +0 -0
  225. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/examples/sessions/bench_1_5_camera/session-definition.yaml +0 -0
  226. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ros2docker.json.example +0 -0
  227. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/.vscode/c_cpp_properties.json +0 -0
  228. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/.vscode/settings.json +0 -0
  229. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_easy_mode.xml.template +0 -0
  230. {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
  231. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v2.xml.template +0 -0
  232. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v3.xml.template +0 -0
  233. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v4.xml.template +0 -0
  234. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v5.xml.template +0 -0
  235. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/create_zenoh_json5.py +0 -0
  236. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/cyclonedds_local_participants.xml.template +0 -0
  237. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/cyclonedds_minimal.xml.template +0 -0
  238. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/cyclonedds_tuned.xml.template +0 -0
  239. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/fastdds_unicast.xml.template +0 -0
  240. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/get_ota_xml.py +0 -0
  241. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/utils.py +0 -0
  242. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ota_configs/zenoh.json5.template +0 -0
  243. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/.gitkeep +0 -0
  244. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_cpp/CMakeLists.txt +0 -0
  245. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_cpp/COLCON_IGNORE +0 -0
  246. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_cpp/LICENSE.txt +0 -0
  247. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_cpp/package.xml +0 -0
  248. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_cpp/src/hz_monitor.cpp +0 -0
  249. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_compressor.cpp +0 -0
  250. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_decompressor.cpp +0 -0
  251. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_msgs/CMakeLists.txt +0 -0
  252. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_msgs/LICENSE.txt +0 -0
  253. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/CompressedData.msg +0 -0
  254. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/EchoHeartbeat.msg +0 -0
  255. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/OtaStamped.msg +0 -0
  256. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/SizedPayload.msg +0 -0
  257. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_msgs/package.xml +0 -0
  258. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/LICENSE.txt +0 -0
  259. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/__init__.py +0 -0
  260. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_in.py +0 -0
  261. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_out.py +0 -0
  262. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/ffmpeg_flags.py +0 -0
  263. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/heartbeat_echo.py +0 -0
  264. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/hz_monitor.py +0 -0
  265. {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
  266. {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
  267. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/lanelet_saver.py +0 -0
  268. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/latch_relay.py +0 -0
  269. {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
  270. {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
  271. {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
  272. {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
  273. {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
  274. {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
  275. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_bytes.py +0 -0
  276. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_trace.py +0 -0
  277. {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
  278. {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
  279. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/msg_transform.py +0 -0
  280. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pair_management.py +0 -0
  281. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/playout_pacer.py +0 -0
  282. {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
  283. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_in.py +0 -0
  284. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_out.py +0 -0
  285. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/restamp.py +0 -0
  286. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/sized_publisher.py +0 -0
  287. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency.py +0 -0
  288. {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
  289. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview.py +0 -0
  290. {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
  291. {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
  292. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_monitor.py +0 -0
  293. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_resolution.py +0 -0
  294. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/trickle.py +0 -0
  295. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_compressor.py +0 -0
  296. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_decompressor.py +0 -0
  297. {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
  298. {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
  299. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/package.xml +0 -0
  300. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/resource/com_py +0 -0
  301. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/setup.cfg +0 -0
  302. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/setup.py +0 -0
  303. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/test/test_copyright.py +0 -0
  304. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/test/test_flake8.py +0 -0
  305. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/ros2src/com_py/test/test_pep257.py +0 -0
  306. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/session/content/network/up_connectivity.py +0 -0
  307. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/session/content/network/wifi_network_analysis_2.py +0 -0
  308. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/session/creation/anonymize_bag.py +0 -0
  309. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/session/creation/catmux_log_setup.sh +0 -0
  310. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/session/creation/create_session_yaml.py +0 -0
  311. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/session/creation/run_session.py +0 -0
  312. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/session/creation/run_session_in_external_terminal.py +0 -0
  313. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/resources/ws/session/creation/strip_ansi.py +0 -0
  314. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/status_eval.py +0 -0
  315. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/stream_stats.py +0 -0
  316. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/trace_profiles.py +0 -0
  317. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom/video_quality.py +0 -0
  318. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom_dev.egg-info/dependency_links.txt +0 -0
  319. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom_dev.egg-info/entry_points.txt +0 -0
  320. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom_dev.egg-info/requires.txt +0 -0
  321. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/src/rosotacom_dev.egg-info/top_level.txt +0 -0
  322. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/terminology.md +0 -0
  323. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_benched_set_registry.py +0 -0
  324. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_findings.py +0 -0
  325. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_ota_source_bundle.py +0 -0
  326. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_package_metadata.py +0 -0
  327. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_profile_covers_generated_commands.py +0 -0
  328. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_pytest_policy.py +0 -0
  329. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_readme_examples.py +0 -0
  330. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_session_configuration_doc.py +0 -0
  331. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_session_template_substitution.py +0 -0
  332. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/contract/test_workflow_contracts.py +0 -0
  333. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/e2e/test_anonymize_e2e.py +0 -0
  334. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/e2e/test_benchmark_ab.py +0 -0
  335. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/e2e/test_benchmark_capacity.py +0 -0
  336. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/e2e/test_benchmark_replay.py +0 -0
  337. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/e2e/test_parallel_smoke.py +0 -0
  338. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/e2e/test_smoke.py +0 -0
  339. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/e2e/test_timeline_stepping.py +0 -0
  340. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/e2e/test_video_quality_e2e.py +0 -0
  341. {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
  342. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota/session-definition.yaml +0 -0
  343. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota-tuned/session-definition.yaml +0 -0
  344. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/sessions/rmw_matrix/1_heartbeat_fastdds/session-definition.yaml +0 -0
  345. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/sessions/rmw_matrix/1_heartbeat_zen-endpoints/session-definition.yaml +0 -0
  346. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_anonymize.py +0 -0
  347. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_bag_ground_truth.py +0 -0
  348. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_benched_set.py +0 -0
  349. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_benchmark_delta.py +0 -0
  350. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_bundle_check.py +0 -0
  351. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_catmux_pane_logging.py +0 -0
  352. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_container_shaping.py +0 -0
  353. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_deployment.py +0 -0
  354. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_ffmpeg_flags.py +0 -0
  355. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_ffmpeg_packet.py +0 -0
  356. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_field_profiles.py +0 -0
  357. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_forensics.py +0 -0
  358. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_geomap.py +0 -0
  359. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_image_cache.py +0 -0
  360. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_link_bytes.py +0 -0
  361. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_link_trace.py +0 -0
  362. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_netem_dist.py +0 -0
  363. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_network_profiles.py +0 -0
  364. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_network_shaper.py +0 -0
  365. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_ota_unwrapper.py +0 -0
  366. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_ota_wrapper.py +0 -0
  367. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_ota_xml.py +0 -0
  368. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_playout_pacer.py +0 -0
  369. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_plots.py +0 -0
  370. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_qos_fallback_logging.py +0 -0
  371. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_session_pipeline.py +0 -0
  372. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_stage_latency.py +0 -0
  373. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_status_eval.py +0 -0
  374. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_status_overview.py +0 -0
  375. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_status_overview_observer.py +0 -0
  376. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_stream_stats.py +0 -0
  377. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_trace_profiles.py +0 -0
  378. {rosotacom_dev-2.5.dev51 → rosotacom_dev-2.5.dev53}/tests/unit/test_video_quality.py +0 -0
@@ -108,6 +108,7 @@ jobs:
108
108
  - cyclone-local-zenoh-ros2dds-ota
109
109
  - cyclone-ota
110
110
  - fastdds
111
+ - fastdds-default
111
112
  - zen-endpoints
112
113
  steps:
113
114
  - name: Check out repository
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rosotacom-dev
3
- Version: 2.5.dev51
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/` (e.g. `fastdds_v1.xml`, `cyclonedds.xml`, `fastdds_easy_mode.xml`). Omit to use the RMW's built-in defaults.
171
- - `easy_mode_ip: <string>` — only honored by `fastdds_easy_mode.xml`; defaults to the first resolved peer address.
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 `udp`.
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 = float(topic_summary.get("loss_pct", 100.0))
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 = float(data.get("loss_pct", 100.0)) if data else 100.0
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)