Skip to content

Add --content-filter support to ros2 topic echo|hz|bw#1213

Open
PavelGuzenfeld wants to merge 1 commit intoros2:rollingfrom
PavelGuzenfeld:feature/content-filter-topic-jazzy
Open

Add --content-filter support to ros2 topic echo|hz|bw#1213
PavelGuzenfeld wants to merge 1 commit intoros2:rollingfrom
PavelGuzenfeld:feature/content-filter-topic-jazzy

Conversation

@PavelGuzenfeld
Copy link
Copy Markdown

Summary

Closes #1126

Adds DDS content filter expression support to ros2 topic echo, ros2 topic hz, and ros2 topic bw commands via new --content-filter and --content-filter-params CLI arguments.

Content filters are applied at the middleware level (via rclpy.subscription_content_filter_options.ContentFilterOptions), so only matching messages are delivered to the subscriber — reducing bandwidth and CPU usage compared to client-side Python --filter expressions.

Usage examples:

# Echo only messages where data contains "Hello"
ros2 topic echo /chatter --content-filter "data LIKE '%Hello%'"

# Measure hz of messages matching a filter with parameters
ros2 topic hz /sensor --content-filter "temperature > %0" --content-filter-params 30.0

# Measure bandwidth of filtered messages
ros2 topic bw /camera/image --content-filter "header.frame_id = %0" --content-filter-params camera_front

Changes:

  • echo.py: Add --content-filter and --content-filter-params arguments, pass ContentFilterOptions to create_subscription
  • hz.py: Same additions, passed through _rostopic_hz
  • bw.py: Same additions, passed through _rostopic_bw

Test plan

  • ros2 topic echo --help shows new --content-filter and --content-filter-params options
  • ros2 topic hz --help shows new options
  • ros2 topic bw --help shows new options
  • E2E: echo with matching filter (data LIKE '%Hello%') receives messages
  • E2E: echo with non-matching filter (data LIKE '%NOMATCH%') receives no messages
  • E2E: echo/hz/bw without --content-filter works unchanged

@PavelGuzenfeld PavelGuzenfeld force-pushed the feature/content-filter-topic-jazzy branch from 9a6125b to 59c1186 Compare March 21, 2026 21:13
@christophebedard
Copy link
Copy Markdown
Member

Thank you for the PR! Please see my note here: ros2/rclcpp#3109 (comment)

@PavelGuzenfeld
Copy link
Copy Markdown
Author

Thanks for the review!

AI disclosure: This PR was authored with the assistance of Claude (Anthropic) as a generative AI coding tool. I have reviewed and validated the changes.

Branch target: Will retarget to rolling now.

@PavelGuzenfeld PavelGuzenfeld changed the base branch from jazzy to rolling March 22, 2026 05:34
@PavelGuzenfeld
Copy link
Copy Markdown
Author

Correction on the AI disclosure: the model used was Claude Opus (Anthropic).

@PavelGuzenfeld PavelGuzenfeld force-pushed the feature/content-filter-topic-jazzy branch from 59c1186 to 8d77247 Compare March 22, 2026 05:42
@PavelGuzenfeld
Copy link
Copy Markdown
Author

Rebased onto rolling as requested. The diff is now clean (1 commit, 3 files changed).

The original feature request (#1126) applies to jazzy and humble as well. Would appreciate a backport to those distros once this is merged into rolling.

Add DDS content filter expression support to `ros2 topic echo`,
`ros2 topic hz`, and `ros2 topic bw` commands via new
`--content-filter` and `--content-filter-params` CLI arguments.

Content filters are applied at the middleware level, so only matching
messages are delivered to the subscriber — reducing bandwidth and CPU
usage compared to client-side Python filtering.

Closes ros2#1126

Signed-off-by: Pavel Guzenfeld <me@pavelguzenfeld.com>
Signed-off-by: Pavel Guzenfeld <pavelguzenfeld@gmail.com>
@PavelGuzenfeld PavelGuzenfeld force-pushed the feature/content-filter-topic-jazzy branch from 8d77247 to 237c9d9 Compare March 22, 2026 06:15
@PavelGuzenfeld
Copy link
Copy Markdown
Author

The CI failure is a flaky test, not caused by this PR:

FAIL: test_topic_echo_field_invalid[rmw_fastrtps_cpp]

The test uses strict=True output matching and expects only the error message, but a DDS "message was lost" event fired during discovery, adding unexpected output:

"A message was lost!!!\n\ttotal count change:1\n\ttotal count: 1---\n
Invalid field '/': 'Arrays' object has no attribute '/'\n"

This PR only adds --content-filter / --content-filter-params arguments and does not modify the --field processing path or the subscribe_and_spin message-lost callback (which already existed). The flaky failure is a DDS-level race condition unrelated to content filtering.

Could a maintainer please re-trigger the CI?

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.

Add support for content filters

2 participants