ros2 / geometry2

A set of ROS packages for keeping track of coordinate transforms.
BSD 3-Clause "New" or "Revised" License
115 stars 193 forks source link

Memory leak on exception #200

Open maxlein opened 4 years ago

maxlein commented 4 years ago

Bug report

I have 2 nodes which lookup a transform from base_link -> map.
As soon as the map transform is not published anymore, in my case the node crashed, memory usage is increasing linearly as seen on the screenshot.
Probably due to the exception being thrown during lookup.

base_link -> static
odom -> still publishing
map -> stopped publishing

On the screenshot you see a purple line which suddenly ends. ( -> Map Tf publisher died )
And after that 2 lines are linearly increasing. ( memory usage of the 2 nodes which lookup the transform )

image

The exact exception which causes this:
Exception when looking up transform: Lookup would require extrapolation into the past. Requested time 1575061102.81358 but the earliest data is at time 1575275920.42176, when looking up transform from frame [base_link] to frame [map]

Required Info:

Steps to reproduce issue

tf.lookupTransform(targetFrame, tf2_time, sourceFrame, tf2_time, targetFrame);

Expected behavior

Memory usage stays constant

Actual behavior

Memory usage increases linearly

hidmic commented 4 years ago

@maxlein could you provide us with a small repro? I can only infer what tf is in tf.lookupTransform(targetFrame, tf2_time, sourceFrame, tf2_time, targetFrame); or in what context the exception is being thrown.

maxlein commented 4 years ago

This is the exact function I call:

static inline geometry_msgs::msg::TransformStamped getTransform(
        const rclcpp::Node & node,
        const tf2_ros::Buffer & tf,
        std::string targetFrame,
        std::string sourceFrame,
        tf2::TimePoint tf2_time = tf2::TimePointZero,
        tf2::Duration timeout = tf2::Duration(100ms) )
{
   RCLCPP_DEBUG(node.get_logger(), "getTransform for time %ld",
                tf2_time.time_since_epoch().count() );
   return tf.lookupTransform(targetFrame, tf2_time, sourceFrame, tf2_time, targetFrame);
}

To get a working test that results in the exact exception I would need more time. I have a little test, but it doesn't lead to the correct exception and also didn't check if this one leaks yet.

TEST(TFTest, MemoryLeakTest)
{

   rclcpp::Node node("LeakTestNode");
   auto tf = std::make_shared<tf2_ros::Buffer>( node.get_clock() );
   auto tfListener = std::make_shared<tf2_ros::TransformListener>( *tf);
   std::shared_ptr<tf2_ros::TransformBroadcaster> tfBroadcaster = std::make_shared<tf2_ros::TransformBroadcaster>( node.get_node_topics_interface() );

   std::shared_ptr<geometry_msgs::msg::TransformStamped> mapTfMsg = std::make_shared<geometry_msgs::msg::TransformStamped>();
   mapTfMsg->header.stamp = node.now()-10s;
   mapTfMsg->header.frame_id = "map";
   mapTfMsg->child_frame_id = "base_link";
   mapTfMsg->transform.rotation = tf_utils::getQuaternionFromYaw( 0 );

   tfBroadcaster->sendTransform( *mapTfMsg );
   rclcpp::spin_some(node.get_node_base_interface());

   for ( int i = 0; i < 10000; ++i )
   {
      try
      {
         auto transform = getTransform( node, *tf, "map", "base_link", time_utils::toTimePoint(node.now()) );
         RCLCPP_INFO(node.get_logger(), "Transform succeeded");

      }
      catch (const std::exception &e)
      {
         RCLCPP_ERROR(node.get_logger(), "Exception: %s", e.what());
      }
   }
}
pschalkwijk commented 4 years ago

I've had the same error, and the same memory increase when using nav_amcl for ROS2. After adding a transform tolerance time on the lookupTransform in question, I still have a memory increase over time, without getting the exception mentioned here. I don't think the exception is the cause.

clalancette commented 3 years ago

@maxlein I believe that the memory leak is now fixed with the merging of #281. Would you mind testing the latest code from master and seeing if it is fixed for you? Thanks.

maxlein commented 3 years ago

Great to hear.
But unfortunately I don't have the resources right now to set up a source branch from master.
Right now we are working on foxy debs.