Skip to content
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

fuse -> ROS 2 fuse_core : Messages and Services #285

Merged
merged 6 commits into from
Dec 7, 2022

Conversation

methylDragon
Copy link
Collaborator

@methylDragon methylDragon commented Nov 12, 2022

See: #276

Description

Just a small PR migrating messages and services.

Namespaces and headers were hit.

The only catch is the migration away from ConstPtrs. I tried to make a judgement call for what types to migrate to, and I left notes in the source for when I thought it was iffy.

I'm also kinda suspicious of the number of ConstSharedPtrs that I threw around.

See 43a59d7 for those changes

EDIT: This will just feature changes for fuse_core, the changes from this will be sprinkled around the other packages as we get to them

Pinging @svwilliams for visibility.

Copy link
Contributor

@svwilliams svwilliams left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In ROS1, I reflexively publish and subscribe using shared ptrs to messages. I notice that has been changed to const refs to messages. I don't know enough about ROS2 yet. Is that the standard practice in ROS2?

@@ -36,7 +36,7 @@
#include <fuse_core/eigen_gtest.h>
#include <fuse_core/uuid.h>
#include <fuse_variables/orientation_3d_stamped.h>
#include <geometry_msgs/Quaternion.h>
#include <geometry_msgs/msg/Quaternion.hpp>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the message isn't used here, feel free to drop the include

fuse_core::Transaction& transaction);

ParameterType params_;

geometry_msgs::PoseWithCovarianceStamped::ConstPtr previous_pose_msg_;
geometry_msgs::msg::PoseWithCovarianceStamped::ConstSharedPtr previous_pose_msg_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If process() is not receiving a shared ptr, there's no reason for the previous pose to be a shared ptr either.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would make sense to leave it a ptr type to prevent copy assignment in the implementation of processDifferential I think?
It's also necessary for the conditional

void Pose2D::processDifferential(const geometry_msgs::msg::PoseWithCovarianceStamped& pose, const bool validate,
                                 fuse_core::Transaction& transaction)
{
  auto transformed_pose = std::make_unique<geometry_msgs::msg::PoseWithCovarianceStamped>();
  transformed_pose->header.frame_id = params_.target_frame.empty() ? pose.header.frame_id : params_.target_frame;

  if (!common::transformMessage(tf_buffer_, pose, *transformed_pose))
  {
    RCLCPP_WARN_STREAM_THROTTLE(node_->get_logger(), *node_->get_clock(), 5.0 * 1000,
                                "Cannot transform pose message with stamp " << pose.header.stamp
                                << " to target frame " << params_.target_frame);
    return;
  }

  if (previous_pose_msg_)
  {
    common::processDifferentialPoseWithCovariance(
      name(),
      device_id_,
      *previous_pose_msg_,
      *transformed_pose,
      params_.independent,
      params_.minimum_pose_relative_covariance,
      params_.loss,
      params_.position_indices,
      params_.orientation_indices,
      validate,
      transaction);
  }

  previous_pose_msg_ = std::move(transformed_pose);  <----------------- here
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I will convert the constsharedptr to unique_ptr, though)

Comment on lines 120 to 121
// TODO(CH3): Oh no, there's no equivalent rclcpp method I think...
// Probably just wait a bit?? It's in a test anyway
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can make a subscriber with a callback that populates a std::future. You can then wait on the future here. It is more work, but it means you are not blocking the unit test longer than is needed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems that there actually is a wait_for_message method in rclcpp. I'll use that when it's time to get around to fuse_optimizers. And if that fails I'll go the condition variable route (instead of futures) 😬

@@ -117,26 +117,26 @@ std::vector<Beacon> createNoisyBeacons(const std::vector<Beacon>& beacons)
/**
* @brief Convert the set of beacons into a pointcloud for visualization purposes
*/
sensor_msgs::PointCloud2::ConstPtr beaconsToPointcloud(
sensor_msgs::msg::PointCloud2::ConstSharedPtr beaconsToPointcloud(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These methods are constructing ROS messages to be published. In ROS1 I always publish messages as shared ptrs. But it seems you have been publishing and subscribing with bare objects in ROS2. If that is the case, you can drop the shared pointer complexity here entirely.

*/
void keepCallback(const geometry_msgs::Point::ConstPtr& msg)
// TODO(CH3): I'm iffy on this...
void keepCallback(const geometry_msgs::msg::Point::ConstSharedPtr msg)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The callback signature for the ThrottledMessageCallback is void(const typename M&). So shouldn't this be void keepCallback(const geometry_msgs::msg::Point& msg)?

@sloretz
Copy link
Collaborator

sloretz commented Nov 30, 2022

In ROS1, I reflexively publish and subscribe using shared ptrs to messages. I notice that has been changed to const refs to messages. I don't know enough about ROS2 yet. Is that the standard practice in ROS2?

@svwilliams Yes, most of the time. It has to do with how intra-process communication is handled. There's more information here: https://docs.ros.org/en/rolling/Tutorials/Demos/Intra-Process-Communication.html

If I understand correctly, in most cases const references are the most efficient. If the code is going to modify the message and re-publish it (like in a sensor processing pipeline), then non-const std::unique_ptr may be a better option as rclcpp can choose to std::move() the message from the publisher to the subscriber.

@sloretz
Copy link
Collaborator

sloretz commented Dec 2, 2022

@ros-pull-request-builder retest this please!

Copy link
Collaborator

@sloretz sloretz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'd recommend making these changes on a per-package basis as each package is ported rather than all at once. That will allow using the compiler to check the paths and types are correct.

@@ -40,8 +40,8 @@
#include <fuse_core/serialization.hpp>
#include <fuse_core/uuid.hpp>
#include <fuse_variables/orientation_3d_stamped.h>
#include <geometry_msgs/PoseWithCovariance.h>
#include <geometry_msgs/Quaternion.h>
#include <geometry_msgs/msg/PoseWithCovariance.hpp>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is actually geometry_msgs/msg/pose_with_covariance.hpp. As far as I know all generated headers in ROS 2 are lowercase with underscores, so same comment throughout the PR

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It also looks like PoseWithCovariance is unused in this file, so this include could be removed.

@methylDragon
Copy link
Collaborator Author

I think I'd recommend making these changes on a per-package basis as each package is ported rather than all at once. That will allow using the compiler to check the paths and types are correct.

Could we just get this in first and adjust as we go up the stack? Otherwise it'll be a guaranteed extra step for each package..

@methylDragon
Copy link
Collaborator Author

@ros-pull-request-builder retest this please

@methylDragon methylDragon changed the title fuse -> ROS 2 : Messages and Services fuse -> ROS 2 fuse_core : Messages and Services Dec 2, 2022
fuse_core/test/test_throttled_callback.cpp Show resolved Hide resolved
@@ -74,7 +74,7 @@ class GraphDeserializer
* @return A unique_ptr to a derived Graph object
*/
inline fuse_core::Graph::UniquePtr deserialize(
const fuse_msgs::msg::SerializedGraph::ConstSharedPtr msg) const
const fuse_msgs::msg::SerializedGraph::SharedPtr msg) const
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is just passing through to a method that treats the value as const, I think ConstSharedPtr makes more sense as it would allow both std::shared_ptr<const MessageType> and std::shared_ptr<MessageType> to be pasesd in.

Small example in C++
#include <iostream>
#include <memory>

void const_func(std::shared_ptr<const double> dp)
{
  std::cout << "Const Got some double: " << *dp << "\n";
}

void non_const_func(std::shared_ptr<double> dp)
{
  std::cout << "non Const Got some double: " << *dp << "\n";
}


int main()
{
  auto const_dp = std::make_shared<const double>(42.0);
  auto non_const_dp = std::make_shared<double>(13.0);

  const_func(const_dp);
  const_func(non_const_dp);


  // Can't do this
  // non_const_func(const_dp);
  //
  // because:
  //    $ g++ -std=c++17 a.cpp 
  //    a.cpp: In function ‘int main()’:
  //    a.cpp:23:18: error: could not convert ‘const_dp’ from ‘shared_ptr<const double>’ to ‘shared_ptr<double>’
  //       23 |   non_const_func(const_dp);
  //          |                  ^~~~~~~~
  //          |                  |
  //          |                  shared_ptr<const double>
  //

  non_const_func(non_const_dp);

  return 0;
}

fuse_core::Transaction deserialize(const fuse_msgs::msg::SerializedTransaction::SharedPtr msg)
const;
inline fuse_core::Transaction::UniquePtr deserialize(
const fuse_msgs::msg::SerializedTransaction::SharedPtr msg) const
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment about ConstSharedPtr

@sloretz
Copy link
Collaborator

sloretz commented Dec 2, 2022

@ros-pull-request-builder retest this please

Copy link
Collaborator

@sloretz sloretz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM if the Rpr job comes back green

@methylDragon
Copy link
Collaborator Author

@ros-pull-request-builder retest this please

@methylDragon
Copy link
Collaborator Author

methylDragon commented Dec 3, 2022

Rpr is unstable due to deadlocking issues.
#294 should be merged first to fix it.

@methylDragon methylDragon force-pushed the rolling-msg-srv branch 2 times, most recently from 71d6264 to 15499e1 Compare December 3, 2022 05:05
@methylDragon
Copy link
Collaborator Author

@ros-pull-request-builder retest this please

Signed-off-by: methylDragon <methylDragon@gmail.com>
Signed-off-by: methylDragon <methylDragon@gmail.com>
Signed-off-by: methylDragon <methylDragon@gmail.com>
Signed-off-by: methylDragon <methylDragon@gmail.com>
Signed-off-by: methylDragon <methylDragon@gmail.com>
Signed-off-by: methylDragon <methylDragon@gmail.com>
@methylDragon methylDragon merged commit 4c87579 into locusrobotics:rolling Dec 7, 2022
@methylDragon methylDragon deleted the rolling-msg-srv branch December 7, 2022 21:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants