message_filters icon indicating copy to clipboard operation
message_filters copied to clipboard

Synchronizing latched topics works in Python but not C++

Open zkytony opened this issue 2 years ago • 0 comments

Issue description

I am trying to implement a system of three nodes like this:

  • foo: publishes to /topic_foo (latched)
  • bar: publishes to /topic_bar continuously
  • syncer: approximately synchronizes messages from /topic_foo and /topic_bar

I am able to achieve this using message_filters in Python, but not so with C++. I am using ROS 2 Humble.

Reproduction

Check out this Gist message_filter_minimum.py for a Python implementation that does the above. To run this program, just do python message_filter_minimum.py inside a ROS 2 Humble environment.

Check out this Gist message_filter_minimum.cpp for my attempt at an equivalent C++ implementation. To run this program, add the following to your CMakeLists.txt (of some arbitrary package):

add_executable(message_filter_minimum
  path/to/message_filter_minimum.cpp)
ament_target_dependencies(message_filter_minimum
  rclcpp std_msgs geometry_msgs message_filters)
install(TARGETS
  message_filter_minimum
  DESTINATION lib/${PROJECT_NAME}
)

Then, after compilation, you can run it with ros2 run <pkg_name> message_filter_minimum.

Expected Output

When running the Python program, you will get the expected behavior, which looks like:

$ python message_filter_minimum.py
[INFO] [1681059940.027053883] [foo]: foo published!
[INFO] [1681059940.537453616] [bar]: bar published!
[INFO] [1681059940.538126797] [syncer]: Received messages!!
[INFO] [1681059940.538889366] [syncer]: from Foo: geometry_msgs.msg.PointStamped(header=std_msgs.msg.Header(stamp=builtin_interfaces.msg
.Time(sec=1681059940, nanosec=17754646), frame_id=''), point=geometry_msgs.msg.Point(x=1.0, y=0.0, z=0.0))
[INFO] [1681059940.539450511] [syncer]: from Bar: geometry_msgs.msg.PointStamped(header=std_msgs.msg.Header(stamp=builtin_interfaces.msg
.Time(sec=1681059940, nanosec=530389836), frame_id=''), point=geometry_msgs.msg.Point(x=0.0, y=0.0, z=1.0))
[INFO] [1681059941.039520412] [bar]: bar published!
[INFO] [1681059941.537791646] [bar]: bar published!
[INFO] [1681059942.040768503] [bar]: bar published!
[INFO] [1681059942.538500992] [bar]: bar published!
[INFO] [1681059943.039352663] [bar]: bar published!
[INFO] [1681059943.537148395] [bar]: bar published!
[INFO] [1681059944.035679004] [bar]: bar published!

To explain: Since /topic_foo is latched, the synchronizer Syncer's callback will only ever be called once. Afterwards, you should only see bar published! printed on the screen.

Actual Output

When running the C++ program, however, no synchronization happens. I only get

$ ros2 run <pkg_name> message_filter_minimum 
[INFO] [1681060193.486347829] [foo]: foo published!
[INFO] [1681060193.987998543] [bar]: bar published!
[INFO] [1681060194.488068847] [bar]: bar published!
[INFO] [1681060194.988011731] [bar]: bar published!
[INFO] [1681060195.488036074] [bar]: bar published!

Questions

  • What is wrong with the C++ program that caused this behavior, assuming that message_filters works properly?
  • Also, what is the C++ -equivalent of the 'slop' parameter in Python that's used to configure delay allowed between messages from different topics? I cannot find examples or documentation for this.

Thank you!

zkytony avatar Apr 09 '23 17:04 zkytony