Skip to content

Update subscriber filter#126

Merged
ahcorde merged 13 commits intoros-perception:rollingfrom
elsayedelsheikh:advanced_subscriber_filter
Jul 21, 2025
Merged

Update subscriber filter#126
ahcorde merged 13 commits intoros-perception:rollingfrom
elsayedelsheikh:advanced_subscriber_filter

Conversation

@elsayedelsheikh
Copy link
Contributor

@elsayedelsheikh elsayedelsheikh commented Jun 26, 2025

Related to #124

Work Description

  • Initially, New FullSubscriberFilter class inherited from message_filters::SubscriberBase and message_filters::SimpleFilter<sensor_msgs::msg::PointCloud2> then I thought why not inherit from existing implementation SubscriberFilter and avoid repeatition.

  • So I've changed a few things in the original SubscriberFilter and voila new FullSubscriberFilter

  • I'm also suggesting renaming classes to change the old SubscriberFilter name to SimpleSubscriberFilter and the new one from FullSubscriberFilter to SubscriberFilter

  • About inheriting from SubscriberBase , We need to override these 2 functions but our subscriber needs more node_interfaces so I left them empty and shouldn't be used

      void subscribe(
        RequiredInterfaces /*node_interfaces*/, const std::string & /*topic*/,
        const rclcpp::QoS & /*qos*/) override
      {}
      void subscribe(
        RequiredInterfaces  /*node_interfaces*/,
        const std::string & /*topic*/,
        const rclcpp::QoS & /*qos*/,
        rclcpp::SubscriptionOptions /*options*/) override
      {}

Edit:

Updated the existing SubscriberFilter:

  • Inherits from message_filters::SubscriberBase as well as message_filters::SimpleFilter
  • New constructor that accepts Node or/ LifecycleNode
  • New subscriber(...) that accepts Node or/ LifecycleNode
  • New subscibe() method to re-subscribe if this subscriber has previously been initialized.

Example Usage

// During initialization
auto sub = std::make_shared<point_cloud_transport::SubscriberFilter>(
  node, topic, transport_type, custom_qos, sub_opt);
/*or*/
auto sub = std::make_shared<point_cloud_transport::SubscriberFilter>();
sub->subscribe(node, topic, transport_type, custom_qos, sub_opt);

sub->unsubscribe();  // Arguments still stored internally

// On activate
if (sub != nullptr) {
  sub->subscribe();  // Reuses stored arguments to re-create a subscriber
}

// On deactivate (already implemented)
sub->unsubscribe();

FYI @ahcorde @SteveMacenski

@SteveMacenski
Copy link
Member

I think this should modify the existing subscriber filter, not add a new one, no?

@elsayedelsheikh
Copy link
Contributor Author

I think this should modify the existing subscriber filter, not add a new one, no?

It adds a new one with slight changes on the old one:

  • change access modifier on the callback function from private to protected
  • change subscribe(node_interfaces, ...) method to be virtual so I can override to save passed args

@elsayedelsheikh
Copy link
Contributor Author

Should we rid of the existing subscriber filter? 🤔

@SteveMacenski
Copy link
Member

I think this should be applied to the existing filter so we only have a diff of the changes needed rather than a whole new implementation :-) Those changes seem pretty minimal to me to not just update the existing implementation

@elsayedelsheikh
Copy link
Contributor Author

I think this should be applied to the existing filter so we only have a diff of the changes needed rather than a whole new implementation :-) Those changes seem pretty minimal to me to not just update the existing implementation

Got it! :)

@elsayedelsheikh
Copy link
Contributor Author

I think this should be applied to the existing filter so we only have a diff of the changes needed rather than a whole new implementation :-) Those changes seem pretty minimal to me to not just update the existing implementation

Done!

@elsayedelsheikh elsayedelsheikh changed the title New subscriber filter Update subscriber filter Jun 26, 2025
Signed-off-by: elsayedelsheikh <elsayed.elsheikh97@gmail.com>
Signed-off-by: elsayedelsheikh <elsayed.elsheikh97@gmail.com>
Signed-off-by: elsayedelsheikh <elsayed.elsheikh97@gmail.com>
Signed-off-by: elsayedelsheikh <elsayed.elsheikh97@gmail.com>
Signed-off-by: elsayedelsheikh <elsayed.elsheikh97@gmail.com>
@elsayedelsheikh elsayedelsheikh force-pushed the advanced_subscriber_filter branch from 0762c9b to da90eff Compare June 27, 2025 11:31
@elsayedelsheikh
Copy link
Contributor Author

