rosotacom-dev 2.5.dev53__tar.gz → 2.5.dev54__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 (377) hide show
  1. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/PKG-INFO +1 -1
  2. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/session-configuration.md +28 -0
  3. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/session/content/base/session_plugin_base.yaml +18 -4
  4. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/session/creation/generate_session_files.py +91 -16
  5. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom_dev.egg-info/PKG-INFO +1 -1
  6. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom_dev.egg-info/scm_version.json +2 -2
  7. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_session_pipeline.py +88 -0
  8. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/.devcontainer/devcontainer.json.template +0 -0
  9. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/.devcontainer/re_generate_devcontainer_json.py +0 -0
  10. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/.github/CODEOWNERS +0 -0
  11. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/.github/ISSUE_TEMPLATE/documentation-audit.md +0 -0
  12. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/.github/ISSUE_TEMPLATE/implementation-cleanup.md +0 -0
  13. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/.github/ISSUE_TEMPLATE/quality-workflow.md +0 -0
  14. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/.github/ISSUE_TEMPLATE/redesign.md +0 -0
  15. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/.github/ISSUE_TEMPLATE/release-process.md +0 -0
  16. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/.github/ISSUE_TEMPLATE/repository-diagnosis.md +0 -0
  17. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/.github/ISSUE_TEMPLATE/test-ci-audit.md +0 -0
  18. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/.github/ISSUE_TEMPLATE/work-item.md +0 -0
  19. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  20. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/.github/actions/setup-just/action.yml +0 -0
  21. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/.github/dependabot.yml +0 -0
  22. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/.github/workflows/benchmark-calibrate.yml +0 -0
  23. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/.github/workflows/benchmark-gate.yml +0 -0
  24. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/.github/workflows/dev-release.yml +0 -0
  25. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/.github/workflows/image-scan.yml +0 -0
  26. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/.github/workflows/nightly-e2e.yml +0 -0
  27. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/.github/workflows/pr-lightweight.yml +0 -0
  28. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/.github/workflows/pr-merge-gate.yml +0 -0
  29. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/.github/workflows/release.yml +0 -0
  30. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/.pre-commit-config.yaml +0 -0
  31. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/AGENTS.md +0 -0
  32. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/CONCURRENCY.md +0 -0
  33. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/CONTRIBUTING.md +0 -0
  34. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/DEVELOPMENT_PRINCIPLES.md +0 -0
  35. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/LICENSE.txt +0 -0
  36. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/MANIFEST.in +0 -0
  37. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/README.md +0 -0
  38. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/budgets.jsonl +0 -0
  39. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/calibration/README.md +0 -0
  40. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/calibration/capacity-size-tight-cyclone.json +0 -0
  41. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/calibration/probe-loss-gop-tight-cyclone.json +0 -0
  42. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/calibration/probe-loss-nominal-cyclone.json +0 -0
  43. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/calibration/probe-loss-tight-cyclone.json +0 -0
  44. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/calibration/probe-loss-tight-fastdds.json +0 -0
  45. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/calibration/probe-loss-tight-zenoh.json +0 -0
  46. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/codecov.yml +0 -0
  47. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/deployment-configuration.md +0 -0
  48. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/benchmark-ab.md +0 -0
  49. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/benchmark-bag-as-load.md +0 -0
  50. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/ci.md +0 -0
  51. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/ffmpeg-keyframes.md +0 -0
  52. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/findings/README.md +0 -0
  53. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/findings/cyclone-spdp-discovery-bursts.md +0 -0
  54. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/findings/delay-alone-no-loss.md +0 -0
  55. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/findings/fastdds-datagram-cap-drops-large-samples.md +0 -0
  56. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/findings/graph-derived-types-block-a-non-graph-transport.md +0 -0
  57. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/findings/head-of-line-irregularity.md +0 -0
  58. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/findings/jitter-loss-bandwidth-latency.md +0 -0
  59. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/findings/keyframe-loss-kills-the-next-deltas.md +0 -0
  60. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/findings/lighter-message-loss.md +0 -0
  61. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/findings/oversubscription-queues-not-losses.md +0 -0
  62. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/findings/reorder-becomes-reader-loss.md +0 -0
  63. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/findings/repro/decode_chain_repro.py +0 -0
  64. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/findings/repro/reorder_drop_repro.py +0 -0
  65. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/findings/sender-rows-make-a-dead-link-look-loss-free.md +0 -0
  66. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/findings/zero-loss-boundaries-18kb-20hz.md +0 -0
  67. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/forensics-report.md +0 -0
  68. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/geo-link-map.md +0 -0
  69. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/github-repository-settings.md +0 -0
  70. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/link-bandwidth.md +0 -0
  71. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/link-trace.md +0 -0
  72. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/owner-runbook.md +0 -0
  73. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/performance-bands.md +0 -0
  74. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/playbooks/README.md +0 -0
  75. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/quality-model.md +0 -0
  76. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/release-notes/TEMPLATE.md +0 -0
  77. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/release-notes/v2.1.md +0 -0
  78. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/release-notes/v2.2.md +0 -0
  79. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/release-notes/v2.3.md +0 -0
  80. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/release-notes/v2.4.md +0 -0
  81. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/release.md +0 -0
  82. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/rfcs/0001-expectation-driven-test-suite.md +0 -0
  83. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/rfcs/0002-expectation-concepts.md +0 -0
  84. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/rfcs/0003-metric-backbone.md +0 -0
  85. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/rfcs/0004-network-profiles.md +0 -0
  86. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/rfcs/0005-benchmark-genres-and-ci.md +0 -0
  87. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/rfcs/0006-dynamic-qos.md +0 -0
  88. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/rfcs/0007-regression-gate.md +0 -0
  89. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/rfcs/README.md +0 -0
  90. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/testing.md +0 -0
  91. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/docs/work-items.md +0 -0
  92. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/install.sh +0 -0
  93. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/justfile +0 -0
  94. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/media/control_center.png +0 -0
  95. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/media/echo_test.png +0 -0
  96. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/media/forensics-report-example.png +0 -0
  97. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/media/host.png +0 -0
  98. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/media/vehicle.png +0 -0
  99. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/pyproject.toml +0 -0
  100. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/requirements.txt +0 -0
  101. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/rosotacom.yaml +0 -0
  102. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/setup.cfg +0 -0
  103. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/__init__.py +0 -0
  104. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/__main__.py +0 -0
  105. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/anonymize.py +0 -0
  106. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/bag_ground_truth.py +0 -0
  107. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/benched_set.py +0 -0
  108. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/benchmark.py +0 -0
  109. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/benchmark_delta.py +0 -0
  110. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/bundle_check.py +0 -0
  111. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/cli.py +0 -0
  112. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/cli_benchmark.py +0 -0
  113. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/deployment.py +0 -0
  114. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/ffmpeg_packet.py +0 -0
  115. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/forensics.py +0 -0
  116. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/geomap.py +0 -0
  117. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/image_cache.py +0 -0
  118. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/netem_dist.py +0 -0
  119. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/network_preflight.py +0 -0
  120. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/network_profiles.py +0 -0
  121. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/network_shaper.py +0 -0
  122. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/plots.py +0 -0
  123. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/py.typed +0 -0
  124. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/benched-set.yaml +0 -0
  125. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/.gitignore +0 -0
  126. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/README.md +0 -0
  127. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/__init__.py +0 -0
  128. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/bags/8_drop_reference/metadata.yaml +0 -0
  129. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/deployment.example.yaml +0 -0
  130. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/dist/field-20260817.dist +0 -0
  131. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/profiles.yaml +0 -0
  132. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/ros2docker.json +0 -0
  133. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/rosotacom.yaml +0 -0
  134. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scenarios/2_native_chatter/scenario-definition.yaml +0 -0
  135. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_a.sh +0 -0
  136. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_b.sh +0 -0
  137. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/external.ros2docker.json +0 -0
  138. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_communication.sh +0 -0
  139. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_external.py +0 -0
  140. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/wait_for_echo_topic.sh +0 -0
  141. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/external.ros2docker.json +0 -0
  142. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_communication.sh +0 -0
  143. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_external.py +0 -0
  144. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external.ros2docker.json +0 -0
  145. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external_session.yaml +0 -0
  146. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/foxglove.json +0 -0
  147. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_communication.sh +0 -0
  148. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_external.py +0 -0
  149. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
  150. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/metadata.yaml +0 -0
  151. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/external.ros2docker.json +0 -0
  152. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_communication.sh +0 -0
  153. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_external.py +0 -0
  154. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external.ros2docker.json +0 -0
  155. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external_session.yaml +0 -0
  156. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/foxglove.json +0 -0
  157. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_communication.sh +0 -0
  158. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_external.py +0 -0
  159. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
  160. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/metadata.yaml +0 -0
  161. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/external.ros2docker.json +0 -0
  162. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_communication.sh +0 -0
  163. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_external.py +0 -0
  164. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external.ros2docker.json +0 -0
  165. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external_session.yaml +0 -0
  166. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_communication.sh +0 -0
  167. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_external.py +0 -0
  168. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external.ros2docker.json +0 -0
  169. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external_session.yaml +0 -0
  170. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_communication.sh +0 -0
  171. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_external.py +0 -0
  172. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external.ros2docker.json +0 -0
  173. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external_session.yaml +0 -0
  174. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_communication.sh +0 -0
  175. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_external.py +0 -0
  176. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external.ros2docker.json +0 -0
  177. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external_session.yaml +0 -0
  178. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_communication.sh +0 -0
  179. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_external.py +0 -0
  180. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/sessions/10_restamp/session-definition.yaml +0 -0
  181. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/sessions/11_trickle/session-definition.yaml +0 -0
  182. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/sessions/12_content_integrity/session-definition.yaml +0 -0
  183. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/sessions/13_link_latency/session-definition.yaml +0 -0
  184. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/sessions/14_remote_assist_anonymized/session-definition.yaml +0 -0
  185. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/sessions/15_remote_assist_anonymized_costmap/session-definition.yaml +0 -0
  186. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/sessions/16_remote_assist_anonymized_camera/session-definition.yaml +0 -0
  187. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/sessions/17_synthetic_camera_quality/session-definition.yaml +0 -0
  188. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/sessions/1_heartbeat/session-definition.yaml +0 -0
  189. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/sessions/1_heartbeat_status/session-definition.yaml +0 -0
  190. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/sessions/2_native_chatter/session-definition.yaml +0 -0
  191. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/sessions/3_comp_occ_grid/session-definition.yaml +0 -0
  192. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/sessions/4_comp_occ_grid_zen/session-definition.yaml +0 -0
  193. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/sessions/5_sized_payload/session-definition.yaml +0 -0
  194. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/sessions/6_sized_payload_zen/session-definition.yaml +0 -0
  195. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/sessions/7_latched_static/session-definition.yaml +0 -0
  196. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/sessions/8_drop/session-definition.yaml +0 -0
  197. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/sessions/9_throttle/session-definition.yaml +0 -0
  198. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/sessions/bench_1_1_capacity/session-definition.yaml +0 -0
  199. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/sessions/bench_1_2_load_sweep/session-definition.yaml +0 -0
  200. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/sessions/bench_1_3_ramp/session-definition.yaml +0 -0
  201. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/sessions/bench_1_4_recovery/session-definition.yaml +0 -0
  202. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/examples/sessions/bench_1_5_camera/session-definition.yaml +0 -0
  203. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ros2docker.json.example +0 -0
  204. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/.vscode/c_cpp_properties.json +0 -0
  205. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/.vscode/settings.json +0 -0
  206. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_easy_mode.xml.template +0 -0
  207. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_initial_peer_list.xml.template +0 -0
  208. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v2.xml.template +0 -0
  209. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v3.xml.template +0 -0
  210. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v4.xml.template +0 -0
  211. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v5.xml.template +0 -0
  212. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ota_configs/create_zenoh_json5.py +0 -0
  213. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ota_configs/cyclonedds_local_participants.xml.template +0 -0
  214. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ota_configs/cyclonedds_minimal.xml.template +0 -0
  215. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ota_configs/cyclonedds_tuned.xml.template +0 -0
  216. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ota_configs/fastdds_easy_mode.xml.template +0 -0
  217. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ota_configs/fastdds_tuned.xml.template +0 -0
  218. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ota_configs/fastdds_unicast.xml.template +0 -0
  219. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ota_configs/get_ota_xml.py +0 -0
  220. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ota_configs/utils.py +0 -0
  221. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ota_configs/zenoh.json5.template +0 -0
  222. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/.gitkeep +0 -0
  223. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_cpp/CMakeLists.txt +0 -0
  224. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_cpp/COLCON_IGNORE +0 -0
  225. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_cpp/LICENSE.txt +0 -0
  226. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_cpp/package.xml +0 -0
  227. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_cpp/src/hz_monitor.cpp +0 -0
  228. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_compressor.cpp +0 -0
  229. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_decompressor.cpp +0 -0
  230. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_msgs/CMakeLists.txt +0 -0
  231. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_msgs/LICENSE.txt +0 -0
  232. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/CompressedData.msg +0 -0
  233. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/EchoHeartbeat.msg +0 -0
  234. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/OtaStamped.msg +0 -0
  235. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/SizedPayload.msg +0 -0
  236. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_msgs/package.xml +0 -0
  237. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/LICENSE.txt +0 -0
  238. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/__init__.py +0 -0
  239. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/base_bridge_relay.py +0 -0
  240. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_in.py +0 -0
  241. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_out.py +0 -0
  242. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/ffmpeg_flags.py +0 -0
  243. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/heartbeat_echo.py +0 -0
  244. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/hz_monitor.py +0 -0
  245. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_bandwidth_reducer.py +0 -0
  246. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_pixel_capper.py +0 -0
  247. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/lanelet_saver.py +0 -0
  248. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/latch_relay.py +0 -0
  249. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/costmap_remapper.py +0 -0
  250. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/marker_remapper.py +0 -0
  251. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/speed_test.py +0 -0
  252. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/tf_remapper.py +0 -0
  253. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/traffic_monitor.py +0 -0
  254. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/wifi_network_analysis_1.py +0 -0
  255. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_bytes.py +0 -0
  256. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_trace.py +0 -0
  257. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/local_global_frame_bridge.py +0 -0
  258. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/localization_map_split_reduce_saver.py +0 -0
  259. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/msg_transform.py +0 -0
  260. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pair_management.py +0 -0
  261. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/playout_pacer.py +0 -0
  262. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/playout_pacer_core.py +0 -0
  263. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pub_sub_pair.py +0 -0
  264. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/qos.py +0 -0
  265. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_in.py +0 -0
  266. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_out.py +0 -0
  267. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/restamp.py +0 -0
  268. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/sized_publisher.py +0 -0
  269. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency.py +0 -0
  270. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency_core.py +0 -0
  271. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview.py +0 -0
  272. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview_core.py +0 -0
  273. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/tf_map_to_cart_saver.py +0 -0
  274. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_monitor.py +0 -0
  275. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_resolution.py +0 -0
  276. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/trickle.py +0 -0
  277. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_compressor.py +0 -0
  278. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_decompressor.py +0 -0
  279. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_unwrapper.py +0 -0
  280. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_wrapper.py +0 -0
  281. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/package.xml +0 -0
  282. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/resource/com_py +0 -0
  283. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/setup.cfg +0 -0
  284. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/setup.py +0 -0
  285. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/test/test_copyright.py +0 -0
  286. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/test/test_flake8.py +0 -0
  287. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/ros2src/com_py/test/test_pep257.py +0 -0
  288. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/session/content/network/up_connectivity.py +0 -0
  289. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/session/content/network/wifi_network_analysis_2.py +0 -0
  290. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/session/creation/anonymize_bag.py +0 -0
  291. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/session/creation/catmux_log_setup.sh +0 -0
  292. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/session/creation/create_session_yaml.py +0 -0
  293. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/session/creation/run_session.py +0 -0
  294. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/session/creation/run_session_in_external_terminal.py +0 -0
  295. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/resources/ws/session/creation/strip_ansi.py +0 -0
  296. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/status_eval.py +0 -0
  297. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/stream_stats.py +0 -0
  298. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/trace_profiles.py +0 -0
  299. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/transit.py +0 -0
  300. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom/video_quality.py +0 -0
  301. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom_dev.egg-info/SOURCES.txt +0 -0
  302. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom_dev.egg-info/dependency_links.txt +0 -0
  303. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom_dev.egg-info/entry_points.txt +0 -0
  304. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom_dev.egg-info/requires.txt +0 -0
  305. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom_dev.egg-info/scm_file_list.json +0 -0
  306. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/src/rosotacom_dev.egg-info/top_level.txt +0 -0
  307. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/terminology.md +0 -0
  308. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/contract/test_benched_set_registry.py +0 -0
  309. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/contract/test_findings.py +0 -0
  310. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/contract/test_markdown_links.py +0 -0
  311. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/contract/test_ota_source_bundle.py +0 -0
  312. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/contract/test_package_metadata.py +0 -0
  313. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/contract/test_packaged_resources.py +0 -0
  314. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/contract/test_profile_covers_generated_commands.py +0 -0
  315. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/contract/test_pytest_policy.py +0 -0
  316. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/contract/test_readme_examples.py +0 -0
  317. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/contract/test_security_maintenance_config.py +0 -0
  318. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/contract/test_session_configuration_doc.py +0 -0
  319. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/contract/test_session_template_substitution.py +0 -0
  320. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/contract/test_workflow_contracts.py +0 -0
  321. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/e2e/conftest.py +0 -0
  322. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/e2e/test_anonymize_e2e.py +0 -0
  323. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/e2e/test_benchmark_ab.py +0 -0
  324. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/e2e/test_benchmark_capacity.py +0 -0
  325. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/e2e/test_benchmark_replay.py +0 -0
  326. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/e2e/test_parallel_smoke.py +0 -0
  327. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/e2e/test_smoke.py +0 -0
  328. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/e2e/test_timeline_stepping.py +0 -0
  329. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/e2e/test_video_quality_e2e.py +0 -0
  330. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/sessions/generate_rmw_matrix.py +0 -0
  331. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-local_zenoh-ros2dds-ota/session-definition.yaml +0 -0
  332. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota/session-definition.yaml +0 -0
  333. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota-tuned/session-definition.yaml +0 -0
  334. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/sessions/rmw_matrix/1_heartbeat_fastdds/session-definition.yaml +0 -0
  335. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/sessions/rmw_matrix/1_heartbeat_fastdds-default/session-definition.yaml +0 -0
  336. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/sessions/rmw_matrix/1_heartbeat_zen-endpoints/session-definition.yaml +0 -0
  337. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_anonymize.py +0 -0
  338. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_bag_ground_truth.py +0 -0
  339. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_benched_set.py +0 -0
  340. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_benchmark.py +0 -0
  341. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_benchmark_delta.py +0 -0
  342. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_bundle_check.py +0 -0
  343. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_catmux_pane_logging.py +0 -0
  344. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_cli.py +0 -0
  345. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_cli_benchmark.py +0 -0
  346. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_concurrency.py +0 -0
  347. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_container_shaping.py +0 -0
  348. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_deployment.py +0 -0
  349. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_ffmpeg_flags.py +0 -0
  350. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_ffmpeg_packet.py +0 -0
  351. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_field_profiles.py +0 -0
  352. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_forensics.py +0 -0
  353. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_geomap.py +0 -0
  354. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_image_cache.py +0 -0
  355. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_link_bytes.py +0 -0
  356. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_link_trace.py +0 -0
  357. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_netem_dist.py +0 -0
  358. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_network_preflight.py +0 -0
  359. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_network_profiles.py +0 -0
  360. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_network_shaper.py +0 -0
  361. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_ota_link_configs.py +0 -0
  362. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_ota_unwrapper.py +0 -0
  363. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_ota_wrapper.py +0 -0
  364. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_ota_xml.py +0 -0
  365. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_playout_pacer.py +0 -0
  366. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_plots.py +0 -0
  367. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_pub_sub_pair_types.py +0 -0
  368. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_qos_fallback_logging.py +0 -0
  369. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_relay_optional_parameters.py +0 -0
  370. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_stage_latency.py +0 -0
  371. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_status_eval.py +0 -0
  372. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_status_overview.py +0 -0
  373. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_status_overview_observer.py +0 -0
  374. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_stream_stats.py +0 -0
  375. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_trace_profiles.py +0 -0
  376. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/tests/unit/test_transit.py +0 -0
  377. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev54}/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.dev53
3
+ Version: 2.5.dev54
4
4
  Summary: Host CLI for ROS OTA communication sessions.
5
5
  Author: develNor
6
6
  License-Expression: BSD-3-Clause
@@ -674,6 +674,7 @@ Declaratively, add a `playout` block to the transport:
674
674
  target_ms: 350 # fixed budget when adaptive: false
675
675
  min_ms: 100 # adaptive clamp above the observed delay floor
676
676
  max_ms: 800
677
+ republish: paced # paced (default) | unpaced | both
677
678
  ```
678
679
 
679
680
  The receiving peer then runs the pacer in its own `PACE` window against the
@@ -684,6 +685,33 @@ why `playout` requires `remote_republish`: without a republish the pacer's
684
685
  The sender's own preview decode (`local_republish`) is never paced — it reads
685
686
  the local copy of what was just encoded, so there is no jitter to absorb.
686
687
 
688
+ ##### `republish`: which stream reaches the display
689
+
690
+ Pacing under an unchanged topic name is what keeps applications working, and it
691
+ is also what makes the improvement invisible — nothing shows paced and unpaced
692
+ together. `republish` names which stream the receiver decodes:
693
+
694
+ | value | decodes | publishes |
695
+ |---|---|---|
696
+ | `paced` (default) | `<encoded>/paced` | `<encoded>/<remote_republish>` |
697
+ | `unpaced` | `<encoded>` | `<encoded>/<remote_republish>` |
698
+ | `both` | both | delivered as above, comparison on `<encoded>/unpaced/<remote_republish>` |
699
+
700
+ **The delivered name is the same in all three.** Only what feeds the decode
701
+ moves, so switching modes never changes what an application subscribes to.
702
+
703
+ `unpaced` still runs the pacer: `/paced` and its `budget_ms` / `queue_depth`
704
+ debug topics are published and recordable, they just do not reach the display.
705
+ That is the A/B control — measure a pacer on a live link without changing what
706
+ an operator sees.
707
+
708
+ `both` runs the receiver's expensive stage twice (a codec decode plus, for
709
+ `compressed`, a JPEG encode per frame) and adds one local topic; nothing extra
710
+ crosses the link. It also consumes one of the four reverse-transport slots. It
711
+ is a rehearsal and diagnosis switch — the comparison stream is deliberately not
712
+ a status pipeline stage, because it is not something the link promises to
713
+ deliver.
714
+
687
715
  The node also runs standalone against any packet stream:
688
716
 
689
717
  ```bash
@@ -230,22 +230,32 @@ parameters:
230
230
  it_4_foxglove_qmax: -1
231
231
  it_4_outgoing_suffix: # e.g. compressed (defaults to it_4_transport if not set)
232
232
 
233
+ # `irt_N_out_topic` overrides where a decode publishes. It exists so two slots
234
+ # can decode the *same* stream — the paced one under the name applications
235
+ # already subscribe to, an unpaced copy next to it for comparison
236
+ # (transport.playout.republish: both). Left unset, a decode publishes on
237
+ # ${irt_N_topic}/${irt_N_out_transport}, which is the only shape any session
238
+ # had before and the one every unpaced link still has.
233
239
  irt: false
234
240
  irt_1_topic: # e.g. /sensors/camera/front_wide/image_color
235
241
  irt_1_transport: # e.g. raw
236
242
  irt_1_out_transport: compressed # e.g. raw, compressed – determines the output remap format
243
+ irt_1_out_topic: # overrides the output remap; defaults to ${irt_1_topic}/${irt_1_out_transport}
237
244
  irt_1_paced: # "true" -> decode reads ${irt_1_topic}/paced (playout pacer, PACE window)
238
245
  irt_2_topic: # e.g. /sensors/front_camera/image_raw/compressed
239
246
  irt_2_transport: # e.g. raw
240
247
  irt_2_out_transport: compressed # e.g. raw, compressed – determines the output remap format
248
+ irt_2_out_topic: # overrides the output remap; defaults to ${irt_2_topic}/${irt_2_out_transport}
241
249
  irt_2_paced: # "true" -> decode reads ${irt_2_topic}/paced
242
250
  irt_3_topic: # e.g. /sensor/front_camera/image_color/compressed
243
251
  irt_3_transport: # e.g. raw
244
252
  irt_3_out_transport: compressed # e.g. raw, compressed – determines the output remap format
253
+ irt_3_out_topic: # overrides the output remap; defaults to ${irt_3_topic}/${irt_3_out_transport}
245
254
  irt_3_paced: # "true" -> decode reads ${irt_3_topic}/paced
246
255
  irt_4_topic: # e.g. /sensor/front_camera/image_color/compressed
247
256
  irt_4_transport: # e.g. raw
248
257
  irt_4_out_transport: compressed # e.g. raw, compressed – determines the output remap format
258
+ irt_4_out_topic: # overrides the output remap; defaults to ${irt_4_topic}/${irt_4_out_transport}
249
259
  irt_4_paced: # "true" -> decode reads ${irt_4_topic}/paced
250
260
 
251
261
  # Receiver-side playout pacing (transport.playout in the session definition):
@@ -707,31 +717,35 @@ windows:
707
717
  - if [ '${irt_1_topic}' = "None" ]; then exit; fi
708
718
  - if [[ "${irt_1_out_transport}" == "raw" ]]; then out_remap="out"; else out_remap="out/${irt_1_out_transport}"; fi
709
719
  - if [[ "${irt_1_paced}" != "None" ]]; then irt_in_topic="${irt_1_topic}/paced"; else irt_in_topic="${irt_1_topic}"; fi
720
+ - if [[ "${irt_1_out_topic}" != "None" ]]; then irt_out_topic="${irt_1_out_topic}"; else irt_out_topic="${irt_1_topic}/${irt_1_out_transport}"; fi
710
721
  - args=(ros2 run image_transport republish --ros-args -r __node:=irt_republish1 -p in_transport:=${irt_1_transport} -p out_transport:=${irt_1_out_transport}
711
- --remap in/${irt_1_transport}:=${irt_in_topic} --remap ${out_remap}:=${irt_1_topic}/${irt_1_out_transport})
722
+ --remap in/${irt_1_transport}:=${irt_in_topic} --remap ${out_remap}:=${irt_out_topic})
712
723
  - echo ${args[@]}
713
724
  - ${args[@]}
714
725
  - commands:
715
726
  - if [ '${irt_2_topic}' = "None" ]; then exit; fi
716
727
  - if [[ "${irt_2_out_transport}" == "raw" ]]; then out_remap="out"; else out_remap="out/${irt_2_out_transport}"; fi
717
728
  - if [[ "${irt_2_paced}" != "None" ]]; then irt_in_topic="${irt_2_topic}/paced"; else irt_in_topic="${irt_2_topic}"; fi
729
+ - if [[ "${irt_2_out_topic}" != "None" ]]; then irt_out_topic="${irt_2_out_topic}"; else irt_out_topic="${irt_2_topic}/${irt_2_out_transport}"; fi
718
730
  - args=(ros2 run image_transport republish --ros-args -r __node:=irt_republish2 -p in_transport:=${irt_2_transport} -p out_transport:=${irt_2_out_transport}
719
- --remap in/${irt_2_transport}:=${irt_in_topic} --remap ${out_remap}:=${irt_2_topic}/${irt_2_out_transport})
731
+ --remap in/${irt_2_transport}:=${irt_in_topic} --remap ${out_remap}:=${irt_out_topic})
720
732
  - echo ${args[@]}
721
733
  - ${args[@]}
722
734
  - commands:
723
735
  - if [ '${irt_3_topic}' = "None" ]; then exit; fi
724
736
  - if [[ "${irt_3_out_transport}" == "raw" ]]; then out_remap="out"; else out_remap="out/${irt_3_out_transport}"; fi
725
737
  - if [[ "${irt_3_paced}" != "None" ]]; then irt_in_topic="${irt_3_topic}/paced"; else irt_in_topic="${irt_3_topic}"; fi
738
+ - if [[ "${irt_3_out_topic}" != "None" ]]; then irt_out_topic="${irt_3_out_topic}"; else irt_out_topic="${irt_3_topic}/${irt_3_out_transport}"; fi
726
739
  - args=(ros2 run image_transport republish --ros-args -r __node:=irt_republish3 -p in_transport:=${irt_3_transport} -p out_transport:=${irt_3_out_transport}
727
- --remap in/${irt_3_transport}:=${irt_in_topic} --remap ${out_remap}:=${irt_3_topic}/${irt_3_out_transport})
740
+ --remap in/${irt_3_transport}:=${irt_in_topic} --remap ${out_remap}:=${irt_out_topic})
728
741
  - echo ${args[@]}
729
742
  - ${args[@]}
730
743
  - commands:
731
744
  - if [ '${irt_4_topic}' = "None" ]; then exit; fi
732
745
  - if [[ "${irt_4_out_transport}" == "raw" ]]; then out_remap="out"; else out_remap="out/${irt_4_out_transport}"; fi
733
746
  - if [[ "${irt_4_paced}" != "None" ]]; then irt_in_topic="${irt_4_topic}/paced"; else irt_in_topic="${irt_4_topic}"; fi
747
+ - if [[ "${irt_4_out_topic}" != "None" ]]; then irt_out_topic="${irt_4_out_topic}"; else irt_out_topic="${irt_4_topic}/${irt_4_out_transport}"; fi
734
748
  - args=(ros2 run image_transport republish --ros-args -r __node:=irt_republish4 -p in_transport:=${irt_4_transport} -p out_transport:=${irt_4_out_transport}
735
- --remap in/${irt_4_transport}:=${irt_in_topic} --remap ${out_remap}:=${irt_4_topic}/${irt_4_out_transport})
749
+ --remap in/${irt_4_transport}:=${irt_in_topic} --remap ${out_remap}:=${irt_out_topic})
736
750
  - echo ${args[@]}
737
751
  - ${args[@]}
@@ -101,6 +101,44 @@ class TransportSpec:
101
101
  playout: Optional[Dict[str, Any]] = None
102
102
 
103
103
 
104
+ #: What `transport.playout.republish` may say, and what each answer decodes.
105
+ #: The delivered topic name is the same in all three -- only what feeds the
106
+ #: decode moves, and `both` adds a second decode under a name of its own.
107
+ PLAYOUT_REPUBLISH_MODES = ("paced", "unpaced", "both")
108
+ PLAYOUT_REPUBLISH_DEFAULT = "paced"
109
+
110
+
111
+ def playout_republish(playout: Dict[str, Any]) -> str:
112
+ """Which stream the receiver decodes, for a link that declares `playout`.
113
+
114
+ Only meaningful where a pacer runs. A link without `playout` has no paced
115
+ copy to read, so callers decide that case before asking -- passing None here
116
+ would answer 'paced' for a stream nothing paces.
117
+ """
118
+ return str((playout or {}).get("republish", PLAYOUT_REPUBLISH_DEFAULT))
119
+
120
+
121
+ @dataclass
122
+ class IrtSlot:
123
+ """One reverse-transport decode: what it reads, and where it publishes.
124
+
125
+ Four of these fit in the base plugin. Most links use one per direction, but
126
+ a comparison decode (`playout.republish: both`) is a second slot on the same
127
+ topic -- which is the only reason `out_topic` exists, since two decodes of
128
+ one stream would otherwise remap onto the same output name.
129
+ """
130
+
131
+ topic: str
132
+ ttype: str
133
+ out_transport: str
134
+ #: Set only for the slot that a pacer feeds; the pacer is configured from it.
135
+ playout: Optional[Dict[str, Any]] = None
136
+ #: Read '<topic>/paced' rather than '<topic>'.
137
+ reads_paced: bool = False
138
+ #: Override the output remap; None means '<topic>/<out_transport>'.
139
+ out_topic: Optional[str] = None
140
+
141
+
104
142
  @dataclass
105
143
  class TopicEntry:
106
144
  base: str
@@ -1746,7 +1784,7 @@ def _compute_pipeline(
1746
1784
  if playout_cfg is not None:
1747
1785
  if not isinstance(playout_cfg, dict):
1748
1786
  raise ValueError(f"transport.playout must be a mapping for topic '{entry.base}'")
1749
- allowed = {"adaptive", "target_ms", "min_ms", "max_ms"}
1787
+ allowed = {"adaptive", "target_ms", "min_ms", "max_ms", "republish"}
1750
1788
  unknown = sorted(set(playout_cfg) - allowed)
1751
1789
  if unknown:
1752
1790
  raise ValueError(
@@ -1769,6 +1807,15 @@ def _compute_pipeline(
1769
1807
  raise ValueError(f"transport.playout.max_ms must be >= min_ms for topic '{entry.base}'")
1770
1808
  if "adaptive" in playout_cfg and not isinstance(playout_cfg["adaptive"], bool):
1771
1809
  raise ValueError(f"transport.playout.adaptive must be a boolean for topic '{entry.base}'")
1810
+ if "republish" in playout_cfg and playout_cfg["republish"] not in PLAYOUT_REPUBLISH_MODES:
1811
+ raise ValueError(
1812
+ f"transport.playout.republish for topic '{entry.base}' is "
1813
+ f"{playout_cfg['republish']!r}; allowed: {list(PLAYOUT_REPUBLISH_MODES)}. "
1814
+ "'paced' decodes the paced copy (the default), 'unpaced' runs the pacer "
1815
+ "without putting it on the display path, and 'both' adds a second decode "
1816
+ "on '<encoded>/unpaced/<transport>' for comparison. The delivered topic "
1817
+ "name is the same in all three."
1818
+ )
1772
1819
  playout = dict(playout_cfg)
1773
1820
 
1774
1821
  params = {k: v for k, v in t.items() if k not in ("type", "playout", *republish_keys)}
@@ -2781,11 +2828,12 @@ def func(
2781
2828
  nor_items.append((base, suffix))
2782
2829
 
2783
2830
  # Hard limits from session_plugin_base.yaml.
2784
- def _assert_max(label: str, items: List[Any], limit: int) -> None:
2831
+ def _assert_max(label: str, items: List[Any], limit: int, note: str = "") -> None:
2785
2832
  if len(items) > limit:
2786
2833
  raise RuntimeError(
2787
2834
  f"peer '{local}': too many '{label}' entries ({len(items)}). "
2788
2835
  f"The base session plugin supports at most {limit}."
2836
+ + (f" Note: {note}." if note else "")
2789
2837
  )
2790
2838
 
2791
2839
  _assert_max("drp", drp_items, 8)
@@ -3319,31 +3367,58 @@ def func(
3319
3367
  # The sender's own preview decode is never paced: it reads the local
3320
3368
  # copy of what it just encoded, so there is no network jitter to
3321
3369
  # absorb. Playout pacing exists on the receiving side only.
3322
- irt_all: List[Tuple[str, str, str, Optional[Dict[str, Any]]]] = []
3370
+ irt_all: List[IrtSlot] = []
3323
3371
  for t, tspec in irt_items_local:
3324
3372
  assert tspec is not None
3325
- irt_all.append((t, tspec.type, str(tspec.local_republish), None))
3326
- irt_all.extend(
3327
- (topic, tspec.type, str(tspec.remote_republish), tspec.playout) for topic, tspec in irt_items_remote
3373
+ irt_all.append(IrtSlot(t, tspec.type, str(tspec.local_republish)))
3374
+ for topic, tspec in irt_items_remote:
3375
+ out_transport = str(tspec.remote_republish)
3376
+ if tspec.playout is None:
3377
+ # No pacer on this link: the decode reads what arrived. Asking
3378
+ # it for '<topic>/paced' would give it a name nothing publishes,
3379
+ # which advertises an output and then never fills it.
3380
+ irt_all.append(IrtSlot(topic, tspec.type, out_transport))
3381
+ continue
3382
+ mode = playout_republish(tspec.playout)
3383
+ # The decode an application reads keeps its name in every mode; only
3384
+ # what feeds it moves. `unpaced` still runs the pacer -- it publishes
3385
+ # '<topic>/paced' and its debug topics for measurement -- and simply
3386
+ # does not put it on the display path.
3387
+ irt_all.append(
3388
+ IrtSlot(topic, tspec.type, out_transport, playout=tspec.playout, reads_paced=mode != "unpaced")
3389
+ )
3390
+ if mode == "both":
3391
+ # The comparison branch: same stream, undelayed, under a name of
3392
+ # its own. `<topic>/unpaced` is a valid image_transport base, so
3393
+ # a viewer subscribes to it exactly like the delivered one.
3394
+ irt_all.append(
3395
+ IrtSlot(topic, tspec.type, out_transport, out_topic=f"{topic}/unpaced/{out_transport}")
3396
+ )
3397
+ _assert_max(
3398
+ "irt",
3399
+ irt_all,
3400
+ 4,
3401
+ note="a `playout.republish: both` comparison decode consumes a slot of its own",
3328
3402
  )
3329
- _assert_max("irt", irt_all, 4)
3330
3403
  if irt_all:
3331
3404
  items2 = [("irt", True)]
3332
- for i, (topic, _ttype, _out_transport, _playout) in enumerate(irt_all, 1):
3333
- items2.append((f"irt_{i}_topic", topic))
3334
- for i, (_topic, ttype, out_transport, playout) in enumerate(irt_all, 1):
3335
- items2.append((f"irt_{i}_transport", ttype))
3336
- items2.append((f"irt_{i}_out_transport", out_transport))
3337
- if playout is not None:
3405
+ for i, slot in enumerate(irt_all, 1):
3406
+ items2.append((f"irt_{i}_topic", slot.topic))
3407
+ for i, slot in enumerate(irt_all, 1):
3408
+ items2.append((f"irt_{i}_transport", slot.ttype))
3409
+ items2.append((f"irt_{i}_out_transport", slot.out_transport))
3410
+ if slot.out_topic is not None:
3411
+ items2.append((f"irt_{i}_out_topic", slot.out_topic))
3412
+ if slot.reads_paced:
3338
3413
  # Points the decode's input remap at '<topic>/paced'; the
3339
3414
  # pacer itself runs in the PACE window below.
3340
3415
  items2.append((f"irt_{i}_paced", "true"))
3341
3416
  blocks.append(PluginBlock("irt", items2))
3342
3417
 
3343
3418
  paced_entries = [
3344
- (i, topic, ttype, playout)
3345
- for i, (topic, ttype, _out_transport, playout) in enumerate(irt_all, 1)
3346
- if playout is not None
3419
+ (i, slot.topic, slot.ttype, slot.playout)
3420
+ for i, slot in enumerate(irt_all, 1)
3421
+ if slot.playout is not None
3347
3422
  ]
3348
3423
  if paced_entries:
3349
3424
  items_pace: List[Tuple[str, Any]] = [("pace", True)]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rosotacom-dev
3
- Version: 2.5.dev53
3
+ Version: 2.5.dev54
4
4
  Summary: Host CLI for ROS OTA communication sessions.
5
5
  Author: develNor
6
6
  License-Expression: BSD-3-Clause
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "tag": "2.4",
3
- "distance": 53,
4
- "node": "g05d5905a4728651003afe5bc2feb657a96a1d395",
3
+ "distance": 54,
4
+ "node": "g28ff3da22234e297b05850ec0df7553546665959",
5
5
  "dirty": false,
6
6
  "branch": "HEAD",
7
7
  "node_date": "2026-08-19"
@@ -306,3 +306,91 @@ def test_generated_peer_files_wire_the_pacer(tmp_path: Path) -> None:
306
306
  sender = (tmp_path / "b" / "plugin.yaml").read_text(encoding="utf-8")
307
307
  assert "pace" not in sender or "pace_1_topic" not in sender
308
308
  assert "irt_1_paced" not in sender
309
+
310
+
311
+ # `transport.playout.republish` — which stream the receiver decodes (#302).
312
+ #
313
+ # The improvement a pacer makes is invisible while it replaces the picture under
314
+ # the same name: there is no moment where paced and unpaced are on screen
315
+ # together. `both` puts them there. What must hold across all three modes is
316
+ # that the *delivered* name never moves — an application subscribes to
317
+ # `<encoded>/<out_transport>` whatever the mode, which is the rule #276 exists
318
+ # to protect and exactly what a comparison switch could break in silence.
319
+
320
+
321
+ def _receiver_plugin(tmp_path: Path, playout: dict | None) -> str:
322
+ transport: dict = {"type": "ffmpeg", "remote_republish": "compressed"}
323
+ if playout is not None:
324
+ transport["playout"] = playout
325
+ generator.func(
326
+ session_config_obj=_camera_cfg({"transport": transport, "use_ota_wrapper": True}),
327
+ output_dir=str(tmp_path),
328
+ force=True,
329
+ peer_addresses={"a": "127.0.0.1", "b": "127.0.0.2"},
330
+ )
331
+ return (tmp_path / "a" / "plugin.yaml").read_text(encoding="utf-8")
332
+
333
+
334
+ def test_a_receiver_without_playout_decodes_what_arrived(tmp_path: Path) -> None:
335
+ """A link that paces nothing has no '/paced' for its decode to read.
336
+
337
+ Worth its own test because of how it fails: `image_transport republish`
338
+ advertises its output whether or not its input exists, so a decode pointed
339
+ at a name nobody publishes looks alive and delivers nothing. That is what
340
+ the `17_synthetic_camera_quality` slice caught while the whole unit suite
341
+ stayed green — the receiver's *unpaced* case had no assertion at all.
342
+ """
343
+ receiver = _receiver_plugin(tmp_path, None)
344
+
345
+ assert "irt_1_topic: /camera/image/ffmpeg" in receiver
346
+ assert "irt_1_paced" not in receiver
347
+ assert "irt_1_out_topic" not in receiver
348
+ assert "pace_1_topic" not in receiver
349
+
350
+
351
+ def test_republish_rejects_a_mode_that_is_not_one_of_the_three() -> None:
352
+ with pytest.raises(ValueError, match="allowed: \\['paced', 'unpaced', 'both'\\]"):
353
+ _pipeline(_ffmpeg(playout={"republish": "compare"}))
354
+
355
+
356
+ def test_paced_is_the_default_and_needs_no_output_override() -> None:
357
+ _entry, pipe = _pipeline(_ffmpeg(playout={}))
358
+ assert generator.playout_republish(pipe["transport"].playout) == "paced"
359
+
360
+
361
+ def test_unpaced_runs_the_pacer_but_keeps_it_off_the_display_path(tmp_path: Path) -> None:
362
+ """The measurement mode: '/paced' and its debug topics exist, nothing reads them."""
363
+ receiver = _receiver_plugin(tmp_path, {"republish": "unpaced"})
364
+
365
+ assert "pace_1_topic: /camera/image/ffmpeg" in receiver
366
+ assert "irt_1_paced" not in receiver
367
+ assert "irt_1_out_topic" not in receiver
368
+
369
+
370
+ def test_both_adds_a_second_decode_under_a_name_of_its_own(tmp_path: Path) -> None:
371
+ receiver = _receiver_plugin(tmp_path, {"republish": "both"})
372
+
373
+ # Slot 1 is the delivered one: paced input, unchanged output name.
374
+ assert "irt_1_topic: /camera/image/ffmpeg" in receiver
375
+ assert "irt_1_paced" in receiver
376
+ assert "irt_1_out_topic" not in receiver
377
+ # Slot 2 is the comparison: same stream, undelayed, qualified output.
378
+ assert "irt_2_topic: /camera/image/ffmpeg" in receiver
379
+ assert "irt_2_out_topic: /camera/image/ffmpeg/unpaced/compressed" in receiver
380
+ assert "irt_2_paced" not in receiver
381
+ # One pacer, not two -- the second decode reads what the first one's pacer
382
+ # was fed, and a second pacer on the same topic would publish onto the same
383
+ # '/paced' name.
384
+ assert "pace_2_topic" not in receiver
385
+
386
+
387
+ def test_every_mode_delivers_the_same_topic_name(tmp_path: Path) -> None:
388
+ """The one invariant a comparison switch must not break."""
389
+ delivered = set()
390
+ for mode in ("paced", "unpaced", "both"):
391
+ _entry, pipe = _pipeline(_ffmpeg(playout={"republish": mode}))
392
+ delivered.add(generator._delivered_topic(pipe, pipe["final"]))
393
+ _entry, unpaced_link = _pipeline(_ffmpeg())
394
+ delivered.add(generator._delivered_topic(unpaced_link, unpaced_link["final"]))
395
+
396
+ assert len(delivered) == 1, delivered