Skip to content

feat(recorder): support ROS topic QoS configuration#138

Merged
Nauyix merged 5 commits into
mainfrom
feature/recorder-ros-topic-qos-config
Jun 9, 2026
Merged

feat(recorder): support ROS topic QoS configuration#138
Nauyix merged 5 commits into
mainfrom
feature/recorder-ros-topic-qos-config

Conversation

@Nauyix

@Nauyix Nauyix commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Pull Request Checklist

Please ensure your PR meets the following requirements:

  • Code follows the style guidelines
  • Tests pass locally (make test or make docker-test)
  • Code is formatted (make format)
  • Documentation updated if needed
  • Commit messages follow conventional commits
  • PR description is complete and clear

Summary

Adds per-topic ROS QoS configuration to axon recorder, including blank-field fallback behavior and ROS 2 auto QoS resolution from discovered publishers. Also extends the local Docker mirror strategy to ROS/C++/Zenoh test images and local CI scripts to avoid slow upstream apt/LLVM downloads.


Motivation

  • Recorder subscriptions need to match publisher QoS for ROS 2 topics such as camera, IMU, and sensor streams.
  • Users should be able to leave QoS fields blank and keep the existing defaults.
  • Local CI Docker builds were blocked by very slow direct upstream apt/LLVM downloads in this environment.

Changes

Modified Files

  • apps/axon_recorder/src/config/config_parser.cpp - Parses nested qos blocks, preserves blank/default fallback, validates supported policy values, and saves QoS overrides.
  • apps/axon_recorder/src/config/task_config.hpp - Adds task and subscription QoS data structures.
  • apps/axon_recorder/src/core/recorder.cpp - Propagates task-scoped topic QoS into recorder subscriptions and runtime payloads.
  • apps/axon_recorder/src/http/rpc_handlers.cpp - Accepts topic QoS through RPC config payloads and returns QoS in state payloads.
  • apps/axon_recorder/src/http/event_broadcaster.cpp - Includes topic QoS in config/state events.
  • apps/axon_recorder/src/http/ws_rpc_client.cpp - Preserves QoS fields through WebSocket RPC config handling.
  • middlewares/ros2/src/ros2_subscription_wrapper.cpp - Resolves auto QoS policies from publisher endpoint information with default fallbacks.
  • middlewares/ros2/src/ros2_plugin_export.cpp - Passes subscription QoS options through the plugin boundary.
  • middlewares/ros2/include/ros2_subscription_wrapper.hpp - Extends ROS 2 subscription options for QoS policy overrides.
  • apps/axon_recorder/config/default_config_ros2.yaml - Enables qos.mode: auto in ROS 2 template subscriptions.
  • apps/axon_recorder/config/default_config_hybrid.yaml - Enables qos.mode: auto for the ROS 2 hybrid sample topic.
  • apps/axon_recorder/config/README.md - Documents nested QoS fields, auto, and blank default fallback.
  • docs/designs/rpc-api-design.md - Documents RPC topic QoS payloads.
  • docker/Dockerfile.ros1 - Applies configurable apt/ROS/LLVM mirror setup.
  • docker/Dockerfile.ros2.humble - Applies configurable apt/ROS/LLVM mirror setup.
  • docker/Dockerfile.ros2.jazzy - Applies configurable apt/ROS/LLVM mirror setup.
  • docker/Dockerfile.ros2.rolling - Applies configurable apt/ROS/LLVM mirror setup.
  • docker/Dockerfile.cpp-test - Applies configurable apt/LLVM mirror setup.
  • docker/Dockerfile.zenoh - Applies configurable apt mirror setup.
  • docker/scripts/setup-apt-mirror.sh - Adds Tsinghua/TUNA LLVM mirror support.
  • scripts/ci-docker-zenoh.sh - Uses mirror build args, host networking, and an isolated Zenoh build directory.
  • scripts/docker-test-cpp.sh - Uses shared mirror selection and host-network Docker builds.
  • scripts/docker-test-ros.sh - Uses shared mirror selection and host-network Docker builds.
  • scripts/docker-test-e2e.sh - Uses shared mirror selection and host-network Docker builds.

Added Files

  • scripts/docker-apt-mirror-common.sh - Shared local Docker mirror selection helper with AXON_APT_MIRROR=auto defaulting to the Tsinghua/TUNA mirror when appropriate.

Deleted Files

None.


Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update (documentation changes only)
  • Refactoring (code improvement without functional changes)
  • Performance improvement (code changes that improve performance)
  • Test changes (adding, modifying, or removing tests)

Impact Analysis

Breaking Changes

None.

Backward Compatibility

Fully backward compatible. Existing qos_depth continues to work, omitted or blank nested QoS fields fall back to the existing defaults, and explicit QoS overrides are optional.


Testing

Test Environment

  • Tested head SHA: d9276d81719fc1176da673f94ca3bdf4baf2386f
  • Base: origin/main at merge-base 48fc72b1f574d4eb1644f09dce473194ad515c89
  • ROS Distribution: ROS 1 Noetic, ROS 2 Humble, ROS 2 Jazzy
  • OS: Linux host with Docker test containers
  • Build Type: local CI defaults plus Release for WS RPC client E2E

Test Cases

  • Unit tests pass locally
  • Integration tests pass locally
  • E2E tests pass (if applicable)
  • Manual testing completed

Manual Testing Steps

  1. Ran the full local CI gate from a clean detached worktree:
    AXON_APT_MIRROR=tsinghua ./scripts/ci-all-local.sh
    Result: passed in 28m 30s, including format, REUSE, C++ unit tests, Zenoh plugin tests, C++ integration, ROS tests, and E2E tests for noetic/humble/jazzy.
  2. Ran the WS RPC client E2E workflow commands not covered by ci-all-local.sh:
    python3 -m venv .venv-ws-e2e
    .venv-ws-e2e/bin/python -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple websockets
    make app-axon-recorder BUILD_TYPE=Release
    make build-mock BUILD_TYPE=Release
    cd apps/axon_recorder/test
    chmod +x e2e/test_ws_rpc_client_e2e.py mock_keystone_server.py
    ../../../.venv-ws-e2e/bin/python e2e/test_ws_rpc_client_e2e.py
    Result: passed.
  3. Validated Docker image build paths affected by the mirror changes:
    docker build --network=host --build-arg AXON_APT_MIRROR=tsinghua -f docker/Dockerfile.ros1 -t axon:test-noetic .
    docker build --network=host --build-arg AXON_APT_MIRROR=tsinghua -f docker/Dockerfile.ros2.humble -t axon:test-humble .
    docker build --network=host --build-arg AXON_APT_MIRROR=tsinghua -f docker/Dockerfile.ros2.jazzy -t axon:test-jazzy .
    docker build --network=host --build-arg AXON_APT_MIRROR=tsinghua -f docker/Dockerfile.zenoh -t axon:zenoh .
    Result: passed.
  4. Ran script syntax and whitespace checks:
    bash -n scripts/docker-apt-mirror-common.sh scripts/ci-docker-zenoh.sh scripts/docker-test-cpp.sh scripts/docker-test-ros.sh scripts/docker-test-e2e.sh
    sh -n docker/scripts/setup-apt-mirror.sh
    git diff --check
    Result: passed.

Test Coverage

  • New tests added
  • Existing tests updated
  • Coverage maintained or improved

New/updated coverage includes config parser QoS handling, blank-field fallback, invalid QoS validation, RPC topic QoS payload handling, and ROS 2 auto QoS resolution behavior.


Screenshots / Recordings

N/A.


Performance Impact

  • Memory usage: No meaningful runtime change
  • CPU usage: No meaningful runtime change
  • Recording throughput: No intended change
  • Lock contention: No change
  • CI/build downloads: Improved for local China-network Docker builds by routing apt/ROS/LLVM sources through the configured mirror and using host networking for Docker builds/runs

Documentation


Related Issues

  • N/A

Additional Notes

  • docker/Dockerfile.ros2.rolling received the same mirror strategy as the other ROS Dockerfiles, but a dedicated rolling image build/test was skipped per requester instruction.
  • The main working tree has unrelated local changes that are not included in this PR.
  • The original slow path was not fully covered by the earlier mirror change because it only addressed apt/ROS/LLVM apt sources. Docker bridge networking later stalled on GitHub/CMake dependency fetches, so the local Docker CI scripts now use host networking as well.

Reviewers

N/A


Notes for Reviewers

  • Please focus on QoS override compatibility between config files, RPC payloads, recorder task conversion, and the ROS 2 plugin boundary.
  • Please verify the auto QoS fallback behavior is acceptable when publisher endpoint information is unavailable or mixed across publishers.
  • Please review the local Docker mirror defaults and host-network usage for CI portability.

Checklist for Reviewers

  • Code changes are correct and well-implemented
  • Tests are adequate and pass
  • Documentation is updated and accurate
  • No unintended side effects
  • Performance impact is acceptable
  • Backward compatibility maintained (if applicable)

Nauyix added 5 commits June 9, 2026 15:31
- Add ROS QoS fields to task and subscription configs

- Parse nested YAML and RPC QoS objects while preserving blank defaults

- Apply task-scoped QoS overrides to session subscriptions

- Echo QoS settings through state, event, and config update payloads
- Parse mode:auto and per-field auto QoS subscription options

- Resolve auto QoS from publisher endpoint info with topic fallbacks

- Enable auto QoS in recorder ROS2 templates

- Document auto QoS fields in config and RPC docs

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@Nauyix Nauyix merged commit 335acb3 into main Jun 9, 2026
12 checks passed
@Nauyix Nauyix deleted the feature/recorder-ros-topic-qos-config branch June 9, 2026 11:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant