-
Notifications
You must be signed in to change notification settings - Fork 278
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
Provide direct serialization of ROS2 messsage to ROS1 streams #381
Provide direct serialization of ROS2 messsage to ROS1 streams #381
Conversation
Please rebase your PR to incorporate the changes from #377. |
bc435c7
to
555a8f7
Compare
Done |
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 function names in this PR all need re-thinking. Many of them do not say what the function actually does, and some appear to be opposite of what the function does. This makes the code quite hard to read and understand.
Factory< | ||
std_msgs::Duration, | ||
builtin_interfaces::msg::Duration | ||
>::msg_2_to_1_stream( |
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.
Is this function going in the opposite direction to the function above? If so the name is probably incorrect.
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.
Please correct me if I'm wrong, this seems like separate functions for read(IStream), write(OStream) and length(LStream) functionality, nothing to do with ROS 2 to 1 direction? The description mentions use of "same internal function", this is the backbone function overloading?
(applies to other comments below 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.
ROS1 offers an all-in-one function to provide read(), write(), and length() without needing to implement each independently. I'm doing the same with this function.
Here's a tutorial that discusses creation of custom serializers for ROS1
http:https://wiki.ros.org/roscpp/Overview/MessagesSerializationAndAdaptingTypes#Serializer_Specialization
Here's a link to the ROS1 code that implements the "all-in-in" serialization:
https://github.com/ros/roscpp_core/blob/72ce04f8b2849e0e4587ea4d598be6ec5d24d8ca/roscpp_serialization/include/ros/serialization.h#L74
I agree the name is confusing the context of serialization direction. Some other ideas?
- msg_all_in_one_stream
- msg_2_and_1_stream
- msg_2_from_or_to_1_stream
I'm open to any other suggestions for this function name?
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 it would be best to follow the convention of the other functions in ros1_bridge
and use names starting with convert_
.
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.
Made naming change in 3rd commit
include/ros1_bridge/factory.hpp
Outdated
/** | ||
* @brief Reads (deserializes) a ROS2 class directly from a ROS1 stream | ||
*/ | ||
static void read_2_to_1_stream(ros::serialization::IStream & in_stream, ROS2_T & msg); |
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.
This function is named incorrectly.
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.
Should I also change argument ordering for write_2_to_1_stream (above)?
static void write_2_to_1_stream(const ROS2_T & msg, ros::serialization::OStream & out_stream);
static void read_1_to_2_stream(ros::serialization::IStream & in_stream, ROS2_T & msg);
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.
Follow the convention of the existing conversion functions in ros1_bridge
.
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.
Made change to naming in 3rd commit
Factory< | ||
std_msgs::Duration, | ||
builtin_interfaces::msg::Duration | ||
>::msg_2_to_1_stream( |
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.
Please correct me if I'm wrong, this seems like separate functions for read(IStream), write(OStream) and length(LStream) functionality, nothing to do with ROS 2 to 1 direction? The description mentions use of "same internal function", this is the backbone function overloading?
(applies to other comments below too)
72d9149
to
e98cd30
Compare
@gbiggs It looks like some/all the of integration tests were failing because the rosmaster wasn't coming up? |
The |
I'm not trying to emulate the ROS1 naming scheme, I'm am using a strategy from ROS1 to avoid repeating code 3x times.
The write and read functions have been changes to exactly match the naming convention of ros1_bridge. The argument ordering have been changed to be "correct".
|
I think that would be better. |
@gbiggs I made the name change, but couldn't make the function private, because a whole bunch of other Factory types need to use it. |
7914a7a
to
dd4febe
Compare
@gbiggs is it possible to trigger a full test run? |
@gbiggs ping |
Please fix the build failures. |
Signed-off-by: Derek King <[email protected]>
Signed-off-by: Derek King <[email protected]>
Signed-off-by: Derek King <[email protected]>
Signed-off-by: Derek King <[email protected]>
Signed-off-by: Derek King <[email protected]>
dd4febe
to
68a4ddf
Compare
Signed-off-by: Derek King <[email protected]>
I was able to reproduce this build failure by compiling with optimization turned on
It looks like the RelWithDebInfo build causes the internal functions to get inlined inside the generated *.cpp files so there are no symbols for them. I can't define the function specializations in factory.hpp because I can't have a function specialization in a non-specialized class type. Since header files are not generated, its would be difficult add generation of type-specific headers. My work-around is to just use operator overloading for the different stream types instead of templating and template specialization. For example the auto-generated C++ code for PoseStamped now looks like: template<>
void
Factory<
geometry_msgs::PoseStamped,
geometry_msgs::msg::PoseStamped
>::internal_stream_translate_helper(
ros::serialization::OStream & stream,
geometry_msgs::msg::PoseStamped const & ros2_msg)
{
// write non-array field
// write sub message field
Factory<
std_msgs::Header,
std_msgs::msg::Header
>::internal_stream_translate_helper(stream, ros2_msg.header);
// write non-array field
// write sub message field
Factory<
geometry_msgs::Pose,
geometry_msgs::msg::Pose
>::internal_stream_translate_helper(stream, ros2_msg.pose);
}
template<>
void
Factory<
geometry_msgs::PoseStamped,
geometry_msgs::msg::PoseStamped
>::internal_stream_translate_helper(
ros::serialization::IStream & stream,
geometry_msgs::msg::PoseStamped & ros2_msg)
{
// write non-array field
// write sub message field
Factory<
std_msgs::Header,
std_msgs::msg::Header
>::internal_stream_translate_helper(stream, ros2_msg.header);
// write non-array field
// write sub message field
Factory<
geometry_msgs::Pose,
geometry_msgs::msg::Pose
>::internal_stream_translate_helper(stream, ros2_msg.pose);
}
template<>
void
Factory<
geometry_msgs::PoseStamped,
geometry_msgs::msg::PoseStamped
>::internal_stream_translate_helper(
ros::serialization::LStream & stream,
geometry_msgs::msg::PoseStamped const & ros2_msg)
{
// write non-array field
// write sub message field
Factory<
std_msgs::Header,
std_msgs::msg::Header
>::internal_stream_translate_helper(stream, ros2_msg.header);
// write non-array field
// write sub message field
Factory<
geometry_msgs::Pose,
geometry_msgs::msg::Pose
>::internal_stream_translate_helper(stream, ros2_msg.pose);
} I'm now divided on whether I should have internal_stream_translate_helper based on overloading, or I should just have 3 different code generations routines for the different convert and length functions. I'll prototype this out to see if it seems better or worse than this approach. @gbiggs Would it be possible to trigger a CI build on the farm just to see if this makes it through? |
@gbiggs Looks like stuff compiled, but most/all live tests are failing because they can't access the rosmaster ?
|
It looks like just linting issues @gbiggs https://ci.ros2.org/job/ci_packaging_linux/536/testReport/ |
@dbking77 could you fix those linting issues? :> |
Signed-off-by: Derek King <[email protected]>
@gbiggs Fixed linting issues |
@gbiggs Can you re-trigger? apt-get update failed
|
@gbiggs Looks like build/test is failing because of missing release file for Jammy debians. It could just be a problem with http:https://packages.ros.org/ros/ubuntu mirror, but maybe is a problem in general?
|
Where are you seeing that output? |
THe CI / ros1_bridge (pull_request) : https://github.com/ros2/ros1_bridge/actions/runs/3682873863/jobs/6230902918 |
That automatic check hasn't been re-run; the manual CI run I did above passes so we're happy anyway. |
Is there anything else I need to do for this to get merged? |
CI passed, despite the automatic check failing, so merging this. |
Short Description
Provide functions to potentially save some CPU when converting ROS messages by allow "direct" serialization of ROS2 message classes to ROS1 streams.
Long Description
Currently, when ros1_bridge bridges a ROS2 topics to a ROS1 topics, it requires three steps
Using new feature removes a conversion step
Here's what the convert_2_to_1 function looks like geometry_msgs::Vector3
Here's what the direct serialization function looks like (same internal function is used to implement read, write, and length)
Auto-Generated Code Examples
PoseStamped
sensor_msgs::Image
Message Definition
Streaming Code
sensor_msgs::Imu
Imu message definition
Streaming code