rosotacom-dev 2.5.dev29__tar.gz → 2.5.dev34__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 (347) hide show
  1. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/PKG-INFO +1 -1
  2. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/session-configuration.md +23 -7
  3. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/ros2docker.json +13 -6
  4. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/sessions/17_synthetic_camera_quality/session-definition.yaml +11 -0
  5. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ros2docker.json.example +13 -6
  6. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview.py +20 -5
  7. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview_core.py +27 -0
  8. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_wrapper.py +7 -1
  9. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/session/creation/generate_session_files.py +70 -33
  10. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom_dev.egg-info/PKG-INFO +1 -1
  11. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom_dev.egg-info/SOURCES.txt +3 -0
  12. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom_dev.egg-info/scm_file_list.json +3 -0
  13. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom_dev.egg-info/scm_version.json +2 -2
  14. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/contract/test_packaged_resources.py +78 -0
  15. rosotacom_dev-2.5.dev34/tests/unit/test_ota_wrapper.py +170 -0
  16. rosotacom_dev-2.5.dev34/tests/unit/test_session_pipeline.py +196 -0
  17. rosotacom_dev-2.5.dev34/tests/unit/test_status_overview_observer.py +225 -0
  18. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/.devcontainer/devcontainer.json.template +0 -0
  19. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/.devcontainer/re_generate_devcontainer_json.py +0 -0
  20. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/.github/CODEOWNERS +0 -0
  21. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/.github/ISSUE_TEMPLATE/documentation-audit.md +0 -0
  22. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/.github/ISSUE_TEMPLATE/implementation-cleanup.md +0 -0
  23. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/.github/ISSUE_TEMPLATE/quality-workflow.md +0 -0
  24. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/.github/ISSUE_TEMPLATE/redesign.md +0 -0
  25. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/.github/ISSUE_TEMPLATE/release-process.md +0 -0
  26. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/.github/ISSUE_TEMPLATE/repository-diagnosis.md +0 -0
  27. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/.github/ISSUE_TEMPLATE/test-ci-audit.md +0 -0
  28. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/.github/ISSUE_TEMPLATE/work-item.md +0 -0
  29. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  30. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/.github/actions/setup-just/action.yml +0 -0
  31. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/.github/dependabot.yml +0 -0
  32. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/.github/workflows/benchmark-calibrate.yml +0 -0
  33. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/.github/workflows/benchmark-gate.yml +0 -0
  34. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/.github/workflows/dev-release.yml +0 -0
  35. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/.github/workflows/image-scan.yml +0 -0
  36. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/.github/workflows/nightly-e2e.yml +0 -0
  37. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/.github/workflows/pr-lightweight.yml +0 -0
  38. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/.github/workflows/pr-merge-gate.yml +0 -0
  39. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/.github/workflows/release.yml +0 -0
  40. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/.pre-commit-config.yaml +0 -0
  41. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/AGENTS.md +0 -0
  42. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/CONCURRENCY.md +0 -0
  43. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/CONTRIBUTING.md +0 -0
  44. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/DEVELOPMENT_PRINCIPLES.md +0 -0
  45. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/LICENSE.txt +0 -0
  46. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/MANIFEST.in +0 -0
  47. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/README.md +0 -0
  48. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/budgets.jsonl +0 -0
  49. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/calibration/README.md +0 -0
  50. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/calibration/capacity-size-tight-cyclone.json +0 -0
  51. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/calibration/probe-loss-gop-tight-cyclone.json +0 -0
  52. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/calibration/probe-loss-nominal-cyclone.json +0 -0
  53. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/calibration/probe-loss-tight-cyclone.json +0 -0
  54. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/calibration/probe-loss-tight-fastdds.json +0 -0
  55. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/calibration/probe-loss-tight-zenoh.json +0 -0
  56. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/codecov.yml +0 -0
  57. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/deployment-configuration.md +0 -0
  58. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/benchmark-ab.md +0 -0
  59. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/benchmark-bag-as-load.md +0 -0
  60. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/ci.md +0 -0
  61. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/ffmpeg-keyframes.md +0 -0
  62. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/findings/README.md +0 -0
  63. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/findings/cyclone-spdp-discovery-bursts.md +0 -0
  64. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/findings/delay-alone-no-loss.md +0 -0
  65. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/findings/head-of-line-irregularity.md +0 -0
  66. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/findings/jitter-loss-bandwidth-latency.md +0 -0
  67. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/findings/lighter-message-loss.md +0 -0
  68. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/findings/zero-loss-boundaries-18kb-20hz.md +0 -0
  69. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/forensics-report.md +0 -0
  70. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/geo-link-map.md +0 -0
  71. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/github-repository-settings.md +0 -0
  72. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/link-trace.md +0 -0
  73. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/owner-runbook.md +0 -0
  74. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/performance-bands.md +0 -0
  75. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/playbooks/README.md +0 -0
  76. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/quality-model.md +0 -0
  77. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/release-notes/TEMPLATE.md +0 -0
  78. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/release-notes/v2.1.md +0 -0
  79. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/release-notes/v2.2.md +0 -0
  80. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/release-notes/v2.3.md +0 -0
  81. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/release-notes/v2.4.md +0 -0
  82. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/release.md +0 -0
  83. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/rfcs/0001-expectation-driven-test-suite.md +0 -0
  84. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/rfcs/0002-expectation-concepts.md +0 -0
  85. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/rfcs/0003-metric-backbone.md +0 -0
  86. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/rfcs/0004-network-profiles.md +0 -0
  87. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/rfcs/0005-benchmark-genres-and-ci.md +0 -0
  88. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/rfcs/0006-dynamic-qos.md +0 -0
  89. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/rfcs/0007-regression-gate.md +0 -0
  90. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/rfcs/README.md +0 -0
  91. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/testing.md +0 -0
  92. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/docs/work-items.md +0 -0
  93. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/install.sh +0 -0
  94. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/justfile +0 -0
  95. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/media/control_center.png +0 -0
  96. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/media/echo_test.png +0 -0
  97. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/media/forensics-report-example.png +0 -0
  98. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/media/host.png +0 -0
  99. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/media/vehicle.png +0 -0
  100. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/pyproject.toml +0 -0
  101. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/requirements.txt +0 -0
  102. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/rosotacom.yaml +0 -0
  103. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/run_session_in_container.py +0 -0
  104. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/setup.cfg +0 -0
  105. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/__init__.py +0 -0
  106. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/__main__.py +0 -0
  107. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/anonymize.py +0 -0
  108. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/bag_ground_truth.py +0 -0
  109. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/benched_set.py +0 -0
  110. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/benchmark.py +0 -0
  111. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/benchmark_delta.py +0 -0
  112. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/bundle_check.py +0 -0
  113. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/cli.py +0 -0
  114. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/cli_benchmark.py +0 -0
  115. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/deployment.py +0 -0
  116. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/ffmpeg_packet.py +0 -0
  117. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/forensics.py +0 -0
  118. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/geomap.py +0 -0
  119. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/image_cache.py +0 -0
  120. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/network_profiles.py +0 -0
  121. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/network_shaper.py +0 -0
  122. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/plots.py +0 -0
  123. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/py.typed +0 -0
  124. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/benched-set.yaml +0 -0
  125. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/.gitignore +0 -0
  126. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/README.md +0 -0
  127. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/__init__.py +0 -0
  128. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/bags/8_drop_reference/metadata.yaml +0 -0
  129. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/deployment.example.yaml +0 -0
  130. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/profiles.yaml +0 -0
  131. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/rosotacom.yaml +0 -0
  132. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scenarios/2_native_chatter/scenario-definition.yaml +0 -0
  133. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_a.sh +0 -0
  134. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_b.sh +0 -0
  135. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/external.ros2docker.json +0 -0
  136. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_communication.sh +0 -0
  137. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_external.py +0 -0
  138. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/wait_for_echo_topic.sh +0 -0
  139. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/external.ros2docker.json +0 -0
  140. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_communication.sh +0 -0
  141. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_external.py +0 -0
  142. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external.ros2docker.json +0 -0
  143. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external_session.yaml +0 -0
  144. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/foxglove.json +0 -0
  145. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_communication.sh +0 -0
  146. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_external.py +0 -0
  147. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
  148. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/metadata.yaml +0 -0
  149. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/external.ros2docker.json +0 -0
  150. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_communication.sh +0 -0
  151. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_external.py +0 -0
  152. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external.ros2docker.json +0 -0
  153. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external_session.yaml +0 -0
  154. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/foxglove.json +0 -0
  155. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_communication.sh +0 -0
  156. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_external.py +0 -0
  157. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
  158. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/metadata.yaml +0 -0
  159. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/external.ros2docker.json +0 -0
  160. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_communication.sh +0 -0
  161. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_external.py +0 -0
  162. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external.ros2docker.json +0 -0
  163. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external_session.yaml +0 -0
  164. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_communication.sh +0 -0
  165. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_external.py +0 -0
  166. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external.ros2docker.json +0 -0
  167. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external_session.yaml +0 -0
  168. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_communication.sh +0 -0
  169. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_external.py +0 -0
  170. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external.ros2docker.json +0 -0
  171. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external_session.yaml +0 -0
  172. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_communication.sh +0 -0
  173. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_external.py +0 -0
  174. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external.ros2docker.json +0 -0
  175. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external_session.yaml +0 -0
  176. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_communication.sh +0 -0
  177. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_external.py +0 -0
  178. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/sessions/10_restamp/session-definition.yaml +0 -0
  179. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/sessions/11_trickle/session-definition.yaml +0 -0
  180. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/sessions/12_content_integrity/session-definition.yaml +0 -0
  181. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/sessions/13_link_latency/session-definition.yaml +0 -0
  182. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/sessions/14_remote_assist_anonymized/session-definition.yaml +0 -0
  183. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/sessions/15_remote_assist_anonymized_costmap/session-definition.yaml +0 -0
  184. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/sessions/16_remote_assist_anonymized_camera/session-definition.yaml +0 -0
  185. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/sessions/1_heartbeat/session-definition.yaml +0 -0
  186. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/sessions/1_heartbeat_status/session-definition.yaml +0 -0
  187. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/sessions/2_native_chatter/session-definition.yaml +0 -0
  188. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/sessions/3_comp_occ_grid/session-definition.yaml +0 -0
  189. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/sessions/4_comp_occ_grid_zen/session-definition.yaml +0 -0
  190. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/sessions/5_sized_payload/session-definition.yaml +0 -0
  191. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/sessions/6_sized_payload_zen/session-definition.yaml +0 -0
  192. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/sessions/7_latched_static/session-definition.yaml +0 -0
  193. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/sessions/8_drop/session-definition.yaml +0 -0
  194. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/sessions/9_throttle/session-definition.yaml +0 -0
  195. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/sessions/bench_1_1_capacity/session-definition.yaml +0 -0
  196. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/sessions/bench_1_2_load_sweep/session-definition.yaml +0 -0
  197. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/sessions/bench_1_3_ramp/session-definition.yaml +0 -0
  198. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/sessions/bench_1_4_recovery/session-definition.yaml +0 -0
  199. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/examples/sessions/bench_1_5_camera/session-definition.yaml +0 -0
  200. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/.vscode/c_cpp_properties.json +0 -0
  201. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/.vscode/settings.json +0 -0
  202. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_easy_mode.xml.template +0 -0
  203. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_initial_peer_list.xml.template +0 -0
  204. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v2.xml.template +0 -0
  205. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v3.xml.template +0 -0
  206. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v4.xml.template +0 -0
  207. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v5.xml.template +0 -0
  208. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ota_configs/create_zenoh_json5.py +0 -0
  209. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ota_configs/cyclonedds_minimal.xml.template +0 -0
  210. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ota_configs/cyclonedds_tuned.xml.template +0 -0
  211. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ota_configs/fastdds_unicast.xml.template +0 -0
  212. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ota_configs/get_ota_xml.py +0 -0
  213. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ota_configs/utils.py +0 -0
  214. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ota_configs/zenoh.json5.template +0 -0
  215. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/.gitkeep +0 -0
  216. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_cpp/CMakeLists.txt +0 -0
  217. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_cpp/COLCON_IGNORE +0 -0
  218. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_cpp/LICENSE.txt +0 -0
  219. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_cpp/package.xml +0 -0
  220. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_cpp/src/hz_monitor.cpp +0 -0
  221. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_compressor.cpp +0 -0
  222. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_decompressor.cpp +0 -0
  223. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_msgs/CMakeLists.txt +0 -0
  224. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_msgs/LICENSE.txt +0 -0
  225. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/CompressedData.msg +0 -0
  226. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/EchoHeartbeat.msg +0 -0
  227. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/OtaStamped.msg +0 -0
  228. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/SizedPayload.msg +0 -0
  229. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_msgs/package.xml +0 -0
  230. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/LICENSE.txt +0 -0
  231. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/__init__.py +0 -0
  232. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/base_bridge_relay.py +0 -0
  233. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_in.py +0 -0
  234. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_out.py +0 -0
  235. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/heartbeat_echo.py +0 -0
  236. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/hz_monitor.py +0 -0
  237. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_bandwidth_reducer.py +0 -0
  238. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_pixel_capper.py +0 -0
  239. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/lanelet_saver.py +0 -0
  240. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/latch_relay.py +0 -0
  241. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/costmap_remapper.py +0 -0
  242. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/marker_remapper.py +0 -0
  243. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/speed_test.py +0 -0
  244. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/tf_remapper.py +0 -0
  245. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/traffic_monitor.py +0 -0
  246. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/wifi_network_analysis_1.py +0 -0
  247. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_bytes.py +0 -0
  248. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_trace.py +0 -0
  249. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/local_global_frame_bridge.py +0 -0
  250. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/localization_map_split_reduce_saver.py +0 -0
  251. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/msg_transform.py +0 -0
  252. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pair_management.py +0 -0
  253. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pub_sub_pair.py +0 -0
  254. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/qos.py +0 -0
  255. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_in.py +0 -0
  256. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_out.py +0 -0
  257. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/restamp.py +0 -0
  258. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/sized_publisher.py +0 -0
  259. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency.py +0 -0
  260. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency_core.py +0 -0
  261. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/tf_map_to_cart_saver.py +0 -0
  262. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_monitor.py +0 -0
  263. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_resolution.py +0 -0
  264. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/trickle.py +0 -0
  265. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_compressor.py +0 -0
  266. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_decompressor.py +0 -0
  267. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_unwrapper.py +0 -0
  268. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/package.xml +0 -0
  269. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/resource/com_py +0 -0
  270. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/setup.cfg +0 -0
  271. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/setup.py +0 -0
  272. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/test/test_copyright.py +0 -0
  273. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/test/test_flake8.py +0 -0
  274. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/ros2src/com_py/test/test_pep257.py +0 -0
  275. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/session/content/base/session_plugin_base.yaml +0 -0
  276. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/session/content/network/up_connectivity.py +0 -0
  277. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/session/content/network/wifi_network_analysis_2.py +0 -0
  278. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/session/creation/anonymize_bag.py +0 -0
  279. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/session/creation/catmux_log_setup.sh +0 -0
  280. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/session/creation/create_session_yaml.py +0 -0
  281. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/session/creation/run_session.py +0 -0
  282. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/session/creation/run_session_in_external_terminal.py +0 -0
  283. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/resources/ws/session/creation/strip_ansi.py +0 -0
  284. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/status_eval.py +0 -0
  285. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/stream_stats.py +0 -0
  286. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/trace_profiles.py +0 -0
  287. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/transit.py +0 -0
  288. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom/video_quality.py +0 -0
  289. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom_dev.egg-info/dependency_links.txt +0 -0
  290. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom_dev.egg-info/entry_points.txt +0 -0
  291. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom_dev.egg-info/requires.txt +0 -0
  292. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/src/rosotacom_dev.egg-info/top_level.txt +0 -0
  293. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/stop_session_in_container.py +0 -0
  294. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/terminology.md +0 -0
  295. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/contract/test_benched_set_registry.py +0 -0
  296. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/contract/test_findings.py +0 -0
  297. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/contract/test_markdown_links.py +0 -0
  298. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/contract/test_ota_source_bundle.py +0 -0
  299. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/contract/test_package_metadata.py +0 -0
  300. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/contract/test_profile_covers_generated_commands.py +0 -0
  301. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/contract/test_pytest_policy.py +0 -0
  302. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/contract/test_readme_examples.py +0 -0
  303. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/contract/test_security_maintenance_config.py +0 -0
  304. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/contract/test_session_configuration_doc.py +0 -0
  305. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/contract/test_workflow_contracts.py +0 -0
  306. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/e2e/conftest.py +0 -0
  307. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/e2e/test_anonymize_e2e.py +0 -0
  308. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/e2e/test_benchmark_ab.py +0 -0
  309. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/e2e/test_benchmark_capacity.py +0 -0
  310. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/e2e/test_benchmark_replay.py +0 -0
  311. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/e2e/test_parallel_smoke.py +0 -0
  312. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/e2e/test_smoke.py +0 -0
  313. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/e2e/test_timeline_stepping.py +0 -0
  314. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/e2e/test_video_quality_e2e.py +0 -0
  315. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/sessions/generate_rmw_matrix.py +0 -0
  316. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-local_zenoh-ros2dds-ota/session-definition.yaml +0 -0
  317. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota/session-definition.yaml +0 -0
  318. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota-tuned/session-definition.yaml +0 -0
  319. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/sessions/rmw_matrix/1_heartbeat_fastdds/session-definition.yaml +0 -0
  320. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/sessions/rmw_matrix/1_heartbeat_zen-endpoints/session-definition.yaml +0 -0
  321. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_anonymize.py +0 -0
  322. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_bag_ground_truth.py +0 -0
  323. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_benched_set.py +0 -0
  324. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_benchmark.py +0 -0
  325. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_benchmark_delta.py +0 -0
  326. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_bundle_check.py +0 -0
  327. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_cli.py +0 -0
  328. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_cli_benchmark.py +0 -0
  329. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_concurrency.py +0 -0
  330. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_deployment.py +0 -0
  331. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_ffmpeg_packet.py +0 -0
  332. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_forensics.py +0 -0
  333. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_geomap.py +0 -0
  334. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_image_cache.py +0 -0
  335. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_link_bytes.py +0 -0
  336. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_link_trace.py +0 -0
  337. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_network_profiles.py +0 -0
  338. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_network_shaper.py +0 -0
  339. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_ota_xml.py +0 -0
  340. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_plots.py +0 -0
  341. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_stage_latency.py +0 -0
  342. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_status_eval.py +0 -0
  343. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_status_overview.py +0 -0
  344. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_stream_stats.py +0 -0
  345. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_trace_profiles.py +0 -0
  346. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/tests/unit/test_transit.py +0 -0
  347. {rosotacom_dev-2.5.dev29 → rosotacom_dev-2.5.dev34}/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.dev29
