[ros-users] [Discourse.ros.org] [Next Generation ROS] Help to implement an other RMW
ros.discourse at gmail.com
Tue Apr 11 23:14:38 UTC 2017
[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)
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:
In C++, the same thing is done, but using a template instead of a macro to get the specialized function name:
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 ?
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.
More information about the ros-users