rosotacom-dev 2.5.dev69__tar.gz → 2.5.dev71__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 (394) hide show
  1. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/PKG-INFO +1 -1
  2. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/ota-pcap.md +17 -0
  3. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/ota_pcap.py +42 -5
  4. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview.py +15 -1
  5. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom_dev.egg-info/PKG-INFO +1 -1
  6. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom_dev.egg-info/scm_version.json +2 -2
  7. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_ota_pcap.py +46 -0
  8. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/.devcontainer/devcontainer.json.template +0 -0
  9. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/.devcontainer/re_generate_devcontainer_json.py +0 -0
  10. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/.github/CODEOWNERS +0 -0
  11. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/.github/ISSUE_TEMPLATE/documentation-audit.md +0 -0
  12. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/.github/ISSUE_TEMPLATE/implementation-cleanup.md +0 -0
  13. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/.github/ISSUE_TEMPLATE/quality-workflow.md +0 -0
  14. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/.github/ISSUE_TEMPLATE/redesign.md +0 -0
  15. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/.github/ISSUE_TEMPLATE/release-process.md +0 -0
  16. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/.github/ISSUE_TEMPLATE/repository-diagnosis.md +0 -0
  17. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/.github/ISSUE_TEMPLATE/test-ci-audit.md +0 -0
  18. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/.github/ISSUE_TEMPLATE/work-item.md +0 -0
  19. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  20. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/.github/actions/setup-just/action.yml +0 -0
  21. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/.github/dependabot.yml +0 -0
  22. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/.github/workflows/benchmark-calibrate.yml +0 -0
  23. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/.github/workflows/benchmark-gate.yml +0 -0
  24. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/.github/workflows/dev-release.yml +0 -0
  25. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/.github/workflows/image-scan.yml +0 -0
  26. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/.github/workflows/nightly-e2e.yml +0 -0
  27. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/.github/workflows/pr-lightweight.yml +0 -0
  28. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/.github/workflows/pr-merge-gate.yml +0 -0
  29. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/.github/workflows/release.yml +0 -0
  30. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/.pre-commit-config.yaml +0 -0
  31. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/AGENTS.md +0 -0
  32. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/CONCURRENCY.md +0 -0
  33. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/CONTRIBUTING.md +0 -0
  34. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/DEVELOPMENT_PRINCIPLES.md +0 -0
  35. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/LICENSE.txt +0 -0
  36. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/MANIFEST.in +0 -0
  37. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/README.md +0 -0
  38. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/budgets.jsonl +0 -0
  39. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/calibration/README.md +0 -0
  40. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/calibration/capacity-size-tight-cyclone.json +0 -0
  41. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/calibration/probe-loss-gop-tight-cyclone.json +0 -0
  42. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/calibration/probe-loss-nominal-cyclone.json +0 -0
  43. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/calibration/probe-loss-tight-cyclone.json +0 -0
  44. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/calibration/probe-loss-tight-fastdds.json +0 -0
  45. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/calibration/probe-loss-tight-zenoh.json +0 -0
  46. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/codecov.yml +0 -0
  47. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/deployment-configuration.md +0 -0
  48. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/benchmark-ab.md +0 -0
  49. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/benchmark-bag-as-load.md +0 -0
  50. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/ci.md +0 -0
  51. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/ffmpeg-keyframes.md +0 -0
  52. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/findings/README.md +0 -0
  53. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/findings/a-transport-element-doubles-every-fastdds-sample.md +0 -0
  54. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/findings/cyclone-fragment-equal-to-max-drops-fragmented-samples.md +0 -0
  55. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/findings/cyclone-spdp-discovery-bursts.md +0 -0
  56. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/findings/delay-alone-no-loss.md +0 -0
  57. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/findings/fastdds-datagram-cap-drops-large-samples.md +0 -0
  58. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/findings/graph-derived-types-block-a-non-graph-transport.md +0 -0
  59. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/findings/head-of-line-irregularity.md +0 -0
  60. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/findings/jitter-loss-bandwidth-latency.md +0 -0
  61. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/findings/keyframe-loss-kills-the-next-deltas.md +0 -0
  62. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/findings/lifespan-is-enforced-by-one-reader-and-not-the-other.md +0 -0
  63. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/findings/lighter-message-loss.md +0 -0
  64. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/findings/one-domain-two-cyclone-configs-stop-interoperating.md +0 -0
  65. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/findings/oversubscription-queues-not-losses.md +0 -0
  66. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/findings/reorder-becomes-reader-loss.md +0 -0
  67. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/findings/repro/decode_chain_repro.py +0 -0
  68. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/findings/repro/reorder_drop_repro.py +0 -0
  69. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/findings/sender-rows-make-a-dead-link-look-loss-free.md +0 -0
  70. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/findings/zero-loss-boundaries-18kb-20hz.md +0 -0
  71. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/forensics-report.md +0 -0
  72. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/geo-link-map.md +0 -0
  73. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/github-repository-settings.md +0 -0
  74. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/link-bandwidth.md +0 -0
  75. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/link-trace.md +0 -0
  76. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/owner-runbook.md +0 -0
  77. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/performance-bands.md +0 -0
  78. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/playbooks/README.md +0 -0
  79. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/quality-model.md +0 -0
  80. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/release-notes/TEMPLATE.md +0 -0
  81. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/release-notes/v2.1.md +0 -0
  82. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/release-notes/v2.2.md +0 -0
  83. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/release-notes/v2.3.md +0 -0
  84. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/release-notes/v2.4.md +0 -0
  85. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/release.md +0 -0
  86. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/rfcs/0001-expectation-driven-test-suite.md +0 -0
  87. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/rfcs/0002-expectation-concepts.md +0 -0
  88. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/rfcs/0003-metric-backbone.md +0 -0
  89. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/rfcs/0004-network-profiles.md +0 -0
  90. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/rfcs/0005-benchmark-genres-and-ci.md +0 -0
  91. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/rfcs/0006-dynamic-qos.md +0 -0
  92. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/rfcs/0007-regression-gate.md +0 -0
  93. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/rfcs/README.md +0 -0
  94. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/testing.md +0 -0
  95. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/docs/work-items.md +0 -0
  96. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/install.sh +0 -0
  97. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/justfile +0 -0
  98. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/media/control_center.png +0 -0
  99. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/media/echo_test.png +0 -0
  100. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/media/forensics-report-example.png +0 -0
  101. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/media/host.png +0 -0
  102. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/media/vehicle.png +0 -0
  103. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/pyproject.toml +0 -0
  104. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/requirements.txt +0 -0
  105. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/rosotacom.yaml +0 -0
  106. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/session-configuration.md +0 -0
  107. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/setup.cfg +0 -0
  108. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/__init__.py +0 -0
  109. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/__main__.py +0 -0
  110. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/anonymize.py +0 -0
  111. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/bag_ground_truth.py +0 -0
  112. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/benched_set.py +0 -0
  113. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/benchmark.py +0 -0
  114. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/benchmark_delta.py +0 -0
  115. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/bundle_check.py +0 -0
  116. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/cli.py +0 -0
  117. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/cli_benchmark.py +0 -0
  118. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/deployment.py +0 -0
  119. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/ffmpeg_packet.py +0 -0
  120. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/forensics.py +0 -0
  121. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/geomap.py +0 -0
  122. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/image_cache.py +0 -0
  123. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/netem_dist.py +0 -0
  124. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/network_preflight.py +0 -0
  125. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/network_profiles.py +0 -0
  126. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/network_shaper.py +0 -0
  127. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/plots.py +0 -0
  128. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/py.typed +0 -0
  129. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/benched-set.yaml +0 -0
  130. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/.gitignore +0 -0
  131. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/README.md +0 -0
  132. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/__init__.py +0 -0
  133. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/bags/8_drop_reference/metadata.yaml +0 -0
  134. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/deployment.example.yaml +0 -0
  135. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/dist/field-20260817.dist +0 -0
  136. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/profiles.yaml +0 -0
  137. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/ros2docker.json +0 -0
  138. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/ros2docker.lyrical.json +0 -0
  139. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/rosotacom.yaml +0 -0
  140. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scenarios/2_native_chatter/scenario-definition.yaml +0 -0
  141. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_a.sh +0 -0
  142. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_b.sh +0 -0
  143. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/external.lyrical.ros2docker.json +0 -0
  144. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/external.ros2docker.json +0 -0
  145. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_communication.sh +0 -0
  146. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_external.py +0 -0
  147. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/wait_for_echo_topic.sh +0 -0
  148. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/external.lyrical.ros2docker.json +0 -0
  149. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/external.ros2docker.json +0 -0
  150. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_communication.sh +0 -0
  151. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_external.py +0 -0
  152. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external.ros2docker.json +0 -0
  153. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external_session.yaml +0 -0
  154. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/foxglove.json +0 -0
  155. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_communication.sh +0 -0
  156. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_external.py +0 -0
  157. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
  158. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/metadata.yaml +0 -0
  159. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/external.ros2docker.json +0 -0
  160. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_communication.sh +0 -0
  161. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_external.py +0 -0
  162. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external.ros2docker.json +0 -0
  163. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external_session.yaml +0 -0
  164. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/foxglove.json +0 -0
  165. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_communication.sh +0 -0
  166. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_external.py +0 -0
  167. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
  168. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/metadata.yaml +0 -0
  169. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/external.ros2docker.json +0 -0
  170. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_communication.sh +0 -0
  171. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_external.py +0 -0
  172. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external.ros2docker.json +0 -0
  173. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external_session.yaml +0 -0
  174. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_communication.sh +0 -0
  175. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_external.py +0 -0
  176. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external.ros2docker.json +0 -0
  177. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external_session.yaml +0 -0
  178. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_communication.sh +0 -0
  179. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_external.py +0 -0
  180. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external.ros2docker.json +0 -0
  181. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external_session.yaml +0 -0
  182. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_communication.sh +0 -0
  183. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_external.py +0 -0
  184. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external.ros2docker.json +0 -0
  185. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external_session.yaml +0 -0
  186. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_communication.sh +0 -0
  187. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_external.py +0 -0
  188. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/sessions/10_restamp/session-definition.yaml +0 -0
  189. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/sessions/11_trickle/session-definition.yaml +0 -0
  190. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/sessions/12_content_integrity/session-definition.yaml +0 -0
  191. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/sessions/13_link_latency/session-definition.yaml +0 -0
  192. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/sessions/14_remote_assist_anonymized/session-definition.yaml +0 -0
  193. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/sessions/15_remote_assist_anonymized_costmap/session-definition.yaml +0 -0
  194. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/sessions/16_remote_assist_anonymized_camera/session-definition.yaml +0 -0
  195. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/sessions/17_synthetic_camera_quality/session-definition.yaml +0 -0
  196. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/sessions/1_heartbeat/session-definition.yaml +0 -0
  197. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/sessions/1_heartbeat_status/session-definition.yaml +0 -0
  198. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/sessions/2_native_chatter/session-definition.yaml +0 -0
  199. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/sessions/3_comp_occ_grid/session-definition.yaml +0 -0
  200. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/sessions/4_comp_occ_grid_zen/session-definition.yaml +0 -0
  201. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/sessions/5_sized_payload/session-definition.yaml +0 -0
  202. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/sessions/6_sized_payload_zen/session-definition.yaml +0 -0
  203. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/sessions/7_latched_static/session-definition.yaml +0 -0
  204. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/sessions/8_drop/session-definition.yaml +0 -0
  205. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/sessions/9_throttle/session-definition.yaml +0 -0
  206. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/sessions/bench_1_1_capacity/session-definition.yaml +0 -0
  207. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/sessions/bench_1_2_load_sweep/session-definition.yaml +0 -0
  208. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/sessions/bench_1_3_ramp/session-definition.yaml +0 -0
  209. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/sessions/bench_1_4_recovery/session-definition.yaml +0 -0
  210. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/examples/sessions/bench_1_5_camera/session-definition.yaml +0 -0
  211. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ros2docker.json.example +0 -0
  212. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ros2docker.lyrical.json.example +0 -0
  213. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/.vscode/c_cpp_properties.json +0 -0
  214. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/.vscode/settings.json +0 -0
  215. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_easy_mode.xml.template +0 -0
  216. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_initial_peer_list.xml.template +0 -0
  217. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v2.xml.template +0 -0
  218. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v3.xml.template +0 -0
  219. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v4.xml.template +0 -0
  220. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v5.xml.template +0 -0
  221. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ota_configs/create_zenoh_json5.py +0 -0
  222. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ota_configs/cyclonedds_local_participants.xml.template +0 -0
  223. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ota_configs/cyclonedds_minimal.xml.template +0 -0
  224. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ota_configs/cyclonedds_scoped.xml.template +0 -0
  225. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ota_configs/cyclonedds_tuned.xml.template +0 -0
  226. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ota_configs/fastdds_easy_mode.xml.template +0 -0
  227. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ota_configs/fastdds_local.xml.template +0 -0
  228. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ota_configs/fastdds_tuned.xml.template +0 -0
  229. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ota_configs/fastdds_unicast.xml.template +0 -0
  230. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ota_configs/get_ota_xml.py +0 -0
  231. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ota_configs/utils.py +0 -0
  232. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ota_configs/zenoh.json5.template +0 -0
  233. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/.gitkeep +0 -0
  234. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_cpp/CMakeLists.txt +0 -0
  235. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_cpp/COLCON_IGNORE +0 -0
  236. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_cpp/LICENSE.txt +0 -0
  237. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_cpp/package.xml +0 -0
  238. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_cpp/src/hz_monitor.cpp +0 -0
  239. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_compressor.cpp +0 -0
  240. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_decompressor.cpp +0 -0
  241. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_msgs/CMakeLists.txt +0 -0
  242. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_msgs/LICENSE.txt +0 -0
  243. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/CompressedData.msg +0 -0
  244. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/EchoHeartbeat.msg +0 -0
  245. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/OtaStamped.msg +0 -0
  246. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/SizedPayload.msg +0 -0
  247. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_msgs/package.xml +0 -0
  248. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/LICENSE.txt +0 -0
  249. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/__init__.py +0 -0
  250. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/base_bridge_relay.py +0 -0
  251. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_in.py +0 -0
  252. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_out.py +0 -0
  253. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/ffmpeg_flags.py +0 -0
  254. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/heartbeat_echo.py +0 -0
  255. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/hz_monitor.py +0 -0
  256. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_bandwidth_reducer.py +0 -0
  257. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_pixel_capper.py +0 -0
  258. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/lanelet_saver.py +0 -0
  259. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/latch_relay.py +0 -0
  260. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/costmap_remapper.py +0 -0
  261. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/marker_remapper.py +0 -0
  262. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/speed_test.py +0 -0
  263. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/tf_remapper.py +0 -0
  264. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/traffic_monitor.py +0 -0
  265. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/wifi_network_analysis_1.py +0 -0
  266. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_bytes.py +0 -0
  267. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_trace.py +0 -0
  268. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/local_global_frame_bridge.py +0 -0
  269. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/localization_map_split_reduce_saver.py +0 -0
  270. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/msg_transform.py +0 -0
  271. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pair_management.py +0 -0
  272. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/playout_pacer.py +0 -0
  273. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/playout_pacer_core.py +0 -0
  274. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pub_sub_pair.py +0 -0
  275. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/qos.py +0 -0
  276. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_in.py +0 -0
  277. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_out.py +0 -0
  278. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/restamp.py +0 -0
  279. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/sized_publisher.py +0 -0
  280. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency.py +0 -0
  281. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency_core.py +0 -0
  282. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview_core.py +0 -0
  283. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/tf_map_to_cart_saver.py +0 -0
  284. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_monitor.py +0 -0
  285. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_resolution.py +0 -0
  286. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/trickle.py +0 -0
  287. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_compressor.py +0 -0
  288. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_decompressor.py +0 -0
  289. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_unwrapper.py +0 -0
  290. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_wrapper.py +0 -0
  291. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/package.xml +0 -0
  292. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/resource/com_py +0 -0
  293. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/setup.cfg +0 -0
  294. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/setup.py +0 -0
  295. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/test/test_copyright.py +0 -0
  296. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/test/test_flake8.py +0 -0
  297. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/ros2src/com_py/test/test_pep257.py +0 -0
  298. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/session/content/base/session_plugin_base.yaml +0 -0
  299. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/session/content/network/up_connectivity.py +0 -0
  300. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/session/content/network/wifi_network_analysis_2.py +0 -0
  301. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/session/creation/anonymize_bag.py +0 -0
  302. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/session/creation/catmux_log_setup.sh +0 -0
  303. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/session/creation/create_session_yaml.py +0 -0
  304. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/session/creation/generate_session_files.py +0 -0
  305. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/session/creation/run_session.py +0 -0
  306. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/session/creation/run_session_in_external_terminal.py +0 -0
  307. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/resources/ws/session/creation/strip_ansi.py +0 -0
  308. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/status_eval.py +0 -0
  309. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/stream_stats.py +0 -0
  310. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/trace_profiles.py +0 -0
  311. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/transit.py +0 -0
  312. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom/video_quality.py +0 -0
  313. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom_dev.egg-info/SOURCES.txt +0 -0
  314. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom_dev.egg-info/dependency_links.txt +0 -0
  315. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom_dev.egg-info/entry_points.txt +0 -0
  316. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom_dev.egg-info/requires.txt +0 -0
  317. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom_dev.egg-info/scm_file_list.json +0 -0
  318. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/src/rosotacom_dev.egg-info/top_level.txt +0 -0
  319. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/terminology.md +0 -0
  320. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/contract/test_benched_set_registry.py +0 -0
  321. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/contract/test_findings.py +0 -0
  322. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/contract/test_generated_topics_have_a_producer.py +0 -0
  323. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/contract/test_lyrical_runtime_compat.py +0 -0
  324. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/contract/test_markdown_links.py +0 -0
  325. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/contract/test_ota_source_bundle.py +0 -0
  326. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/contract/test_package_metadata.py +0 -0
  327. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/contract/test_packaged_resources.py +0 -0
  328. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/contract/test_profile_covers_generated_commands.py +0 -0
  329. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/contract/test_pytest_policy.py +0 -0
  330. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/contract/test_readme_examples.py +0 -0
  331. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/contract/test_security_maintenance_config.py +0 -0
  332. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/contract/test_session_configuration_doc.py +0 -0
  333. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/contract/test_session_template_substitution.py +0 -0
  334. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/contract/test_workflow_contracts.py +0 -0
  335. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/e2e/conftest.py +0 -0
  336. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/e2e/test_anonymize_e2e.py +0 -0
  337. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/e2e/test_benchmark_ab.py +0 -0
  338. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/e2e/test_benchmark_capacity.py +0 -0
  339. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/e2e/test_benchmark_replay.py +0 -0
  340. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/e2e/test_parallel_smoke.py +0 -0
  341. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/e2e/test_smoke.py +0 -0
  342. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/e2e/test_timeline_stepping.py +0 -0
  343. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/e2e/test_video_quality_e2e.py +0 -0
  344. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/sessions/generate_rmw_matrix.py +0 -0
  345. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-local_zenoh-ros2dds-ota/session-definition.yaml +0 -0
  346. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota/session-definition.yaml +0 -0
  347. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota-tuned/session-definition.yaml +0 -0
  348. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/sessions/rmw_matrix/1_heartbeat_fastdds/session-definition.yaml +0 -0
  349. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/sessions/rmw_matrix/1_heartbeat_fastdds-default/session-definition.yaml +0 -0
  350. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/sessions/rmw_matrix/1_heartbeat_zen-endpoints/session-definition.yaml +0 -0
  351. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_anonymize.py +0 -0
  352. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_bag_ground_truth.py +0 -0
  353. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_benched_set.py +0 -0
  354. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_benchmark.py +0 -0
  355. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_benchmark_delta.py +0 -0
  356. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_bundle_check.py +0 -0
  357. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_catmux_pane_logging.py +0 -0
  358. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_cli.py +0 -0
  359. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_cli_benchmark.py +0 -0
  360. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_concurrency.py +0 -0
  361. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_container_shaping.py +0 -0
  362. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_deployment.py +0 -0
  363. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_ffmpeg_flags.py +0 -0
  364. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_ffmpeg_packet.py +0 -0
  365. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_field_profiles.py +0 -0
  366. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_forensics.py +0 -0
  367. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_geomap.py +0 -0
  368. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_image_cache.py +0 -0
  369. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_link_bytes.py +0 -0
  370. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_link_trace.py +0 -0
  371. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_netem_dist.py +0 -0
  372. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_network_preflight.py +0 -0
  373. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_network_profiles.py +0 -0
  374. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_network_shaper.py +0 -0
  375. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_ota_link_configs.py +0 -0
  376. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_ota_unwrapper.py +0 -0
  377. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_ota_wrapper.py +0 -0
  378. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_ota_xml.py +0 -0
  379. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_playout_pacer.py +0 -0
  380. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_plots.py +0 -0
  381. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_pub_sub_pair_types.py +0 -0
  382. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_qos_fallback_logging.py +0 -0
  383. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_relay_optional_parameters.py +0 -0
  384. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_ros_node_entity_ownership.py +0 -0
  385. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_session_pipeline.py +0 -0
  386. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_stage_latency.py +0 -0
  387. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_status_eval.py +0 -0
  388. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_status_overview.py +0 -0
  389. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_status_overview_observer.py +0 -0
  390. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_stream_stats.py +0 -0
  391. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_terminology_stage_ownership.py +0 -0
  392. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_trace_profiles.py +0 -0
  393. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/tests/unit/test_transit.py +0 -0
  394. {rosotacom_dev-2.5.dev69 → rosotacom_dev-2.5.dev71}/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.dev69
