ros2 / ros1_bridge

ROS 2 package that provides bidirectional communication between ROS 1 and ROS 2
Apache License 2.0
425 stars 275 forks source link

Parameter Bridge Should Exit if it cannot find parameters #373

Open mhl787156 opened 1 year ago

mhl787156 commented 1 year ago

Hi,

I am currently using the parameter bridge as a de-facto filter between a ros1 library (mavros) and ros2. I have a ros1 and a ros2 launch file. The ros1 launch file uses a rosparam to load the parameter bridge params as a yaml file (topics, services_1to2, services_2to1 all namespaced and verified correct and lining up.) The Ros2 launch executes the ros1 launch and the ros2 parameter bridge.

Annoyingly some of the time, the parameter bridge fails to read the parameter bridge parameters from the ros1 parameter server, leading to the following:

[parameter_bridge-2] The parameter '/vehicle_12/topics' either doesn't exist or isn't an array
[parameter_bridge-2] The parameter '/vehicle_12/services_1to2' either doesn't exist or isn't an array
[parameter_bridge-2] The parameter '/vehicle_12/services_2to1' either doesn't exist or isn't an array

I have no idea what the reason for this read failure happening some of the time, but my best guess is a race condition between ros1 and 2. Some of the time it works absolutely as expected, creating bidirectional bridges for all of the expected topics and working well (implying that my weird general parameter/namespacing etc setup does work so is not the problem here)

For this particular report, I would like to ask whether the parameter bridge should exit if no parameters are found?

If it is a race condition, simply setting respawn=true might solve the problem - but since the parameter bridge doesnt exit, I struggle to find a method to restart the bridge.

Steps to reproduce issue

ros2 launch file

    <!-- Launch the ROS1 stack -->
    <executable cmd="/ros_ws/scripts/run_ros1.sh roslaunch /ros_ws/launch/mavros.launch
            vehicle_namespace:=$(var vehicle_namespace)
            firmware:=$(var firmware)
            fcu_url:=$(var fcu_url)
            gcs_url:=$(var gcs_url)
            target_system:=$(var target_system)
            system_id:=$(var system_id)
            config_yaml:=$(var config_yaml)
            pluginlists_yaml:=$(var pluginlists_yaml)
            bridge_yaml:=$(var bridge_yaml)"
        output="screen"
    />

    <!-- Launch the bridge in the correct namespace to avoid collisions-->
    <!-- Note that args must be included to ensure the namespace is remapped -->
    <!-- Delay is needed to ensure that roscore has been instantiated -->
    <node pkg="ros1_bridge"
          exec="parameter_bridge"
          args="/$(var vehicle_namespace)/topics /$(var vehicle_namespace)/services_1to2 /$(var vehicle_namespace)/services_2to1"
          namespace="$(var vehicle_namespace)"
          respawn="true"
          launch-prefix="bash -c 'sleep $(var bridge_launch_delay); $0 $@' ">
    </node>

ros1 launch snippet (mavros.launch)

<arg name="bridge_yaml" default="$(env BRIDGE_MOD_CONFIG_PATH)"/>
...
<rosparam command="load" file="$(arg bridge_yaml)" ns="$(arg vehicle_namespace)"/>
...

bridge_config.yaml

topics:
   - ...
services_2to1
  - ...
services_1to2
  - ...

You may be able to experience it if you run this docker container:

docker run -it --rm uobflightlabstarling/starling-mavros

Additional information

Feature request

Feature description

Parameter bridge should possibly exit if no parameters are successfully read from ros1 param server.

Many Thanks!

KKSTB commented 9 months ago

I encountered similar race condition issue when launching ROS1 with parameters and the bridge using scripts. I temporarily solve the issue by adding sleep before launching the bridge to ensure ROS1 parameters are loaded.

But I think even though restarting the bridge when topics or other bridge parameters are missing might work most of the time, this may not guarantee the race condition that if there are many parameters. some parameters are still loading and not read by the bridge.

It may be solved if there is a sum / total entry in the parameter, and then the bridge quits and restart if the total entry does not match.