foxglove / ros-foxglove-bridge

Foxglove WebSocket bridge for ROS 1 and ROS 2
MIT License
168 stars 75 forks source link

ROS2 static transforms partially propagating through the web bridge to studio #238

Closed asymingt closed 1 year ago

asymingt commented 1 year ago

Description

Steps To Reproduce

Take a look at this simple launch file that sets up a basic static transform hierarchy: https://gist.github.com/asymingt/1d833ac9857ecba36eb2fa523137a7ba

Launch like this from a ROS2 rolling distribution:

$ ros2 launch static_frame_issue.launch.py

Confirm you see the correct frames with:

$ ros2 topic echo /tf_static
transforms:
- header:
    stamp:
      sec: 1687902344
      nanosec: 58697684
    frame_id: bar_child1
  child_frame_id: bar_child1_grandchild
  transform:
    translation:
      x: 0.0
      y: 0.0
      z: 0.0
    rotation:
      x: 0.0
      y: 0.0
      z: 0.0
      w: 1.0
---
transforms:
- header:
    stamp:
      sec: 1687902344
      nanosec: 55601655
    frame_id: bar
  child_frame_id: foo
  transform:
    translation:
      x: 0.0
      y: 0.0
      z: 0.0
    rotation:
      x: 0.0
      y: 0.0
      z: 0.0
      w: 1.0
---
transforms:
- header:
    stamp:
      sec: 1687902344
      nanosec: 54859102
    frame_id: bar
  child_frame_id: bar_child1
  transform:
    translation:
      x: 0.5
      y: 1.0
      z: 2.0
    rotation:
      x: 0.0
      y: 0.0
      z: 0.0
      w: 1.0
---
transforms:
- header:
    stamp:
      sec: 1687902344
      nanosec: 56240568
    frame_id: bar_child2
  child_frame_id: bar_child2_grandchild
  transform:
    translation:
      x: 0.0
      y: 0.0
      z: 0.0
    rotation:
      x: 0.0
      y: 0.0
      z: 0.0
      w: 1.0
---
transforms:
- header:
    stamp:
      sec: 1687902344
      nanosec: 56478622
    frame_id: bar
  child_frame_id: bar_child2
  transform:
    translation:
      x: 0.5
      y: -1.0
      z: 2.0
    rotation:
      x: 0.0
      y: 0.0
      z: 0.0
      w: 1.0
---

Expected Behavior

I would expect to see a transform hierarchy that looks like this, in both the Transforms section of the 3D panel, as well as in the 3D visualization itself:

+ baz
  + bar
    + bar_child1
      + bar_child1_grandchild
    + bar_child2
      + bar_child2_grandchild
    + foo

However, only a subset of the frames are actually received and drawn. So, for example sometimes you see this:

+ baz
  + bar
    + bar_child1
      + bar_child1_grandchild

And sometimes you see this:

+ baz
  + bar
    + bar_child2
      + bar_child2_grandchild

Example screenshot of the problematic Transforms panel:

Screen Shot 2023-06-27 at 2 30 44 PM

Example screenshot of the problematic 3D window:

Screen Shot 2023-06-27 at 2 32 04 PM

foxhubber[bot] commented 1 year ago

Internal tracking ticket: FG-4047

achim-k commented 1 year ago

Launch like this from a ROS2 rolling distribution:

$ ros2 launch static_frame_issue.launch.py

Confirm you see the correct frames with:

Note that ros2 topic echo also doesn't show all transforms: You publish 6 transforms, but ros2 topic echo only shows 5 messages. The transform baz-bar is not printed.

You can fix this by increasing the qos depth:

ros2 topic echo --qos-depth 10 --qos-durability transient_local --qos-reliability reliable /tf_static

You can do the same for foxglove bridge:

ros2 launch foxglove_bridge foxglove_bridge_launch.xml min_qos_depth:=10

I believe that this solves your issue?

achim-k commented 1 year ago

Doing ros2 topic info -v /tf_static, I can see that the depth of the /tf_static publishers is reported as UNKNOWN (using the default rmw). This probably prevents foxglove_bridge to select an appropriate QoS depth. Maybe we can use a fallback depth of 1 if the publisher's depth could not be determined.

QoS profile:
  Reliability: RELIABLE
  History (Depth): UNKNOWN
  Durability: TRANSIENT_LOCAL
  Lifespan: Infinite
  Deadline: Infinite
  Liveliness: AUTOMATIC
  Liveliness lease duration: Infinite

Edit: This depends on the used RMW:

RMW History
rmw_fastrtps_cpp (default on iron) UNKNOWN
rmw_connextdds UNKNOWN
rmw_cyclonedds_cpp KEEP_LAST (1)
asymingt commented 1 year ago

I'm just conforming that I am using RTI ConnextDDS, so depth UNKNOWN applies to my case, and may be the cause of the issue.

asymingt commented 1 year ago

@achim-k I can confirm that your proposed fix min_qos_depth:=10 works well for me! Is there any way we might be able to make that the default argument, or have a longer default fallback depth in the case the bridge detects it as UNKNOWN?

achim-k commented 1 year ago

Is there any way we might be able to make that the default argument, or have a longer default fallback depth in the case the bridge detects it as UNKNOWN?

Yes, we have to be smarter here. Will transfer this issue to https://github.com/foxglove/ros-foxglove-bridge and submit a PR that fixes it.