Skip to content

Conversation

@EsipovPA
Copy link
Contributor

@EsipovPA EsipovPA commented Jan 3, 2026

Description

Add a tutorial for using the SimpleFilter class to create new filters.

Adresses #130

Is this user-facing behavior change?

Yes. It is a UX improvement.

Did you use Generative AI?

No, I did not.

Additional Information

Copy link
Contributor

@fujitatomoya fujitatomoya left a comment

Choose a reason for hiding this comment

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

overall lgtm with minor comments.

@CursedRock17 can you take a look at this?

This filter class will be a successor to the ``SimpleFilter`` class, but this is a topic for another tutorial.

.. TODO: @EsipovPA: Add message_filters.SimpleFilter tutorial reference, when ready
For more information on this topic, please refer to the `SimpleFilter for Python tutorial <https://docs.ros.org/en/jazzy/p/message_filters/doc/Tutorials/SimpleFilter-Python.html>`.
Copy link
Contributor

Choose a reason for hiding this comment

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

should we point it to the rolling branch? (the same comment goes else where.)

Suggested change
For more information on this topic, please refer to the `SimpleFilter for Python tutorial <https://docs.ros.org/en/jazzy/p/message_filters/doc/Tutorials/SimpleFilter-Python.html>`.
For more information on this topic, please refer to the `SimpleFilter for Python tutorial <https://docs.ros.org/en/rolling/p/message_filters/doc/Tutorials/SimpleFilter-Python.html>`.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes I would agree with changing this rolling

Copy link
Contributor Author

@EsipovPA EsipovPA Jan 9, 2026

Choose a reason for hiding this comment

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

Thanks for noticing this. Also, it might be an issue when backporting this to other releases. This should be valid for every release, so it should be changed by hand before merging MRs created by the bot if will be used.

upd

Fixed here in this PR

1. Create a Basic Node
~~~~~~~~~~~~~~~~~~~~~~

Let's assume, you've already created an empty ROS 2 package for C++.
Copy link
Contributor

Choose a reason for hiding this comment

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

to keep the consistency, probably we would want to quote it? or maybe unquote all of them?

Suggested change
Let's assume, you've already created an empty ROS 2 package for C++.
Let's assume, you've already created an empty ROS 2 package for ``C++``.


.. More on this succession mechanism should be in the corresponding tutorial
.. TODO: @EsipovPA Add link to the message_filters.SimpleFilter tutorial, when added.
For more information on this succession mechanism, please refer to the `SimpleFilter for Python tutorial <https://docs.ros.org/en/jazzy/p/message_filters/doc/Tutorials/SimpleFilter-Python.html>`.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
For more information on this succession mechanism, please refer to the `SimpleFilter for Python tutorial <https://docs.ros.org/en/jazzy/p/message_filters/doc/Tutorials/SimpleFilter-Python.html>`.
For more information on this succession mechanism, please refer to the `SimpleFilter for Python tutorial <https://docs.ros.org/en/rolling/p/message_filters/doc/Tutorials/SimpleFilter-Python.html>`.

Comment on lines 1 to 2
SimpleFilter (C++):
------------
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
SimpleFilter (C++):
------------
SimpleFilter (C++):
-------------------

ament_auto_add_executable(simple_filter_tutorial src/simple_filter_tutorial.cpp)
Finally, add the install(TARGETS…) section so ros2 run can find your executable:
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Finally, add the install(TARGETS…) section so ros2 run can find your executable:
Finally, add the ``install(TARGETS…)`` section so ros2 run can find your executable:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed here and in another tutorials as well.

Comment on lines 473 to 482
.. code-block:: console
[INFO] [1766958211.195602859] [SimpleFilterExampleNode]: No messages published yet
[INFO] [1766958212.195809044] [SimpleFilterExampleNode]: Published messages count: 1. Last message: Pub count: 1
[INFO] [1766958213.195618995] [SimpleFilterExampleNode]: Published messages count: 2. Last message: Pub count: 2
[INFO] [1766958214.195599466] [SimpleFilterExampleNode]: Published messages count: 3. Last message: Pub count: 3
[INFO] [1766958215.195890964] [SimpleFilterExampleNode]: Published messages count: 4. Last message: Pub count: 4
[INFO] [1766958216.195910443] [SimpleFilterExampleNode]: Published messages count: 5. Last message: Pub count: 5
[INFO] [1766958217.195906785] [SimpleFilterExampleNode]: Published messages count: 6. Last message: Pub count: 6
[INFO] [1766958218.195652168] [SimpleFilterExampleNode]: Published messages count: 7. Last message: Pub count: 7
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
.. code-block:: console
[INFO] [1766958211.195602859] [SimpleFilterExampleNode]: No messages published yet
[INFO] [1766958212.195809044] [SimpleFilterExampleNode]: Published messages count: 1. Last message: Pub count: 1
[INFO] [1766958213.195618995] [SimpleFilterExampleNode]: Published messages count: 2. Last message: Pub count: 2
[INFO] [1766958214.195599466] [SimpleFilterExampleNode]: Published messages count: 3. Last message: Pub count: 3
[INFO] [1766958215.195890964] [SimpleFilterExampleNode]: Published messages count: 4. Last message: Pub count: 4
[INFO] [1766958216.195910443] [SimpleFilterExampleNode]: Published messages count: 5. Last message: Pub count: 5
[INFO] [1766958217.195906785] [SimpleFilterExampleNode]: Published messages count: 6. Last message: Pub count: 6
[INFO] [1766958218.195652168] [SimpleFilterExampleNode]: Published messages count: 7. Last message: Pub count: 7
.. code-block:: console
[INFO] [1766958211.195602859] [SimpleFilterExampleNode]: No messages published yet
[INFO] [1766958212.195809044] [SimpleFilterExampleNode]: Published messages count: 1. Last message: Pub count: 1
[INFO] [1766958213.195618995] [SimpleFilterExampleNode]: Published messages count: 2. Last message: Pub count: 2
[INFO] [1766958214.195599466] [SimpleFilterExampleNode]: Published messages count: 3. Last message: Pub count: 3
[INFO] [1766958215.195890964] [SimpleFilterExampleNode]: Published messages count: 4. Last message: Pub count: 4
[INFO] [1766958216.195910443] [SimpleFilterExampleNode]: Published messages count: 5. Last message: Pub count: 5
[INFO] [1766958217.195906785] [SimpleFilterExampleNode]: Published messages count: 6. Last message: Pub count: 6
[INFO] [1766958218.195652168] [SimpleFilterExampleNode]: Published messages count: 7. Last message: Pub count: 7

typedef MessageEvent<M const> EventType;

We start with a few ``typedef declarations`` for ``MConstPtr``, ``Callback`` and ``EventType``.
These will make the following code clearer and easyer to read.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
These will make the following code clearer and easyer to read.
These will make the following code clearer and easier to read.

);
}

In order to create a connection with another filter, this method registeres the ``add`` method of this class
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
In order to create a connection with another filter, this method registeres the ``add`` method of this class
In order to create a connection with another filter, this method registers the ``add`` method of this class


The private section in this case is rather simple.
It consists of the ``counter_`` and the ``last_message_cache_`` fields and the ``incoming_connection_`` field.
First two are the part of the buisness logic of this class.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
First two are the part of the buisness logic of this class.
First two are the part of the business logic of this class.

[INFO] [1766958217.195906785] [SimpleFilterExampleNode]: Published messages count: 6. Last message: Pub count: 6
[INFO] [1766958218.195652168] [SimpleFilterExampleNode]: Published messages count: 7. Last message: Pub count: 7

Note that when the first query is executed, there were no messages that have pasesd the filter, as is indicated by the console output.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Note that when the first query is executed, there were no messages that have pasesd the filter, as is indicated by the console output.
Note that when the first query is executed, there were no messages that have passed the filter, as is indicated by the console output.

@EsipovPA
Copy link
Contributor Author

EsipovPA commented Jan 7, 2026

Thank you all for the review.
I'm out of town for a few days and with not that good of an internet connection.

I'll definetely fix the code when I'm back home.

Copy link
Contributor

@CursedRock17 CursedRock17 left a comment

Choose a reason for hiding this comment

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

For the most part LGTM, I just wanted to go through and build the node just to make sure it was followable. Found a slight error in a typo with the main CounterWilthLastMessageCache which has wilth instead of with. Other than that just nitpicking for readability.

Great work!

This filter class will be a successor to the ``SimpleFilter`` class, but this is a topic for another tutorial.

.. TODO: @EsipovPA: Add message_filters.SimpleFilter tutorial reference, when ready
For more information on this topic, please refer to the `SimpleFilter for Python tutorial <https://docs.ros.org/en/jazzy/p/message_filters/doc/Tutorials/SimpleFilter-Python.html>`.
Copy link
Contributor

Choose a reason for hiding this comment

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

Yes I would agree with changing this rolling

namespace message_filters
{
template<class M>
class CounterWilthLastMessageCache : public SimpleFilter<M> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo on Class

Suggested change
class CounterWilthLastMessageCache : public SimpleFilter<M> {
class CounterWithLastMessageCache : public SimpleFilter<M> {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Omg 🥲

Comment on lines 52 to 57
virtual ~CounterWilthLastMessageCache() {}

CounterWilthLastMessageCache() {}

template<typename F>
explicit CounterWilthLastMessageCache(F & filter)
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo continued.

Suggested change
virtual ~CounterWilthLastMessageCache() {}
CounterWilthLastMessageCache() {}
template<typename F>
explicit CounterWilthLastMessageCache(F & filter)
virtual ~CounterWithLastMessageCache() {}
CounterWithLastMessageCache() {}
template<typename F>
explicit CounterWithLastMessageCache(F & filter)

Copy link
Contributor Author

@EsipovPA EsipovPA Jan 9, 2026

Choose a reason for hiding this comment

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

It was a typo in a first class declaration in the actual project where I've tested the code, and after that is was autocompletion in vscode. Should always remind myself not to trust autocompletion completely (this one is intended) 🤦‍♂️

incoming_connection_ = filter.registerCallback(
typename SimpleFilter<M>::EventCallback(
std::bind(
&CounterWilthLastMessageCache::add,
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
&CounterWilthLastMessageCache::add,
&CounterWithLastMessageCache::add,

This tutorial demonstrates how to create a custom filter that is going to be a successor to the ``SimpleFilter`` class.
The ``SimpleFilter`` is a base class for almost all of message filters implemented in ``C++``.
It provides the basic functionality for building filters.
To demonstrate the functionality of this filter we are going to create a ``CounterWilthLastMessageCache`` filter class.
Copy link
Contributor

Choose a reason for hiding this comment

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

Small Typo.

Suggested change
To demonstrate the functionality of this filter we are going to create a ``CounterWilthLastMessageCache`` filter class.
To demonstrate the functionality of this filter we are going to create a ``CounterWithLastMessageCache`` filter class.

The private section in this case is rather simple.
It consists of the ``counter_`` and the ``last_message_cache_`` fields and the ``incoming_connection_`` field.
First two are the part of the buisness logic of this class.
The last one is required for managing the connection with a filter that does pass messages to this one.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
The last one is required for managing the connection with a filter that does pass messages to this one.
The last one manages the connection with a filter that passes messages to this one.

Comment on lines 366 to 367
The instance of the ``SubscriberFilter``is used to receive messages from the ``TUTORIAL_TOPIC``.
The instance of the ``CounterWilthLastMessageCache`` filter is immediately connected to the ``subscriber_filter_``'s output.
Copy link
Contributor

Choose a reason for hiding this comment

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

Inline code block breaking up and typo change.

Suggested change
The instance of the ``SubscriberFilter``is used to receive messages from the ``TUTORIAL_TOPIC``.
The instance of the ``CounterWilthLastMessageCache`` filter is immediately connected to the ``subscriber_filter_``'s output.
The instance of the ``SubscriberFilter`` receives messages from the ``TUTORIAL_TOPIC``.
The instance of the ``CounterWithLastMessageCache`` filter is immediately connected to the ``subscriber_filter_``'s output.

Comment on lines 370 to 372
And the two timers are added to automate the work.
The ``publisher_timer_`` to automate message publishing.
And the ``query_timer_`` to automate the introspection of the node filters state.
Copy link
Contributor

Choose a reason for hiding this comment

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

Breaking up the section

Suggested change
And the two timers are added to automate the work.
The ``publisher_timer_`` to automate message publishing.
And the ``query_timer_`` to automate the introspection of the node filters state.
Two timers are added to automate the work:
The ``publisher_timer_`` automates message publishing.
The ``query_timer_`` automates the introspection of the node filter's state.

incoming_connection_ = filter.registerCallback(
typename SimpleFilter<M>::EventCallback(
std::bind(
&CounterWilthLastMessageCache::add,
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo continued.

Suggested change
&CounterWilthLastMessageCache::add,
&CounterWithLastMessageCache::add,


private:
message_filters::Subscriber<std_msgs::msg::String> subscriber_filter_;
message_filters::CounterWilthLastMessageCache<std_msgs::msg::String> counter_filter_;
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo Continued.

Suggested change
message_filters::CounterWilthLastMessageCache<std_msgs::msg::String> counter_filter_;
message_filters::CounterWithLastMessageCache<std_msgs::msg::String> counter_filter_;

…ference. Fix minor typos in Chain and Cache tutorials

Signed-off-by: EsipovPA <esipov.p@mail.ru>
Signed-off-by: EsipovPA <esipov.p@mail.ru>
@EsipovPA EsipovPA force-pushed the 130_add_simple_filter_tutorial_for_cpp branch from 4c6021e to 6459e47 Compare January 9, 2026 21:53
@ahcorde
Copy link
Contributor

ahcorde commented Jan 12, 2026

Pulls: #239
Gist: https://gist.githubusercontent.com/ahcorde/876b4e0cbc45e2c50fb341b16729bf14/raw/bffcf0b08eed6bfb9507ec43d57498314d6678f0/ros2.repos
BUILD args: --packages-above-and-dependencies message_filters
TEST args: --packages-above message_filters
ROS Distro: rolling
Job: ci_launcher
ci_launcher ran: https://ci.ros2.org/job/ci_launcher/17909

  • Linux Build Status
  • Linux-aarch64 Build Status
  • Linux-rhel Build Status
  • Windows Build Status

@EsipovPA EsipovPA requested a review from CursedRock17 January 12, 2026 15:44
@EsipovPA
Copy link
Contributor Author

Hello @ahcorde! Thanks for the review and for the approval. It seems like the 'Linux' job is not running. It was in a 'failing' state for some time, but now it is just in 'not run'. Is there anything to be done about it? Maybe there is something, I can do? Sorry for bothering, if I'm being inconvenient.

@ahcorde ahcorde merged commit 92af2b7 into ros2:rolling Jan 13, 2026
2 checks passed
@ahcorde
Copy link
Contributor

ahcorde commented Jan 13, 2026

https://github.com/Mergifyio backport kilted jazzy humble

@mergify
Copy link

mergify bot commented Jan 13, 2026

backport kilted jazzy humble

✅ Backports have been created

Details

mergify bot pushed a commit that referenced this pull request Jan 13, 2026
Signed-off-by: EsipovPA <esipov.p@mail.ru>
(cherry picked from commit 92af2b7)
mergify bot pushed a commit that referenced this pull request Jan 13, 2026
Signed-off-by: EsipovPA <esipov.p@mail.ru>
(cherry picked from commit 92af2b7)
mergify bot pushed a commit that referenced this pull request Jan 13, 2026
Signed-off-by: EsipovPA <esipov.p@mail.ru>
(cherry picked from commit 92af2b7)
ahcorde added a commit that referenced this pull request Jan 13, 2026
* #130 add simple filter tutorial for cpp (#239)

Signed-off-by: EsipovPA <esipov.p@mail.ru>
(cherry picked from commit 92af2b7)
Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
Co-authored-by: Pavel Esipov <38457822+EsipovPA@users.noreply.github.com>
Co-authored-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
ahcorde added a commit that referenced this pull request Jan 13, 2026
* #130 add simple filter tutorial for cpp (#239)

Signed-off-by: EsipovPA <esipov.p@mail.ru>
(cherry picked from commit 92af2b7)
Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
Co-authored-by: Pavel Esipov <38457822+EsipovPA@users.noreply.github.com>
Co-authored-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
ahcorde added a commit that referenced this pull request Jan 13, 2026
* #130 add simple filter tutorial for cpp (#239)

Signed-off-by: EsipovPA <esipov.p@mail.ru>
(cherry picked from commit 92af2b7)
Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
Co-authored-by: Pavel Esipov <38457822+EsipovPA@users.noreply.github.com>
Co-authored-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
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.

4 participants