3
+ Version: 2.5.dev71
4
4
  Summary: Host CLI for ROS OTA communication sessions.
5
5
  Author: develNor
6
6
  License-Expression: BSD-3-Clause
@@ -87,6 +87,16 @@ reached the packet.
87
87
  }
88
88
  ```
89
89
 
90
+ `stopped_because` reads `running` until something stops the capture, and that
91
+ is deliberate: **neither file depends on a clean shutdown.** A session usually
92
+ ends by its container being stopped, which does not reach this process as a
93
+ signal it can act on — the first bench run ended exactly that way and left a
94
+ pcap truncated at a buffer boundary and no sidecar at all. The pcap is flushed
95
+ once a second and the sidecar is written at the start and rewritten on the same
96
+ interval, so a killed capture still leaves a readable file and a description of
97
+ it. Verified by `SIGKILL`ing a running capture: `capinfos` reads the pcap and
98
+ the sidecar reports the packets up to the last checkpoint.
99
+
90
100
  **`kernel_drops` is a gap in the file, not on the link.** A capture that fell
91
101
  behind looks exactly like radio loss to anyone reading the pcap months later,
92
102
  so subtract it before reading any loss out of the capture. Zero is the normal
@@ -140,6 +150,13 @@ thread, so a capture that misbehaves cannot reach the snapshot an operator is
140
150
  watching. It is stopped with `SIGINT` and waited for, because that is what
141
151
  writes the sidecar JSON.
142
152
 
153
+ It is launched by **file path**, not as `python3 -m com_py.ota_pcap`. sudo
154
+ resets the environment, so `PYTHONPATH` does not survive it and the package is
155
+ not importable on the other side — which is what a two-host run answered,
156
+ `No module named 'com_py'`, once the permission problem was out of the way.
157
+ `ota_pcap.py` imports nothing but the standard library, so a path needs no
158
+ package at all, and a test pins that it stays that way.
159
+
143
160
  ## Cost
144
161
 
145
162
  Header-only at 96 bytes: about 6 MB per minute at 500 packets/s, so a two-hour
@@ -79,6 +79,15 @@ A capture that quietly drops packets is worse than none: the analysis would
79
79
  read the gap as radio loss. So `PACKET_STATISTICS` is read from the kernel and
80
80
  the sidecar `.json` reports `kernel_drops` next to `packets`. A non-zero drop
81
81
  count means this process fell behind, not that the link did.
82
+
83
+ Neither file depends on a clean shutdown, and that is deliberate. A session
84
+ usually ends by the container being stopped, which does not reach this process
85
+ as a signal it can act on — the first bench run ended exactly that way and left
86
+ a pcap truncated at a buffer boundary and no sidecar at all. So the pcap is
87
+ flushed on an interval and the sidecar is written at the *start* and rewritten
88
+ on the same interval, with `stopped_because: "running"` until something stops
89
+ it. A killed capture therefore still leaves a readable pcap and a sidecar that
90
+ says what it was and how much it had seen, rather than an unexplained file.
82
91
  """
83
92
 
84
93
  from __future__ import annotations
@@ -135,6 +144,12 @@ DEFAULT_MAX_MB = 2000
135
144
  #: is where `kernel_drops` comes from on a burst.
136
145
  RCVBUF_BYTES = 4 << 20
137
146
 
147
+ #: How often the pcap is flushed and the sidecar rewritten. A session that ends
148
+ #: by having its container stopped never reaches this process, so what is on
149
+ #: disk at any moment is what the run will be read from. One second costs a
150
+ #: ~300-byte write and bounds the loss to the packets of that second.
151
+ CHECKPOINT_S = 1.0
152
+
138
153
 
139
154
  def log(message: str) -> None:
140
155
  print(f"[ota_pcap] {message}", flush=True)
@@ -326,7 +341,7 @@ class Capture:
326
341
  self.kernel_seen = 0
327
342
  self.first_ts: float | None = None
328
343
  self.last_ts: float | None = None
329
- self.stopped_because = "signal"
344
+ self.stopped_because = "running"
330
345
 
331
346
  def sidecar(self) -> dict:
332
347
  """What the file is, and what it is missing. Written next to the pcap."""
@@ -348,6 +363,14 @@ class Capture:
348
363
  "stopped_because": self.stopped_because,
349
364
  }
350
365
 
366
+ def write_sidecar(self) -> None:
367
+ """The sidecar as of now. Cheap enough to call on every checkpoint."""
368
+ try:
369
+ self.out.with_suffix(".json").write_text(
370
+ json.dumps(self.sidecar(), indent=2) + "\n", encoding="utf-8")
371
+ except OSError as error:
372
+ log(f"WARN could not write the sidecar: {error}")
373
+
351
374
  def run(self, stop: list) -> None:
352
375
  sock = open_socket(self.iface)
353
376
  # Root was needed for that one call and for nothing after it.
@@ -360,8 +383,22 @@ class Capture:
360
383
  with open(self.out, "wb", buffering=1 << 20) as handle:
361
384
  handle.write(pcap_header(self.snaplen))
362
385
  self.bytes_written = 24
386
+ handle.flush()
387
+ # Written before a single packet arrives, so a capture that is
388
+ # killed with its container still explains itself.
389
+ self.write_sidecar()
390
+ next_checkpoint = time.monotonic() + CHECKPOINT_S
363
391
  sock.settimeout(0.5)
364
392
  while not stop:
393
+ # `tick`, not `now`: the timestamp fallback below rebinds `now`
394
+ # to wall-clock time, and comparing that against a monotonic
395
+ # deadline would checkpoint on every single packet.
396
+ tick = time.monotonic()
397
+ if tick >= next_checkpoint:
398
+ next_checkpoint = tick + CHECKPOINT_S
399
+ self._collect(sock)
400
+ handle.flush()
401
+ self.write_sidecar()
365
402
  try:
366
403
  packet, ancdata, _flags, address = sock.recvmsg(65535, ancillary)
367
404
  except socket.timeout:
@@ -395,8 +432,9 @@ class Capture:
395
432
  f"after {self.packets} packets — the recording is untouched")
396
433
  self.stopped_because = "size ceiling"
397
434
  break
398
- if self.packets % 20000 == 0:
399
- self._collect(sock)
435
+ handle.flush()
436
+ if self.stopped_because == "running":
437
+ self.stopped_because = "signal"
400
438
  self._collect(sock)
401
439
  sock.close()
402
440
 
@@ -445,9 +483,8 @@ def main(argv: list[str] | None = None) -> int:
445
483
  log(f"FAIL {error}")
446
484
  return 3
447
485
 
486
+ capture.write_sidecar()
448
487
  sidecar = capture.sidecar()
449
- args.out.with_suffix(".json").write_text(
450
- json.dumps(sidecar, indent=2) + "\n", encoding="utf-8")
451
488
  log(f"{sidecar['packets']} packets, {sidecar['bytes'] / 1e6:.1f} MB, "
452
489
  f"{sidecar['kernel_drops']} dropped by the kernel")
453
490
  if sidecar["kernel_drops"]:
@@ -58,6 +58,7 @@ import signal
58
58
  import subprocess
59
59
  import sys
60
60
  import threading
61
+ from pathlib import Path
61
62
  from typing import Dict, Optional
62
63
 
63
64
  import yaml
@@ -558,8 +559,21 @@ class StatusOverview(Node):
558
559
  return
559
560
 
560
561
  path = os.path.join(output_dir, "ota.pcap")
562
+ # By file path, not `-m com_py.ota_pcap`. sudo resets the environment,
563
+ # so PYTHONPATH does not survive and the package is not importable on
564
+ # the other side of it — a two-host run answered exactly that,
565
+ # "No module named 'com_py'", after the permission problem was fixed.
566
+ # `ota_pcap.py` imports nothing but the standard library (a test pins
567
+ # that), so a path needs no package at all.
568
+ script = Path(__file__).resolve().with_name("ota_pcap.py")
569
+ if not script.is_file():
570
+ self.get_logger().warning(
571
+ f"status_overview: ota_pcap is enabled but {script} is not here; "
572
+ "capturing nothing"
573
+ )
574
+ return
561
575
  argv = [
562
- sys.executable, "-m", "com_py.ota_pcap",
576
+ sys.executable, str(script),
563
577
  "--iface", interface,
564
578
  "--out", path,
565
579
  "--snaplen", str(int(self.get_parameter("ota_pcap_snaplen").value)),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rosotacom-dev
3
- Version: 2.5.dev69
3
+ Version: 2.5.dev71
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": 69,
4
- "node": "g429a2536fa56d96c76f3c306809f3dc6864f051e",
3
+ "distance": 71,
4
+ "node": "gbdc19f9281e1d18fdd99cbb852a3a652d45f9de3",
5
5
  "dirty": false,
6
6
  "branch": "HEAD",
7
7
  "node_date": "2026-08-21"
@@ -11,6 +11,7 @@ Three layers, like the status overview it is started beside:
11
11
  from __future__ import annotations
12
12
 
13
13
  import importlib.util
14
+ import json
14
15
  import socket
15
16
  import struct
16
17
  import sys
@@ -345,6 +346,10 @@ def test_the_node_launches_it_through_sudo_and_hands_root_straight_back() -> Non
345
346
  source because the node needs rclpy, which the host suite does not have."""
346
347
  source = (WS_PY / "com_py" / "status_overview.py").read_text(encoding="utf-8")
347
348
  assert 'argv = ["sudo", "-n", *argv]' in source
349
+ # By path, never `-m`: sudo resets the environment, so PYTHONPATH does not
350
+ # reach the other side of it and the package is not importable there.
351
+ assert '"-m", "com_py.ota_pcap"' not in source
352
+ assert 'Path(__file__).resolve().with_name("ota_pcap.py")' in source
348
353
  assert '"--drop-to", f"{os.getuid()}:{os.getgid()}"' in source
349
354
  # And the stop goes the same way: the child is root, so an ordinary kill
350
355
  # would be refused — and it must be SIGINT, which is what writes ota.json.
@@ -355,3 +360,44 @@ def test_the_capture_is_a_process_not_a_thread_in_the_status_node() -> None:
355
360
  """A capture that misbehaves must not reach the snapshot an operator watches."""
356
361
  source = (WS_PY / "com_py" / "status_overview.py").read_text(encoding="utf-8")
357
362
  assert "subprocess.Popen(argv, start_new_session=True)" in source
363
+
364
+
365
+ # ---------------------------------------------------------------------------
366
+ # neither file depends on a clean shutdown
367
+ # ---------------------------------------------------------------------------
368
+
369
+
370
+ def test_the_sidecar_says_running_until_something_stops_the_capture() -> None:
371
+ """A session usually ends by its container being stopped, which never
372
+ reaches this process. So the sidecar exists from the first moment and says
373
+ what it is, rather than appearing only if the capture is asked nicely."""
374
+ capture = ota_pcap.Capture("tun0", Path("/tmp/x.pcap"))
375
+ assert capture.sidecar()["stopped_because"] == "running"
376
+
377
+
378
+ def test_the_sidecar_is_written_before_a_single_packet_arrives(tmp_path: Path) -> None:
379
+ capture = ota_pcap.Capture("tun0", tmp_path / "ota.pcap")
380
+ capture.write_sidecar()
381
+ written = json.loads((tmp_path / "ota.json").read_text(encoding="utf-8"))
382
+ assert written["interface"] == "tun0"
383
+ assert written["packets"] == 0
384
+ assert written["stopped_because"] == "running"
385
+
386
+
387
+ def test_a_sidecar_that_cannot_be_written_is_a_warning_not_a_crash(tmp_path: Path, capsys) -> None:
388
+ """The capture is the artifact; its description is not worth losing it for."""
389
+ capture = ota_pcap.Capture("tun0", tmp_path / "no" / "such" / "dir" / "ota.pcap")
390
+ capture.write_sidecar()
391
+ assert "WARN" in capsys.readouterr().out
392
+
393
+
394
+ def test_the_capture_checkpoints_rather_than_trusting_the_shutdown() -> None:
395
+ source = (WS_PY / "com_py" / "ota_pcap.py").read_text(encoding="utf-8")
396
+ assert "CHECKPOINT_S" in source
397
+ body = source[source.index("def run(self, stop") : source.index("def _collect")]
398
+ assert "handle.flush()" in body
399
+ assert "self.write_sidecar()" in body
400
+ # And the deadline is monotonic, compared against a name the timestamp
401
+ # fallback cannot rebind — that collision would checkpoint every packet.
402
+ assert "tick = time.monotonic()" in body
403
+ assert "if tick >= next_checkpoint:" in body