rosotacom-dev 2.5.dev53__tar.gz → 2.5.dev55__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (378) hide show
  1. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/PKG-INFO +1 -1
  2. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/testing.md +35 -0
  3. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/session-configuration.md +28 -0
  4. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/session/content/base/session_plugin_base.yaml +18 -4
  5. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/session/creation/generate_session_files.py +91 -16
  6. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom_dev.egg-info/PKG-INFO +1 -1
  7. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom_dev.egg-info/SOURCES.txt +1 -0
  8. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom_dev.egg-info/scm_file_list.json +1 -0
  9. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom_dev.egg-info/scm_version.json +2 -2
  10. rosotacom_dev-2.5.dev55/tests/contract/test_generated_topics_have_a_producer.py +467 -0
  11. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_session_pipeline.py +88 -0
  12. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/.devcontainer/devcontainer.json.template +0 -0
  13. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/.devcontainer/re_generate_devcontainer_json.py +0 -0
  14. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/.github/CODEOWNERS +0 -0
  15. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/.github/ISSUE_TEMPLATE/documentation-audit.md +0 -0
  16. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/.github/ISSUE_TEMPLATE/implementation-cleanup.md +0 -0
  17. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/.github/ISSUE_TEMPLATE/quality-workflow.md +0 -0
  18. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/.github/ISSUE_TEMPLATE/redesign.md +0 -0
  19. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/.github/ISSUE_TEMPLATE/release-process.md +0 -0
  20. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/.github/ISSUE_TEMPLATE/repository-diagnosis.md +0 -0
  21. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/.github/ISSUE_TEMPLATE/test-ci-audit.md +0 -0
  22. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/.github/ISSUE_TEMPLATE/work-item.md +0 -0
  23. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  24. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/.github/actions/setup-just/action.yml +0 -0
  25. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/.github/dependabot.yml +0 -0
  26. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/.github/workflows/benchmark-calibrate.yml +0 -0
  27. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/.github/workflows/benchmark-gate.yml +0 -0
  28. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/.github/workflows/dev-release.yml +0 -0
  29. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/.github/workflows/image-scan.yml +0 -0
  30. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/.github/workflows/nightly-e2e.yml +0 -0
  31. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/.github/workflows/pr-lightweight.yml +0 -0
  32. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/.github/workflows/pr-merge-gate.yml +0 -0
  33. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/.github/workflows/release.yml +0 -0
  34. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/.pre-commit-config.yaml +0 -0
  35. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/AGENTS.md +0 -0
  36. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/CONCURRENCY.md +0 -0
  37. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/CONTRIBUTING.md +0 -0
  38. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/DEVELOPMENT_PRINCIPLES.md +0 -0
  39. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/LICENSE.txt +0 -0
  40. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/MANIFEST.in +0 -0
  41. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/README.md +0 -0
  42. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/budgets.jsonl +0 -0
  43. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/calibration/README.md +0 -0
  44. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/calibration/capacity-size-tight-cyclone.json +0 -0
  45. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/calibration/probe-loss-gop-tight-cyclone.json +0 -0
  46. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/calibration/probe-loss-nominal-cyclone.json +0 -0
  47. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/calibration/probe-loss-tight-cyclone.json +0 -0
  48. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/calibration/probe-loss-tight-fastdds.json +0 -0
  49. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/calibration/probe-loss-tight-zenoh.json +0 -0
  50. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/codecov.yml +0 -0
  51. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/deployment-configuration.md +0 -0
  52. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/benchmark-ab.md +0 -0
  53. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/benchmark-bag-as-load.md +0 -0
  54. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/ci.md +0 -0
  55. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/ffmpeg-keyframes.md +0 -0
  56. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/findings/README.md +0 -0
  57. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/findings/cyclone-spdp-discovery-bursts.md +0 -0
  58. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/findings/delay-alone-no-loss.md +0 -0
  59. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/findings/fastdds-datagram-cap-drops-large-samples.md +0 -0
  60. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/findings/graph-derived-types-block-a-non-graph-transport.md +0 -0
  61. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/findings/head-of-line-irregularity.md +0 -0
  62. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/findings/jitter-loss-bandwidth-latency.md +0 -0
  63. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/findings/keyframe-loss-kills-the-next-deltas.md +0 -0
  64. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/findings/lighter-message-loss.md +0 -0
  65. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/findings/oversubscription-queues-not-losses.md +0 -0
  66. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/findings/reorder-becomes-reader-loss.md +0 -0
  67. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/findings/repro/decode_chain_repro.py +0 -0
  68. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/findings/repro/reorder_drop_repro.py +0 -0
  69. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/findings/sender-rows-make-a-dead-link-look-loss-free.md +0 -0
  70. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/findings/zero-loss-boundaries-18kb-20hz.md +0 -0
  71. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/forensics-report.md +0 -0
  72. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/geo-link-map.md +0 -0
  73. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/github-repository-settings.md +0 -0
  74. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/link-bandwidth.md +0 -0
  75. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/link-trace.md +0 -0
  76. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/owner-runbook.md +0 -0
  77. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/performance-bands.md +0 -0
  78. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/playbooks/README.md +0 -0
  79. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/quality-model.md +0 -0
  80. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/release-notes/TEMPLATE.md +0 -0
  81. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/release-notes/v2.1.md +0 -0
  82. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/release-notes/v2.2.md +0 -0
  83. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/release-notes/v2.3.md +0 -0
  84. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/release-notes/v2.4.md +0 -0
  85. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/release.md +0 -0
  86. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/rfcs/0001-expectation-driven-test-suite.md +0 -0
  87. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/rfcs/0002-expectation-concepts.md +0 -0
  88. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/rfcs/0003-metric-backbone.md +0 -0
  89. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/rfcs/0004-network-profiles.md +0 -0
  90. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/rfcs/0005-benchmark-genres-and-ci.md +0 -0
  91. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/rfcs/0006-dynamic-qos.md +0 -0
  92. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/rfcs/0007-regression-gate.md +0 -0
  93. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/rfcs/README.md +0 -0
  94. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/docs/work-items.md +0 -0
  95. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/install.sh +0 -0
  96. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/justfile +0 -0
  97. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/media/control_center.png +0 -0
  98. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/media/echo_test.png +0 -0
  99. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/media/forensics-report-example.png +0 -0
  100. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/media/host.png +0 -0
  101. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/media/vehicle.png +0 -0
  102. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/pyproject.toml +0 -0
  103. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/requirements.txt +0 -0
  104. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/rosotacom.yaml +0 -0
  105. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/setup.cfg +0 -0
  106. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/__init__.py +0 -0
  107. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/__main__.py +0 -0
  108. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/anonymize.py +0 -0
  109. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/bag_ground_truth.py +0 -0
  110. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/benched_set.py +0 -0
  111. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/benchmark.py +0 -0
  112. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/benchmark_delta.py +0 -0
  113. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/bundle_check.py +0 -0
  114. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/cli.py +0 -0
  115. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/cli_benchmark.py +0 -0
  116. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/deployment.py +0 -0
  117. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/ffmpeg_packet.py +0 -0
  118. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/forensics.py +0 -0
  119. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/geomap.py +0 -0
  120. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/image_cache.py +0 -0
  121. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/netem_dist.py +0 -0
  122. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/network_preflight.py +0 -0
  123. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/network_profiles.py +0 -0
  124. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/network_shaper.py +0 -0
  125. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/plots.py +0 -0
  126. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/py.typed +0 -0
  127. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/benched-set.yaml +0 -0
  128. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/.gitignore +0 -0
  129. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/README.md +0 -0
  130. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/__init__.py +0 -0
  131. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/bags/8_drop_reference/metadata.yaml +0 -0
  132. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/deployment.example.yaml +0 -0
  133. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/dist/field-20260817.dist +0 -0
  134. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/profiles.yaml +0 -0
  135. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/ros2docker.json +0 -0
  136. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/rosotacom.yaml +0 -0
  137. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scenarios/2_native_chatter/scenario-definition.yaml +0 -0
  138. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_a.sh +0 -0
  139. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_b.sh +0 -0
  140. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/external.ros2docker.json +0 -0
  141. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_communication.sh +0 -0
  142. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_external.py +0 -0
  143. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/wait_for_echo_topic.sh +0 -0
  144. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/external.ros2docker.json +0 -0
  145. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_communication.sh +0 -0
  146. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_external.py +0 -0
  147. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external.ros2docker.json +0 -0
  148. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external_session.yaml +0 -0
  149. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/foxglove.json +0 -0
  150. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_communication.sh +0 -0
  151. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_external.py +0 -0
  152. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
  153. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/metadata.yaml +0 -0
  154. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/external.ros2docker.json +0 -0
  155. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_communication.sh +0 -0
  156. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_external.py +0 -0
  157. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external.ros2docker.json +0 -0
  158. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external_session.yaml +0 -0
  159. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/foxglove.json +0 -0
  160. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_communication.sh +0 -0
  161. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_external.py +0 -0
  162. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
  163. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/metadata.yaml +0 -0
  164. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/external.ros2docker.json +0 -0
  165. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_communication.sh +0 -0
  166. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_external.py +0 -0
  167. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external.ros2docker.json +0 -0
  168. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external_session.yaml +0 -0
  169. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_communication.sh +0 -0
  170. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_external.py +0 -0
  171. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external.ros2docker.json +0 -0
  172. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external_session.yaml +0 -0
  173. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_communication.sh +0 -0
  174. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_external.py +0 -0
  175. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external.ros2docker.json +0 -0
  176. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external_session.yaml +0 -0
  177. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_communication.sh +0 -0
  178. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_external.py +0 -0
  179. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external.ros2docker.json +0 -0
  180. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external_session.yaml +0 -0
  181. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_communication.sh +0 -0
  182. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_external.py +0 -0
  183. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/sessions/10_restamp/session-definition.yaml +0 -0
  184. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/sessions/11_trickle/session-definition.yaml +0 -0
  185. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/sessions/12_content_integrity/session-definition.yaml +0 -0
  186. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/sessions/13_link_latency/session-definition.yaml +0 -0
  187. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/sessions/14_remote_assist_anonymized/session-definition.yaml +0 -0
  188. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/sessions/15_remote_assist_anonymized_costmap/session-definition.yaml +0 -0
  189. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/sessions/16_remote_assist_anonymized_camera/session-definition.yaml +0 -0
  190. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/sessions/17_synthetic_camera_quality/session-definition.yaml +0 -0
  191. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/sessions/1_heartbeat/session-definition.yaml +0 -0
  192. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/sessions/1_heartbeat_status/session-definition.yaml +0 -0
  193. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/sessions/2_native_chatter/session-definition.yaml +0 -0
  194. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/sessions/3_comp_occ_grid/session-definition.yaml +0 -0
  195. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/sessions/4_comp_occ_grid_zen/session-definition.yaml +0 -0
  196. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/sessions/5_sized_payload/session-definition.yaml +0 -0
  197. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/sessions/6_sized_payload_zen/session-definition.yaml +0 -0
  198. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/sessions/7_latched_static/session-definition.yaml +0 -0
  199. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/sessions/8_drop/session-definition.yaml +0 -0
  200. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/sessions/9_throttle/session-definition.yaml +0 -0
  201. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/sessions/bench_1_1_capacity/session-definition.yaml +0 -0
  202. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/sessions/bench_1_2_load_sweep/session-definition.yaml +0 -0
  203. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/sessions/bench_1_3_ramp/session-definition.yaml +0 -0
  204. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/sessions/bench_1_4_recovery/session-definition.yaml +0 -0
  205. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/examples/sessions/bench_1_5_camera/session-definition.yaml +0 -0
  206. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ros2docker.json.example +0 -0
  207. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/.vscode/c_cpp_properties.json +0 -0
  208. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/.vscode/settings.json +0 -0
  209. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_easy_mode.xml.template +0 -0
  210. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_initial_peer_list.xml.template +0 -0
  211. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v2.xml.template +0 -0
  212. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v3.xml.template +0 -0
  213. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v4.xml.template +0 -0
  214. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v5.xml.template +0 -0
  215. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ota_configs/create_zenoh_json5.py +0 -0
  216. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ota_configs/cyclonedds_local_participants.xml.template +0 -0
  217. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ota_configs/cyclonedds_minimal.xml.template +0 -0
  218. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ota_configs/cyclonedds_tuned.xml.template +0 -0
  219. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ota_configs/fastdds_easy_mode.xml.template +0 -0
  220. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ota_configs/fastdds_tuned.xml.template +0 -0
  221. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ota_configs/fastdds_unicast.xml.template +0 -0
  222. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ota_configs/get_ota_xml.py +0 -0
  223. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ota_configs/utils.py +0 -0
  224. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ota_configs/zenoh.json5.template +0 -0
  225. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/.gitkeep +0 -0
  226. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_cpp/CMakeLists.txt +0 -0
  227. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_cpp/COLCON_IGNORE +0 -0
  228. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_cpp/LICENSE.txt +0 -0
  229. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_cpp/package.xml +0 -0
  230. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_cpp/src/hz_monitor.cpp +0 -0
  231. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_compressor.cpp +0 -0
  232. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_decompressor.cpp +0 -0
  233. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_msgs/CMakeLists.txt +0 -0
  234. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_msgs/LICENSE.txt +0 -0
  235. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/CompressedData.msg +0 -0
  236. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/EchoHeartbeat.msg +0 -0
  237. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/OtaStamped.msg +0 -0
  238. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/SizedPayload.msg +0 -0
  239. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_msgs/package.xml +0 -0
  240. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/LICENSE.txt +0 -0
  241. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/__init__.py +0 -0
  242. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/base_bridge_relay.py +0 -0
  243. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_in.py +0 -0
  244. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_out.py +0 -0
  245. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/ffmpeg_flags.py +0 -0
  246. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/heartbeat_echo.py +0 -0
  247. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/hz_monitor.py +0 -0
  248. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_bandwidth_reducer.py +0 -0
  249. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_pixel_capper.py +0 -0
  250. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/lanelet_saver.py +0 -0
  251. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/latch_relay.py +0 -0
  252. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/costmap_remapper.py +0 -0
  253. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/marker_remapper.py +0 -0
  254. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/speed_test.py +0 -0
  255. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/tf_remapper.py +0 -0
  256. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/traffic_monitor.py +0 -0
  257. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/wifi_network_analysis_1.py +0 -0
  258. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_bytes.py +0 -0
  259. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_trace.py +0 -0
  260. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/local_global_frame_bridge.py +0 -0
  261. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/localization_map_split_reduce_saver.py +0 -0
  262. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/msg_transform.py +0 -0
  263. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pair_management.py +0 -0
  264. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/playout_pacer.py +0 -0
  265. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/playout_pacer_core.py +0 -0
  266. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pub_sub_pair.py +0 -0
  267. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/qos.py +0 -0
  268. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_in.py +0 -0
  269. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_out.py +0 -0
  270. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/restamp.py +0 -0
  271. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/sized_publisher.py +0 -0
  272. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency.py +0 -0
  273. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency_core.py +0 -0
  274. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview.py +0 -0
  275. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview_core.py +0 -0
  276. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/tf_map_to_cart_saver.py +0 -0
  277. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_monitor.py +0 -0
  278. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_resolution.py +0 -0
  279. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/trickle.py +0 -0
  280. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_compressor.py +0 -0
  281. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_decompressor.py +0 -0
  282. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_unwrapper.py +0 -0
  283. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_wrapper.py +0 -0
  284. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/package.xml +0 -0
  285. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/resource/com_py +0 -0
  286. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/setup.cfg +0 -0
  287. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/setup.py +0 -0
  288. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/test/test_copyright.py +0 -0
  289. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/test/test_flake8.py +0 -0
  290. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/ros2src/com_py/test/test_pep257.py +0 -0
  291. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/session/content/network/up_connectivity.py +0 -0
  292. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/session/content/network/wifi_network_analysis_2.py +0 -0
  293. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/session/creation/anonymize_bag.py +0 -0
  294. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/session/creation/catmux_log_setup.sh +0 -0
  295. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/session/creation/create_session_yaml.py +0 -0
  296. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/session/creation/run_session.py +0 -0
  297. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/session/creation/run_session_in_external_terminal.py +0 -0
  298. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/resources/ws/session/creation/strip_ansi.py +0 -0
  299. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/status_eval.py +0 -0
  300. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/stream_stats.py +0 -0
  301. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/trace_profiles.py +0 -0
  302. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/transit.py +0 -0
  303. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom/video_quality.py +0 -0
  304. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom_dev.egg-info/dependency_links.txt +0 -0
  305. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom_dev.egg-info/entry_points.txt +0 -0
  306. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom_dev.egg-info/requires.txt +0 -0
  307. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/src/rosotacom_dev.egg-info/top_level.txt +0 -0
  308. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/terminology.md +0 -0
  309. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/contract/test_benched_set_registry.py +0 -0
  310. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/contract/test_findings.py +0 -0
  311. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/contract/test_markdown_links.py +0 -0
  312. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/contract/test_ota_source_bundle.py +0 -0
  313. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/contract/test_package_metadata.py +0 -0
  314. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/contract/test_packaged_resources.py +0 -0
  315. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/contract/test_profile_covers_generated_commands.py +0 -0
  316. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/contract/test_pytest_policy.py +0 -0
  317. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/contract/test_readme_examples.py +0 -0
  318. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/contract/test_security_maintenance_config.py +0 -0
  319. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/contract/test_session_configuration_doc.py +0 -0
  320. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/contract/test_session_template_substitution.py +0 -0
  321. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/contract/test_workflow_contracts.py +0 -0
  322. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/e2e/conftest.py +0 -0
  323. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/e2e/test_anonymize_e2e.py +0 -0
  324. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/e2e/test_benchmark_ab.py +0 -0
  325. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/e2e/test_benchmark_capacity.py +0 -0
  326. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/e2e/test_benchmark_replay.py +0 -0
  327. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/e2e/test_parallel_smoke.py +0 -0
  328. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/e2e/test_smoke.py +0 -0
  329. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/e2e/test_timeline_stepping.py +0 -0
  330. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/e2e/test_video_quality_e2e.py +0 -0
  331. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/sessions/generate_rmw_matrix.py +0 -0
  332. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-local_zenoh-ros2dds-ota/session-definition.yaml +0 -0
  333. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota/session-definition.yaml +0 -0
  334. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota-tuned/session-definition.yaml +0 -0
  335. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/sessions/rmw_matrix/1_heartbeat_fastdds/session-definition.yaml +0 -0
  336. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/sessions/rmw_matrix/1_heartbeat_fastdds-default/session-definition.yaml +0 -0
  337. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/sessions/rmw_matrix/1_heartbeat_zen-endpoints/session-definition.yaml +0 -0
  338. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_anonymize.py +0 -0
  339. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_bag_ground_truth.py +0 -0
  340. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_benched_set.py +0 -0
  341. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_benchmark.py +0 -0
  342. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_benchmark_delta.py +0 -0
  343. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_bundle_check.py +0 -0
  344. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_catmux_pane_logging.py +0 -0
  345. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_cli.py +0 -0
  346. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_cli_benchmark.py +0 -0
  347. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_concurrency.py +0 -0
  348. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_container_shaping.py +0 -0
  349. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_deployment.py +0 -0
  350. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_ffmpeg_flags.py +0 -0
  351. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_ffmpeg_packet.py +0 -0
  352. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_field_profiles.py +0 -0
  353. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_forensics.py +0 -0
  354. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_geomap.py +0 -0
  355. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_image_cache.py +0 -0
  356. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_link_bytes.py +0 -0
  357. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_link_trace.py +0 -0
  358. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_netem_dist.py +0 -0
  359. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_network_preflight.py +0 -0
  360. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_network_profiles.py +0 -0
  361. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_network_shaper.py +0 -0
  362. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_ota_link_configs.py +0 -0
  363. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_ota_unwrapper.py +0 -0
  364. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_ota_wrapper.py +0 -0
  365. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_ota_xml.py +0 -0
  366. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_playout_pacer.py +0 -0
  367. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_plots.py +0 -0
  368. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_pub_sub_pair_types.py +0 -0
  369. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_qos_fallback_logging.py +0 -0
  370. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_relay_optional_parameters.py +0 -0
  371. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_stage_latency.py +0 -0
  372. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_status_eval.py +0 -0
  373. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_status_overview.py +0 -0
  374. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_status_overview_observer.py +0 -0
  375. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_stream_stats.py +0 -0
  376. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_trace_profiles.py +0 -0
  377. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/tests/unit/test_transit.py +0 -0
  378. {rosotacom_dev-2.5.dev53 → rosotacom_dev-2.5.dev55}/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.dev55
4
4
  Summary: Host CLI for ROS OTA communication sessions.
5
5
  Author: develNor
6
6
  License-Expression: BSD-3-Clause
@@ -25,6 +25,41 @@ slice. The full local suite also runs nightly, as does the blocking benchmark
25
25
  regression matrix ([performance-bands.md](performance-bands.md)). The external
26
26
  OTA gate remains operator-started before a promotion to `main`.
27
27
 
28
+ ## Every read has a producer
29
+
30
+ `tests/contract/test_generated_topics_have_a_producer.py` generates every
31
+ example session and asserts that each topic a node is *configured to read* is
32
+ either written by another node on the same peer or a stage that peer's own
33
+ `pipeline_spec.yaml` models. Writes are deliberately not required to be stages:
34
+ a node may publish for a human (`NOR` restores `/tf`, the pacer publishes
35
+ `budget_ms`) and none of that is something the link promises to deliver.
36
+
37
+ It exists because this project's characteristic defect — #12, #259, #276, #304 —
38
+ is always the same one: a ROS node advertises its output whether or not its
39
+ input exists, so a node pointed at a name nobody publishes starts, stays up,
40
+ reports healthy and delivers nothing. #304 was the first of the four caught by
41
+ any check at all, and that check was a six-minute Docker slice covering one
42
+ example. This one runs the same corpus in about a second.
43
+
44
+ Two guards keep it honest, and both fail loudly rather than degrading:
45
+
46
+ - every parameter `session_plugin_base.yaml` declares must be classified in the
47
+ check, so a new window cannot arrive unmodelled and be silently covered;
48
+ - the composed names the check derives (`<topic>/paced`, `<topic>/drop1of2`, …)
49
+ are asserted to be the forms the template itself composes.
50
+
51
+ It also pins **which window families the examples actually exercise**. Today
52
+ `fb`, `ipx`, `nor` and `pace` are exercised by no example, so the check models
53
+ them unverified — `pace` most notably, since the playout pacer is deployed on a
54
+ real link. Tracked in
55
+ [#307](https://github.com/develNor/ros_communication_devcontainer/issues/307);
56
+ adding an example that uses one of them is the way to close it.
57
+
58
+ The check covers reads by nodes *the session configures*. It cannot see an
59
+ application outside the session subscribing to a name the link no longer
60
+ delivers — that half of #12 and #276 needs the consumer to be declared
61
+ somewhere, and nothing declares it today.
62
+
28
63
  ## Expectations
29
64
 
30
65
  Per-topic `expect` blocks are behavioral contracts in `session-definition.yaml`.
@@ -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.dev55
4
4
  Summary: Host CLI for ROS OTA communication sessions.
5
5
  Author: develNor
6
6
  License-Expression: BSD-3-Clause
@@ -304,6 +304,7 @@ src/rosotacom_dev.egg-info/scm_version.json
304
304
  src/rosotacom_dev.egg-info/top_level.txt
305
305
  tests/contract/test_benched_set_registry.py
306
306
  tests/contract/test_findings.py
307
+ tests/contract/test_generated_topics_have_a_producer.py
307
308
  tests/contract/test_markdown_links.py
308
309
  tests/contract/test_ota_source_bundle.py
309
310
  tests/contract/test_package_metadata.py
@@ -299,6 +299,7 @@
299
299
  "terminology.md",
300
300
  "tests/contract/test_benched_set_registry.py",
301
301
  "tests/contract/test_findings.py",
302
+ "tests/contract/test_generated_topics_have_a_producer.py",
302
303
  "tests/contract/test_markdown_links.py",
303
304
  "tests/contract/test_ota_source_bundle.py",
304
305
  "tests/contract/test_package_metadata.py",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "tag": "2.4",
3
- "distance": 53,
4
- "node": "g05d5905a4728651003afe5bc2feb657a96a1d395",
3
+ "distance": 55,
4
+ "node": "gd772be38947b2d3b6d4fc5d45d9fa57da1e1723a",
5
5
  "dirty": false,
6
6
  "branch": "HEAD",
7
7
  "node_date": "2026-08-19"