rosotacom-dev 2.5.dev38__tar.gz → 2.5.dev39__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.dev38 → rosotacom_dev-2.5.dev39}/PKG-INFO +1 -1
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/base_bridge_relay.py +32 -2
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/qos.py +8 -2
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/session/content/base/session_plugin_base.yaml +49 -36
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom_dev.egg-info/PKG-INFO +1 -1
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom_dev.egg-info/SOURCES.txt +2 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom_dev.egg-info/scm_file_list.json +2 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom_dev.egg-info/scm_version.json +2 -2
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_catmux_pane_logging.py +74 -0
- rosotacom_dev-2.5.dev39/tests/unit/test_qos_fallback_logging.py +139 -0
- rosotacom_dev-2.5.dev39/tests/unit/test_relay_optional_parameters.py +176 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.devcontainer/devcontainer.json.template +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.devcontainer/re_generate_devcontainer_json.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.github/CODEOWNERS +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.github/ISSUE_TEMPLATE/documentation-audit.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.github/ISSUE_TEMPLATE/implementation-cleanup.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.github/ISSUE_TEMPLATE/quality-workflow.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.github/ISSUE_TEMPLATE/redesign.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.github/ISSUE_TEMPLATE/release-process.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.github/ISSUE_TEMPLATE/repository-diagnosis.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.github/ISSUE_TEMPLATE/test-ci-audit.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.github/ISSUE_TEMPLATE/work-item.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.github/actions/setup-just/action.yml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.github/dependabot.yml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.github/workflows/benchmark-calibrate.yml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.github/workflows/benchmark-gate.yml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.github/workflows/dev-release.yml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.github/workflows/image-scan.yml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.github/workflows/nightly-e2e.yml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.github/workflows/pr-lightweight.yml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.github/workflows/pr-merge-gate.yml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.github/workflows/release.yml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.pre-commit-config.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/AGENTS.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/CONCURRENCY.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/CONTRIBUTING.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/DEVELOPMENT_PRINCIPLES.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/MANIFEST.in +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/README.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/budgets.jsonl +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/calibration/README.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/calibration/capacity-size-tight-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/calibration/probe-loss-gop-tight-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/calibration/probe-loss-nominal-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/calibration/probe-loss-tight-cyclone.json +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/calibration/probe-loss-tight-fastdds.json +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/calibration/probe-loss-tight-zenoh.json +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/codecov.yml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/deployment-configuration.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/benchmark-ab.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/benchmark-bag-as-load.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/ci.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/ffmpeg-keyframes.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/findings/README.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/findings/cyclone-spdp-discovery-bursts.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/findings/delay-alone-no-loss.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/findings/head-of-line-irregularity.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/findings/jitter-loss-bandwidth-latency.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/findings/lighter-message-loss.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/findings/zero-loss-boundaries-18kb-20hz.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/forensics-report.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/geo-link-map.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/github-repository-settings.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/link-bandwidth.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/link-trace.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/owner-runbook.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/performance-bands.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/playbooks/README.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/quality-model.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/release-notes/TEMPLATE.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/release-notes/v2.1.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/release-notes/v2.2.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/release-notes/v2.3.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/release-notes/v2.4.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/release.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/rfcs/0001-expectation-driven-test-suite.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/rfcs/0002-expectation-concepts.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/rfcs/0003-metric-backbone.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/rfcs/0004-network-profiles.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/rfcs/0005-benchmark-genres-and-ci.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/rfcs/0006-dynamic-qos.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/rfcs/0007-regression-gate.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/rfcs/README.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/testing.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/docs/work-items.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/install.sh +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/justfile +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/media/control_center.png +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/media/echo_test.png +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/media/forensics-report-example.png +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/media/host.png +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/media/vehicle.png +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/pyproject.toml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/requirements.txt +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/rosotacom.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/session-configuration.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/setup.cfg +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/__init__.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/__main__.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/anonymize.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/bag_ground_truth.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/benched_set.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/benchmark.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/benchmark_delta.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/bundle_check.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/cli.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/cli_benchmark.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/deployment.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/ffmpeg_packet.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/forensics.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/geomap.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/image_cache.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/network_profiles.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/network_shaper.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/plots.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/py.typed +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/benched-set.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/.gitignore +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/README.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/__init__.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/bags/8_drop_reference/metadata.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/deployment.example.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/profiles.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/rosotacom.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scenarios/2_native_chatter/scenario-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_a.sh +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_b.sh +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/wait_for_echo_topic.sh +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/foxglove.json +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/metadata.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/foxglove.json +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/metadata.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_external.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external.ros2docker.json +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external_session.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_communication.sh +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_external.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/10_restamp/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/11_trickle/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/12_content_integrity/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/13_link_latency/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/14_remote_assist_anonymized/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/15_remote_assist_anonymized_costmap/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/16_remote_assist_anonymized_camera/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/17_synthetic_camera_quality/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/1_heartbeat/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/1_heartbeat_status/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/2_native_chatter/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/3_comp_occ_grid/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/4_comp_occ_grid_zen/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/5_sized_payload/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/6_sized_payload_zen/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/7_latched_static/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/8_drop/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/9_throttle/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/bench_1_1_capacity/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/bench_1_2_load_sweep/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/bench_1_3_ramp/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/bench_1_4_recovery/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/bench_1_5_camera/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ros2docker.json.example +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/.vscode/c_cpp_properties.json +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/.vscode/settings.json +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_easy_mode.xml.template +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_initial_peer_list.xml.template +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v2.xml.template +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v3.xml.template +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v4.xml.template +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v5.xml.template +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/create_zenoh_json5.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/cyclonedds_local_participants.xml.template +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/cyclonedds_minimal.xml.template +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/cyclonedds_tuned.xml.template +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/fastdds_unicast.xml.template +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/get_ota_xml.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/utils.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/zenoh.json5.template +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/.gitkeep +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_cpp/CMakeLists.txt +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_cpp/COLCON_IGNORE +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_cpp/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_cpp/package.xml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_cpp/src/hz_monitor.cpp +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_compressor.cpp +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_decompressor.cpp +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_msgs/CMakeLists.txt +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_msgs/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/CompressedData.msg +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/EchoHeartbeat.msg +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/OtaStamped.msg +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/SizedPayload.msg +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_msgs/package.xml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/LICENSE.txt +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/__init__.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_in.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_out.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/heartbeat_echo.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/hz_monitor.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_bandwidth_reducer.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_pixel_capper.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/lanelet_saver.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/latch_relay.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/costmap_remapper.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/marker_remapper.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/speed_test.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/tf_remapper.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/traffic_monitor.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/wifi_network_analysis_1.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_bytes.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_trace.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/local_global_frame_bridge.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/localization_map_split_reduce_saver.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/msg_transform.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pair_management.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pub_sub_pair.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_in.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_out.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/restamp.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/sized_publisher.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency_core.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview_core.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/tf_map_to_cart_saver.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_monitor.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_resolution.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/trickle.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_compressor.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_decompressor.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_unwrapper.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_wrapper.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/package.xml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/resource/com_py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/setup.cfg +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/setup.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/test/test_copyright.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/test/test_flake8.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/test/test_pep257.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/session/content/network/up_connectivity.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/session/content/network/wifi_network_analysis_2.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/session/creation/anonymize_bag.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/session/creation/catmux_log_setup.sh +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/session/creation/create_session_yaml.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/session/creation/generate_session_files.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/session/creation/run_session.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/session/creation/run_session_in_external_terminal.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/session/creation/strip_ansi.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/status_eval.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/stream_stats.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/trace_profiles.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/transit.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom/video_quality.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom_dev.egg-info/dependency_links.txt +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom_dev.egg-info/entry_points.txt +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom_dev.egg-info/requires.txt +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom_dev.egg-info/top_level.txt +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/terminology.md +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/contract/test_benched_set_registry.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/contract/test_findings.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/contract/test_markdown_links.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/contract/test_ota_source_bundle.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/contract/test_package_metadata.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/contract/test_packaged_resources.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/contract/test_profile_covers_generated_commands.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/contract/test_pytest_policy.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/contract/test_readme_examples.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/contract/test_security_maintenance_config.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/contract/test_session_configuration_doc.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/contract/test_session_template_substitution.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/contract/test_workflow_contracts.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/e2e/conftest.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/e2e/test_anonymize_e2e.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/e2e/test_benchmark_ab.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/e2e/test_benchmark_capacity.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/e2e/test_benchmark_replay.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/e2e/test_parallel_smoke.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/e2e/test_smoke.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/e2e/test_timeline_stepping.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/e2e/test_video_quality_e2e.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/sessions/generate_rmw_matrix.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-local_zenoh-ros2dds-ota/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota-tuned/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/sessions/rmw_matrix/1_heartbeat_fastdds/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/sessions/rmw_matrix/1_heartbeat_zen-endpoints/session-definition.yaml +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_anonymize.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_bag_ground_truth.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_benched_set.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_benchmark.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_benchmark_delta.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_bundle_check.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_cli.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_cli_benchmark.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_concurrency.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_deployment.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_ffmpeg_packet.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_forensics.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_geomap.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_image_cache.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_link_bytes.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_link_trace.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_network_profiles.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_network_shaper.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_ota_unwrapper.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_ota_wrapper.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_ota_xml.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_plots.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_session_pipeline.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_stage_latency.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_status_eval.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_status_overview.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_status_overview_observer.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_stream_stats.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_trace_profiles.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_transit.py +0 -0
- {rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/tests/unit/test_video_quality.py +0 -0
|
@@ -61,8 +61,8 @@ class BaseBridgeRelay(Node, PairRefreshMixin):
|
|
|
61
61
|
self.qos_config_file = self.declare_parameter('qos_config_file', '').value
|
|
62
62
|
|
|
63
63
|
# Optional parameters with defaults
|
|
64
|
-
self.source_names = self.
|
|
65
|
-
self.target_names = self.
|
|
64
|
+
self.source_names = self.declare_optional_string_array('source_names')
|
|
65
|
+
self.target_names = self.declare_optional_string_array('target_names')
|
|
66
66
|
|
|
67
67
|
# Derived classes can declare additional parameters here (must happen before initialize_node()).
|
|
68
68
|
self.declare_additional_parameters()
|
|
@@ -73,6 +73,36 @@ class BaseBridgeRelay(Node, PairRefreshMixin):
|
|
|
73
73
|
# Create timer for periodic refresh of invalid pairs
|
|
74
74
|
self.init_pair_refresh(period_s=5.0, log_prefix=self.node_role)
|
|
75
75
|
|
|
76
|
+
def declare_optional_string_array(self, name: str) -> list:
|
|
77
|
+
"""Declare an optional STRING_ARRAY that reads as [] rather than as unset.
|
|
78
|
+
|
|
79
|
+
Declaring a type without a value leaves the parameter
|
|
80
|
+
PARAMETER_NOT_SET. This node never notices — it reads the value once,
|
|
81
|
+
here, and an unset parameter simply yields None. Everything *else*
|
|
82
|
+
notices: reading a not-set parameter raises, and rclpy's parameter
|
|
83
|
+
service logs one warning per read against this node,
|
|
84
|
+
|
|
85
|
+
[WARN] [ota_relay_out]: Failed to get parameters: The parameter
|
|
86
|
+
'source_names' is not initialized: source_names
|
|
87
|
+
|
|
88
|
+
which anything that enumerates parameters then produces on a timer. A
|
|
89
|
+
Foxglove bridge with a parameter panel open put 107 of those lines into
|
|
90
|
+
a single pane in one session — the kind of noise that hides the message
|
|
91
|
+
somebody actually needs to see.
|
|
92
|
+
|
|
93
|
+
A plain default cannot express this: `declare_parameter(name, [])`
|
|
94
|
+
infers the type from the value, and an empty list satisfies the
|
|
95
|
+
BYTE_ARRAY test first (`all(...)` is true for an empty sequence). The
|
|
96
|
+
parameter would be typed BYTE_ARRAY and the real string array refused
|
|
97
|
+
later with "Wrong parameter type, expected '5' got '9'". Declaring the
|
|
98
|
+
type and then setting the empty value keeps it STRING_ARRAY, so a wrong
|
|
99
|
+
type is still rejected and an override still wins.
|
|
100
|
+
"""
|
|
101
|
+
self.declare_parameter(name, rclpy.Parameter.Type.STRING_ARRAY)
|
|
102
|
+
if self.get_parameter_or(name).type_ == rclpy.Parameter.Type.NOT_SET:
|
|
103
|
+
self.set_parameters([rclpy.Parameter(name, rclpy.Parameter.Type.STRING_ARRAY, [])])
|
|
104
|
+
return self.get_parameter(name).value
|
|
105
|
+
|
|
76
106
|
def initialize_node(self):
|
|
77
107
|
"""Initialize node with resolved topics and QoS configuration."""
|
|
78
108
|
try:
|
|
@@ -139,7 +139,13 @@ def get_topic_qos(logger, qos_config: dict, topic_name: str, role_name: str):
|
|
|
139
139
|
Additionally supports a fallback lookup: if no exact match for topic_name exists
|
|
140
140
|
in qos_config['topics'], we look for the most specific configured base topic key
|
|
141
141
|
that matches as a path segment within topic_name (e.g. '/tf' for
|
|
142
|
-
'/shuttle_ella/tf/restamped').
|
|
142
|
+
'/shuttle_ella/tf/restamped'). Such a fallback is logged at debug level: it is
|
|
143
|
+
the designed path, not a degradation. Every processing stage appends a suffix,
|
|
144
|
+
so a session that uses framebridge, latching or a transport reaches it for most
|
|
145
|
+
of its topics, and a definition that declares QoS on the base topic and lets the
|
|
146
|
+
processed names inherit it is doing exactly what the schema intends. Logged as a
|
|
147
|
+
warning it was two lines per topic per peer at every start — enough noise around
|
|
148
|
+
a bring-up to bury an actual fault.
|
|
143
149
|
"""
|
|
144
150
|
default = qos_config.get('default', {})
|
|
145
151
|
|
|
@@ -151,7 +157,7 @@ def get_topic_qos(logger, qos_config: dict, topic_name: str, role_name: str):
|
|
|
151
157
|
if topic_name not in topics_cfg:
|
|
152
158
|
base_match = _find_best_base_topic_match(topics_cfg, topic_name)
|
|
153
159
|
if base_match is not None:
|
|
154
|
-
logger.
|
|
160
|
+
logger.debug(
|
|
155
161
|
f"[dds_qos] No exact QoS match for topic='{topic_name}'. "
|
|
156
162
|
f"Falling back to base topic='{base_match}'."
|
|
157
163
|
)
|
|
@@ -534,6 +534,19 @@ windows:
|
|
|
534
534
|
- commands:
|
|
535
535
|
- if [ '${ipx_4_topics}' = "None" ]; then exit; fi
|
|
536
536
|
- ros2 run com_py image_pixel_capper --ros-args -p topics:=[${ipx_4_topics}] -p max_pixels_preset:=${ipx_4_preset} -p qos_config_file:='${qos_config_file}'
|
|
537
|
+
# `if ...; then ...; fi`, never `[[ ... ]] && ...`, for the optional argument
|
|
538
|
+
# lines below. catmux sends every one of these to an interactive shell, and
|
|
539
|
+
# `catmux_log_setup.sh` hooks the pane-exit recorder into PROMPT_COMMAND — so
|
|
540
|
+
# it sees the status of each line, not just of the node the pane finally runs.
|
|
541
|
+
# `&&` short-circuits to status 1 whenever the option is unset, which is the
|
|
542
|
+
# normal case for every option a session does not override, so each of these
|
|
543
|
+
# lines wrote itself into `pane_failures.log` as a dead pane:
|
|
544
|
+
#
|
|
545
|
+
# pane=13-IT/0 exit=1 command=[[ "None" != "None" ]] && args+=(-p "ut.foxglove.bit_rate:=None")
|
|
546
|
+
#
|
|
547
|
+
# A peer then reported `STARTUP CHECK FAILED ... 4 pane(s) exited` on every
|
|
548
|
+
# start while nothing was wrong, which is the one thing that check must not
|
|
549
|
+
# do: it exists to make a genuinely dead pane visible in seconds.
|
|
537
550
|
- name: IT
|
|
538
551
|
if: it
|
|
539
552
|
layout: even-vertical
|
|
@@ -542,15 +555,15 @@ windows:
|
|
|
542
555
|
- if [ '${it_1_topic}' = "None" ]; then exit; fi
|
|
543
556
|
- if [[ "${it_1_topic}" == *"/compressed"* ]]; then it_in_transport="compressed"; else it_in_transport="raw"; fi
|
|
544
557
|
- args=(ros2 run image_transport republish --ros-args -r __node:=republish1 -p in_transport:=${it_in_transport})
|
|
545
|
-
- '[[ "${it_1_transport}" != "None" ]]
|
|
546
|
-
- '[[ "${it_1_compressed_jpeg_quality}" != "None" ]]
|
|
547
|
-
- '[[ "${it_1_ffmpeg_gop_size}" != "None" ]]
|
|
548
|
-
- '[[ "${it_1_ffmpeg_encoder_av_options}" != "None" ]]
|
|
549
|
-
- '[[ "${it_1_ffmpeg_bit_rate}" != "None" ]]
|
|
550
|
-
- '[[ "${it_1_foxglove_gop_size}" != "None" ]]
|
|
551
|
-
- '[[ "${it_1_foxglove_encoder_av_options}" != "None" ]]
|
|
552
|
-
- '[[ "${it_1_foxglove_bit_rate}" != "None" ]]
|
|
553
|
-
- '[[ "${it_1_foxglove_qmax}" != "None" ]]
|
|
558
|
+
- 'if [[ "${it_1_transport}" != "None" ]]; then args+=(-p "out_transport:=${it_1_transport}"); fi'
|
|
559
|
+
- 'if [[ "${it_1_compressed_jpeg_quality}" != "None" ]]; then args+=(-p "ut.compressed.jpeg_quality:=${it_1_compressed_jpeg_quality}"); fi'
|
|
560
|
+
- 'if [[ "${it_1_ffmpeg_gop_size}" != "None" ]]; then args+=(-p "ut.ffmpeg.gop_size:=${it_1_ffmpeg_gop_size}"); fi'
|
|
561
|
+
- 'if [[ "${it_1_ffmpeg_encoder_av_options}" != "None" ]]; then args+=(-p "ut.ffmpeg.encoder_av_options:=${it_1_ffmpeg_encoder_av_options}"); fi'
|
|
562
|
+
- 'if [[ "${it_1_ffmpeg_bit_rate}" != "None" ]]; then args+=(-p "ut.ffmpeg.bit_rate:=${it_1_ffmpeg_bit_rate}"); fi'
|
|
563
|
+
- 'if [[ "${it_1_foxglove_gop_size}" != "None" ]]; then args+=(-p "ut.foxglove.gop_size:=${it_1_foxglove_gop_size}"); fi'
|
|
564
|
+
- 'if [[ "${it_1_foxglove_encoder_av_options}" != "None" ]]; then args+=(-p "ut.foxglove.encoder_av_options:=${it_1_foxglove_encoder_av_options}"); fi'
|
|
565
|
+
- 'if [[ "${it_1_foxglove_bit_rate}" != "None" ]]; then args+=(-p "ut.foxglove.bit_rate:=${it_1_foxglove_bit_rate}"); fi'
|
|
566
|
+
- 'if [[ "${it_1_foxglove_qmax}" != "None" ]]; then args+=(-p "ut.foxglove.qmax:=${it_1_foxglove_qmax}"); fi'
|
|
554
567
|
- if [[ "${it_1_outgoing_suffix}" != "None" ]]; then outgoing_suffix="${it_1_outgoing_suffix}"; else outgoing_suffix="${it_1_transport}"; fi
|
|
555
568
|
- if [[ "${it_in_transport}" == "raw" ]]; then in_remap="in"; else in_remap="in/${it_in_transport}"; fi
|
|
556
569
|
- args+=(--remap "${in_remap}:=${it_1_topic}" --remap "out/${it_1_transport}:=${it_1_topic}/${outgoing_suffix}")
|
|
@@ -560,15 +573,15 @@ windows:
|
|
|
560
573
|
- if [ '${it_2_topic}' = "None" ]; then exit; fi
|
|
561
574
|
- if [[ "${it_2_topic}" == *"/compressed"* ]]; then it_in_transport="compressed"; else it_in_transport="raw"; fi
|
|
562
575
|
- args=(ros2 run image_transport republish --ros-args -r __node:=republish2 -p in_transport:=${it_in_transport})
|
|
563
|
-
- '[[ "${it_2_transport}" != "None" ]]
|
|
564
|
-
- '[[ "${it_2_compressed_jpeg_quality}" != "None" ]]
|
|
565
|
-
- '[[ "${it_2_ffmpeg_gop_size}" != "None" ]]
|
|
566
|
-
- '[[ "${it_2_ffmpeg_encoder_av_options}" != "None" ]]
|
|
567
|
-
- '[[ "${it_2_ffmpeg_bit_rate}" != "None" ]]
|
|
568
|
-
- '[[ "${it_2_foxglove_gop_size}" != "None" ]]
|
|
569
|
-
- '[[ "${it_2_foxglove_encoder_av_options}" != "None" ]]
|
|
570
|
-
- '[[ "${it_2_foxglove_bit_rate}" != "None" ]]
|
|
571
|
-
- '[[ "${it_2_foxglove_qmax}" != "None" ]]
|
|
576
|
+
- 'if [[ "${it_2_transport}" != "None" ]]; then args+=(-p "out_transport:=${it_2_transport}"); fi'
|
|
577
|
+
- 'if [[ "${it_2_compressed_jpeg_quality}" != "None" ]]; then args+=(-p "ut.compressed.jpeg_quality:=${it_2_compressed_jpeg_quality}"); fi'
|
|
578
|
+
- 'if [[ "${it_2_ffmpeg_gop_size}" != "None" ]]; then args+=(-p "ut.ffmpeg.gop_size:=${it_2_ffmpeg_gop_size}"); fi'
|
|
579
|
+
- 'if [[ "${it_2_ffmpeg_encoder_av_options}" != "None" ]]; then args+=(-p "ut.ffmpeg.encoder_av_options:=${it_2_ffmpeg_encoder_av_options}"); fi'
|
|
580
|
+
- 'if [[ "${it_2_ffmpeg_bit_rate}" != "None" ]]; then args+=(-p "ut.ffmpeg.bit_rate:=${it_2_ffmpeg_bit_rate}"); fi'
|
|
581
|
+
- 'if [[ "${it_2_foxglove_gop_size}" != "None" ]]; then args+=(-p "ut.foxglove.gop_size:=${it_2_foxglove_gop_size}"); fi'
|
|
582
|
+
- 'if [[ "${it_2_foxglove_encoder_av_options}" != "None" ]]; then args+=(-p "ut.foxglove.encoder_av_options:=${it_2_foxglove_encoder_av_options}"); fi'
|
|
583
|
+
- 'if [[ "${it_2_foxglove_bit_rate}" != "None" ]]; then args+=(-p "ut.foxglove.bit_rate:=${it_2_foxglove_bit_rate}"); fi'
|
|
584
|
+
- 'if [[ "${it_2_foxglove_qmax}" != "None" ]]; then args+=(-p "ut.foxglove.qmax:=${it_2_foxglove_qmax}"); fi'
|
|
572
585
|
- if [[ "${it_2_outgoing_suffix}" != "None" ]]; then outgoing_suffix="${it_2_outgoing_suffix}"; else outgoing_suffix="${it_2_transport}"; fi
|
|
573
586
|
- if [[ "${it_in_transport}" == "raw" ]]; then in_remap="in"; else in_remap="in/${it_in_transport}"; fi
|
|
574
587
|
- args+=(--remap "${in_remap}:=${it_2_topic}" --remap "out/${it_2_transport}:=${it_2_topic}/${outgoing_suffix}")
|
|
@@ -578,15 +591,15 @@ windows:
|
|
|
578
591
|
- if [ '${it_3_topic}' = "None" ]; then exit; fi
|
|
579
592
|
- if [[ "${it_3_topic}" == *"/compressed"* ]]; then it_in_transport="compressed"; else it_in_transport="raw"; fi
|
|
580
593
|
- args=(ros2 run image_transport republish --ros-args -r __node:=republish3 -p in_transport:=${it_in_transport})
|
|
581
|
-
- '[[ "${it_3_transport}" != "None" ]]
|
|
582
|
-
- '[[ "${it_3_compressed_jpeg_quality}" != "None" ]]
|
|
583
|
-
- '[[ "${it_3_ffmpeg_gop_size}" != "None" ]]
|
|
584
|
-
- '[[ "${it_3_ffmpeg_encoder_av_options}" != "None" ]]
|
|
585
|
-
- '[[ "${it_3_ffmpeg_bit_rate}" != "None" ]]
|
|
586
|
-
- '[[ "${it_3_foxglove_gop_size}" != "None" ]]
|
|
587
|
-
- '[[ "${it_3_foxglove_encoder_av_options}" != "None" ]]
|
|
588
|
-
- '[[ "${it_3_foxglove_bit_rate}" != "None" ]]
|
|
589
|
-
- '[[ "${it_3_foxglove_qmax}" != "None" ]]
|
|
594
|
+
- 'if [[ "${it_3_transport}" != "None" ]]; then args+=(-p "out_transport:=${it_3_transport}"); fi'
|
|
595
|
+
- 'if [[ "${it_3_compressed_jpeg_quality}" != "None" ]]; then args+=(-p "ut.compressed.jpeg_quality:=${it_3_compressed_jpeg_quality}"); fi'
|
|
596
|
+
- 'if [[ "${it_3_ffmpeg_gop_size}" != "None" ]]; then args+=(-p "ut.ffmpeg.gop_size:=${it_3_ffmpeg_gop_size}"); fi'
|
|
597
|
+
- 'if [[ "${it_3_ffmpeg_encoder_av_options}" != "None" ]]; then args+=(-p "ut.ffmpeg.encoder_av_options:=${it_3_ffmpeg_encoder_av_options}"); fi'
|
|
598
|
+
- 'if [[ "${it_3_ffmpeg_bit_rate}" != "None" ]]; then args+=(-p "ut.ffmpeg.bit_rate:=${it_3_ffmpeg_bit_rate}"); fi'
|
|
599
|
+
- 'if [[ "${it_3_foxglove_gop_size}" != "None" ]]; then args+=(-p "ut.foxglove.gop_size:=${it_3_foxglove_gop_size}"); fi'
|
|
600
|
+
- 'if [[ "${it_3_foxglove_encoder_av_options}" != "None" ]]; then args+=(-p "ut.foxglove.encoder_av_options:=${it_3_foxglove_encoder_av_options}"); fi'
|
|
601
|
+
- 'if [[ "${it_3_foxglove_bit_rate}" != "None" ]]; then args+=(-p "ut.foxglove.bit_rate:=${it_3_foxglove_bit_rate}"); fi'
|
|
602
|
+
- 'if [[ "${it_3_foxglove_qmax}" != "None" ]]; then args+=(-p "ut.foxglove.qmax:=${it_3_foxglove_qmax}"); fi'
|
|
590
603
|
- if [[ "${it_3_outgoing_suffix}" != "None" ]]; then outgoing_suffix="${it_3_outgoing_suffix}"; else outgoing_suffix="${it_3_transport}"; fi
|
|
591
604
|
- if [[ "${it_in_transport}" == "raw" ]]; then in_remap="in"; else in_remap="in/${it_in_transport}"; fi
|
|
592
605
|
- args+=(--remap "${in_remap}:=${it_3_topic}" --remap "out/${it_3_transport}:=${it_3_topic}/${outgoing_suffix}")
|
|
@@ -596,15 +609,15 @@ windows:
|
|
|
596
609
|
- if [ '${it_4_topic}' = "None" ]; then exit; fi
|
|
597
610
|
- if [[ "${it_4_topic}" == *"/compressed"* ]]; then it_in_transport="compressed"; else it_in_transport="raw"; fi
|
|
598
611
|
- args=(ros2 run image_transport republish --ros-args -r __node:=republish4 -p in_transport:=${it_in_transport})
|
|
599
|
-
- '[[ "${it_4_transport}" != "None" ]]
|
|
600
|
-
- '[[ "${it_4_compressed_jpeg_quality}" != "None" ]]
|
|
601
|
-
- '[[ "${it_4_ffmpeg_gop_size}" != "None" ]]
|
|
602
|
-
- '[[ "${it_4_ffmpeg_encoder_av_options}" != "None" ]]
|
|
603
|
-
- '[[ "${it_4_ffmpeg_bit_rate}" != "None" ]]
|
|
604
|
-
- '[[ "${it_4_foxglove_gop_size}" != "None" ]]
|
|
605
|
-
- '[[ "${it_4_foxglove_encoder_av_options}" != "None" ]]
|
|
606
|
-
- '[[ "${it_4_foxglove_bit_rate}" != "None" ]]
|
|
607
|
-
- '[[ "${it_4_foxglove_qmax}" != "None" ]]
|
|
612
|
+
- 'if [[ "${it_4_transport}" != "None" ]]; then args+=(-p "out_transport:=${it_4_transport}"); fi'
|
|
613
|
+
- 'if [[ "${it_4_compressed_jpeg_quality}" != "None" ]]; then args+=(-p "ut.compressed.jpeg_quality:=${it_4_compressed_jpeg_quality}"); fi'
|
|
614
|
+
- 'if [[ "${it_4_ffmpeg_gop_size}" != "None" ]]; then args+=(-p "ut.ffmpeg.gop_size:=${it_4_ffmpeg_gop_size}"); fi'
|
|
615
|
+
- 'if [[ "${it_4_ffmpeg_encoder_av_options}" != "None" ]]; then args+=(-p "ut.ffmpeg.encoder_av_options:=${it_4_ffmpeg_encoder_av_options}"); fi'
|
|
616
|
+
- 'if [[ "${it_4_ffmpeg_bit_rate}" != "None" ]]; then args+=(-p "ut.ffmpeg.bit_rate:=${it_4_ffmpeg_bit_rate}"); fi'
|
|
617
|
+
- 'if [[ "${it_4_foxglove_gop_size}" != "None" ]]; then args+=(-p "ut.foxglove.gop_size:=${it_4_foxglove_gop_size}"); fi'
|
|
618
|
+
- 'if [[ "${it_4_foxglove_encoder_av_options}" != "None" ]]; then args+=(-p "ut.foxglove.encoder_av_options:=${it_4_foxglove_encoder_av_options}"); fi'
|
|
619
|
+
- 'if [[ "${it_4_foxglove_bit_rate}" != "None" ]]; then args+=(-p "ut.foxglove.bit_rate:=${it_4_foxglove_bit_rate}"); fi'
|
|
620
|
+
- 'if [[ "${it_4_foxglove_qmax}" != "None" ]]; then args+=(-p "ut.foxglove.qmax:=${it_4_foxglove_qmax}"); fi'
|
|
608
621
|
- if [[ "${it_4_outgoing_suffix}" != "None" ]]; then outgoing_suffix="${it_4_outgoing_suffix}"; else outgoing_suffix="${it_4_transport}"; fi
|
|
609
622
|
- if [[ "${it_in_transport}" == "raw" ]]; then in_remap="in"; else in_remap="in/${it_in_transport}"; fi
|
|
610
623
|
- args+=(--remap "${in_remap}:=${it_4_topic}" --remap "out/${it_4_transport}:=${it_4_topic}/${outgoing_suffix}")
|
|
@@ -337,6 +337,8 @@ tests/unit/test_ota_unwrapper.py
|
|
|
337
337
|
tests/unit/test_ota_wrapper.py
|
|
338
338
|
tests/unit/test_ota_xml.py
|
|
339
339
|
tests/unit/test_plots.py
|
|
340
|
+
tests/unit/test_qos_fallback_logging.py
|
|
341
|
+
tests/unit/test_relay_optional_parameters.py
|
|
340
342
|
tests/unit/test_session_pipeline.py
|
|
341
343
|
tests/unit/test_stage_latency.py
|
|
342
344
|
tests/unit/test_status_eval.py
|
{rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/src/rosotacom_dev.egg-info/scm_file_list.json
RENAMED
|
@@ -332,6 +332,8 @@
|
|
|
332
332
|
"tests/unit/test_ota_wrapper.py",
|
|
333
333
|
"tests/unit/test_ota_xml.py",
|
|
334
334
|
"tests/unit/test_plots.py",
|
|
335
|
+
"tests/unit/test_qos_fallback_logging.py",
|
|
336
|
+
"tests/unit/test_relay_optional_parameters.py",
|
|
335
337
|
"tests/unit/test_session_pipeline.py",
|
|
336
338
|
"tests/unit/test_stage_latency.py",
|
|
337
339
|
"tests/unit/test_status_eval.py",
|
|
@@ -111,3 +111,77 @@ def test_the_hook_is_installed_once_even_if_sourced_twice(pane_env: tuple[Path,
|
|
|
111
111
|
|
|
112
112
|
(line,) = [ln for ln in result.stdout.splitlines() if ln.startswith("PC=")]
|
|
113
113
|
assert line.count("__rosotacom_note_exit") == 1
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
# What the recorder cannot know, and why the session template has to care.
|
|
117
|
+
#
|
|
118
|
+
# The hook runs from PROMPT_COMMAND, so it sees every line a pane shell runs --
|
|
119
|
+
# including the lines that only assemble an argument list before the node
|
|
120
|
+
# starts. A line of the form `[[ cond ]] && args+=(...)` exits 1 whenever the
|
|
121
|
+
# condition is false, which is the normal case for every option a session leaves
|
|
122
|
+
# unset, so each one recorded itself as a dead pane. A peer then reported four
|
|
123
|
+
# exited panes at every start while nothing was wrong.
|
|
124
|
+
|
|
125
|
+
_UNSET_OPTION = '[[ "None" != "None" ]]'
|
|
126
|
+
_SET_OPTION = '[[ "22" != "None" ]]'
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def _failure_log(catmux_dir: Path) -> Path:
|
|
130
|
+
return catmux_dir.parent / "pane_failures.log"
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def test_the_short_circuit_form_records_a_false_failure(pane_env: tuple[Path, dict[str, str]]) -> None:
|
|
134
|
+
"""The shape that was in the template: correct behaviour, status 1."""
|
|
135
|
+
catmux_dir, env = pane_env
|
|
136
|
+
|
|
137
|
+
_run(f'args=(); {_UNSET_OPTION} && args+=(-p "bit_rate:=None")', env)
|
|
138
|
+
|
|
139
|
+
assert _failure_log(catmux_dir).is_file()
|
|
140
|
+
assert "exit=1" in _failure_log(catmux_dir).read_text(encoding="utf-8")
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def test_the_if_form_leaves_an_unset_option_silent(pane_env: tuple[Path, dict[str, str]]) -> None:
|
|
144
|
+
"""The shape it was replaced with: same behaviour, status 0."""
|
|
145
|
+
catmux_dir, env = pane_env
|
|
146
|
+
|
|
147
|
+
_run(f'args=(); if {_UNSET_OPTION}; then args+=(-p "bit_rate:=None"); fi', env)
|
|
148
|
+
|
|
149
|
+
assert not _failure_log(catmux_dir).exists()
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def test_the_if_form_still_appends_a_set_option(pane_env: tuple[Path, dict[str, str]]) -> None:
|
|
153
|
+
"""Silencing the status must not silence the argument."""
|
|
154
|
+
catmux_dir, env = pane_env
|
|
155
|
+
|
|
156
|
+
result = _run(
|
|
157
|
+
f'args=(); if {_SET_OPTION}; then args+=(-p "bit_rate:=22"); fi\necho "ARGS=${{args[*]}}"',
|
|
158
|
+
env,
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
assert "ARGS=-p bit_rate:=22" in result.stdout
|
|
162
|
+
assert not _failure_log(catmux_dir).exists()
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def test_no_session_template_line_uses_the_short_circuit_form() -> None:
|
|
166
|
+
"""The template is where this reaches a running session, so it is checked there."""
|
|
167
|
+
template = (
|
|
168
|
+
REPO_ROOT
|
|
169
|
+
/ "src"
|
|
170
|
+
/ "rosotacom"
|
|
171
|
+
/ "resources"
|
|
172
|
+
/ "ws"
|
|
173
|
+
/ "session"
|
|
174
|
+
/ "content"
|
|
175
|
+
/ "base"
|
|
176
|
+
/ "session_plugin_base.yaml"
|
|
177
|
+
)
|
|
178
|
+
offenders = [
|
|
179
|
+
line.strip()
|
|
180
|
+
for line in template.read_text(encoding="utf-8").splitlines()
|
|
181
|
+
if line.lstrip().startswith("- '[[") and "&&" in line
|
|
182
|
+
]
|
|
183
|
+
|
|
184
|
+
assert offenders == [], (
|
|
185
|
+
"these lines exit non-zero when their option is unset and land in "
|
|
186
|
+
f"pane_failures.log; use `if ...; then ...; fi`: {offenders}"
|
|
187
|
+
)
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"""At which level `get_topic_qos` reports a base-topic fallback.
|
|
2
|
+
|
|
3
|
+
A session declares QoS on the base topic (`/tf_static`), and every processing
|
|
4
|
+
stage appends a suffix to the name that is actually published
|
|
5
|
+
(`/tf_static/globalframe`). Resolving the suffixed name through its base is
|
|
6
|
+
therefore the designed path, not a degradation — and it was logged as a warning,
|
|
7
|
+
twice per topic per peer, at every bring-up. That is the noise a real message has
|
|
8
|
+
to compete with while a peer is starting, which is exactly when somebody is
|
|
9
|
+
reading the pane.
|
|
10
|
+
|
|
11
|
+
The module imports rclpy, which the host suite does not have, so its ROS surface
|
|
12
|
+
is stubbed before the module is loaded by file path (same approach as
|
|
13
|
+
`tests/unit/test_ota_unwrapper.py`).
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import importlib.util
|
|
19
|
+
import sys
|
|
20
|
+
from collections.abc import Iterator
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
from types import ModuleType
|
|
23
|
+
|
|
24
|
+
import pytest
|
|
25
|
+
|
|
26
|
+
REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
27
|
+
QOS_PY = REPO_ROOT / "src" / "rosotacom" / "resources" / "ws" / "ros2src" / "com_py" / "com_py" / "qos.py"
|
|
28
|
+
|
|
29
|
+
_STUBBED = ("rclpy", "rclpy.node", "rclpy.qos", "rclpy.duration", "rosidl_runtime_py", "rosidl_runtime_py.utilities")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class _QoSProfile:
|
|
33
|
+
def __init__(self, depth: int = 10) -> None:
|
|
34
|
+
self.depth = depth
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class _Policy:
|
|
38
|
+
BEST_EFFORT = "best_effort"
|
|
39
|
+
RELIABLE = "reliable"
|
|
40
|
+
KEEP_ALL = "keep_all"
|
|
41
|
+
KEEP_LAST = "keep_last"
|
|
42
|
+
TRANSIENT_LOCAL = "transient_local"
|
|
43
|
+
VOLATILE = "volatile"
|
|
44
|
+
AUTOMATIC = "automatic"
|
|
45
|
+
MANUAL_BY_TOPIC = "manual_by_topic"
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _stub_module(name: str, **attrs: object) -> ModuleType:
|
|
49
|
+
module = ModuleType(name)
|
|
50
|
+
for key, value in attrs.items():
|
|
51
|
+
setattr(module, key, value)
|
|
52
|
+
sys.modules[name] = module
|
|
53
|
+
return module
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class _RecordingLogger:
|
|
57
|
+
"""Counts what was said and at which level."""
|
|
58
|
+
|
|
59
|
+
def __init__(self) -> None:
|
|
60
|
+
self.warnings: list[str] = []
|
|
61
|
+
self.debugs: list[str] = []
|
|
62
|
+
|
|
63
|
+
def warning(self, message: str) -> None:
|
|
64
|
+
self.warnings.append(message)
|
|
65
|
+
|
|
66
|
+
def debug(self, message: str) -> None:
|
|
67
|
+
self.debugs.append(message)
|
|
68
|
+
|
|
69
|
+
def info(self, message: str) -> None:
|
|
70
|
+
pass
|
|
71
|
+
|
|
72
|
+
def error(self, message: str) -> None:
|
|
73
|
+
pass
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@pytest.fixture(scope="module")
|
|
77
|
+
def qos_module() -> Iterator[ModuleType]:
|
|
78
|
+
saved = {name: sys.modules.get(name) for name in _STUBBED}
|
|
79
|
+
_stub_module("rclpy")
|
|
80
|
+
_stub_module("rclpy.node", Node=object)
|
|
81
|
+
_stub_module(
|
|
82
|
+
"rclpy.qos",
|
|
83
|
+
QoSProfile=_QoSProfile,
|
|
84
|
+
ReliabilityPolicy=_Policy,
|
|
85
|
+
HistoryPolicy=_Policy,
|
|
86
|
+
DurabilityPolicy=_Policy,
|
|
87
|
+
LivelinessPolicy=_Policy,
|
|
88
|
+
)
|
|
89
|
+
_stub_module("rclpy.duration", Duration=lambda **kwargs: kwargs)
|
|
90
|
+
_stub_module("rosidl_runtime_py", utilities=None)
|
|
91
|
+
_stub_module("rosidl_runtime_py.utilities", get_message=lambda type_str: None)
|
|
92
|
+
|
|
93
|
+
spec = importlib.util.spec_from_file_location("rosotacom_qos_fallback", QOS_PY)
|
|
94
|
+
assert spec and spec.loader
|
|
95
|
+
module = importlib.util.module_from_spec(spec)
|
|
96
|
+
sys.modules["rosotacom_qos_fallback"] = module
|
|
97
|
+
spec.loader.exec_module(module)
|
|
98
|
+
yield module
|
|
99
|
+
|
|
100
|
+
sys.modules.pop("rosotacom_qos_fallback", None)
|
|
101
|
+
for name, previous in saved.items():
|
|
102
|
+
if previous is None:
|
|
103
|
+
sys.modules.pop(name, None)
|
|
104
|
+
else:
|
|
105
|
+
sys.modules[name] = previous
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
CONFIG = {
|
|
109
|
+
"default": {"depth": 10},
|
|
110
|
+
"topics": {"/tf_static": {"reliability": "reliable", "durability": "transient_local"}},
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def test_a_processed_name_resolves_through_its_base_without_warning(qos_module: ModuleType) -> None:
|
|
115
|
+
logger = _RecordingLogger()
|
|
116
|
+
|
|
117
|
+
qos_module.get_topic_qos(logger, CONFIG, "/tf_static/globalframe", "ota_pub")
|
|
118
|
+
|
|
119
|
+
assert logger.warnings == []
|
|
120
|
+
assert any("Falling back to base topic='/tf_static'" in line for line in logger.debugs)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def test_the_fallback_still_delivers_the_base_topic_settings(qos_module: ModuleType) -> None:
|
|
124
|
+
"""Quiet must not mean ignored: the resolved profile is the base topic's."""
|
|
125
|
+
logger = _RecordingLogger()
|
|
126
|
+
|
|
127
|
+
profile = qos_module.get_topic_qos(logger, CONFIG, "/tf_static/globalframe", "ota_pub")
|
|
128
|
+
|
|
129
|
+
assert profile.reliability == _Policy.RELIABLE
|
|
130
|
+
assert profile.durability == _Policy.TRANSIENT_LOCAL
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def test_an_exact_match_says_nothing_at_all(qos_module: ModuleType) -> None:
|
|
134
|
+
logger = _RecordingLogger()
|
|
135
|
+
|
|
136
|
+
qos_module.get_topic_qos(logger, CONFIG, "/tf_static", "ota_pub")
|
|
137
|
+
|
|
138
|
+
assert logger.warnings == []
|
|
139
|
+
assert not any("Falling back" in line for line in logger.debugs)
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"""Optional relay parameters must read as empty, not as unset.
|
|
2
|
+
|
|
3
|
+
`source_names` and `target_names` are optional: a peer that names no sources
|
|
4
|
+
simply has none. They were declared with a type and no value, which leaves them
|
|
5
|
+
PARAMETER_NOT_SET. The node itself never noticed, because it reads them once
|
|
6
|
+
through `.value or []`. Every *other* reader did: reading a not-set parameter
|
|
7
|
+
raises, and rclpy's parameter service logs one warning per read against the
|
|
8
|
+
node, so anything that enumerates parameters on a timer — a Foxglove bridge with
|
|
9
|
+
a parameter panel open is the usual one — filled the pane with
|
|
10
|
+
|
|
11
|
+
[WARN] [ota_relay_out]: Failed to get parameters: The parameter
|
|
12
|
+
'source_names' is not initialized: source_names
|
|
13
|
+
|
|
14
|
+
An empty list cannot be a plain default: `declare_parameter(name, [])` infers
|
|
15
|
+
the type from the value and an empty sequence satisfies the BYTE_ARRAY test
|
|
16
|
+
first, so the parameter ends up typed BYTE_ARRAY and a real string array is
|
|
17
|
+
refused later. The fakes below reproduce that rclpy behaviour, which was
|
|
18
|
+
confirmed against a live rclpy node before this was written.
|
|
19
|
+
|
|
20
|
+
rclpy is not available to the host suite, so the ROS surface is stubbed and the
|
|
21
|
+
module is loaded by file path (same approach as `tests/unit/test_ota_unwrapper.py`).
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
from __future__ import annotations
|
|
25
|
+
|
|
26
|
+
import importlib.util
|
|
27
|
+
import sys
|
|
28
|
+
from collections.abc import Iterator
|
|
29
|
+
from pathlib import Path
|
|
30
|
+
from types import ModuleType
|
|
31
|
+
|
|
32
|
+
import pytest
|
|
33
|
+
|
|
34
|
+
REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
35
|
+
COM_PY = REPO_ROOT / "src" / "rosotacom" / "resources" / "ws" / "ros2src" / "com_py" / "com_py"
|
|
36
|
+
RELAY_PY = COM_PY / "base_bridge_relay.py"
|
|
37
|
+
|
|
38
|
+
_STUBBED = (
|
|
39
|
+
"rclpy",
|
|
40
|
+
"rclpy.node",
|
|
41
|
+
"com_py",
|
|
42
|
+
"com_py.topic_resolution",
|
|
43
|
+
"com_py.qos",
|
|
44
|
+
"com_py.pub_sub_pair",
|
|
45
|
+
"com_py.pair_management",
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class _Type:
|
|
50
|
+
NOT_SET = "not_set"
|
|
51
|
+
STRING_ARRAY = "string_array"
|
|
52
|
+
STRING = "string"
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class _Parameter:
|
|
56
|
+
Type = _Type
|
|
57
|
+
|
|
58
|
+
def __init__(self, name: str, type_: str = _Type.NOT_SET, value: object = None) -> None:
|
|
59
|
+
self.name = name
|
|
60
|
+
self.type_ = type_
|
|
61
|
+
self.value = value
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class _FakeNode:
|
|
65
|
+
"""rclpy's declare/get/set semantics, only as far as this method uses them."""
|
|
66
|
+
|
|
67
|
+
def __init__(self, overrides: dict[str, list[str]] | None = None) -> None:
|
|
68
|
+
self._overrides = overrides or {}
|
|
69
|
+
self._parameters: dict[str, _Parameter] = {}
|
|
70
|
+
self.set_calls: list[tuple[str, str, object]] = []
|
|
71
|
+
|
|
72
|
+
def declare_parameter(self, name: str, type_: str) -> _Parameter:
|
|
73
|
+
if name in self._overrides:
|
|
74
|
+
parameter = _Parameter(name, type_, self._overrides[name])
|
|
75
|
+
else:
|
|
76
|
+
parameter = _Parameter(name, _Type.NOT_SET, None)
|
|
77
|
+
self._parameters[name] = parameter
|
|
78
|
+
return parameter
|
|
79
|
+
|
|
80
|
+
def get_parameter_or(self, name: str) -> _Parameter:
|
|
81
|
+
return self._parameters.get(name, _Parameter(name))
|
|
82
|
+
|
|
83
|
+
def get_parameter(self, name: str) -> _Parameter:
|
|
84
|
+
parameter = self._parameters[name]
|
|
85
|
+
if parameter.type_ == _Type.NOT_SET:
|
|
86
|
+
raise RuntimeError(f"The parameter '{name}' is not initialized: {name}")
|
|
87
|
+
return parameter
|
|
88
|
+
|
|
89
|
+
def set_parameters(self, parameters: list[_Parameter]) -> None:
|
|
90
|
+
for parameter in parameters:
|
|
91
|
+
self.set_calls.append((parameter.name, parameter.type_, parameter.value))
|
|
92
|
+
self._parameters[parameter.name] = parameter
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _stub_module(name: str, **attrs: object) -> ModuleType:
|
|
96
|
+
module = ModuleType(name)
|
|
97
|
+
for key, value in attrs.items():
|
|
98
|
+
setattr(module, key, value)
|
|
99
|
+
sys.modules[name] = module
|
|
100
|
+
return module
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
@pytest.fixture(scope="module")
|
|
104
|
+
def relay_module() -> Iterator[ModuleType]:
|
|
105
|
+
saved = {name: sys.modules.get(name) for name in _STUBBED}
|
|
106
|
+
_stub_module("rclpy", Parameter=_Parameter)
|
|
107
|
+
# Distinct classes: `BaseBridgeRelay(Node, PairRefreshMixin)` cannot be built
|
|
108
|
+
# from one base twice.
|
|
109
|
+
_stub_module("rclpy.node", Node=type("Node", (), {}))
|
|
110
|
+
_stub_module("com_py")
|
|
111
|
+
_stub_module("com_py.topic_resolution", resolve_topics=lambda *a, **k: [])
|
|
112
|
+
_stub_module("com_py.qos", load_qos_config=lambda *a, **k: {})
|
|
113
|
+
_stub_module("com_py.pub_sub_pair", PubSubPair=type("PubSubPair", (), {}))
|
|
114
|
+
_stub_module("com_py.pair_management", PairRefreshMixin=type("PairRefreshMixin", (), {}))
|
|
115
|
+
|
|
116
|
+
spec = importlib.util.spec_from_file_location("rosotacom_base_bridge_relay", RELAY_PY)
|
|
117
|
+
assert spec and spec.loader
|
|
118
|
+
module = importlib.util.module_from_spec(spec)
|
|
119
|
+
sys.modules["rosotacom_base_bridge_relay"] = module
|
|
120
|
+
spec.loader.exec_module(module)
|
|
121
|
+
yield module
|
|
122
|
+
|
|
123
|
+
sys.modules.pop("rosotacom_base_bridge_relay", None)
|
|
124
|
+
for name, previous in saved.items():
|
|
125
|
+
if previous is None:
|
|
126
|
+
sys.modules.pop(name, None)
|
|
127
|
+
else:
|
|
128
|
+
sys.modules[name] = previous
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def _declare(module: ModuleType, node: _FakeNode, name: str = "source_names") -> object:
|
|
132
|
+
"""The method under test, unbound — the surrounding __init__ needs a live ROS graph."""
|
|
133
|
+
return module.BaseBridgeRelay.declare_optional_string_array(node, name)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def test_an_unsupplied_parameter_becomes_an_empty_string_array(relay_module: ModuleType) -> None:
|
|
137
|
+
node = _FakeNode()
|
|
138
|
+
|
|
139
|
+
value = _declare(relay_module, node)
|
|
140
|
+
|
|
141
|
+
assert value == []
|
|
142
|
+
assert node.set_calls == [("source_names", _Type.STRING_ARRAY, [])]
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def test_the_parameter_is_readable_afterwards(relay_module: ModuleType) -> None:
|
|
146
|
+
"""The whole point: a read no longer raises, so nothing logs a warning."""
|
|
147
|
+
node = _FakeNode()
|
|
148
|
+
|
|
149
|
+
_declare(relay_module, node)
|
|
150
|
+
|
|
151
|
+
assert node.get_parameter("source_names").value == []
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def test_supplied_names_are_left_alone(relay_module: ModuleType) -> None:
|
|
155
|
+
node = _FakeNode(overrides={"source_names": ["center", "vehicle"]})
|
|
156
|
+
|
|
157
|
+
value = _declare(relay_module, node)
|
|
158
|
+
|
|
159
|
+
assert value == ["center", "vehicle"]
|
|
160
|
+
assert node.set_calls == [], "an override must not be overwritten by the default"
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def test_it_stays_a_string_array(relay_module: ModuleType) -> None:
|
|
164
|
+
"""Not BYTE_ARRAY, which is what a plain `[]` default would have inferred."""
|
|
165
|
+
node = _FakeNode()
|
|
166
|
+
|
|
167
|
+
_declare(relay_module, node)
|
|
168
|
+
|
|
169
|
+
assert node.get_parameter("source_names").type_ == _Type.STRING_ARRAY
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def test_both_optional_parameters_use_it(relay_module: ModuleType) -> None:
|
|
173
|
+
source = RELAY_PY.read_text(encoding="utf-8")
|
|
174
|
+
|
|
175
|
+
for name in ("source_names", "target_names"):
|
|
176
|
+
assert f"self.declare_optional_string_array('{name}')" in source
|
{rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.devcontainer/devcontainer.json.template
RENAMED
|
File without changes
|
{rosotacom_dev-2.5.dev38 → rosotacom_dev-2.5.dev39}/.devcontainer/re_generate_devcontainer_json.py
RENAMED
|
File without changes
|