We're ready for review here :) @ahcorde

Signed-off-by: elsayedelsheikh <elsayed.elsheikh97@gmail.com>
Signed-off-by: elsayedelsheikh <elsayed.elsheikh97@gmail.com>

template<typename NodeT = rclcpp::Node::SharedPtr>
POINT_CLOUD_TRANSPORT_PUBLIC
SubscriberFilter(
Copy link
Member

@SteveMacenski SteveMacenski Jun 27, 2025

Choose a reason for hiding this comment

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

I think this could remove the previous 2x constructors in this class. The NodeT will be deduced automatically since its a direct constructor argument, so you both don't actually need to specify a default and it'll automatically deduce it at compile time :-)

Also, we should have some default for the QoS - what's the default used if not specified by the base class?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a default QoS and removed the old constructor.
As for the node_interfaces constructor, I think we should keep this one preserving the general style followed in point_cloud_transport, no?

Copy link
Collaborator

Choose a reason for hiding this comment

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

is there any chance to deprecate old constructors?

Copy link
Contributor Author

@elsayedelsheikh elsayedelsheikh Jul 1, 2025

Choose a reason for hiding this comment

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

I think rclcpp::Node constructor would work here so there's no need to deprecate it, right? -> Should remove it
The one that should be deprecated is the node_interfaces constructor if you're ok with it😀

