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

Add time jump callback #608

Merged
merged 3 commits into from Jun 15, 2023
Merged

Conversation

erichlf
Copy link
Contributor

@erichlf erichlf commented Jun 14, 2023

When use_sim_time is set the python tf2 buffer should be cleared. However, this wasn't happening. To handle this a time jump callback was added to clear the buffer when a time jump is detected.

When use_sim_time is set the python tf2 buffer should be cleared. However, this
wasn't happening. To handle this a time jump callback was added to clear the
buffer when a time jump is detected.
@erichlf
Copy link
Contributor Author

erichlf commented Jun 14, 2023

This build errors make no sense to me

E     File "/tmp/ws/src/geometry2/tf2_ros_py/tf2_ros/buffer.py", line 98
E       post_callback=time_jump_callback
E       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E   SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='

Comment on lines 95 to 99
self.jump_handle = rclpy.clock.Clock().create_jump_callback
(
threshold,
post_callback=self.time_jump_callback
)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this needs to be done in a slightly different way.

In particular, I'm pretty sure that the clock object has to be kept around, otherwise this whole thing will be destroyed immediately.

There are then two paths we have to deal with; when the node is passed in, and when it is not. When it is passed in, we can just use the clock object that is stored in the Node. When it is not, then we have to create and hold onto a clock object ourselves. So something like:

if node is not None:
    self.jump_handle = node.get_clock().create_jump_callback(threshold, post_callback=self.time_jump_callback)
else:
    self.clock = rclpy.clock.Clock()
    self.jump_handle = self.clock.create_jump_callback(threshold, post_callback=self.time_jump_callback)

(that else case is actually problematic since it isn't respecting use_sim_time for simulation; the only way to deal with that would be to make node non-optional here. But we can do that later.)

@erichlf
Copy link
Contributor Author

erichlf commented Jun 14, 2023

These failing tests are baffling. This is definitely valid syntax.

@erichlf erichlf force-pushed the erichlf/python_time_jump branch 2 times, most recently from 795086c to c7f073c Compare June 15, 2023 17:09
Copy link
Contributor

@clalancette clalancette left a comment

Choose a reason for hiding this comment

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

One thing to change, then this looks good and I'll run CI on it.

tf2_ros_py/tf2_ros/buffer.py Outdated Show resolved Hide resolved
@erichlf erichlf requested a review from clalancette June 15, 2023 17:30
@clalancette
Copy link
Contributor

@ros-pull-request-builder retest this please

Copy link
Contributor

@clalancette clalancette left a comment

Choose a reason for hiding this comment

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

This looks good to me now, thanks for iterating!

@clalancette
Copy link
Contributor

CI:

  • Linux Build Status
  • Linux-aarch64 Build Status
  • Windows Build Status

@clalancette clalancette merged commit dfb7eb5 into ros2:rolling Jun 15, 2023
2 checks passed
@dhood
Copy link
Member

dhood commented Dec 5, 2023

thank you @erichlf , I am looking forward to using this! 🙌

@@ -94,6 +104,10 @@ def __get_frames(
) -> FrameGraphSrvResponse:
return FrameGraph.Response(frame_yaml=self.all_frames_as_yaml())

def time_jump_callback(time_jump: TimeJump):
rclpy.logging.get_logger("tf2_buffer").warning("Detected jump back in time. Clearing tf buffer.")
self.clear()
Copy link
Member

Choose a reason for hiding this comment

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

@erichlf @clalancette I'd like to use this functionality, so I gave this a monkey patch test drive on humble but didn't manage to get the callback to trigger, alas. (when my rosbag looped).

Quick debugging: it doesn't seem to get unregistered, which is good, but the callback_shim doesn't seem to get called.

This method doesn't look like it captures self so even if it were triggered I'm not sure this behaves how expected anymore (presumably it was working at some point but I saw there was refactoring during the PR).

Might be in need of some test coverage before the feature gets released 🙂

Copy link
Member

Choose a reason for hiding this comment

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

OH and I'm willing to admit that there's a slew of more complex reasons why I can't get it to trigger on my side (like, for example, monkey patching onto humble 😆 ). But I'm hoping that the comment is helpful for rolling development nonetheless! 🙇

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants