Ros1_bridge failed to pass tf_static message when subscribed from rviz

I’m doing a ROS sensor porting to ROS2 Ardent. To verify my porting job “done”, I use rviz (I attempted to use rviz2 but looks unready) to visualize all the sensor messages passed via ros1_bridge. And I found the “tf2_msgs/TFMessage” failed to be broadcasted via ros1_bridge for the topic “tf_static”.

This happen in a very specific scenario, and I have made one workaround in my ROS2 sensor. Would like to share the story here, and learn if anybody else facing the similar issue when porting other ROS2 sensors, or any suggestions on using ros1_bridge.

The scenario follows the ros1_bridge usage Example 1b

  1. launch roscore
  2. launch ros1_bridge “ros2 run ros1_bridge dynamic_bridge”
  3. launch the ROS subscriber (rviz in my case), which listen to the sensor data and then the tf messages
  4. launch the ROS2 sensor, which publish the sensor data and broadcast the tf messages

Till here rviz tells “No tf data”. The console debug outputs

[ WARN] [1517480472.064368531]: MessageFilter [target=camera_link ]: Dropped 100.00% of messages so far. Please turn the [ros.rviz.message_notifier] rosconsole logger to DEBUG for more information.
[DEBUG] [1517460244.760264411]: MessageFilter [target=camera_link ]: Removed oldest message because buffer is full, count now 10 (frame_id=camera_depth_optical_frame, stamp=1517460244.212398)
[DEBUG] [1517460244.760436306]: MessageFilter [target=camera_link ]: Added message in frame camera_depth_optical_frame at time 1517460244.666, count now 10

Problem still observed even when I stop/re-launch the ROS subscriber, or when I reversed the above #3 and #4.
Surprisingly, I found if I stop/re-launch the ROS2 sensor here, ros1_bridge will start to pass the tf_static!

Before digging into codes, some behaviors are obvious. Firstly, ros1_bridge will pass the messages only when the topic is subscribed AND published. Secondly, the “tf_static” topic is skipped by the ros1_bridge for certain reason. Most likely, the tf_static topic had not been subscribed when ros1_bridge doing a check when the ROS2 sensor publish its first tf message.

To be specific, here’s the problematic sequence (align with the above launch sequences)

3, ROS sub: subscribe sensor data

4a, ROS2 sensor: advertise and publish sensor data

4b, ROS2 sensor: broadcast tf_static

5, ros1_bridge: create 2to1 bridges for all topics (including sensor topics and tf_static topic)

6, ros1_bridge: passing sensor data, since those topics are both subscribed and published

7, ros1_bridge: skipping tf_static, since no listener yet

8, ROS sub: received sensor data

9, ROS sub: listen to tf_static but it has been skipped by ros1_bridge

I made a workaround in my ROS2 sensor, that is to move step #4b to the bottom. Then the problem disappeared. However the workaround is not perfect, since a ROS subscriber can start listen to a tf_static topic dynamically (anytime later).

Without digging in too much, my guess is that rviz is launched after the bridge and the bridge doesn’t support latching (or transient local durability for ROS 2), see:

The right fix is to support latching in the ros1_bridge, but there was some discussion on how to best support that and it was never resolved.

The other option would be to modift tf2 in ROS 2 to publish /tf_static periodically.

1 Like

Right, optional workaround is to broadcast the tf_static messages periodically. “rosrun tf static_transform_publisher” also make the problem disappeared. Yet a subscriber may not expect repeatedly receiving tf_static messages – it might trigger additional actions like compare with last messages and re-calculation.

I didn’t say it was a good solution, just a workaround for now. I’m not aware of any systems that will behave badly when /tf_static is periodic, off-hand. Since most migrated from tf1, where there was no /tf_static, it should be ok for now.

Long term we obviously need to improve the bridge so that latching is supported.

There should be no problems with rebroadcasting /tf_static periodically with the same value. It will just store the “updated” value each time in the cache. Slight overhead, but I believe unmeasurable beyond the extra messages being sent.

What did you end up doing to handle the tf_static topic? robot_state_publisher needs the tf_static topic transferred into ROS2, this seems like a major breaking issue. What possible workarounds are there?

ros1-bridge doesn’t manage QoS very well. transient_local is not supported, needed for tf_static.

You can also have some real-time problems. The continuous data stream doesn’t work very well.

I recommend to develop your own dedicated bridges, like the ones here:

I hope it helps

1 Like