ros2 / launch

Tools for launching multiple processes and for writing tests involving multiple processes.
Apache License 2.0
126 stars 144 forks source link

Launching composable nodes from different launch files(in xml format ) with in the same node_container #730

Closed nrasulnrasul closed 1 year ago

nrasulnrasul commented 1 year ago

Bug report

Required Info:

Steps to reproduce issue

Try to launch composable nodes from different launch files(in xml format ) with in the same node_container.

Example : I want to launch 2 instances of node 'my_launch_test::MinimalPublisher' in container with name 'cntr_a'

launch file 1 : launch_test.launch

<launch>
    <node_container pkg="rclcpp_components" exec="component_container" name="cntr_a" namespace="cntr_ns_a"> 
          <composable_node pkg="my_launch_test" plugin="my_launch_test::MinimalPublisher" name="node_a"/>          
    </node_container>
    <include file="$(find-pkg-share my_launch_test)/launch/launch2.launch"/>    
</launch>

launch file 2 : launch2.launch

<launch>
    <node_container pkg="rclcpp_components" exec="component_container" name="cntr_a" namespace="cntr_ns_a">    
          <composable_node pkg="my_launch_test" plugin="my_launch_test::MinimalPublisher" name="node_b">            
          </composable_node>          
    </node_container>
</launch>

Expected behavior

container cntr_a must start once and load the 2 nodes with names node_a and node_b once.

Actual behavior

container cntr_a starts 2 times and each instance of container loads both nodes. i.e node_a starts 2 times, node_b starts 2 times.

output after launching above launch file:

$ ros2 launch my_launch_test launch_test.launch 
[INFO] [launch]: All log files can be found below /home/wnm/.ros/log/2023-09-08-14-49-39-670902-WE-Z7655-355540
[INFO] [launch]: Default logging verbosity is set to INFO
[WARNING] [component_container-2]: there are now at least 2 nodes with the name /cntr_ns_a/cntr_a created within this launch context
[INFO] [component_container-1]: process started with pid [355554]
[INFO] [component_container-2]: process started with pid [355556]
[component_container-2] [INFO] [1694177380.154807155] [cntr_ns_a.cntr_a]: Load Library: /home/wnm/sandbox/ros2_ws/install/my_launch_test/lib/libmy_launch_test.so
[component_container-1] [INFO] [1694177380.154815144] [cntr_ns_a.cntr_a]: Load Library: /home/wnm/sandbox/ros2_ws/install/my_launch_test/lib/libmy_launch_test.so
[component_container-2] [INFO] [1694177380.158069389] [cntr_ns_a.cntr_a]: Found class: rclcpp_components::NodeFactoryTemplate<my_launch_test::MinimalPublisher>
[component_container-2] [INFO] [1694177380.158139946] [cntr_ns_a.cntr_a]: Instantiate class: rclcpp_components::NodeFactoryTemplate<my_launch_test::MinimalPublisher>
[component_container-1] [INFO] [1694177380.158118547] [cntr_ns_a.cntr_a]: Found class: rclcpp_components::NodeFactoryTemplate<my_launch_test::MinimalPublisher>
[component_container-1] [INFO] [1694177380.158184404] [cntr_ns_a.cntr_a]: Instantiate class: rclcpp_components::NodeFactoryTemplate<my_launch_test::MinimalPublisher>
[component_container-1] [INFO] [1694177380.173248306] [node_a]: ########################################################### process id : 140183137521472 node name: node_a
[INFO] [launch_ros.actions.load_composable_nodes]: Loaded node '/node_a' in container '/cntr_ns_a/cntr_a'
[component_container-2] [INFO] [1694177380.173896829] [node_a]: ########################################################### process id : 140083940761408 node name: node_a
[component_container-1] [INFO] [1694177380.182307758] [cntr_ns_a.cntr_a]: Found class: rclcpp_components::NodeFactoryTemplate<my_launch_test::MinimalPublisher>
[component_container-1] [INFO] [1694177380.182394085] [cntr_ns_a.cntr_a]: Instantiate class: rclcpp_components::NodeFactoryTemplate<my_launch_test::MinimalPublisher>
[component_container-2] [INFO] [1694177380.182375620] [cntr_ns_a.cntr_a]: Found class: rclcpp_components::NodeFactoryTemplate<my_launch_test::MinimalPublisher>
[component_container-2] [INFO] [1694177380.182451299] [cntr_ns_a.cntr_a]: Instantiate class: rclcpp_components::NodeFactoryTemplate<my_launch_test::MinimalPublisher>
[component_container-1] [INFO] [1694177380.196302110] [node_b]: ########################################################### process id : 140183137521472 node name: node_b
[INFO] [launch_ros.actions.load_composable_nodes]: Loaded node '/node_b' in container '/cntr_ns_a/cntr_a'
[component_container-2] [INFO] [1694177380.198040361] [node_b]: ########################################################### process id : 140083940761408 node name: node_b

You can observer the process id and node name which were printed from node constructor.

output from ros2 node list

$ ros2 node list 
WARNING: Be aware that are nodes in the graph that share an exact name, this can have unintended side effects.
/cntr_ns_a/cntr_a
/cntr_ns_a/cntr_a
/launch_ros_358378
/node_a
/node_a
/node_b
/node_b

Additional information

Assume 2 launch files L1, L2. L1 starts a container with name 'C1' and loads 'Node1'. L2 starts a container with name 'C1' and loads 'Node2'. Now start L1 and L2 in different terminals. Result will be Container 'C1' starts 2 times but loads 'Node1' and 'Node2' only once.

clalancette commented 1 year ago

So this may be somewhat surprising, but I think it is expected behavior.

In particular, what you've done is to ask for two containers to be launched with the exact same name (you have two node_container entries). But that is a very dangerous thing to do (and is why we have the warning you see in ros2 node list), because now they share service names. The launch process loads in components using service calls, and since they share service names it looks like they are both getting the plugins loaded into them.

The solution here is to make sure to name the two container nodes differently.

nrasulnrasul commented 1 year ago

Thanks for the reply.

The intention of above code is to launch 2 nodes in same container (i.e. in same process) to avoid message copying when intra process communication is enabled. That's why same name is used for container in both launch files.

I have seen ROS 2 examples of running multiple nodes in same container in same launch file but not from multiple launch files.

In ROS1, it was possible to launch multiple nodelets in the same nodelet manager from different launch files.

nrasulnrasul commented 1 year ago

I was able to load components in same container by using 'load_composable_node' tag.