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

QoS for Clients and Services #391

Open
samouwow opened this issue Apr 15, 2024 · 6 comments
Open

QoS for Clients and Services #391

samouwow opened this issue Apr 15, 2024 · 6 comments

Comments

@samouwow
Copy link

samouwow commented Apr 15, 2024

The API for creating new clients and services (create_client() and create_service()) doesn't allow for specifying non-default QoS.

From what I can tell, adding the ability to specify QoS should be as simple as passing a QosProfile structure through to the client_options / service_options parameter of the rcl_init functions.

I'm happy to open a PR to add this feature but before I do, I wanted to ask:

  1. Is there a reason create_client() and create_service() don't currently allow for a QoS profile?
  2. It seems the cleanest way to add this feature will be to modify the existing node function signatures, is there as standard way to make breaking changes like this? (E.g. just go ahead, or make a new function and deprecate the old one?)
@Guelakais
Copy link
Contributor

Guelakais commented Apr 17, 2024

I had the same problem. You can simply create your own QoSprofile or modify an existing QosProfile. This then works as follows:

fn new(context: &Context) -> Result<Self, RclrsError> {
        let node = create_node(context, "simple_publisher").unwrap();
        let _publisher = node
            .create_publisher("publish_hello", QOS_PROFILE_DEFAULT.keep_last(5))
            .unwrap();
        Ok(Self { node, _publisher })
    }

In this example, the QoSprofile que depth was adjusted using the keeplast() method. This is exactly how you can adjust any value of an existing QoSprofile. Unfortunately, I only found the methods in github. If you have any more questions about the Qosprofile implementation of rclrs, just ask me. I am currently working with it.

Ah. Hang on, wait a minute. Could it be that you are not allowed to create the QosProfile for services? In the Python and the cpp API for ros2 this is not possible either.

@mxgrey
Copy link
Collaborator

mxgrey commented Apr 17, 2024

I think custom QoS is discouraged for clients and services because there's a significant risk that they'll misbehave if you give them anything other than reliable quality.

That being said I think it could be reasonable to customize some things like history depth. I'm not sure what the default service setting is for depth, but I can imagine a very busy service could get overwhelmed if that value isn't high enough.

@samouwow
Copy link
Author

samouwow commented May 20, 2024

@Guelakais thanks for the example, are you suggesting I use a standard publisher instead of a client as a workaround for custom QoS?

Ah. Hang on, wait a minute. Could it be that you are not allowed to create the QosProfile for services? In the Python and the cpp API for ros2 this is not possible either.

It seems it's possible, just hidden behind default arguments (for both rclpy and rclcpp).

That being said I think it could be reasonable to customize some things like history depth. I'm not sure what the default service setting is for depth, but I can imagine a very busy service could get overwhelmed if that value isn't high enough.

@mxgrey I think customising history is a good example. It's currently set via the rcl_client_get_default_options() function, which uses rmw_qos_profile_services_default (reliable, history 10). My specific use case uses a service to change a closed-loop set point in a micro-controller, which then echos back a confirmation. Given the resource constrained environment, Best_Effort gives a significant performance improvement over Reliable, hence my need to customise the QoS.

As an additional argument in support of setting custom QoS, rclrs already has QOS_PROFILE_SERVICES_DEFAULT. If the create_client() function was updated to better align with create_subscription() (and the same for servers / publishers), users would simply need to pass this existing default QoS in to get the current behaviour.

@Guelakais
Copy link
Contributor

Ros2 publishers and subscribers are different from clients and services. Currently in rclrs, custom QoS profiles are only allowed for publishers and subscribers. Not for clients or services. I won't recommend changing the currently implemented methods for creating services or clients, because the underlying struct itself only uses the nodehandle struct, which in turn only uses predefined links from the rcl_bindings. Individual access by rclrs clients and services to the already implemented QoS profiles is not yet implemented at all.
At the moment there is simply a lack of a proper implementation, which would be necessary to be able to assign a custom QoS to a client or service at all.

@samouwow
Copy link
Author

@Guelakais I believe I've achieved it with only minor changes to the rclrs client/server code. All that really needed to happen was to connect an API to the rcl QoS struct used to create the client/server.

Would you mind taking a peek at the PR and let me know how that aligns with your comment?

@Guelakais
Copy link
Contributor

We will see. :)

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

No branches or pull requests

3 participants