Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connect/Disconnect notification/callback support #330

Closed
11 tasks done
Tracked by #120
fujitatomoya opened this issue Sep 13, 2022 · 44 comments
Closed
11 tasks done
Tracked by #120

Connect/Disconnect notification/callback support #330

fujitatomoya opened this issue Sep 13, 2022 · 44 comments
Labels
backlog enhancement New feature or request

Comments

@fujitatomoya
Copy link
Collaborator

fujitatomoya commented Sep 13, 2022

Feature request

Feature description

  • RMW can notify the event that any subscriptions connect / disconnect on the topic to each publisher.
  • Based on this capability, in rclcpp and rclpy, user application can register user callback that will be called when subscription connects or disconnects on the topic for publisher.

ROS 1 Similar function: https://docs.ros.org/en/noetic/api/roscpp/html/classros_1_1NodeHandle.html#ae4711ef282892176ba145d02f8f45f8d

Use case

On visualization node, to suppress unnecessary CPU utilization, enable its visualization process only when RViz is connected.

image

Related Information / Reference

Implementation considerations

Since all tier-1 rmw implementation is DDS implementation, we can support this feature with on_publication_matched of DataWriterListener Interface. (we confirmed the code of Fast-DDS.)

@fujitatomoya
Copy link
Collaborator Author

@ivanpauno @wjwwood @asorbini @MiguelCompany @alsora @SteveMacenski @mikeferguson
CC: @ros2/middleware_working_group @Barry-Xu-2018

This is to open discussion, could you share your thoughts?

@ivanpauno
Copy link
Member

Adding this like a new rmw_event_t seems reasonable to me

@ivanpauno ivanpauno added the enhancement New feature or request label Sep 13, 2022
@mikeferguson
Copy link

mikeferguson commented Sep 13, 2022

I think this is super useful - at the moment, you can't easily build something like rgbd_launch in ROS2 (where all of the various pipeline elements are lazy publishers/subscribers) - I didn't even realize this wasn't already ticketed somewhere...

I had some notes about use cases (and my current lazy subscriber workaround with a timer that checks get_subscription_count once a second) here: https://www.robotandchisel.com/2020/06/16/ubr1-on-ros2/

EDIT: there was also additional information in my post on 5 things ROS2 needed in 2020: https://www.robotandchisel.com/2020/07/29/five-things-ros2/

@alsora
Copy link
Contributor

alsora commented Sep 14, 2022

I'm not familiar with the on_publication_matched API.
Would it be equivalent to checking get_subscription_count() on the publishers objects?
Obviously having a callback would be much better than continuously checking that API, but I just want to make sure that I understand how it would work.

In general this looks a great feature to add.

@fujitatomoya
Copy link
Collaborator Author

Would it be equivalent to checking get_subscription_count() on the publishers objects?

the main difference is, application can be notified with event on connect/disconnect.

@MiguelCompany
Copy link

This would be a nice addition, probably as a new rmw_event_t as @ivanpauno suggests. We could interpret it as having an event notifying of changes on get_subscription_count()

We could do the same for subscriptions, though we should probably have that as a separate issue.

@Barry-Xu-2018
Copy link
Contributor

We all agreed adding new event.
I submitted a PR to add connect/disconnect event and define rmw_matched_status_t for publisher and subscription event callback.
Please review it.

@Barry-Xu-2018
Copy link
Contributor

@fujitatomoya

We should remove rmw_implementation in change list since the rmw interface isn't changed in #331

@MiguelCompany
Copy link

We should remove rmw_implementation in change list since the rmw interface isn't changed in #331

@Barry-Xu-2018 I don't think so, since that repository is there the tests for this feature should be added.

@Barry-Xu-2018
Copy link
Contributor

@MiguelCompany

I don't think so, since that repository is there the tests for this feature should be added.

Thank you for your kind reminder.
Yes. I will check and add tests.

@Barry-Xu-2018
Copy link
Contributor

In rmw_implementation, there is no test related to event currently (Including existing events).
So I need to add events test file.
Besides, rmw_implementation test depend on rmw_xxxx (e.g. rmw_fastrtps).
So I will implement rmw_fastrtps, rmw_connextdds, rmw_cyclonedds at first and then add test to rmw_implementation.

