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

Bridge does not work without --bridge-all-topics #200

Closed
mabelzhang opened this issue May 24, 2019 · 7 comments
Closed

Bridge does not work without --bridge-all-topics #200

mabelzhang opened this issue May 24, 2019 · 7 comments

Comments

@mabelzhang
Copy link
Contributor

Bug report

The issue basically means that selective bridging doesn't work.

Required Info:

  • Operating System: Ubuntu 18.04
  • Installation type: ros-melodic-* binary, ros-crystal-* binary, ros1_bridge from source
  • Version or commit hash: 0959b19
    This is an older hash from Apr 28, which builds with Crystal. I have not been able to run the latest bridge in Dashing with custom types (Gives error Failed to load entry point 'info' which was resolvable before by careful workspace setup in Crystal, but the same steps did not fix it in Dashing). When I'm able to run it in Dashing, I'll update this bug report.
  • DDS implementation: Fast-RTPS
  • Client library (if applicable): N/A

Steps to reproduce issue

This will check out a simple custom message containing only a float64 field, in a ROS 1 package and a ROS 2 package, and build ros1_bridge from source.

# Shell 1, compile ROS 1 custom message
git clone https://github.com/mabelzhang/ros1_bridge_sandbox.git
cd ros1_bridge_sandbox
. /opt/ros/melodic/setup.bash
catkin_make_isolated --install
. install_isolated/setup.bash 
roscore &

# Shell 2, compile ROS 2 custom message
. /opt/ros/crystal/setup.bash
cd ros1_bridge_sandbox/ros2_msgs_ws
colcon build --packages-select bridge_msgs
. install/local_setup.bash
# Publishes bridge_msgs/JointCommand type to /joint_command topic
python3 src/bridge_msgs/src/ros2_emulator.py

# Shell 3
# Check out ros1_bridge at commit hash compilable with Crystal
cd <parent_path_of_ros1_bridge_sandbox>
mkdir -p bridge_ws/src
cd bridge_ws/src
git clone https://github.com/ros2/ros1_bridge.git
cd ros1_bridge
git checkout 0959b19f67637fcc98d47bceac069c9feb1872fd
cd ../..
# Compile ros1_bridge
. /opt/ros/melodic/setup.bash
. /opt/ros/crystal/setup.bash
. ../ros1_bridge_sandbox/ros1_msgs_ws/install_isolated/setup.bash 
. ../ros1_bridge_sandbox/ros2_msgs_ws/install/local_setup.bash 
colcon build --packages-select ros1_bridge --cmake-force-configure
. install/local_setup.bash
# This should print:   - 'bridge_msgs/JointCommand' (ROS 2) <=> 'bridge_msgs/JointCommand' (ROS 1)
ros2 run ros1_bridge dynamic_bridge --print-pairs | grep bridge
# This is the test line that exposes the bug
ros2 run ros1_bridge dynamic_bridge

Expected behavior

Even without --bridge-all-topics, we should be able to echo in a ROS 1 shell (which establishes a subscriber to) the ROS 2 message /joint_command, which is being continuously published in Shell 2:

# Shell 1
rostopic echo /joint_command

Actual behavior

It cannot be echoed. The selective bridge is not established for the matching subscriber.

# Shell 1
$ rostopic echo /joint_command
WARNING: topic [/joint_command] does not appear to be published yet

ROS 2 topic /joint_command can only be echoed in ROS 1 if --bridge-all-topics is specified:

# Shell 3
$ ros2 run ros1_bridge dynamic_bridge --bridge-all-topics

# Shell 1
$ rostopic list
/joint_command
/rosout
/rosout_agg

$ rostopic echo /joint_command
position: 0.57594316322

Additionally, if the bridge is killed and restarted without --bridge-all-topics, the it can still be echoed in ROS 1, which is correct behavior, but this could not be done in the first try above. This is the case even if the ROS 1 subscriber and the ROS 2 publisher are also killed and restarted.

# Shell 3
$ ros2 run ros1_bridge dynamic_bridge

# Shell 1
$ rostopic list
/rosout
/rosout_agg

$ rostopic eo /joint_command
position: 0.839265978024

The fact that this happens might be because once --bridge-all-topics establishes the mapping in ROS 1 master, it persists after the ROS 1 node and ROS 2 node are killed.

Additional information

Bug is reflected by printing payload printout in dynamic_bridge.cpp, after it is populated by this line:

      if (!ros::master::execute("getSystemState", args, result, payload, true)) {

Even without --bridge-all-topics, /joint_command should be listed as subscriber when rostopic echo /joint_command is running, but it is never listed:

# Formatted for readability
{
  {
    {/rosout,{/rostopic_5468_1557280775160,/ros_bridge}},
    {/rosout_agg,{/rosout}}
  },
  {
    {/rosout,{/rosout}}
  },
  {
    {/ros_bridge/set_logger_level,{/ros_bridge}},
    {/rostopic_5468_1557280775160/get_loggers,{/rostopic_5468_1557280775160}},
    {/rosout/get_loggers,{/rosout}},
    {/rostopic_5468_1557280775160/set_logger_level,{/rostopic_5468_1557280775160}},
    {/ros_bridge/get_loggers,{/ros_bridge}},
    {/rosout/set_logger_level,{/rosout}}
  }
}

With --bridge-all-topics, /joint_command is listed as subscriber by rostopic echo:

# Formatted for readability, see lines marked HERE
{
  {
    {/rosout,{/rostopic_3586_1557850688797,/ros_bridge}},
    {/joint_command,{/ros_bridge}},  # HERE
    {/rosout_agg,{/rosout}}
  },
  {
    {/rosout,{/rosout}},
    {/joint_command,{/rostopic_3586_1557850688797}}  # HERE
  },
  {
    {/ros_bridge/set_logger_level,{/ros_bridge}},
    {/rostopic_3586_1557850688797/set_logger_level,{/rostopic_3586_1557850688797}},
    {/rosout/get_loggers,{/rosout}},
    {/rostopic_3586_1557850688797/get_loggers,{/rostopic_3586_1557850688797}},
    {/rosout/set_logger_level,{/rosout}},
    {/ros_bridge/get_loggers,{/ros_bridge}}
  }
}
@dirk-thomas
Copy link
Member

Even without --bridge-all-topics, we should be able to echo in a ROS 1 shell

Actually, no, this isn't going to work. rostopic echo first tries to determine the type of the topic and only once that has been determined it creates a subscriber with that specific type.

Since the dynamic bridge only bridges topics which have a publisher on one side and a subscriber on the other it doesn't bridge the topic since there is no subscriber yet.

@mabelzhang
Copy link
Contributor Author

Hmm, let me try it with an actual subscriber.

@mabelzhang
Copy link
Contributor Author

mabelzhang commented May 28, 2019

Verified this works when a ROS 1 subscriber is started - the subscriber works right away; rostopic echo also works after the subscriber has started. The same behavior is verified with a ROS 1 publisher + ROS 2 subscriber + ros2 topic echo.

I'll add this point to the ros1_bridge documentation PR.

A weird behavior in both direction though, is that if I just run and kill the subscriber repeatedly, it still does not get the messages intermittently. This is true even for built-in messages like Float32, with FastRTPS. I have not looked into this.
One case that this happens is after the publisher is killed and restarted. The subscriber will never get the messages even after repeated restarts. The only way to get the messages again is to restart the publisher again.

The fact that rostopic echo doesn't work is probably confusing to people trying out the bridge, unless they read what's to be added to the documentation.

@dirk-thomas
Copy link
Member

I'll add this point to the ros1_bridge documentation PR.

Please create a separate PR for this unrelated change.

@clalancette
Copy link
Contributor

The fact that rostopic echo doesn't work is probably confusing to people trying out the bridge, unless they read what's to be added to the documentation.

I think we should open a separate issue to track this problem and try to figure out a way to improve it. The first thing people will do when trying out the bridge is to do a ros2 topic pub on one side and a rostopic echo on the other (or vice-versa), and the fact that this doesn't work will frustrate them and/or cause them to abandon the bridge (we've already seen this happen in practice).

@dirk-thomas
Copy link
Member

I think we should open a separate issue to track this problem and try to figure out a way to improve it.

I think a new ticket only makes sense if you have a proposal how it could be improved.

@clalancette
Copy link
Contributor

I think a new ticket only makes sense if you have a proposal how it could be improved.

I see, we already have #132 tracking this problem.

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

No branches or pull requests

3 participants