-
Notifications
You must be signed in to change notification settings - Fork 70
add: get clients, servers info #371
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
base: rolling
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think in rmw service endpoints are handled as topics internally, precisely client is DataReader
and server is DataWriter
to fill in the topic endpoint information. so all the field of rmw_topic_endpoint_info_t
can be filled in with calling the graph cache.
IMO i think in rmw we can use rmw_topic_endpoint_info_t
as it is now, but i would add comment that says this structure is used for service client and server as well.
@wjwwood Mind taking a look at this new rmw API 🧇 ? |
@leeminju531 , any updates from your end? |
Signed-off-by: Minju, Lee <dlalswn531@naver.com>
Signed-off-by: Minju, Lee <dlalswn531@naver.com>
2c52767
to
3ac5f99
Compare
@methylDragon @fujitatomoya, Updated with underlying implementations first:). |
@leeminju531 thanks for putting the effort on this. i will do the another review once they are ready, so please let me know. |
Sorry for the late response 🙃 Based on ros2/ros2cli#916 (comment), we need service information from I came up with the following structure. Could you take a look and let me know your thoughts? typedef struct RMW_PUBLIC_TYPE rmw_service_endpoint_info_s
{
/// Information about an internally used topic for service communication.
/// For clients, this field contains a DataReader, while for servers, it holds a DataWriter.
/// Nullptr for systems that explicitly support services without using topics.
rmw_topic_endpoint_info_t * internal_topic_info;
/// The name of the node providing the service.
const char * node_name;
/// The namespace of the node providing the service.
const char * node_namespace;
/// The type name of the associated service.
const char * service_type;
/// A hash representing the service type's description.
/// Nullptr for systems without explicit service support.
/// This may be populated in future implementations.
rosidl_type_hash_t * service_type_hash;
/// Specifies whether the endpoint is a CLIENT or SERVER.
rmw_endpoint_type_t endpoint_type;
/// Globally unique identifier (GID) of the endpoint.
/// Initialized to zeros (0) for systems without explicit service support.
/// In future implementations, this may be used to uniquely identify the endpoint.
uint8_t endpoint_gid[RMW_GID_STORAGE_SIZE];
/// The QoS profile applied to the service's communication.
/// This is typically shared for both request and response messages
/// as they often use the same communication characteristics.
rmw_qos_profile_t qos_profile;
} rmw_service_endpoint_info_t; |
@leeminju531 glad you came back 😃 let me have some time, i will bring this up to next PMC meeting. |
@leeminju531 we had a discussion on the information from |
@fujitatomoya Here’s the revised typedef struct RMW_PUBLIC_TYPE rmw_service_endpoint_info_s
{
/// The name of the node providing the service.
const char * node_name;
/// The namespace of the node providing the service.
const char * node_namespace;
/// The type name of the associated service.
const char * service_type;
/// A hash representing the service type's description.
rosidl_type_hash_t * service_type_hash;
/// Specifies whether the endpoint is a CLIENT or SERVER.
rmw_endpoint_type_t endpoint_type;
/// The Globally Unique Identifier (GID) of the endpoint.
/// For systems without explicit service support, this retrieves the Writer's GID.
uint8_t endpoint_gid[RMW_GID_STORAGE_SIZE];
/// The Quality of Service (QoS) profile applied to the service's communication.
/// This is typically shared between the request and response messages as they often use the same communication settings.
rmw_qos_profile_t qos_profile;
} rmw_service_endpoint_info_t; Modifications:
One thing I’m still unsure about is the PS: I’ll be more available in two months and can dive into the details then. |
Dear @fujitatomoya , @wjwwood I implemented a quick prototype based on the definition provided above. The definition appears suitable for middleware that explicitly support services, such as Zenoh.
After further consideration, I revised the structure as follows: typedef struct RMW_PUBLIC_TYPE rmw_service_endpoint_info_s
{
/// Name of the node
const char * node_name;
/// Namespace of the node
const char * node_namespace;
/// The associated service type's name
const char * service_type;
/// The endpoint type. (CLIENT or SERVER)
rmw_endpoint_type_t endpoint_type;
/// Specifies whether the middleware explicitly supports services (e.g., Zenoh).
/// The `endpoint_count` value is determined as follows:
/// - 1 if the middleware explicitly supports services.
/// - 2 if request/response are represented as separate reader/writer topics.
size_t endpoint_count;
/// Hashed value for service type's description
rosidl_type_hash_t * service_type_hashes;
/// The GID of the endpoint
uint8_t (*endpoint_gids)[RMW_GID_STORAGE_SIZE];
/// QoS profile of the endpoint
rmw_qos_profile_t * qos_profiles;
} rmw_service_endpoint_info_t; In this revised structure, I introduced the Here’s the output when using Zenoh (an explicit service middleware): If the middleware does not support explicit services, the output would look like this: Node name: minimal_service
Node namespace: /
Service type: example_interfaces/srv/AddTwoInts
Service type hashes:
- RIHS01_e118de6bf5eeb66a2491b5bda11202e7b68f198d6f67922cf30364858239c81a
- RIHS01_e118de6bf5eeb66a2491b5bda11202e7b68f198d6f67922cf30364858239c81b
Endpoint type: SERVER
Endpoint count: 2
GIDs:
- c1.e9.6a.12.53.b3.5e.28.c7.25.0b.30.36.53.8a.ad
- c1.e9.6a.12.53.b3.5e.28.c7.25.0b.30.36.53.8a.ae
QoS profiles:
- Reliability: RELIABLE
History (Depth): KEEP_LAST (10)
Durability: VOLATILE
Lifespan: Infinite
Deadline: Infinite
Liveliness: AUTOMATIC
Liveliness lease duration: Infinite
- Reliability: RELIABLE
History (Depth): KEEP_LAST (10)
Durability: VOLATILE
Lifespan: Infinite
Deadline: Infinite
Liveliness: AUTOMATIC
Liveliness lease duration: Infinite
Please let me know if you need further adjustments or improvements. I would greatly appreciate any feedback or suggestions to ensure it is as effective as possible. Thanks! |
@leeminju531 thanks for the update and checking in details. images are broken, especially for zenoh one, could you attach it again? |
i think service type needs to be collected from service typesupport, and that is what rmw_zenoh does with do you happen to have any thought how to manage service type hash in the graph for DDS rmws?
this is true. Requested QoS and actual one can be different, and there is no unique service entity GID... |
To handle READER/WRITER distinction, I propose we implicitly guide the interpretation by defining the order clearly in the comments. typedef struct RMW_PUBLIC_TYPE rmw_service_endpoint_info_s
{
...
/// GIDs of the endpoints.
/// If `endpoint_count` is 2, ordered as [REQUEST_READER, RESPONSE_WRITER].
uint8_t (*endpoint_gids)[RMW_GID_STORAGE_SIZE];
/// QoS profile of the endpoint
/// If `endpoint_count` is 2, ordered as [REQUEST_READER, RESPONSE_WRITER].
rmw_qos_profile_t * qos_profiles;
...
} rmw_service_endpoint_info_t; Then in rclpy or rclcpp, we can explicitly print or represent which is READER or WRITER by reading the order.
Yeah, I agree. I’ll look into it, but it’d be super helpful if someone could share some guidance on how this should be handled properly. |
hmmm, yeah this is hard to come up with good solution. i mean we can add service type hash and graph to the DDS-based rmw implementation like rmw_zenoh, but it always comes back to QoS problem... |
@leeminju531 so we talked about this at ROS PMC once again.
what do you think? |
This pull request has been mentioned on ROS Discourse. There might be relevant details there: https://discourse.ros.org/t/ros-pmc-minutes-for-april-22-2025/43346/1 |
@fujitatomoya , Thanks for bringing this up again. As far as I understand, the previous definition is generally acceptable, except for internal topic type hashes. Additionally, we could explore a cleaner or more user-friendly way to display this information in ros2cli at the rclpy layer like this. Right now, the challenge I’m facing is retrieving the |
Add get clients, servers info
Refer to ros2/ros2cli#916