-
Notifications
You must be signed in to change notification settings - Fork 650
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
Adding support for ON_REQUESTED_INCOMPATIBLE_QOS and ON_OFFERED_INCOMPATIBLE_QOS event callbacks in ROS2. #822
Comments
ON_REQUESTED_INCOMPATIBLE_QOS
and ON_OFFERED_INCOMPATIBLE_QOS
event callbacks in ROS2.
@ivanpauno Could you please take a look at this? The PRs are also open for review. |
Extra feature: Adding incompatible event callbacks to |
I gave an initial review of the connect pull requests. I think we need to do a few things related to
I'm inclined to be flexible on these points, so we can get it in if possible, because for the implementations where it does work it will be very useful. |
@wjwwood, if the user registers incompatible QoS event callbacks and the RMW implementation being used does not support it, how about we log a warning and the user's callbacks will never be triggered? If the user does not register any incompatible QoS event callbacks, we do not log/issue such a warning. |
I don't feel like a warning is sufficient myself. If the user wanted a callback for this, it should fail programmatically with an exception or return code. If the user chooses to do so, they may ignore this error and log a warning themselves. But allowing it to essentially pass silently when the user asks to be called when this event occurs (warnings from libraries are often overlooked) I think is a bad idea. Also, I think unless the user defines their own callback it would be nice to have a default callback which logs a warning when this event occurs. It would be ok, in this default case, to ignore such an error as "unimplemented" I think. Though I'd like to see a notice or warning that this is the case, something like (once) "[WARN] the rmw implementation being used does not support ON_REQUESTED_INCOMPATIBLE_QOS events, you will not be notified when publishers and subscribers on the same topic do not have matching QoS". |
Okay, that's reasonable. Between throwing an exception and returning an error code, this is how I imagine them:
I think having a default callback is a good idea as well. |
Registration of this callback happens at creation of the pub/sub right? In that case I think it would be best to just have the creation fail. The caller can check the reason and retry without the callback if they so chose. That would avoid the need for "is supported" like API's. |
Correct, the registration of the callbacks happen at the creation of the publisher/subscription. "Is supported"-like APIs would still be needed even if we're returning an error code instead of an exception on creation of the publisher/subscription, or else those callbacks would just simply never fire. Would returning an error code work? If the creation of a publisher/subscription fails, it will return a NULL EDIT: Oh okay, I think you're saying fail at the |
Oh I see, nvm, you're right that the support is not checked below rmw at creation of the pub/sub. Instead, we could check if you tried to add those to the wait set and error at that point. So you'd get no exception if you created a pub/sub with the callback registered, but when you tried to spin on it, then it would fail due to not supporting that kind of event in the wait set. |
I think there might be a way. When EDIT: Oh, it actually looks like |
That sounds like a bad experience. How would the user code respond at the point? It would need to recreate a bunch of publishers and subscriptions, as we don't support removing callbacks from already created publishers/subscriptions. Even if we did, I think that would make the user's code quite messy (ie. create publishers/subscriptions, do a trial spin, remove some callbacks, start spinning for real). I think if we're okay with seeing errors after spinning starts (instead of at time of publisher/subscription creation / before spinning starts), having the callback return a It looks like in order to see errors before spinning starts, new APIs would be needed. |
I agree, I was just offering that we could check there too. Sounds like checking when we create the event types is the right way to do it. |
So we'll add a new |
👍
Can't |
That's what I am suggesting we do, but |
Oh, I didn't see that that function was implemented in |
I think we still haven't settled on how
What do you think, @wjwwood and @ivanpauno? |
That's the best option IMO. |
Is it recommendable for a function in |
Yeah, that's what I found out.
I have indeed implemented it this way. The following are the set of pull requests related to this feature:
( |
If there are no strong objections, I'd like to keep it the way it is. We're now at least able to properly check the |
I don’t care strongly either though I have a slight preference for keeping it as is. It leaves the door open for other optimizations for the middleware impl and it ensures we don’t get in an inconsistent state event wise (if someone were to use rmw directly but not check if it is supported first, for example). |
@mm318 It would be great to open a PR in |
Looking at the code in @ivanpauno, perhaps do you think this should be a made into a |
I think that a custom exception (e.g.: |
This one still should be finished with the others: ros2/rclpy#459. |
First set have been merged! |
@wjwwood can we implement this as a follow-up? |
Yeah, sure. |
I have opened issues ros2/rclcpp#1048 and ros2/rclpy#533 for tracking the addition of default incompatible QoS callbacks to |
All implementation work (except for |
Feature description
Currently, it is possible for ROS2 users to create publishers and subscriptions to a topic with incompatible QoS policies; for example: subscription to a topic with a deadline smaller than the deadline for a publisher to the topic. This results in the subscription not receiving any data even though the publisher is publishing to the topic. These scenarios are difficult to debug and hence the user needs to be notified/warned when they create publishers/subscriptions with incompatible QoS Policies.
Thankfully, the DDS spec has callbacks in place which help with this, namely
on_requested_incompatible_qos
andon_offered_incompatible_qos
.Implementation considerations
The implementation can follow the same procedure as the existing event callbacks (
on_offered_deadline_missed
,on_requested_deadline_missed
,on_liveliness_lost
andon_liveliness_changed
).Listing out briefly the work required in each package:
ros2/rmw
RMW_EVENT_REQUESTED_INCOMPATIBLE_QOS
andRMW_EVENT_OFFERED_INCOMPATIBLE_QOS
values to the enumrmw_event_type_t
rmw_requested_incompatible_qos_status_t
andrmw_offered_incompatible_qos_status_t
.Something like this:
Note:
QosPolicyCountSeq policies
is something that I have skipped and would like to add as an enhancement once this is completed and merged. This is because we need to figure out how memory allocation for thepolicies
array would work. For now these would alone provide a non zero enhancement to the system as users will be notified when creating incompatible qos policies between publishers and subscribersros2/rcl
RCL_PUBLISHER_OFFERED_INCOMPATIBLE_QOS
andRCL_SUBSCRIPTION_REQUESTED_INCOMPATIBLE_QOS
to enumsrcl_publisher_event_type_t
andrcl_subscription_event_type_t
respectively.RCL_PUBLISHER_OFFERED_INCOMPATIBLE_QOS
andRCL_SUBSCRIPTION_REQUESTED_INCOMPATIBLE_QOS
inside ofrmw_publisher_event_init
andrmw_subscriber_event_init
ros2/rclpy
RCL_PUBLISHER_OFFERED_INCOMPATIBLE_QOS
andRCL_SUBSCRIPTION_REQUESTED_INCOMPATIBLE_QOS
to enumsQoSPublisherEventType
andQoSSubscriptionEventType
rmw_requested_incompatible_qos_status_t
andrmw_offered_incompatible_qos_status_t
that were defined in thermw
package. These are defined as follows:SubscriptionEventCallbacks
andPublisherEventCallbacks
classes to support the newincompatible_qos
callback.incompatible_qos
create_event_handlers
function_rclpy_qos_event.c
rmw_requested_incompatible_qos_status_t
andrmw_offered_incompatible_qos_status_t
to the union_qos_event_callback_data
rmw_requested_incompatible_qos_status_t
andrmw_offered_incompatible_qos_status_t
toPyObject
and return these in the_get_qos_event_data_filler_function_for
functionros2/rclcpp
PublisherEventCallbacks
andSubscriptionEventCallbacks
structs to include a newincompatible_qos_callback
. These callback members should be of typestd::function<void (rmw_offered_incompatible_qos_status_t &)>
andstd::function<void (rmw_requested_incompatible_qos_status_t &)>
respectively.Publisher
andSubscription
ros2/demos
quality_of_service_demo
package; using bothrclpy
andrclcpp
DDS Implementations
ros2/rmw_fastrtps
: Unfortunately, Fastrtps does not have this implemented. I have raised an issue regarding this here.ros2/rmw_opensplice
: Opensplice does have this feature implemented and the work on thermw_implementation
package would be:RMW_EVENT_REQUESTED_INCOMPATIBLE_QOS -> DDS::REQUESTED_INCOMPATIBLE_QOS_STATUS
andRMW_EVENT_OFFERED_INCOMPATIBLE_QOS -> DDS::OFFERED_INCOMPATIBLE_QOS_STATUS
DDS::OFFERED_INCOMPATIBLE_QOS_STATUS
andDDS::REQUESTED_INCOMPATIBLE_QOS_STATUS
inOpenSpliceStaticPublisherInfo::get_status
andOpenSpliceStaticSubscriberInfo::get_status
respectively.ros2/rmw_connext
: Research pending; but from this, I reckon that it is implemented.List of PRs to be tracked towards this:
The text was updated successfully, but these errors were encountered: