ros_gz icon indicating copy to clipboard operation
ros_gz copied to clipboard

[ros2] Ignition Transport message duplication caused by bidirectional bridge

Open AndrejOrsula opened this issue 3 years ago • 2 comments

Environment

  • OS Version: Ubuntu 20.04
  • Ignition: Edifice, built from source
  • ROS 2: Foxy, binary install
  • ros_ign branch: ros2 (54e12e2653054fbb925829784ae9151c793288c3), built from source

Note: Tested inside Docker container. I would appreciate someone to reproduce this issue to ensure it is not caused by my setup.

Description

  • Expected behaviour: Running a bidirectional parameter_bridge with Ignition publisher (separate) should generate only ROS 2 messages.
  • Actual behaviour: Running a bidirectional parameter_bridge with Ignition publisher (separate) generates both ROS 2 messages and duplicate versions of ignition-transport messages.
    • What could happening?:
      • Bidirectional bridge creates Node A: Ignition subscriber + ROS 2 publisher, and Node B: ROS 2 subscriber + Ignition publisher.
      • Once an ignition-transport message is published, Node A receives it and generates ROS 2 message. Subsequently, Node B receives this message generated by Node A and generates a duplicate ignition-transport message. (problem with ROS 2 subscriber configuration?)
      • This is just a speculation, I have not investigated the code. I am sure the original developers thought of this, otherwise there would be an infinite recursion happening if this issue occurred in both directions/multiple times.
  • Workaround: Use unidirectional bridge (99% of the use cases) to prevent message duplication that both decreases performance and could potentially break something. Updating examples to use unidirectional bridge instead of bidirectional bridge might also be an idea.

Note: Issue does not seem to occur for ROS 2 messages, i.e. bridge does not duplicate any ROS 2 messages. Note: I have not tested this with ROS 1, so I am not sure if it experiences the same problem.

Steps to reproduce

Shell 1: ros2 run ros_ign_bridge parameter_bridge /chatter@std_msgs/msg/[email protected]

Shell 2: ign topic -e -t /chatter

Shell 3: ign topic -t /chatter -m ignition.msgs.StringMsg -p 'data:"This message should be received only once"'

Output

root@P5550:~# ign topic -e -t /chatter
data: "This message should be received only once"

data: "This message should be received only once"

Expected output (same as without running any bridge)

root@P5550:~# ign topic -e -t /chatter
data: "This message should be received only once"

AndrejOrsula avatar Mar 26 '21 14:03 AndrejOrsula

Interesting, I thought this had been fixed by https://github.com/ignitionrobotics/ros_ign/pull/33. I see the code that's supposed to prevent it in the ros2 branch:

https://github.com/ignitionrobotics/ros_ign/blob/117e2b2efb2430b199779e82d40344386dd8a253/ros_ign_bridge/src/factory.hpp#L98-L100

Maybe the IntraProcess call is not doing the trick anymore.

chapulina avatar Mar 26 '21 23:03 chapulina

I believe the issue originates solely in the ROS 2 subscriber as there is currently no mechanism preventing this to occur. Ignition IntraProcess seems to work fine (otherwise there would be the same issue in the opposite direction and ROS 2 messages would get duplicated).

I have proposed a solution in #146 that makes use of ignore_local_publications subscriber option. However, it does not fix the issue for all rmw implementations, e.g. Cyclone DDS works, but FastRTPS (ROS 2 Foxy default) still has the issue. I added more info into the PR itself.

AndrejOrsula avatar Mar 27 '21 13:03 AndrejOrsula