rosotacom-dev 2.5.dev48__tar.gz → 2.5.dev49__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.
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/PKG-INFO +1 -1
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/session-configuration.md +29 -7
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/session/content/base/session_plugin_base.yaml +66 -4
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/session/creation/generate_session_files.py +72 -7
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom_dev.egg-info/PKG-INFO +1 -1
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom_dev.egg-info/scm_version.json +2 -2
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_session_pipeline.py +73 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.devcontainer/devcontainer.json.template +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.devcontainer/re_generate_devcontainer_json.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/CODEOWNERS +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/ISSUE_TEMPLATE/documentation-audit.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/ISSUE_TEMPLATE/implementation-cleanup.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/ISSUE_TEMPLATE/quality-workflow.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/ISSUE_TEMPLATE/redesign.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/ISSUE_TEMPLATE/release-process.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/ISSUE_TEMPLATE/repository-diagnosis.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/ISSUE_TEMPLATE/test-ci-audit.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/ISSUE_TEMPLATE/work-item.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/actions/setup-just/action.yml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/dependabot.yml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/workflows/benchmark-calibrate.yml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/workflows/benchmark-gate.yml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/workflows/dev-release.yml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/workflows/image-scan.yml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/workflows/nightly-e2e.yml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/workflows/pr-lightweight.yml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/workflows/pr-merge-gate.yml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/workflows/release.yml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.pre-commit-config.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/AGENTS.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/CONCURRENCY.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/CONTRIBUTING.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/DEVELOPMENT_PRINCIPLES.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/MANIFEST.in +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/README.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/budgets.jsonl +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/calibration/README.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/calibration/capacity-size-tight-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/calibration/probe-loss-gop-tight-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/calibration/probe-loss-nominal-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/calibration/probe-loss-tight-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/calibration/probe-loss-tight-fastdds.json +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/calibration/probe-loss-tight-zenoh.json +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/codecov.yml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/deployment-configuration.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/benchmark-ab.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/benchmark-bag-as-load.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/ci.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/ffmpeg-keyframes.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/findings/README.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/findings/cyclone-spdp-discovery-bursts.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/findings/delay-alone-no-loss.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/findings/head-of-line-irregularity.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/findings/jitter-loss-bandwidth-latency.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/findings/lighter-message-loss.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/findings/reorder-becomes-reader-loss.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/findings/repro/reorder_drop_repro.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/findings/zero-loss-boundaries-18kb-20hz.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/forensics-report.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/geo-link-map.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/github-repository-settings.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/link-bandwidth.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/link-trace.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/owner-runbook.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/performance-bands.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/playbooks/README.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/quality-model.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/release-notes/TEMPLATE.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/release-notes/v2.1.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/release-notes/v2.2.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/release-notes/v2.3.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/release-notes/v2.4.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/release.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/rfcs/0001-expectation-driven-test-suite.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/rfcs/0002-expectation-concepts.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/rfcs/0003-metric-backbone.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/rfcs/0004-network-profiles.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/rfcs/0005-benchmark-genres-and-ci.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/rfcs/0006-dynamic-qos.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/rfcs/0007-regression-gate.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/rfcs/README.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/testing.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/work-items.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/install.sh +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/justfile +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/media/control_center.png +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/media/echo_test.png +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/media/forensics-report-example.png +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/media/host.png +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/media/vehicle.png +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/pyproject.toml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/requirements.txt +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/rosotacom.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/setup.cfg +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/__init__.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/__main__.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/anonymize.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/bag_ground_truth.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/benched_set.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/benchmark.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/benchmark_delta.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/bundle_check.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/cli.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/cli_benchmark.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/deployment.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/ffmpeg_packet.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/forensics.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/geomap.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/image_cache.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/netem_dist.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/network_profiles.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/network_shaper.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/plots.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/py.typed +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/benched-set.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/.gitignore +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/README.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/__init__.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/bags/8_drop_reference/metadata.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/deployment.example.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/dist/field-20260817.dist +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/profiles.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/rosotacom.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scenarios/2_native_chatter/scenario-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_a.sh +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_b.sh +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/wait_for_echo_topic.sh +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/foxglove.json +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/metadata.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/foxglove.json +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/metadata.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/sessions/10_restamp/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/sessions/11_trickle/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/sessions/12_content_integrity/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/sessions/13_link_latency/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/sessions/14_remote_assist_anonymized/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/sessions/15_remote_assist_anonymized_costmap/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/sessions/16_remote_assist_anonymized_camera/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/sessions/17_synthetic_camera_quality/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/sessions/1_heartbeat/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/sessions/1_heartbeat_status/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/sessions/2_native_chatter/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/sessions/3_comp_occ_grid/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/sessions/4_comp_occ_grid_zen/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/sessions/5_sized_payload/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/sessions/6_sized_payload_zen/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/sessions/7_latched_static/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/sessions/8_drop/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/sessions/9_throttle/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/sessions/bench_1_1_capacity/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/sessions/bench_1_2_load_sweep/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/sessions/bench_1_3_ramp/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/sessions/bench_1_4_recovery/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/examples/sessions/bench_1_5_camera/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ros2docker.json.example +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/.vscode/c_cpp_properties.json +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/.vscode/settings.json +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_easy_mode.xml.template +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_initial_peer_list.xml.template +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v2.xml.template +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v3.xml.template +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v4.xml.template +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v5.xml.template +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ota_configs/create_zenoh_json5.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ota_configs/cyclonedds_local_participants.xml.template +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ota_configs/cyclonedds_minimal.xml.template +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ota_configs/cyclonedds_tuned.xml.template +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ota_configs/fastdds_unicast.xml.template +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ota_configs/get_ota_xml.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ota_configs/utils.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ota_configs/zenoh.json5.template +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/.gitkeep +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_cpp/CMakeLists.txt +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_cpp/COLCON_IGNORE +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_cpp/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_cpp/package.xml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_cpp/src/hz_monitor.cpp +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_compressor.cpp +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_decompressor.cpp +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_msgs/CMakeLists.txt +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_msgs/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/CompressedData.msg +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/EchoHeartbeat.msg +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/OtaStamped.msg +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/SizedPayload.msg +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_msgs/package.xml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/__init__.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/base_bridge_relay.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_in.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_out.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/ffmpeg_flags.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/heartbeat_echo.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/hz_monitor.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_bandwidth_reducer.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_pixel_capper.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/lanelet_saver.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/latch_relay.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/costmap_remapper.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/marker_remapper.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/speed_test.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/tf_remapper.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/traffic_monitor.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/wifi_network_analysis_1.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_bytes.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_trace.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/local_global_frame_bridge.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/localization_map_split_reduce_saver.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/msg_transform.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pair_management.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/playout_pacer.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/playout_pacer_core.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pub_sub_pair.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/qos.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_in.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_out.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/restamp.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/sized_publisher.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency_core.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview_core.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/tf_map_to_cart_saver.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_monitor.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_resolution.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/trickle.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_compressor.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_decompressor.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_unwrapper.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_wrapper.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/package.xml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/resource/com_py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/setup.cfg +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/setup.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/test/test_copyright.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/test/test_flake8.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/ros2src/com_py/test/test_pep257.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/session/content/network/up_connectivity.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/session/content/network/wifi_network_analysis_2.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/session/creation/anonymize_bag.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/session/creation/catmux_log_setup.sh +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/session/creation/create_session_yaml.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/session/creation/run_session.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/session/creation/run_session_in_external_terminal.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/resources/ws/session/creation/strip_ansi.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/status_eval.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/stream_stats.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/trace_profiles.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/transit.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom/video_quality.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom_dev.egg-info/SOURCES.txt +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom_dev.egg-info/dependency_links.txt +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom_dev.egg-info/entry_points.txt +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom_dev.egg-info/requires.txt +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom_dev.egg-info/scm_file_list.json +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/src/rosotacom_dev.egg-info/top_level.txt +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/terminology.md +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/contract/test_benched_set_registry.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/contract/test_findings.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/contract/test_markdown_links.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/contract/test_ota_source_bundle.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/contract/test_package_metadata.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/contract/test_packaged_resources.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/contract/test_profile_covers_generated_commands.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/contract/test_pytest_policy.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/contract/test_readme_examples.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/contract/test_security_maintenance_config.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/contract/test_session_configuration_doc.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/contract/test_session_template_substitution.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/contract/test_workflow_contracts.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/e2e/conftest.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/e2e/test_anonymize_e2e.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/e2e/test_benchmark_ab.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/e2e/test_benchmark_capacity.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/e2e/test_benchmark_replay.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/e2e/test_parallel_smoke.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/e2e/test_smoke.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/e2e/test_timeline_stepping.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/e2e/test_video_quality_e2e.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/sessions/generate_rmw_matrix.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-local_zenoh-ros2dds-ota/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota-tuned/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/sessions/rmw_matrix/1_heartbeat_fastdds/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/sessions/rmw_matrix/1_heartbeat_zen-endpoints/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_anonymize.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_bag_ground_truth.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_benched_set.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_benchmark.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_benchmark_delta.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_bundle_check.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_catmux_pane_logging.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_cli.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_cli_benchmark.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_concurrency.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_deployment.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_ffmpeg_flags.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_ffmpeg_packet.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_field_profiles.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_forensics.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_geomap.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_image_cache.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_link_bytes.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_link_trace.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_netem_dist.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_network_profiles.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_network_shaper.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_ota_unwrapper.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_ota_wrapper.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_ota_xml.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_playout_pacer.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_plots.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_qos_fallback_logging.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_relay_optional_parameters.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_stage_latency.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_status_eval.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_status_overview.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_status_overview_observer.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_stream_stats.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_trace_profiles.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_transit.py +0 -0
- {rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/tests/unit/test_video_quality.py +0 -0
|
@@ -568,13 +568,39 @@ number being reported.
|
|
|
568
568
|
- `bit_rate` (int)
|
|
569
569
|
- `encoder_av_options` (string)
|
|
570
570
|
|
|
571
|
-
#### Receiver-side playout pacing
|
|
571
|
+
#### Receiver-side playout pacing
|
|
572
572
|
|
|
573
573
|
A receiver that hands every packet to the decoder the moment it arrives turns
|
|
574
574
|
network delay jitter into display stutter. `com_py playout_pacer` re-times a
|
|
575
575
|
received packet stream to `stamp + budget` (budget adaptive above the fastest
|
|
576
576
|
observed path, clock-offset-proof; late packets pass through immediately, order
|
|
577
|
-
always preserved — the decoder chain sees every packet)
|
|
577
|
+
always preserved — the decoder chain sees every packet). On the 2026-08-17 CCNG
|
|
578
|
+
field trace this removes ~95 % of delay-caused >200 ms display gaps at ~100 ms
|
|
579
|
+
median added age (adaptive mode).
|
|
580
|
+
|
|
581
|
+
Declaratively, add a `playout` block to the transport:
|
|
582
|
+
|
|
583
|
+
```yaml
|
|
584
|
+
transport:
|
|
585
|
+
type: "ffmpeg"
|
|
586
|
+
gop_size: 3
|
|
587
|
+
remote_republish: compressed
|
|
588
|
+
playout: # receiver-side; requires remote_republish
|
|
589
|
+
adaptive: true # default true; false uses target_ms as a fixed budget
|
|
590
|
+
target_ms: 350 # fixed budget when adaptive: false
|
|
591
|
+
min_ms: 100 # adaptive clamp above the observed delay floor
|
|
592
|
+
max_ms: 800
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
The receiving peer then runs the pacer in its own `PACE` window against the
|
|
596
|
+
arrived encoded stream, and the reverse republish decodes `<encoded>/paced`
|
|
597
|
+
instead of the raw arrival — the delivered topic name is unchanged, which is
|
|
598
|
+
why `playout` requires `remote_republish`: without a republish the pacer's
|
|
599
|
+
`/paced` suffix would rename what the receiving application subscribes to.
|
|
600
|
+
The sender's own preview decode (`local_republish`) is never paced — it reads
|
|
601
|
+
the local copy of what was just encoded, so there is no jitter to absorb.
|
|
602
|
+
|
|
603
|
+
The node also runs standalone against any packet stream:
|
|
578
604
|
|
|
579
605
|
```bash
|
|
580
606
|
ros2 run com_py playout_pacer --ros-args \
|
|
@@ -583,11 +609,7 @@ ros2 run com_py playout_pacer --ros-args \
|
|
|
583
609
|
```
|
|
584
610
|
|
|
585
611
|
It republishes on `<topic>/paced` plus `.../paced/budget_ms` and
|
|
586
|
-
`.../paced/queue_depth` debug topics
|
|
587
|
-
decoder) at the paced name. On the 2026-08-17 CCNG field trace this removes
|
|
588
|
-
~95 % of delay-caused >200 ms display gaps at ~100 ms median added age
|
|
589
|
-
(adaptive mode). Declarative wiring as a `transport.playout` block is tracked
|
|
590
|
-
in issue #284.
|
|
612
|
+
`.../paced/queue_depth` debug topics.
|
|
591
613
|
|
|
592
614
|
`type: foxglove` supports (CompressedVideo):
|
|
593
615
|
- `gop_size` (int)
|
|
@@ -232,15 +232,49 @@ parameters:
|
|
|
232
232
|
irt_1_topic: # e.g. /sensors/camera/front_wide/image_color
|
|
233
233
|
irt_1_transport: # e.g. raw
|
|
234
234
|
irt_1_out_transport: compressed # e.g. raw, compressed – determines the output remap format
|
|
235
|
+
irt_1_paced: # "true" -> decode reads ${irt_1_topic}/paced (playout pacer, PACE window)
|
|
235
236
|
irt_2_topic: # e.g. /sensors/front_camera/image_raw/compressed
|
|
236
237
|
irt_2_transport: # e.g. raw
|
|
237
238
|
irt_2_out_transport: compressed # e.g. raw, compressed – determines the output remap format
|
|
239
|
+
irt_2_paced: # "true" -> decode reads ${irt_2_topic}/paced
|
|
238
240
|
irt_3_topic: # e.g. /sensor/front_camera/image_color/compressed
|
|
239
241
|
irt_3_transport: # e.g. raw
|
|
240
242
|
irt_3_out_transport: compressed # e.g. raw, compressed – determines the output remap format
|
|
243
|
+
irt_3_paced: # "true" -> decode reads ${irt_3_topic}/paced
|
|
241
244
|
irt_4_topic: # e.g. /sensor/front_camera/image_color/compressed
|
|
242
245
|
irt_4_transport: # e.g. raw
|
|
243
246
|
irt_4_out_transport: compressed # e.g. raw, compressed – determines the output remap format
|
|
247
|
+
irt_4_paced: # "true" -> decode reads ${irt_4_topic}/paced
|
|
248
|
+
|
|
249
|
+
# Receiver-side playout pacing (transport.playout in the session definition):
|
|
250
|
+
# re-times the arrived encoded stream on '<topic>/paced' so the decode sees a
|
|
251
|
+
# steady cadence instead of the network's delay jitter. Never reorders, never
|
|
252
|
+
# drops; late packets pass through immediately.
|
|
253
|
+
pace: false
|
|
254
|
+
pace_1_topic: # the arrived encoded stream, e.g. /camera/image/ffmpeg
|
|
255
|
+
pace_1_msg_type: # e.g. ffmpeg_image_transport_msgs/msg/FFMPEGPacket
|
|
256
|
+
pace_1_adaptive: # "true" | "false"
|
|
257
|
+
pace_1_target_ms: # fixed budget when adaptive is "false"
|
|
258
|
+
pace_1_min_ms: # adaptive clamp above the observed delay floor
|
|
259
|
+
pace_1_max_ms:
|
|
260
|
+
pace_2_topic:
|
|
261
|
+
pace_2_msg_type:
|
|
262
|
+
pace_2_adaptive:
|
|
263
|
+
pace_2_target_ms:
|
|
264
|
+
pace_2_min_ms:
|
|
265
|
+
pace_2_max_ms:
|
|
266
|
+
pace_3_topic:
|
|
267
|
+
pace_3_msg_type:
|
|
268
|
+
pace_3_adaptive:
|
|
269
|
+
pace_3_target_ms:
|
|
270
|
+
pace_3_min_ms:
|
|
271
|
+
pace_3_max_ms:
|
|
272
|
+
pace_4_topic:
|
|
273
|
+
pace_4_msg_type:
|
|
274
|
+
pace_4_adaptive:
|
|
275
|
+
pace_4_target_ms:
|
|
276
|
+
pace_4_min_ms:
|
|
277
|
+
pace_4_max_ms:
|
|
244
278
|
|
|
245
279
|
common:
|
|
246
280
|
before_commands:
|
|
@@ -623,6 +657,30 @@ windows:
|
|
|
623
657
|
- args+=(--remap "${in_remap}:=${it_4_topic}" --remap "out/${it_4_transport}:=${it_4_topic}/${outgoing_suffix}")
|
|
624
658
|
- echo ${args[@]}
|
|
625
659
|
- ${args[@]}
|
|
660
|
+
- name: PACE
|
|
661
|
+
if: pace
|
|
662
|
+
layout: even-vertical
|
|
663
|
+
splits:
|
|
664
|
+
- commands:
|
|
665
|
+
- if [ '${pace_1_topic}' = "None" ]; then exit; fi
|
|
666
|
+
- args=(ros2 run com_py playout_pacer --ros-args -p topic:=${pace_1_topic} -p msg_type:=${pace_1_msg_type} -p adaptive:=${pace_1_adaptive} -p target_ms:=${pace_1_target_ms} -p min_ms:=${pace_1_min_ms} -p max_ms:=${pace_1_max_ms} -p qos_config_file:='${qos_config_file}')
|
|
667
|
+
- echo ${args[@]}
|
|
668
|
+
- ${args[@]}
|
|
669
|
+
- commands:
|
|
670
|
+
- if [ '${pace_2_topic}' = "None" ]; then exit; fi
|
|
671
|
+
- args=(ros2 run com_py playout_pacer --ros-args -p topic:=${pace_2_topic} -p msg_type:=${pace_2_msg_type} -p adaptive:=${pace_2_adaptive} -p target_ms:=${pace_2_target_ms} -p min_ms:=${pace_2_min_ms} -p max_ms:=${pace_2_max_ms} -p qos_config_file:='${qos_config_file}')
|
|
672
|
+
- echo ${args[@]}
|
|
673
|
+
- ${args[@]}
|
|
674
|
+
- commands:
|
|
675
|
+
- if [ '${pace_3_topic}' = "None" ]; then exit; fi
|
|
676
|
+
- args=(ros2 run com_py playout_pacer --ros-args -p topic:=${pace_3_topic} -p msg_type:=${pace_3_msg_type} -p adaptive:=${pace_3_adaptive} -p target_ms:=${pace_3_target_ms} -p min_ms:=${pace_3_min_ms} -p max_ms:=${pace_3_max_ms} -p qos_config_file:='${qos_config_file}')
|
|
677
|
+
- echo ${args[@]}
|
|
678
|
+
- ${args[@]}
|
|
679
|
+
- commands:
|
|
680
|
+
- if [ '${pace_4_topic}' = "None" ]; then exit; fi
|
|
681
|
+
- args=(ros2 run com_py playout_pacer --ros-args -p topic:=${pace_4_topic} -p msg_type:=${pace_4_msg_type} -p adaptive:=${pace_4_adaptive} -p target_ms:=${pace_4_target_ms} -p min_ms:=${pace_4_min_ms} -p max_ms:=${pace_4_max_ms} -p qos_config_file:='${qos_config_file}')
|
|
682
|
+
- echo ${args[@]}
|
|
683
|
+
- ${args[@]}
|
|
626
684
|
- name: IRT
|
|
627
685
|
if: irt
|
|
628
686
|
layout: even-vertical
|
|
@@ -630,28 +688,32 @@ windows:
|
|
|
630
688
|
- commands:
|
|
631
689
|
- if [ '${irt_1_topic}' = "None" ]; then exit; fi
|
|
632
690
|
- if [[ "${irt_1_out_transport}" == "raw" ]]; then out_remap="out"; else out_remap="out/${irt_1_out_transport}"; fi
|
|
691
|
+
- if [[ "${irt_1_paced}" != "None" ]]; then irt_in_topic="${irt_1_topic}/paced"; else irt_in_topic="${irt_1_topic}"; fi
|
|
633
692
|
- 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}
|
|
634
|
-
--remap in/${irt_1_transport}:=${
|
|
693
|
+
--remap in/${irt_1_transport}:=${irt_in_topic} --remap ${out_remap}:=${irt_1_topic}/${irt_1_out_transport})
|
|
635
694
|
- echo ${args[@]}
|
|
636
695
|
- ${args[@]}
|
|
637
696
|
- commands:
|
|
638
697
|
- if [ '${irt_2_topic}' = "None" ]; then exit; fi
|
|
639
698
|
- if [[ "${irt_2_out_transport}" == "raw" ]]; then out_remap="out"; else out_remap="out/${irt_2_out_transport}"; fi
|
|
699
|
+
- if [[ "${irt_2_paced}" != "None" ]]; then irt_in_topic="${irt_2_topic}/paced"; else irt_in_topic="${irt_2_topic}"; fi
|
|
640
700
|
- 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}
|
|
641
|
-
--remap in/${irt_2_transport}:=${
|
|
701
|
+
--remap in/${irt_2_transport}:=${irt_in_topic} --remap ${out_remap}:=${irt_2_topic}/${irt_2_out_transport})
|
|
642
702
|
- echo ${args[@]}
|
|
643
703
|
- ${args[@]}
|
|
644
704
|
- commands:
|
|
645
705
|
- if [ '${irt_3_topic}' = "None" ]; then exit; fi
|
|
646
706
|
- if [[ "${irt_3_out_transport}" == "raw" ]]; then out_remap="out"; else out_remap="out/${irt_3_out_transport}"; fi
|
|
707
|
+
- if [[ "${irt_3_paced}" != "None" ]]; then irt_in_topic="${irt_3_topic}/paced"; else irt_in_topic="${irt_3_topic}"; fi
|
|
647
708
|
- 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}
|
|
648
|
-
--remap in/${irt_3_transport}:=${
|
|
709
|
+
--remap in/${irt_3_transport}:=${irt_in_topic} --remap ${out_remap}:=${irt_3_topic}/${irt_3_out_transport})
|
|
649
710
|
- echo ${args[@]}
|
|
650
711
|
- ${args[@]}
|
|
651
712
|
- commands:
|
|
652
713
|
- if [ '${irt_4_topic}' = "None" ]; then exit; fi
|
|
653
714
|
- if [[ "${irt_4_out_transport}" == "raw" ]]; then out_remap="out"; else out_remap="out/${irt_4_out_transport}"; fi
|
|
715
|
+
- if [[ "${irt_4_paced}" != "None" ]]; then irt_in_topic="${irt_4_topic}/paced"; else irt_in_topic="${irt_4_topic}"; fi
|
|
654
716
|
- 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}
|
|
655
|
-
--remap in/${irt_4_transport}:=${
|
|
717
|
+
--remap in/${irt_4_transport}:=${irt_in_topic} --remap ${out_remap}:=${irt_4_topic}/${irt_4_out_transport})
|
|
656
718
|
- echo ${args[@]}
|
|
657
719
|
- ${args[@]}
|
|
@@ -92,6 +92,13 @@ class TransportSpec:
|
|
|
92
92
|
#: image_transport itself, or one that only forwards or records packets,
|
|
93
93
|
#: does not want a second copy of every frame.
|
|
94
94
|
remote_republish: Optional[str] = None
|
|
95
|
+
#: Receiver-side playout pacing (issue #284): re-time the arrived packet
|
|
96
|
+
#: stream to smooth network delay jitter before the reverse republish
|
|
97
|
+
#: decodes it. Keys: adaptive / target_ms / min_ms / max_ms (validated in
|
|
98
|
+
#: the parser; defaults live in the playout_pacer node). Requires
|
|
99
|
+
#: `remote_republish`, because the pacer publishes on `<encoded>/paced`
|
|
100
|
+
#: and only the republish remap keeps the delivered topic name unchanged.
|
|
101
|
+
playout: Optional[Dict[str, Any]] = None
|
|
95
102
|
|
|
96
103
|
|
|
97
104
|
@dataclass
|
|
@@ -1692,12 +1699,45 @@ def _compute_pipeline(
|
|
|
1692
1699
|
)
|
|
1693
1700
|
return str(value)
|
|
1694
1701
|
|
|
1695
|
-
|
|
1702
|
+
remote_republish = _republish("remote_republish")
|
|
1703
|
+
|
|
1704
|
+
playout: Optional[Dict[str, Any]] = None
|
|
1705
|
+
playout_cfg = t.get("playout")
|
|
1706
|
+
if playout_cfg is not None:
|
|
1707
|
+
if not isinstance(playout_cfg, dict):
|
|
1708
|
+
raise ValueError(f"transport.playout must be a mapping for topic '{entry.base}'")
|
|
1709
|
+
allowed = {"adaptive", "target_ms", "min_ms", "max_ms"}
|
|
1710
|
+
unknown = sorted(set(playout_cfg) - allowed)
|
|
1711
|
+
if unknown:
|
|
1712
|
+
raise ValueError(
|
|
1713
|
+
f"transport.playout for topic '{entry.base}' has unknown keys {unknown}; "
|
|
1714
|
+
f"allowed: {sorted(allowed)}"
|
|
1715
|
+
)
|
|
1716
|
+
if remote_republish is None:
|
|
1717
|
+
raise ValueError(
|
|
1718
|
+
f"transport.playout for topic '{entry.base}' requires remote_republish: "
|
|
1719
|
+
"the pacer publishes on '<encoded>/paced', and only the reverse republish's "
|
|
1720
|
+
"input remap keeps the delivered topic name unchanged. Without a republish "
|
|
1721
|
+
"the receiver would have to subscribe a renamed topic."
|
|
1722
|
+
)
|
|
1723
|
+
for key in ("target_ms", "min_ms", "max_ms"):
|
|
1724
|
+
if key in playout_cfg and (not isinstance(playout_cfg[key], (int, float)) or playout_cfg[key] <= 0):
|
|
1725
|
+
raise ValueError(f"transport.playout.{key} must be a positive number for topic '{entry.base}'")
|
|
1726
|
+
min_ms = float(playout_cfg.get("min_ms", 100.0))
|
|
1727
|
+
max_ms = float(playout_cfg.get("max_ms", 800.0))
|
|
1728
|
+
if max_ms < min_ms:
|
|
1729
|
+
raise ValueError(f"transport.playout.max_ms must be >= min_ms for topic '{entry.base}'")
|
|
1730
|
+
if "adaptive" in playout_cfg and not isinstance(playout_cfg["adaptive"], bool):
|
|
1731
|
+
raise ValueError(f"transport.playout.adaptive must be a boolean for topic '{entry.base}'")
|
|
1732
|
+
playout = dict(playout_cfg)
|
|
1733
|
+
|
|
1734
|
+
params = {k: v for k, v in t.items() if k not in ("type", "playout", *republish_keys)}
|
|
1696
1735
|
transport = TransportSpec(
|
|
1697
1736
|
type=ttype,
|
|
1698
1737
|
params=params,
|
|
1699
1738
|
local_republish=_republish("local_republish"),
|
|
1700
|
-
remote_republish=
|
|
1739
|
+
remote_republish=remote_republish,
|
|
1740
|
+
playout=playout,
|
|
1701
1741
|
)
|
|
1702
1742
|
|
|
1703
1743
|
topic = entry.base
|
|
@@ -3201,21 +3241,46 @@ def func(
|
|
|
3201
3241
|
# it encoded and (b) the decode of what arrived. Both run on *this* peer;
|
|
3202
3242
|
# what differs is which copy they decode and which transport the session
|
|
3203
3243
|
# asked each of them to publish in.
|
|
3204
|
-
|
|
3244
|
+
# The sender's own preview decode is never paced: it reads the local
|
|
3245
|
+
# copy of what it just encoded, so there is no network jitter to
|
|
3246
|
+
# absorb. Playout pacing exists on the receiving side only.
|
|
3247
|
+
irt_all: List[Tuple[str, str, str, Optional[Dict[str, Any]]]] = []
|
|
3205
3248
|
for t, tspec in irt_items_local:
|
|
3206
3249
|
assert tspec is not None
|
|
3207
|
-
irt_all.append((t, tspec.type, str(tspec.local_republish)))
|
|
3208
|
-
irt_all.extend(
|
|
3250
|
+
irt_all.append((t, tspec.type, str(tspec.local_republish), None))
|
|
3251
|
+
irt_all.extend(
|
|
3252
|
+
(topic, tspec.type, str(tspec.remote_republish), tspec.playout) for topic, tspec in irt_items_remote
|
|
3253
|
+
)
|
|
3209
3254
|
_assert_max("irt", irt_all, 4)
|
|
3210
3255
|
if irt_all:
|
|
3211
3256
|
items2 = [("irt", True)]
|
|
3212
|
-
for i, (topic, _ttype, _out_transport) in enumerate(irt_all, 1):
|
|
3257
|
+
for i, (topic, _ttype, _out_transport, _playout) in enumerate(irt_all, 1):
|
|
3213
3258
|
items2.append((f"irt_{i}_topic", topic))
|
|
3214
|
-
for i, (_topic, ttype, out_transport) in enumerate(irt_all, 1):
|
|
3259
|
+
for i, (_topic, ttype, out_transport, playout) in enumerate(irt_all, 1):
|
|
3215
3260
|
items2.append((f"irt_{i}_transport", ttype))
|
|
3216
3261
|
items2.append((f"irt_{i}_out_transport", out_transport))
|
|
3262
|
+
if playout is not None:
|
|
3263
|
+
# Points the decode's input remap at '<topic>/paced'; the
|
|
3264
|
+
# pacer itself runs in the PACE window below.
|
|
3265
|
+
items2.append((f"irt_{i}_paced", "true"))
|
|
3217
3266
|
blocks.append(PluginBlock("irt", items2))
|
|
3218
3267
|
|
|
3268
|
+
paced_entries = [
|
|
3269
|
+
(i, topic, ttype, playout)
|
|
3270
|
+
for i, (topic, ttype, _out_transport, playout) in enumerate(irt_all, 1)
|
|
3271
|
+
if playout is not None
|
|
3272
|
+
]
|
|
3273
|
+
if paced_entries:
|
|
3274
|
+
items_pace: List[Tuple[str, Any]] = [("pace", True)]
|
|
3275
|
+
for i, topic, ttype, playout in paced_entries:
|
|
3276
|
+
items_pace.append((f"pace_{i}_topic", topic))
|
|
3277
|
+
items_pace.append((f"pace_{i}_msg_type", TRANSPORT_OUTPUT_TYPES[ttype]))
|
|
3278
|
+
items_pace.append((f"pace_{i}_adaptive", "true" if playout.get("adaptive", True) else "false"))
|
|
3279
|
+
items_pace.append((f"pace_{i}_target_ms", float(playout.get("target_ms", 350.0))))
|
|
3280
|
+
items_pace.append((f"pace_{i}_min_ms", float(playout.get("min_ms", 100.0))))
|
|
3281
|
+
items_pace.append((f"pace_{i}_max_ms", float(playout.get("max_ms", 800.0))))
|
|
3282
|
+
blocks.append(PluginBlock("pace", items_pace))
|
|
3283
|
+
|
|
3219
3284
|
if nor_items:
|
|
3220
3285
|
items2 = [("nor", True)]
|
|
3221
3286
|
nor_prefix = f"/{peer_name[remote]}" if bool(inbound_cfg.get("keep_source_prefix", False)) else ""
|
|
@@ -233,3 +233,76 @@ def test_generated_peer_files_wire_the_wrapped_camera(tmp_path: Path) -> None:
|
|
|
233
233
|
# ... and what the application finally reads is the decoded image.
|
|
234
234
|
assert stages["native_in"]["topic"] == "/camera/image/ffmpeg/raw"
|
|
235
235
|
assert stages["native_in"]["type"] == "sensor_msgs/msg/Image"
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
# ---------------------------------------------------------------------------
|
|
239
|
+
# receiver-side playout pacing (transport.playout, issue #284)
|
|
240
|
+
# ---------------------------------------------------------------------------
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def test_playout_requires_a_receiver_republish() -> None:
|
|
244
|
+
"""Without a reverse republish the pacer would rename the delivered topic."""
|
|
245
|
+
with pytest.raises(ValueError, match="requires remote_republish"):
|
|
246
|
+
_pipeline({"transport": {"type": "ffmpeg", "playout": {"min_ms": 100}}})
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def test_playout_rejects_unknown_keys_and_bad_numbers() -> None:
|
|
250
|
+
with pytest.raises(ValueError, match="unknown keys"):
|
|
251
|
+
_pipeline(_ffmpeg(playout={"budget_ms": 350}))
|
|
252
|
+
with pytest.raises(ValueError, match="positive number"):
|
|
253
|
+
_pipeline(_ffmpeg(playout={"target_ms": -1}))
|
|
254
|
+
with pytest.raises(ValueError, match="max_ms must be >= min_ms"):
|
|
255
|
+
_pipeline(_ffmpeg(playout={"min_ms": 500, "max_ms": 100}))
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def test_playout_never_leaks_into_encoder_params() -> None:
|
|
259
|
+
_entry, pipe = _pipeline(_ffmpeg(gop_size=3, playout={"min_ms": 100, "max_ms": 800}))
|
|
260
|
+
tspec = pipe["transport"]
|
|
261
|
+
assert tspec.playout == {"min_ms": 100, "max_ms": 800}
|
|
262
|
+
assert "playout" not in tspec.params
|
|
263
|
+
assert tspec.params["gop_size"] == 3
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
def test_playout_does_not_rename_the_delivered_topic() -> None:
|
|
267
|
+
"""The pacer sits between unwrapper and decode; what the application reads keeps its name."""
|
|
268
|
+
_entry, plain = _pipeline(_ffmpeg())
|
|
269
|
+
_entry, paced = _pipeline(_ffmpeg(playout={}))
|
|
270
|
+
assert generator._delivered_topic(paced, paced["final"]) == generator._delivered_topic(plain, plain["final"])
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def test_generated_peer_files_wire_the_pacer(tmp_path: Path) -> None:
|
|
274
|
+
processing = {
|
|
275
|
+
"transport": {
|
|
276
|
+
"type": "ffmpeg",
|
|
277
|
+
"gop_size": 3,
|
|
278
|
+
"remote_republish": "compressed",
|
|
279
|
+
"playout": {"adaptive": True, "min_ms": 120, "max_ms": 600},
|
|
280
|
+
},
|
|
281
|
+
"use_ota_wrapper": True,
|
|
282
|
+
}
|
|
283
|
+
generator.func(
|
|
284
|
+
session_config_obj=_camera_cfg(processing),
|
|
285
|
+
output_dir=str(tmp_path),
|
|
286
|
+
force=True,
|
|
287
|
+
peer_addresses={"a": "127.0.0.1", "b": "127.0.0.2"},
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
receiver = (tmp_path / "a" / "plugin.yaml").read_text(encoding="utf-8")
|
|
291
|
+
# The pacer runs on the receiving peer against the arrived encoded stream...
|
|
292
|
+
assert "pace_1_topic: /camera/image/ffmpeg" in receiver
|
|
293
|
+
assert "pace_1_msg_type: ffmpeg_image_transport_msgs/msg/FFMPEGPacket" in receiver
|
|
294
|
+
assert (
|
|
295
|
+
"pace_1_adaptive: 'true'" in receiver
|
|
296
|
+
or 'pace_1_adaptive: "true"' in receiver
|
|
297
|
+
or "pace_1_adaptive: true" in receiver
|
|
298
|
+
)
|
|
299
|
+
assert "pace_1_min_ms: 120.0" in receiver
|
|
300
|
+
assert "pace_1_max_ms: 600.0" in receiver
|
|
301
|
+
# ...and the decode reads the paced copy.
|
|
302
|
+
assert "irt_1_paced" in receiver
|
|
303
|
+
|
|
304
|
+
# The sender has no pacer: its preview (if any) reads its own encode, and
|
|
305
|
+
# this session declares no local_republish at all.
|
|
306
|
+
sender = (tmp_path / "b" / "plugin.yaml").read_text(encoding="utf-8")
|
|
307
|
+
assert "pace" not in sender or "pace_1_topic" not in sender
|
|
308
|
+
assert "irt_1_paced" not in sender
|
{rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.devcontainer/devcontainer.json.template
RENAMED
|
File without changes
|
{rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.devcontainer/re_generate_devcontainer_json.py
RENAMED
|
File without changes
|
|
File without changes
|
{rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/ISSUE_TEMPLATE/documentation-audit.md
RENAMED
|
File without changes
|
{rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/ISSUE_TEMPLATE/implementation-cleanup.md
RENAMED
|
File without changes
|
{rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/ISSUE_TEMPLATE/quality-workflow.md
RENAMED
|
File without changes
|
|
File without changes
|
{rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/ISSUE_TEMPLATE/release-process.md
RENAMED
|
File without changes
|
{rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/ISSUE_TEMPLATE/repository-diagnosis.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/.github/workflows/benchmark-calibrate.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/calibration/capacity-size-tight-cyclone.json
RENAMED
|
File without changes
|
{rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/calibration/probe-loss-gop-tight-cyclone.json
RENAMED
|
File without changes
|
{rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/calibration/probe-loss-nominal-cyclone.json
RENAMED
|
File without changes
|
{rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/calibration/probe-loss-tight-cyclone.json
RENAMED
|
File without changes
|
{rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/calibration/probe-loss-tight-fastdds.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/findings/cyclone-spdp-discovery-bursts.md
RENAMED
|
File without changes
|
|
File without changes
|
{rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/findings/head-of-line-irregularity.md
RENAMED
|
File without changes
|
{rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/findings/jitter-loss-bandwidth-latency.md
RENAMED
|
File without changes
|
|
File without changes
|
{rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/findings/reorder-becomes-reader-loss.md
RENAMED
|
File without changes
|
{rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/findings/repro/reorder_drop_repro.py
RENAMED
|
File without changes
|
{rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/findings/zero-loss-boundaries-18kb-20hz.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/rfcs/0001-expectation-driven-test-suite.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rosotacom_dev-2.5.dev48 → rosotacom_dev-2.5.dev49}/docs/rfcs/0005-benchmark-genres-and-ci.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|