3
+ Version: 2.5.dev34
4
4
  Summary: Host CLI for ROS OTA communication sessions.
5
5
  Author: develNor
6
6
  License-Expression: BSD-3-Clause
@@ -477,15 +477,31 @@ Given a base topic like `/tf`, stages are applied in this order:
477
477
 
478
478
  1) base topic (e.g. `/tf`)
479
479
  2) restamp → `+ shared.processing_suffixes.restamped` (default `/restamped`)
480
- 3) drop → `+ /drop{drop_count}of{window_size}` (e.g. `/drop2of3`)
481
- 4) throttle → `+ /max{hz}hz`
482
- 5) pixel cap → `+ /{preset}`
483
- 6) framebridge:
480
+ 3) latch → `+ shared.processing_suffixes.latched` (default `/latched`)
481
+ 4) drop → `+ /drop{drop_count}of{window_size}` (e.g. `/drop2of3`)
482
+ 5) throttle → `+ /max{hz}hz`
483
+ 6) pixel cap → `+ /{preset}`
484
+ 7) framebridge:
484
485
  - `local_to_global`: appended to the current topic state via `+ /globalframe`
485
486
  - `global_to_local`: appended to the base topic via `+ /globalframe` (configured inbound-side)
486
- 7) compress → `+ /<algorithm>` (default `/bz2`)
487
- 8) transport → `+ /<type>` (e.g. `/ffmpeg`, `/foxglove`, `/compressed`)
488
- 9) optional `local_republish: true` triggers reverse-transport configuration.
487
+ 8) compress → `+ /<algorithm>` (default `/bz2`)
488
+ 9) transport → `+ /<type>` (e.g. `/ffmpeg`, `/foxglove`, `/compressed`)
489
+ 10) OTA wrapper `+ /ota_stamped`
490
+
491
+ The wrapper is **always last**. Its `seq` and send stamp are read as a statement
492
+ about the traffic on the link, so it has to wrap exactly what crosses it — an
493
+ encoded stream is wrapped as `<base>/<type>/ota_stamped`, not the other way
494
+ round. Nothing may append a suffix after it, or the delivered topic would be
495
+ renamed under a receiver that subscribes by a fixed name.
496
+
497
+ The receiver undoes the chain in reverse, and every stage there is computed from
498
+ the delivered topic rather than from the OTA topic:
499
+
500
+ 1) unwrap → republishes on the pre-wrap name (so wrapping renames nothing)
501
+ 2) `local_republish: true` → reverse transport decodes into `+ /raw`
502
+ 3) decompress → republishes on the pre-compress name
503
+ 4) framebridge `global_to_local` → the local base topic
504
+ 5) trickle → `+ /trickle`, the only receiver-side stage that adds a suffix
489
505
 