@fujitatomoya
Copy link
Collaborator Author

@Barry-Xu-2018 thanks for checking, i was thinking that there would be some related code or test cases in there, so just make sure that everything we may change on that table at 1st. if we do not need to update, that is also fine, i will remove rmw_implementaion from the issue header.

@fujitatomoya fujitatomoya changed the title Connect/Disconnect notification/callback support on publisher Connect/Disconnect notification/callback support Dec 9, 2022
@ros-discourse
Copy link

This issue has been mentioned on ROS Discourse. There might be relevant details there:

https://discourse.ros.org/t/ros-2-tsc-meeting-minutes-2023-01-19/29423/1

@Barry-Xu-2018
Copy link
Contributor

@fujitatomoya
Copy link
Collaborator Author

@Barry-Xu-2018 thanks, i will be reviewing for sure.

CC: @iuhilnehc-ynos

@fujitatomoya
Copy link
Collaborator Author

@Barry-Xu-2018 Can we start the CI with all dependent PRs to see all related tests complete w/o error? i will be working on review at the same time.

@Barry-Xu-2018
Copy link
Contributor

@fujitatomoya

once everything is rebased, can you start the CI?

Yes. After all are rebased, I will ask @iuhilnehc-ynos help to run CI.

@Barry-Xu-2018
Copy link
Contributor

@fujitatomoya

CI was done.
#331 (comment)

The failed test cases on Windows are unrelated to my change.

@mjcarroll
Copy link
Member

Everything up to rclcpp/rclpy have been approved and merged. I'm going to leave this to you to close when demos/documentation are updated. Thanks for all the hard work and iteration!

@fujitatomoya
Copy link
Collaborator Author

@mjcarroll appreciate it for taking care of those PRs 👍 thanks a lot 🙇‍♂️ (ありがとう)

@fujitatomoya
Copy link
Collaborator Author

@Barry-Xu-2018

the rest will be #330 (comment), can you also address these?

@Barry-Xu-2018
Copy link
Contributor

the rest will be #330 (comment), can you also address these?

Yeah, I am writing demo code and updating the document.

@Barry-Xu-2018
Copy link
Contributor

Demo PR was submitted. ros2/demos#607

About the document, I didn't find a detailed description of the "event" in the document. Only a brief introduction is provided, and there are no examples given.
Based on this file, I add brief introduction for matched as below. (New added event Inconsistent topic isn't described. I add brief introduction)
Barry-Xu-2018/ros2_documentation@c183c93

@fujitatomoya
Copy link
Collaborator Author

Based on this file, I add brief introduction for matched as below. (New added event Inconsistent topic isn't described. I add brief introduction)

I think that would be better to add an introduction like this, i left some comments on it, can you make the PR?

and, probably doc for inconsistent topic, we would want to create another PR.

@Barry-Xu-2018
Copy link
Contributor

I think that would be better to add an introduction like this, i left some comments on it, can you make the PR?

and, probably doc for inconsistent topic, we would want to create another PR.

Okay. I created a PR ros2/ros2_documentation#3406.

@fujitatomoya
Copy link
Collaborator Author

ros2/rmw_fastrtps#683 has been merged.

@fujitatomoya
Copy link
Collaborator Author

complete all related PRs, see https://github.com/ros2/rmw/issues/330#issue-1371797574#353

i will go ahead to close this issue.

@ros-discourse
Copy link

This issue has been mentioned on ROS Discourse. There might be relevant details there:

https://discourse.ros.org/t/ros-2-alternative-middleware-report/33771/19

mikeferguson added a commit to ros-perception/image_pipeline that referenced this issue Jan 18, 2024
This implements #780 for ROS 2 distributions after Iron, where we have:

 * Connect/disconnect callbacks, per ros2/rmw#330 (this made it into Iron)
 * Updated APIs in ros-perception/image_common#272 (this is only in Rolling currently)
@Ryanf55
Copy link

Ryanf55 commented Mar 11, 2024

Hello,

This is a great feature for testing in ROS 2 - you can verify all topics are matched before starting tests.

  1. Is this feature possible to backport to humble?
  2. If not, is there any other approach to verify all topics are matched before starting a test when using rclpy?

Thanks!

@fujitatomoya
Copy link
Collaborator Author

@Ryanf55

Is this feature possible to backport to humble?

unfortunately I do not think so, originally we did not consider the backport of this feature. this adds many APIs including RMW interfaces.

If not, is there any other approach to verify all topics are matched before starting a test when using rclpy?

we can check if corresponding publishers or subscribers on the topic, which uses NodeGraph.

https://github.com/ros2/rclpy/blob/f1873bfb1e3261e617cb0a4c9cfb6ddcf57b6747/rclpy/rclpy/node.py#L2124-L2152

i think this could be used to check if someone is on the other side, but downside is that this is not an event, so we need to do polling to ask if there is someone on the topic.

Note: with rclcpp we can have an event from NodeGraph guard condition update, but this does not tell you what exactly has been updated. after all, we need to check how graph is updated from application.

that is pretty much that i know, hopefully this helps.

@tonynajjar
Copy link

This is a really cool feature but it feels quite verbose for the very common use case: "publish only if there are subscribers". For that I still prefer something as simple as:

  if (publisher_->get_subscription_count() > 0) {
    /* heavy work for visualization
    */
    publisher_->publish(msg);
  }

It was mentioned that the drawback with this approach is the need to constantly poll with an external timer but in many cases this block of code would already be in a timer/subscriber callback (you can see many examples in Nav2). So apart from this drawback, is there anything else matched events are better with? Thanks

@clalancette
Copy link
Contributor

clalancette commented May 15, 2024

  if (publisher_->get_subscription_count() > 0) {

For what it is worth, that already exists, though with a caveat. The caveat is that because of intra-process publishing, just getting the subscription count isn't enough; you also need to get the intra-process subscription count. With that in mind, you can do:

if ((publisher_->get_subscription_count() + publisher_->get_intra_process_subscription_count()) > 0) {
  publisher_->publish();
}

@tonynajjar
Copy link

Yes I know it exists, thanks for mentioning the caveat though. I was just asking if this method has any other known drawbacks compared to matched events + counting subscribers manually (which would be a much more verbose solution for this simple yet very common use case)

@Barry-Xu-2018
Copy link
Contributor

For different use cases, you can choose different methods.
For instance, if you need to perform some actions when certain events occur (e.g. the first subscriber connects or the last one disconnects), using event-driven code would be simpler and more efficient compared to using timers and polling for checks.

@fujitatomoya
Copy link
Collaborator Author

@tonynajjar the original motivation is, we need to create the data pipeline dynamically only if it comes necessary for network and cpu efficiency as we do develop edge devices. having polling mechanism and calling API to query the network connectivity is not really cost effective cz we have to do that every single time and most likely the network connectivity has not changed yet... i think it all comes down to the use case. (we sometimes use get_count as well.)

something i want to mention about the drawback (maybe not drawback but more like feature) as comparison is, that the matched event is synchronized information, that guarantees how the mached endpoits changes.

for example, publisher online -> get_sub_count called and 0 returns -> subscriber online -> subscriber offline -> get_sub_count called and 0 returns, this case it appears that nothing has happened in the network connectivity. but it actually did. the same thing could happen that publisher can see the same 1 count of subscription, but this subscription could be a different one in between get_count API calls. with matched events, we can see those changes for sure, so that could be one of the difference too.

@Barry-Xu-2018 please correct me if i got anything wrong above.

@tonynajjar
Copy link

I see your point about not missing any information in between API calls. Thanks everyone for the clarifications, hopefully that helps more people in the future.

Kotochleb pushed a commit to Kotochleb/image_pipeline that referenced this issue May 27, 2024
This implements ros-perception#780 for ROS 2 distributions after Iron, where we have:

 * Connect/disconnect callbacks, per ros2/rmw#330 (this made it into Iron)
 * Updated APIs in ros-perception/image_common#272 (this is only in Rolling currently)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backlog enhancement New feature or request
Projects
None yet
Development

No branches or pull requests