[Discourse.ros.org] [Next Generation ROS] Help to implement an other RMW

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

[Discourse.ros.org] [Next Generation ROS] Help to implement an other RMW

Joshua Whitley via ros-users



This post is following [a previous github issue](https://github.com/ros2/rmw/issues/99).

Thank you for your answer, @wjwwood

I understand better. But I have an other question.

If for example I want to receive a message of type `std_msgs::msg::String`, does it implies that the parameter `ros_message` of `rwm_take`, which is a `void*` should be casted in `std_msgs::msg::String` ? (I tried so, and the [c++ listener example](https://github.com/ros2/demos/blob/master/demo_nodes_cpp/src/topics/listener.cpp) worked)

Does it mean that if an example is written in an other language (C, for example), it should be casted into `std_msgs__msg__String` ? How do rmw manages that ?

I guess all this should be handled by "rosidl typesupport things", but since it is generated, I have a hard time to understand what happens there.






---
[Visit Topic](https://discourse.ros.org/t/help-to-implement-an-other-rmw/1639/1) or reply to this email to respond.


If you do not want to receive messages from ros-users please use the unsubscribe link below. If you use the one above, you will stop all of ros-users from receiving updates.
______________________________________________________________________________
ros-users mailing list
[hidden email]
http://lists.ros.org/mailman/listinfo/ros-users
Unsubscribe: <http://lists.ros.org/mailman//options/ros-users>
Reply | Threaded
Open this post in threaded view
|

[Discourse.ros.org] [Next Generation ROS] Help to implement an other RMW

Joshua Whitley via ros-users



[quote="astralien3000, post:1, topic:1639"]
If for example I want to receive a message of type std_msgs::msg::String, does it implies that the parameter ros_message of rwm_take, which is a void* should be casted in std_msgs::msg::String ? (I tried so, and the c++ listener example worked)
[/quote]

Yes. The type you need to pass to `take` and `publish` is determined by the `rosidl_message_type_support_t` structure you give when creating the `publisher` or `subscription`.

For messages in C, there is a macro `ROSIDL_GET_MSG_TYPE_SUPPORT` which when given a message type as arguments will resolve to a C function name:

https://github.com/ros2/rosidl/blob/master/rosidl_generator_c/include/rosidl_generator_c/message_type_support_struct.h#L46-L48

In C++, the same thing is done, but using a template instead of a macro to get the specialized function name:

https://github.com/ros2/rosidl/blob/master/rosidl_generator_cpp/include/rosidl_typesupport_cpp/message_type_support.hpp#L24-L25

In either case the resulting function name/namespace encapsulates:

- The typesupport system
- The message package
- The message name
- The native language (C or C++)

This function will return a `rosidl_message_type_support_t` structure which is tailored to that combination.

The "typesupport system" is basically a way to select one of a few typesupport implementations. Some are specific to a particular DDS vendor, like [rosidl_typesupport_connext_c](https://github.com/ros2/rmw_connext/tree/master/rosidl_typesupport_connext_c) for C
 or [rosidl_typesupport_connext_cpp](https://github.com/ros2/rmw_connext/tree/master/rosidl_typesupport_connext_cpp) for C++, but other implementations (like Fast-RTPS) use a general type support implementation called [rosidl_typesupport_introspection_c](https://github.com/ros2/rosidl/tree/master/rosidl_typesupport_introspection_c)
 for C or [rosidl_typesupport_introspection_cpp](https://github.com/ros2/rosidl/tree/master/rosidl_typesupport_introspection_cpp) for C++.

These different implementations of typesupport essentially determine how serialization occurs, but can be responsible for other things as well.

The message package and name uniquely identify the message, so the same type support structure cannot be used for `std_msgs::msg::String` and `std_msgs::msg::Int64`. You need a unique one for each message type. This is typically ok, since publishers and subscriptions only work with one type at a time (at least for now).

Finally, the rosidl structure is unique to the native language for the message type. I use the term native language because a C client library and the Python client library might both use the C type support system. We have a specialized C++ type support system so we don't have to use the C message structures directly in C++ and so that we don't have to convert C++ message structures to C at any point. Practically it means that if you, for example, create a `publisher` of type `std_msgs/String` using the `rosidl_message_type_support_t` structure for C, then you can only publish `std_msgs__msg__String` with it and you cannot publish messages of the C++ type `std_msgs::msg::String`.

I know that seems complicated, but it's the most straightforward way we have found to delegate serialization of custom types. DDS uses a very similar system for separating message type agnostic code from the message specific code.

Unfortunately the C code requires us to lose type safety when calling `publish`, for example. Nothing stops you from creating a publisher for one type but passing a different type into the `void *` argument of `rcl_publish` except that we say it's undefined behavior.

In C++, however, we're able to use templates and RTTI to enforce the types match, at least. We're even able to enforce this at compile time in some cases.

Hopefully that gives you (and others that come across this) a basic understanding of the moving parts are and why they exist.

[quote="astralien3000, post:1, topic:1639"]
Does it mean that if an example is written in an other language (C, for example), it should be casted into std_msgs__msg__String ? How do rmw manages that ?
[/quote]

As I described above, if you want to use C++ message types, then you need to specify that when creating the publisher or subscription. If you have a C message type, but the publisher is C++, then you'd need to convert (i.e. copy not cast) the C data structure to a C++ one first.






---
[Visit Topic](https://discourse.ros.org/t/help-to-implement-an-other-rmw/1639/2) or reply to this email to respond.


If you do not want to receive messages from ros-users please use the unsubscribe link below. If you use the one above, you will stop all of ros-users from receiving updates.
______________________________________________________________________________
ros-users mailing list
[hidden email]
http://lists.ros.org/mailman/listinfo/ros-users
Unsubscribe: <http://lists.ros.org/mailman//options/ros-users>
Reply | Threaded
Open this post in threaded view
|

[Discourse.ros.org] [Next Generation ROS] Help to implement an other RMW

Joshua Whitley via ros-users
In reply to this post by Joshua Whitley via ros-users



Thanks for your detailed answer !






---
[Visit Topic](https://discourse.ros.org/t/help-to-implement-an-other-rmw/1639/3) or reply to this email to respond.


If you do not want to receive messages from ros-users please use the unsubscribe link below. If you use the one above, you will stop all of ros-users from receiving updates.
______________________________________________________________________________
ros-users mailing list
[hidden email]
http://lists.ros.org/mailman/listinfo/ros-users
Unsubscribe: <http://lists.ros.org/mailman//options/ros-users>