490
506
  #### Transport parameters
491
507
  `type: ffmpeg` supports:
@@ -11,7 +11,6 @@
11
11
  "run_args": [
12
12
  "-e", "ROS_DOMAIN_ID=48",
13
13
  "-e", "BUILD_ROS2WS=1",
14
- "-e", "CHECK_ROS2WS_DEPENDENCIES=1",
15
14
  "--network", "host"
16
15
  ],
17
16
 
@@ -27,15 +26,23 @@
27
26
  // The base is ros-base, not desktop-full: 299 MB compressed against 1422 MB,
28
27
  // and nothing here runs a GUI (enable_gui_forwarding is false above). The
29
28
  // e2e suite was run against both to find out what desktop-full had been
30
- // providing without anyone declaring it one package, ros-kilted-gps-msgs,
31
- // which the anonymized remote-assist session needs for gps_msgs/msg/GPSFix.
32
- // It is declared below. Add rviz2 or a simulator here if you want them; that
33
- // is a project's decision, not a default.
29
+ // providing without anyone declaring it. It named ros-kilted-gps-msgs, for
30
+ // the gps_msgs/msg/GPSFix the anonymized remote-assist session publishes.
31
+ //
32
+ // It could not name ros-kilted-compressed-image-transport, and that one is
33
+ // why this list is not just an inventory: no e2e session has a /compressed
34
+ // input topic, so the suite never loaded compressed_sub. A vehicle camera
35
+ // does, on both ends of the link — the sender republishes compressed to
36
+ // ffmpeg, the receiver decodes back to the CompressedImage twin. Declaring
37
+ // ros-kilted-image-transport alone gets you raw and nothing else.
38
+ //
39
+ // Add rviz2 or a simulator here if you want them; that is a project's
40
+ // decision, not a default.
34
41
  "build_args": {
35
42
  "BASE_IMAGE": "ros:kilted-ros-base-noble",
36
43
  "DIGEST": "@sha256:4ca53d5b084bdbe92a7a7d7186f56db6a716a6c7c33ad401ddb0ec82d6e9e479",
37
44
  "INSTALL_ZENOH": "1",
38
- "APT_PACKAGES": "iputils-ping psmisc net-tools snmp iw nload iftop iproute2 tshark ros-kilted-domain-bridge ros-kilted-rmw-cyclonedds-cpp ros-kilted-rmw-zenoh-cpp ros-kilted-topic-tools ros-kilted-image-transport ros-kilted-ffmpeg-image-transport ros-kilted-ffmpeg-image-transport-msgs ros-kilted-gps-msgs",
45
+ "APT_PACKAGES": "iputils-ping psmisc net-tools snmp iw nload iftop iproute2 tshark ros-kilted-domain-bridge ros-kilted-rmw-cyclonedds-cpp ros-kilted-rmw-zenoh-cpp ros-kilted-topic-tools ros-kilted-image-transport ros-kilted-compressed-image-transport ros-kilted-ffmpeg-image-transport ros-kilted-ffmpeg-image-transport-msgs ros-kilted-gps-msgs",
39
46
  "PIP_PACKAGES": "numpy>=1.26,<2 lz4 pysnmp speedtest-cli psutil zstandard opencv-python"
40
47
  }
41
48
  }
@@ -52,6 +52,17 @@ topics:
52
52
  local_republish: true
53
53
  gop_size: 4
54
54
  bit_rate: 2000000
55
+ # Wrapping an encoded stream: the wrapper runs after the encoder, so the
56
+ # envelope carries the FFMPEGPacket that actually crosses the link, and
57
+ # the unwrapper republishes onto `/camera/image/ffmpeg` -- the name the
58
+ # reverse republish already decodes from. Nothing downstream is renamed,
59
+ # which is what this example proves end to end.
60
+ use_ota_wrapper: true
55
61
  expect:
56
62
  hz: { min: 3, max: 8 }
57
63
  latency_ms: { max: 1000 }
64
+ # The bound is the same 30% the video-quality check tolerates on this
65
+ # synthetic link; the assertion's purpose is that the number exists at
66
+ # all. Without the wrapper an encoded stream has no per-message
67
+ # accounting, and `loss_pct` on a topic that cannot report it fails.
68
+ loss_pct: { max: 30 }
@@ -11,7 +11,6 @@
11
11
  "run_args": [
12
12
  "-e", "ROS_DOMAIN_ID=47",
13
13
  "-e", "BUILD_ROS2WS=1",
14
- "-e", "CHECK_ROS2WS_DEPENDENCIES=1",
15
14
  "--network", "host"
16
15
  ],
17
16
 
@@ -27,15 +26,23 @@
27
26
  // The base is ros-base, not desktop-full: 299 MB compressed against 1422 MB,
28
27
  // and nothing here runs a GUI (enable_gui_forwarding is false above). The
29
28
  // e2e suite was run against both to find out what desktop-full had been
30
- // providing without anyone declaring it one package, ros-kilted-gps-msgs,
31
- // which the anonymized remote-assist session needs for gps_msgs/msg/GPSFix.
32
- // It is declared below. Add rviz2 or a simulator here if you want them; that
33
- // is a project's decision, not a default.
29
+ // providing without anyone declaring it. It named ros-kilted-gps-msgs, for
30
+ // the gps_msgs/msg/GPSFix the anonymized remote-assist session publishes.
31
+ //
32
+ // It could not name ros-kilted-compressed-image-transport, and that one is
33
+ // why this list is not just an inventory: no e2e session has a /compressed
34
+ // input topic, so the suite never loaded compressed_sub. A vehicle camera
35
+ // does, on both ends of the link — the sender republishes compressed to
36
+ // ffmpeg, the receiver decodes back to the CompressedImage twin. Declaring
37
+ // ros-kilted-image-transport alone gets you raw and nothing else.
38
+ //
39
+ // Add rviz2 or a simulator here if you want them; that is a project's
40
+ // decision, not a default.
34
41
  "build_args": {
35
42
  "BASE_IMAGE": "ros:kilted-ros-base-noble",
36
43
  "DIGEST": "@sha256:4ca53d5b084bdbe92a7a7d7186f56db6a716a6c7c33ad401ddb0ec82d6e9e479",
37
44
  "INSTALL_ZENOH": "1",
38
- "APT_PACKAGES": "iputils-ping psmisc net-tools snmp iw nload iftop iproute2 tshark ros-kilted-domain-bridge ros-kilted-rmw-cyclonedds-cpp ros-kilted-rmw-zenoh-cpp ros-kilted-topic-tools ros-kilted-image-transport ros-kilted-ffmpeg-image-transport ros-kilted-ffmpeg-image-transport-msgs ros-kilted-gps-msgs",
45
+ "APT_PACKAGES": "iputils-ping psmisc net-tools snmp iw nload iftop iproute2 tshark ros-kilted-domain-bridge ros-kilted-rmw-cyclonedds-cpp ros-kilted-rmw-zenoh-cpp ros-kilted-topic-tools ros-kilted-image-transport ros-kilted-compressed-image-transport ros-kilted-ffmpeg-image-transport ros-kilted-ffmpeg-image-transport-msgs ros-kilted-gps-msgs",
39
46
  "PIP_PACKAGES": "numpy>=1.26,<2 lz4 pysnmp speedtest-cli psutil zstandard opencv-python"
40
47
  }
41
48
  }
@@ -75,6 +75,7 @@ from com_py.status_overview_core import (
75
75
  StatusAggregator,
76
76
  collect_stage_metadata,
77
77
  collect_stage_topics,
78
+ stamp_delay,
78
79
  )
79
80
 
80
81
  ECHO_HEARTBEAT_TYPE = "com_msgs/msg/EchoHeartbeat"
@@ -274,12 +275,26 @@ class StageObserver(Node):
274
275
  stamp = getattr(header, "stamp", None) if header is not None else None
275
276
  if stamp is not None:
276
277
  try:
277
- msg_time = rclpy.time.Time.from_msg(stamp)
278
- d = (now_ros - msg_time).nanoseconds / 1e9
279
- if -1.0 < d < 1000.0: # guard unsynced clocks / zero stamps
280
- delay_s = d
278
+ stamp_s = _stamp_seconds(stamp)
281
279
  except Exception:
282
- delay_s = None
280
+ stamp_s = None
281
+ if stamp_s is not None:
282
+ d = now_ros_s - stamp_s
283
+ # An inbound stage carries a stamp written by the peer's
284
+ # clock, so it is comparable to ours only once the offset
285
+ # the heartbeat measures is applied -- exactly what the
286
+ # OtaStamped branch above does with `t_wrap`. A local
287
+ # stage was stamped by this machine and must stay raw.
288
+ contexts = self._stage_metadata.get(topic, [])
289
+ peer_stamped = any(
290
+ context.get("direction") == "inbound" for context in contexts
291
+ )
292
+ estimate = self.clock_estimator.estimate() if peer_stamped else None
293
+ if estimate is not None:
294
+ clock_offset_s = estimate["offset_s"]
295
+ rtt_s = estimate["rtt_s"]
296
+ raw_delay_s = d
297
+ delay_s = stamp_delay(d, clock_offset_s)
283
298
 
