-
Notifications
You must be signed in to change notification settings - Fork 36
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
Fixed missing C interfaces to obtain service and action type support. #114
Conversation
Signed-off-by: Stefan Fabian <[email protected]>
@sloretz Any idea when you could take a look at it? This is a small change but essential for two large ROS2 libraries that I would like to release in the next week(s). |
This pull request has been mentioned on ROS Discourse. There might be relevant details there: https://discourse.ros.org/t/ros2-babel-fish-released/25201/1 |
bump |
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 I understand the context, and I like the direction this is heading. @StefanFabian would you be willing to do the following? @clalancette thoughts?
- Target this PR at the
master
branch. We'll backport it using mergify, and I'm sure these additions can be backported. - Open a PR to
rosidl_generator_cpp
to declare these functions for actions, services, and messages. None of the existing headers fit so I'd recommend putting them into newaction|msg|srv__type_support.hpp
headers to be included here
If I understand correctly, rosidl_typesupport_interface
defines macros to be used to get handles to typesupports. These macros are defining a C API. If you know the name of the message then you can get the typesupport handle through it. The trouble is it's not consistently implemented.
C typesupport uses rosidl_typesupport_interface
consistently - probably because it has no alternative
rosidl_generator_c
rosidl_typesupport_c
rosidl_typesupport_introspection_c
- Doesn't appear to support actions? Oops!
- Declares the symbol for services here
- Declares the symbol for messages here
- Defines the symbol for services here
- Defines tye symbol for messages here
C++ typesupport doesn't consistently implement rosidl_typesupport_interface
rosidl_generator_cpp
- Does not declare any functions to implement
rosidl_typesupport_interface
for actions, services, or messages
- Does not declare any functions to implement
rosidl_typesupport_cpp
- Does not define functions to implement
rosidl_typesupport_interface
for actions and services - Defines the function for messages here
- Does not define functions to implement
rosidl_typesupport_introspection_cpp
- Doesn't appear to support actions? Oops again!
- Declares the function for services here
- Declares the function for messages here
- Defines the function for services here
- Defines the function for messages here
Instead what's happening in C++ is it's relying on a different interface that gets the typesupport from the C++ type.
rosidl_runtime_cpp
rosidl_typesupport_cpp
I think it's fine for the C++ to have it's own interface, but I think it should implement the rosidl_typesupport_interface
API too. That's what this PR does 🎉
Not to be done here (maybe in the future, I'll open a ticket), but now that I think I understand it I would implement C++'s templated methods differently. I think it'd be more consistent and simpler to have rosidl_generator_cpp
generate get_*_type_support_handle<T>()
in a header file that returned the result of calling the C API defined by rosidl_typesupport_interface
.
Thanks @sloretz for taking a look at this. Sorry for the late reply. |
Okay, not as simple as I've thought. |
@sloretz I've targeted the master here and created a PR for the declaration of the getter methods. |
Is any additional work needed on this PR to get it merge-ready? |
**Public-Facing Changes** - Add ROS2 support for calling server-advertised services **Description** Based on #136 - Adds experimental ROS2 support for advertising/unadvertising services and allowing clients to call them - Implements the services spec that was added in foxglove/ws-protocol#344 Implementation details: The main problem is, that symbols from getting the service type support are missing from the `rosidl_typesupport_cpp` libraries that are generated for each msg/srv package (see ros2/rosidl_typesupport#122). There is an open pull request (ros2/rosidl_typesupport#114) to fix that, but so far it hasn't been merged. I found a working, yet little bit hacky, workaround for this problem which is described more in detail here: https://github.com/foxglove/ros-foxglove-bridge/blob/f978c182185e5deda93a6518132b6d3c339dcaeb/ros2_foxglove_bridge/src/generic_client.cpp#L59-L89 All in all, the implementation is working, but I would consider it as experimental for now. I am not sure if this approach would work on windows / mac
This pull request has been mentioned on ROS Discourse. There might be relevant details there: |
{ | ||
#endif | ||
|
||
ROSIDL_TYPESUPPORT_CPP_PUBLIC |
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.
ROSIDL_GENERATOR_CPP_PUBLIC_@(package_name)
to match ros2/rosidl#703. Mind fixing the one in msg__type_support.cpp.em
too?
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.
The problem is that rosidl_typesupport_cpp
does not depend on rosidl_generator
so I would have to create a visibility header for rosidl_typesupport_cpp
as well.
I can do that but I'm not really sure what for since these libraries are built for dynamic loading anyway and I don't see why anyone should want this method to be anything other than always visible.
However, I'm not 100% sure I understand all use cases of visibility control so if you think that makes sense I can add it.
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.
In general, the PUBLIC macros are mostly there for Windows compatibility. That is, Windows requires that when compiling a library, these macros are set to dllexport
, and that when using the library, these macros are set to dllimport
.
In this particular case, I think I agree with @StefanFabian in that all of the other functions in this package use ROSIDL_TYPESUPPORT_CPP_PUBLIC
, so we can use that here as well. But maybe @sloretz has something else in mind.
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.
Ah, it looks like the generated library is using the visibility symbol ROSIDL_TYPESUPPORT_CPP_BUILDING_DLL
, so ROSIDL_TYPESUPPORT_CPP_PUBLIC
is the one to use.
This looks a little suspicious to me - as the generated library is package specific. It's also used for rosidl_typesupport_cpp
's library. If the generated library includes a header from another generated library, or from the rosidl_typesupport_cpp
main library, then I think dllimport
/dllexport
would be incorrect for symbols from the included header. I opened an issue since it's an existing problem #142
Ah, looks like the |
I have pushed my local copy of the branch back to my fork, does that work? |
It doesn't look like it, no. GitHub UI still says "This repository has been deleted". |
Ah yeah, I accidentally deleted the entire repository. Can't restore that anymore. I could only make a new PR from my "new" fork. |
So, how do we proceed? @sloretz |
Friendly reminder @sloretz @clalancette |
In the hopes that this will help judge the importance of accepting this. Just this little change would allow extremely easily and quickly creating hardware-accelerated user interfaces (for operation or quick visual debugging) such as the one pictured with this already released currently only partially functional package qml_ros2_plugin. |
I just wanted to add my 👍 to @StefanFabian's comment, but more than just a reaction emoji. I have StefanFabian/qml_ros2_plugin#3 open, but without support for services and actions, utility of It would be great if we could get the change proposed here merged. |
{ | ||
#endif | ||
|
||
ROSIDL_TYPESUPPORT_CPP_PUBLIC |
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.
Ah, it looks like the generated library is using the visibility symbol ROSIDL_TYPESUPPORT_CPP_BUILDING_DLL
, so ROSIDL_TYPESUPPORT_CPP_PUBLIC
is the one to use.
This looks a little suspicious to me - as the generated library is package specific. It's also used for rosidl_typesupport_cpp
's library. If the generated library includes a header from another generated library, or from the rosidl_typesupport_cpp
main library, then I think dllimport
/dllexport
would be incorrect for symbols from the included header. I opened an issue since it's an existing problem #142
@StefanFabian This needs one more rebase to catch up with all of the latest changes (I've tested it locally, and it is a trivial rebase). Once you've done that and pushed this, I'll go ahead and run CI on this and ros2/rosidl#703 together. |
I have rebased in #143 and am closing this in favor of this new PR that can be modified. |
Are backports to foxy and humble planned? |
For foxy, definitely not. It is EOL in a week. For humble, I guess we could consider it, but we'll have to make sure there are no ABI changes from merging these PRs. If you'd like to go ahead and verify that, we can then open the backport PRs. |
@clalancette PR ros2/rosidl#703 only declares new free functions (non-member functions) and this PR implements them. According to GCC section Allowed Changes, adding an exported function is an ABI-compatible change. |
Should I create a humble backport PR? |
@StefanFabian that would be highly appreciated. I think I could do it as well if you don't have time for it. |
I'm on vacation until next week Tuesday, so I can't do it before some time end of next week. |
Would also greatly appreciate this. We were just looking at how to handle this with our team and it would save us a lot of headache. |
For
There are similar errors for messages too. The workaround involves a
Can someone explain how the above will change once the fix is back-ported to |
I have limited experience in this area, so correct me if I'm wrong, but I would imagine this workaround wouldn't be needed any longer. Instead the interfaces would just need to be rebuilt with the back-ported fix. |
Tried the backport myself, but I'm unable to make it work.
All failing on @StefanFabian your help would be much appreciated. I'm willing to help test and verify that this works, but I don't know how to proceed. |
Currently, only message type support contains a C interface to dynamically load the type support from a library.
This PR adds a C interface for services and actions.