template<typename NodeT = rclcpp::Node::SharedPtr>
POINT_CLOUD_TRANSPORT_PUBLIC
void subscribe(
NodeT node,
Copy link
Member

@SteveMacenski SteveMacenski Jun 27, 2025

Choose a reason for hiding this comment

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

Ditto, now that its templated the previous method for rclcpp node is not required - rclcpp::Node's will just automatically work here


private:
//! Don't use this method
void subscribe(
Copy link
Member

@SteveMacenski SteveMacenski Jun 27, 2025

Choose a reason for hiding this comment

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

Then remove if it shouldn't be used? 😆

Copy link
Contributor Author

@elsayedelsheikh elsayedelsheikh Jun 28, 2025

Choose a reason for hiding this comment

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

  • About inheriting from SubscriberBase , We need to override these 2 functions but our subscriber needs more node_interfaces so I left them empty and shouldn't be used
      void subscribe(
        RequiredInterfaces /*node_interfaces*/, const std::string & /*topic*/,
        const rclcpp::QoS & /*qos*/) override
      {}
      void subscribe(
        RequiredInterfaces  /*node_interfaces*/,
        const std::string & /*topic*/,
        const rclcpp::QoS & /*qos*/,
        rclcpp::SubscriptionOptions /*options*/) override
      {}

Won't be able to create a class object if not implemented, Check this
So that I put them under private so no one uses them :D

Copy link
Member

Choose a reason for hiding this comment

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

Ugh. I think that should be reverted too with the subscribe function similarly templated by NodeT that can be auto-deduced. Before I think it was a pain because the entire class was templated rather than just the method that can autodeduce the type from the arguments.

@ahcorde what do you think?

Copy link
Member

@SteveMacenski SteveMacenski Jul 1, 2025

Choose a reason for hiding this comment

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

Exposing the RequiredInterfaces to the application code is super nasty and can be populated internally to the message filter from the argument provided NodeT. I think merging this in March was not the best solution ros2/message_filters#113. Using RequiredInterfaces as an input if the method is templated will still work as a NodeT as long as it provides the same get_X_base_interface() method. That appears to be the case https://github.com/ros2/rclcpp/blob/rolling/rclcpp/include/rclcpp/node_interfaces/node_interfaces.hpp#L108-L110

Copy link
Collaborator

Choose a reason for hiding this comment

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

This is very nice documented issue ros2/geometry2#698 why we shouldn't use templates and why we should use rclcpp::node_interfaces::NodeInterfaces

There is a ppt too https://docs.google.com/presentation/d/1bdXOOZPhR9yAnyGNxoLhuO_bU4RW5IjnzvCtrVlpe_g/edit?slide=id.g24afec4abf4_0_0#slide=id.g24afec4abf4_0_0

Maybe we can still improve something in message filter, but I prefer rclcpp::node_interfaces::NodeInterfaces instead of NodeT

Copy link
Member

Choose a reason for hiding this comment

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

Would we need to update message filters too?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think I'm lost here... 🤔
So you guys are proposing to use f(*NodeT) for implicit conversion to node_interfaces, similar to
https://github.com/ros2/message_filters/blob/4f17c17813e7b84e34cc287143ddf70471c78d6c/include/message_filters/subscriber.hpp#L168-L173

Then, Would it be ok to leave SubscriberBase pure virtual methods under private without implementation { }?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Let me create the PR with my suggestions, and we can move forward from there

Copy link
Collaborator

Choose a reason for hiding this comment

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

Here my suggestions #129 @SteveMacenski @elsayedelsheikh

Copy link
Member

Choose a reason for hiding this comment

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

That looks good to me! I think after rebasing onto that, whatever changes are still required for aligning with message filters are still related but simplifies things quite a bit in the best ways.

Just to check, all this works with a rclcpp_lifecycle::LifecycleNode or even a nav2::LifecycleNode in auto-populating that interfaces objcet, correct? All the docs make me think that's the case, but just verifying since I still see the specialized rclcpp::Node constructors in your PR. Couldn't those be removed?

Signed-off-by: elsayedelsheikh <elsayed.elsheikh97@gmail.com>
@elsayedelsheikh
Copy link
Contributor Author

@SteveMacenski Hey Steve, any update?


template<typename NodeT = rclcpp::Node::SharedPtr>
POINT_CLOUD_TRANSPORT_PUBLIC
SubscriberFilter(
Copy link
Collaborator

Choose a reason for hiding this comment

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

is there any chance to deprecate old constructors?

Signed-off-by: ElSayed ElSheikh <elsayed.elsheikh97@gmail.com>
@elsayedelsheikh
Copy link
Contributor Author

Please check the current implementation!
And LMK if there are any final notes🥲

@elsayedelsheikh elsayedelsheikh requested a review from ahcorde July 1, 2025 17:49
/// \param options Subscriber options
///
POINT_CLOUD_TRANSPORT_PUBLIC
void subscribe(
Copy link
Member

Choose a reason for hiding this comment

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

Can this be depreciated?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure!


private:
//! Don't use this method
void subscribe(
Copy link
Member

Choose a reason for hiding this comment

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

Ugh. I think that should be reverted too with the subscribe function similarly templated by NodeT that can be auto-deduced. Before I think it was a pain because the entire class was templated rather than just the method that can autodeduce the type from the arguments.

@ahcorde what do you think?

Signed-off-by: ElSayed ElSheikh <elsayed.elsheikh97@gmail.com>
Copy link
Collaborator

@ahcorde ahcorde left a comment

Choose a reason for hiding this comment

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

Do you mind to fix the conflicts ?

@elsayedelsheikh
Copy link
Contributor Author

Do you mind to fix the conflicts ?

Working on it 😁

Signed-off-by: ElSayed ElSheikh <elsayed.elsheikh97@gmail.com>
Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
@ahcorde
Copy link
Collaborator

ahcorde commented Jul 18, 2025

Pulls: #126
Gist: https://gist.githubusercontent.com/ahcorde/885d35438a0c1b0fe7da399ea6aebfe9/raw/18be47193ab26936a191b9e8710ee84e8c6f40cf/ros2.repos
BUILD args: --packages-above-and-dependencies point_cloud_transport
TEST args: --packages-above point_cloud_transport
ROS Distro: rolling
Job: ci_launcher
ci_launcher ran: https://ci.ros2.org/job/ci_launcher/16529

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

@elsayedelsheikh
Copy link
Contributor Author

@ahcorde I'd like to add one more thing before we merge

Signed-off-by: ElSayed ElSheikh <elsayed.elsheikh97@gmail.com>
@elsayedelsheikh
Copy link
Contributor Author

  • Modified the Class Constructor
  • Throw run time exception for NodeInterfaces<NodeParametersInterface, NodeTopicsInterface> functions

@elsayedelsheikh elsayedelsheikh requested a review from ahcorde July 18, 2025 10:16
@ahcorde
Copy link
Collaborator

ahcorde commented Jul 18, 2025

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

@ahcorde ahcorde merged commit 4d502a3 into ros-perception:rolling Jul 21, 2025
3 checks passed
@elsayedelsheikh elsayedelsheikh deleted the advanced_subscriber_filter branch July 21, 2025 13:27
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.

3 participants