284
299
  obs.record(
285
300
  size,
@@ -148,6 +148,33 @@ class ClockOffsetEstimator:
148
148
  }
149
149
 
150
150
 
151
+ #: Plausibility window (seconds) for a latency derived from a message header
152
+ #: stamp. Outside it the number is not a latency but an unset stamp (epoch 0) or
153
+ #: a clock difference no offset estimate explains.
154
+ STAMP_DELAY_MIN_S = -1.0
155
+ STAMP_DELAY_MAX_S = 1000.0
156
+
157
+
158
+ def stamp_delay(raw_delay_s: float, clock_offset_s: Optional[float] = None) -> Optional[float]:
159
+ """Latency from a header stamp, corrected by the estimated peer clock offset.
160
+
161
+ ``raw_delay_s`` is ``local_now - stamp``. ``clock_offset_s`` is peer clock
162
+ minus local clock (as ``ClockOffsetEstimator`` reports it), so the corrected
163
+ delay is their sum -- the same arithmetic the OtaStamped path uses on its
164
+ ``t_wrap``.
165
+
166
+ Returns ``None`` when the result falls outside the plausibility window. The
167
+ guard is applied to the corrected value on purpose: a topic whose stamp is
168
+ written by the peer used to be dropped for an offset this node has already
169
+ measured, which reads as "no latency available" instead of "latency, once
170
+ the clocks are reconciled".
171
+ """
172
+ corrected = raw_delay_s if clock_offset_s is None else raw_delay_s + clock_offset_s
173
+ if STAMP_DELAY_MIN_S < corrected < STAMP_DELAY_MAX_S:
174
+ return corrected
175
+ return None
176
+
177
+
151
178
  # --- Link overhead (session-level) -----------------------------------------
152
179
 
153
180
  def _payload_kbps(stage: Optional[Dict[str, Any]]) -> float:
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env python3
2
2
 
3
+ import array
3
4
  import re
4
5
  from threading import Lock
5
6
 
@@ -139,7 +140,12 @@ class UniversalOtaWrapperNode(Node):
139
140
  out_msg.header.frame_id = header.frame_id
140
141
  out_msg.seq = self._next_sequence(source_topic)
141
142
  out_msg.msg_type = msg_type_str
142
- out_msg.serialized_msg = list(serialized)
143
+ # array('B', ...) hits the generated setter's fast path and stores the
144
+ # buffer as-is. A list would allocate one Python int per payload byte,
145
+ # inside the interval that `header.stamp` above is meant to measure --
146
+ # and rule out wrapping anything large (a ~100 kB encoded video packet
147
+ # at 10 Hz is 1M allocations per second).
148
+ out_msg.serialized_msg = array.array('B', serialized)
143
149
 
144
150
  publisher.publish(out_msg)
145
151
  except Exception as exc:
@@ -1255,11 +1255,15 @@ def _final_topic_type(entry: TopicEntry, pipe: Dict[str, Any]) -> str:
1255
1255
  f"Unsupported transport type '{transport.type}' for topic '{entry.base}'. "
1256
1256
  f"Known output type mappings: {sorted(TRANSPORT_OUTPUT_TYPES)}"
1257
1257
  )
1258
- return TRANSPORT_OUTPUT_TYPES[transport.type]
1259
1258
 
1259
+ # Same order as the pipeline stages themselves: whatever is applied last
1260
+ # decides the type of what crosses the link, and the wrapper is always last.
1260
1261
  if pipe.get("ota_wrap"):
1261
1262
  return OTA_STAMPED_MSG_TYPE
1262
1263
 
1264
+ if transport is not None:
1265
+ return TRANSPORT_OUTPUT_TYPES[transport.type]
1266
+
1263
1267
  if pipe.get("compress"):
1264
1268
  return COMPRESSED_MSG_TYPE
1265
1269
 
@@ -1271,6 +1275,49 @@ def _final_topic_type(entry: TopicEntry, pipe: Dict[str, Any]) -> str:
1271
1275
  return msg_type
1272
1276
 
1273
1277
 
1278
+ def _delivered_topic(pipe: Dict[str, Any], final: str) -> str:
1279
+ """The topic the receiver's post-processing chain ends on, before trickle.
1280
+
1281
+ The receiver undoes the sender's stages in reverse order, so this walks the
1282
+ same chain backwards rather than picking one branch: unwrap, decode a
1283
+ transport, decompress, framebridge down.
1284
+ """
1285
+ topic = final
1286
+ if pipe.get("ota_wrap"):
1287
+ # The unwrapper republishes on the pre-wrap name, which is why wrapping
1288
+ # renames nothing downstream of it.
1289
+ topic = str(pipe["ota_in"])
1290
+ transport = pipe.get("transport")
1291
+ if isinstance(transport, TransportSpec) and transport.local_republish:
1292
+ # image_transport reverse republish decodes the encoded topic into
1293
+ # `<encoded>/raw`; PSNR/SSIM and application-level checks need that
1294
+ # decoded sensor_msgs/Image stage, not the encoded packet.
1295
+ topic = str(pipe["irt_in"]) + "/raw"
1296
+ elif pipe.get("compress"):
1297
+ topic = str(pipe["comp_in"])
1298
+ if pipe.get("framebridge") == "global_to_local":
1299
+ # global_to_local runs on the receiver: the OTA `final` is the global
1300
+ # (globalframe) topic, and the framebridge transforms it down to the
1301
+ # local base topic -- that base is the post-framebridge native_in.
1302
+ topic = str(pipe["fb_g2l_base"])
1303
+ return topic
1304
+
1305
+
1306
+ def _postprocessed_topic(pipe: Dict[str, Any], final: str) -> str:
1307
+ """The topic the receiving application actually reads."""
1308
+ topic = _delivered_topic(pipe, final)
1309
+ if pipe.get("trickle_hz") is not None:
1310
+ # Receiver-side trickle re-publishes the delivered topic at a fixed rate
1311
+ # to `<delivered>/trickle` (the trickle node's trickle_topic_suffix).
1312
+ # That republished topic is the real delivered output, so it is the
1313
+ # monitored native_in stage -- otherwise the trickle re-publish is an
1314
+ # observability blind spot (its rate cannot be asserted). It republishes
1315
+ # what the application would read, not the envelope: on a wrapped topic
1316
+ # that is the unwrapped one.
1317
+ topic = topic + "/trickle"
1318
+ return topic
1319
+
1320
+
1274
1321
  def _heartbeat_monitor_overrides(heartbeat_expect: Optional[Dict[str, Any]]) -> List[Tuple[str, Any]]:
1275
1322
  """Override the heartbeat_echo status thresholds from a declared
1276
1323
  `shared.heartbeat.expect`. Only latency and loss map cleanly to the monitor's
@@ -1342,31 +1389,6 @@ def _build_status_pipeline_spec(
1342
1389
  return float(pipe["trickle_hz"])
1343
1390
  return None
1344
1391
 
1345
- def _postprocessed_topic(pipe: Dict[str, Any], final: str) -> str:
1346
- if pipe.get("trickle_hz") is not None:
1347
- # Receiver-side trickle re-publishes the delivered OTA `final` at a fixed
1348
- # rate to `<final>/trickle` (the trickle node's trickle_topic_suffix). That
1349
- # republished topic is the real delivered output, so it is the monitored
1350
- # native_in stage -- otherwise the trickle re-publish is an observability
1351
- # blind spot (its rate cannot be asserted).
1352
- return final + "/trickle"
1353
- if pipe.get("compress"):
1354
- return str(pipe["comp_in"])
1355
- if pipe.get("ota_wrap"):
1356
- return str(pipe["ota_in"])
1357
- if pipe.get("framebridge") == "global_to_local":
1358
- # global_to_local runs on the receiver: the OTA `final` is the global
1359
- # (globalframe) topic, and the framebridge transforms it down to the
1360
- # local base topic -- that base is the post-framebridge native_in.
1361
- return str(pipe["fb_g2l_base"])
1362
- transport = pipe.get("transport")
1363
- if isinstance(transport, TransportSpec) and transport.local_republish:
1364
- # image_transport reverse republish decodes `<final>` into
1365
- # `<final>/raw`; PSNR/SSIM and application-level checks need that
1366
- # decoded sensor_msgs/Image stage, not the encoded packet.
1367
- return final + "/raw"
1368
- return final
1369
-
1370
1392
  def _relay_in_local_topic(topic: str) -> str:
1371
1393
  if inbound_keep_source_prefix:
1372
1394
  return f"/{remote_name}{topic}"
@@ -1714,11 +1736,6 @@ def _compute_pipeline(
1714
1736
  comp_in = topic
1715
1737
  topic = topic + comp_alg_suffix
1716
1738
 
1717
- ota_in = None
1718
- if ota_wrap:
1719
- ota_in = topic
1720
- topic = topic + ota_suffix
1721
-
1722
1739
  it_in = None
1723
1740
  irt_in = None
1724
1741
  if transport:
@@ -1727,6 +1744,15 @@ def _compute_pipeline(
1727
1744
  if transport.local_republish:
1728
1745
  irt_in = topic
1729
1746
 
1747
+ # The wrapper is last, always. Its `seq` and send stamp describe whatever it
1748
+ # wraps, so anything applied after it would be measured by an envelope that
1749
+ # never carried it -- and would append its own suffix to the wrapped name,
1750
+ # renaming the delivered topic under a receiver that subscribes by name.
1751
+ ota_in = None
1752
+ if ota_wrap:
1753
+ ota_in = topic
1754
+ topic = topic + ota_suffix
1755
+
1730
1756
  return {
1731
1757
  "final": topic,
1732
1758
  "restamp": restamp,
@@ -2546,8 +2572,16 @@ def func(
2546
2572
  # Trickle: local-only periodic republisher (receiver side only).
2547
2573
  # Subscribes to inbound final topics (with source-name prefix when applicable)
2548
2574
  # and republishes at a fixed rate for visualization software.
2575
+ # Trickle runs at the very end of the receiver chain, so it republishes
2576
+ # what the local post-processing produced -- not the OTA `final`, which
2577
+ # on a wrapped topic is still the envelope. `_delivered_topic` is the
2578
+ # same computation the status pipeline spec uses for `native_in`, so the
2579
+ # two cannot drift apart.
2549
2580
  trickle_in_items = [
2550
- (_prefix_with_source_name_if_needed(local, remote, p["final"]), p["trickle_hz"])
2581
+ (
2582
+ _prefix_with_source_name_if_needed(local, remote, _delivered_topic(p, p["final"])),
2583
+ p["trickle_hz"],
2584
+ )
2551
2585
  for p in in_pipes
2552
2586
  if p["trickle_hz"] is not None
2553
2587
  ]
@@ -2599,7 +2633,10 @@ def func(
2599
2633
  if not p["normalize"]:
2600
2634
  continue
2601
2635
  base = e.base.lstrip("/")
2602
- suffix_source = p["comp_in"] if p["comp_in"] else p["final"]
2636
+ # Normalization is receiver-side too, so it works on the delivered
2637
+ # topic rather than the OTA `final` (identical unless something is
2638
+ # wrapped, where `final` is still the envelope).
2639
+ suffix_source = _delivered_topic(p, p["final"])
2603
2640
  suffix = suffix_source[len(e.base) :]
2604
2641
  nor_items.append((base, suffix))
2605
2642
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rosotacom-dev
3
- Version: 2.5.dev29
3
+ Version: 2.5.dev34
4
4
  Summary: Host CLI for ROS OTA communication sessions.
5
5
  Author: develNor
6
6
  License-Expression: BSD-3-Clause
@@ -331,11 +331,14 @@ tests/unit/test_link_bytes.py
331
331
  tests/unit/test_link_trace.py
332
332
  tests/unit/test_network_profiles.py
333
333
  tests/unit/test_network_shaper.py
334
+ tests/unit/test_ota_wrapper.py
334
335
  tests/unit/test_ota_xml.py
335
336
  tests/unit/test_plots.py
337
+ tests/unit/test_session_pipeline.py
336
338
  tests/unit/test_stage_latency.py
337
339
  tests/unit/test_status_eval.py
338
340
  tests/unit/test_status_overview.py
341
+ tests/unit/test_status_overview_observer.py
339
342
  tests/unit/test_stream_stats.py
340
343
  tests/unit/test_trace_profiles.py
341
344
  tests/unit/test_transit.py
@@ -326,11 +326,14 @@
326
326
  "tests/unit/test_link_trace.py",
327
327
  "tests/unit/test_network_profiles.py",
328
328
  "tests/unit/test_network_shaper.py",
329
+ "tests/unit/test_ota_wrapper.py",
329
330
  "tests/unit/test_ota_xml.py",
330
331
  "tests/unit/test_plots.py",
332
+ "tests/unit/test_session_pipeline.py",
331
333
  "tests/unit/test_stage_latency.py",
332
334
  "tests/unit/test_status_eval.py",
333
335
  "tests/unit/test_status_overview.py",
336
+ "tests/unit/test_status_overview_observer.py",
334
337
  "tests/unit/test_stream_stats.py",
335
338
  "tests/unit/test_trace_profiles.py",
336
339
  "tests/unit/test_transit.py",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "tag": "2.4",
3
- "distance": 29,
4
- "node": "g5cfc936161d0a8d247634ab00c5437cd6a9f7e99",
3
+ "distance": 34,
4
+ "node": "g6799ce5d0e2f5746f9922b5927fc4075c05f36d8",
5
5
  "dirty": false,
6
6
  "branch": "HEAD",
7
7
  "node_date": "2026-08-13"
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import argparse
4
4
  import os
5
+ import re
5
6
  import subprocess
6
7
  from importlib import resources
7
8
  from pathlib import Path
@@ -108,6 +109,83 @@ def test_default_ros2docker_config_pins_supported_kilted_noble_image() -> None:
108
109
  assert "ros-kilted-gps-msgs" in apt_packages
109
110
 
110
111
 
112
+ # `image_transport republish` resolves a transport name to a pluginlib class at
113
+ # runtime, so a transport nobody installed is not a build failure — it is a
114
+ # container that starts fine and aborts on the first image message. `raw` ships
115
+ # with image_transport itself; every other transport needs its own package.
116
+ IMAGE_TRANSPORT_APT_PACKAGES = {
117
+ "raw": "ros-kilted-image-transport",
118
+ "compressed": "ros-kilted-compressed-image-transport",
119
+ "ffmpeg": "ros-kilted-ffmpeg-image-transport",
120
+ }
121
+
122
+
123
+ def _packaged_session_plugin() -> dict:
124
+ return yaml.safe_load(
125
+ (cli.WS_DIR / "session" / "content" / "base" / "session_plugin_base.yaml").read_text(encoding="utf-8")
126
+ )
127
+
128
+
129
+ def test_every_image_transport_the_session_plugin_can_select_is_installed() -> None:
130
+ """The packaged image must carry every transport the packaged session can ask for.
131
+
132
+ This is the guard that was missing when the base image moved from
133
+ desktop-full to ros-base: compressed_image_transport had arrived with
134
+ desktop-full's perception variant, nothing in this repository declared it,
135
+ and no e2e session has a /compressed input topic — so the suite stayed green
136
+ while a vehicle camera link could no longer start. Deriving the transport set
137
+ from the plugin rather than restating it means a new transport, or a thinner
138
+ base image, fails here instead of on a vehicle.
139
+ """
140
+ plugin = _packaged_session_plugin()
141
+
142
+ # Incoming republish: the transport the receiving peer decodes back to.
143
+ selected = {
144
+ str(value)
145
+ for key, value in plugin["parameters"].items()
146
+ if key.startswith("irt_") and key.endswith("_out_transport") and value
147
+ }
148
+ # Outgoing republish: the in-transport is chosen from the source topic name.
149
+ it_window = next(window for window in plugin["windows"] if window["name"] == "IT")
150
+ for split in it_window["splits"]:
151
+ for command in split["commands"]:
152
+ selected.update(re.findall(r'it_in_transport="([a-z]+)"', command))
153
+
154
+ # Both branches of that choice, so a rewrite that drops one is visible here.
155
+ assert {"raw", "compressed"} <= selected
156
+
157
+ unknown = selected - set(IMAGE_TRANSPORT_APT_PACKAGES)
158
+ assert not unknown, f"no apt package recorded for image transport(s): {sorted(unknown)}"
159
+
160
+ required = {IMAGE_TRANSPORT_APT_PACKAGES[transport] for transport in selected}
161
+ for config_path in (cli.DEFAULT_ROS2DOCKER_CONFIG, cli.EXAMPLE_PROJECT_DIR / "ros2docker.json"):
162
+ apt_packages = set(str(cli.load_config(config_path)["build_args"]["APT_PACKAGES"]).split())
163
+ missing = required - apt_packages
164
+ assert not missing, f"{config_path.name} does not install {sorted(missing)}"
165
+
166
+
167
+ def test_packaged_configs_do_not_fetch_rosdep_on_container_start() -> None:
168
+ """Readiness must cover the workspace build, not a third-party index fetch.
169
+
170
+ The packaged workspace dependencies come from the pinned base image and
171
+ explicit image package lists, then Docker smoke exercises the real build.
172
+ Enabling ros2docker's runtime check would run ``rosdep update`` for every
173
+ communication container before that small build and make readiness depend
174
+ on raw.githubusercontent.com.
175
+ """
176
+ configs = (
177
+ cli.DEFAULT_ROS2DOCKER_CONFIG,
178
+ cli.EXAMPLE_PROJECT_DIR / "ros2docker.json",
179
+ )
180
+
181
+ for config_path in configs:
182
+ config = cli.load_config(config_path)
183
+ run_args = [str(value) for value in config["run_args"]]
184
+
185
+ assert "BUILD_ROS2WS=1" in run_args
186
+ assert not any(arg.startswith("CHECK_ROS2WS_DEPENDENCIES=") for arg in run_args)
187
+
188
+
111
189
  def test_external_ros2docker_configs_install_selected_rmw_implementations() -> None:
112
190
  configs = sorted(cli.EXAMPLE_PROJECT_DIR.glob("scripts/**/external.ros2docker.json"))
113
191
  assert configs