Skip to content

Commit 8115cca

Browse files
authored
Extra parameter to start a container (#616)
Signed-off-by: Carlos Agüero <[email protected]>
1 parent 1e30af0 commit 8115cca

File tree

8 files changed

+116
-16
lines changed

8 files changed

+116
-16
lines changed

ros_gz_bridge/launch/ros_gz_bridge.launch

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@
22
<arg name="bridge_name" />
33
<arg name="config_file" />
44
<arg name="container_name" default="ros_gz_container" />
5+
<arg name="create_own_container" default="False" />
56
<arg name="namespace" default="" />
6-
<arg name="use_composition" default="True" />
7+
<arg name="use_composition" default="False" />
78
<arg name="use_respawn" default="False" />
89
<arg name="log_level" default="info" />
910
<ros_gz_bridge
1011
bridge_name="$(var bridge_name)"
1112
config_file="$(var config_file)"
1213
container_name="$(var container_name)"
14+
create_own_container="$(var create_own_container)"
1315
namespace="$(var namespace)"
1416
use_composition="$(var use_composition)"
1517
use_respawn="$(var use_respawn)"

ros_gz_bridge/launch/ros_gz_bridge.launch.py

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from launch.actions import DeclareLaunchArgument, GroupAction
1919
from launch.conditions import IfCondition
2020
from launch.substitutions import LaunchConfiguration, PythonExpression
21-
from launch_ros.actions import LoadComposableNodes, Node
21+
from launch_ros.actions import ComposableNodeContainer, LoadComposableNodes, Node
2222
from launch_ros.descriptions import ComposableNode
2323

2424

@@ -27,6 +27,7 @@ def generate_launch_description():
2727
bridge_name = LaunchConfiguration('bridge_name')
2828
config_file = LaunchConfiguration('config_file')
2929
container_name = LaunchConfiguration('container_name')
30+
create_own_container = LaunchConfiguration('create_own_container')
3031
namespace = LaunchConfiguration('namespace')
3132
use_composition = LaunchConfiguration('use_composition')
3233
use_respawn = LaunchConfiguration('use_respawn')
@@ -46,12 +47,21 @@ def generate_launch_description():
4647
description='Name of container that nodes will load in if use composition',
4748
)
4849

50+
declare_create_own_container_cmd = DeclareLaunchArgument(
51+
'create_own_container',
52+
default_value='False',
53+
description='Whether the bridge should start its own ROS container when using composition \
54+
(not recommended). This option should only be set to true if you plan to put your ROS \
55+
node in the container created by the bridge. This is not needed if you want Gazebo and \
56+
the bridge to be in the same ROS container.',
57+
)
58+
4959
declare_namespace_cmd = DeclareLaunchArgument(
5060
'namespace', default_value='', description='Top-level namespace'
5161
)
5262

5363
declare_use_composition_cmd = DeclareLaunchArgument(
54-
'use_composition', default_value='True', description='Use composed bringup if True'
64+
'use_composition', default_value='False', description='Use composed bringup if True'
5565
)
5666

5767
declare_use_respawn_cmd = DeclareLaunchArgument(
@@ -81,8 +91,29 @@ def generate_launch_description():
8191
],
8292
)
8393

84-
load_composable_nodes = LoadComposableNodes(
85-
condition=IfCondition(use_composition),
94+
load_composable_nodes_with_container = ComposableNodeContainer(
95+
condition=IfCondition(
96+
PythonExpression([use_composition, ' and ', create_own_container])),
97+
name=LaunchConfiguration('container_name'),
98+
namespace='',
99+
package='rclcpp_components',
100+
executable='component_container',
101+
composable_node_descriptions=[
102+
ComposableNode(
103+
package='ros_gz_bridge',
104+
plugin='ros_gz_bridge::RosGzBridge',
105+
name=bridge_name,
106+
namespace=namespace,
107+
parameters=[{'config_file': config_file}],
108+
extra_arguments=[{'use_intra_process_comms': True}],
109+
),
110+
],
111+
output='screen',
112+
)
113+
114+
load_composable_nodes_without_container = LoadComposableNodes(
115+
condition=IfCondition(
116+
PythonExpression([use_composition, ' and not ', create_own_container])),
86117
target_container=container_name,
87118
composable_node_descriptions=[
88119
ComposableNode(
@@ -103,12 +134,14 @@ def generate_launch_description():
103134
ld.add_action(declare_bridge_name_cmd)
104135
ld.add_action(declare_config_file_cmd)
105136
ld.add_action(declare_container_name_cmd)
137+
ld.add_action(declare_create_own_container_cmd)
106138
ld.add_action(declare_namespace_cmd)
107139
ld.add_action(declare_use_composition_cmd)
108140
ld.add_action(declare_use_respawn_cmd)
109141
ld.add_action(declare_log_level_cmd)
110142
# Add the actions to launch all of the bridge nodes
111143
ld.add_action(load_nodes)
112-
ld.add_action(load_composable_nodes)
144+
ld.add_action(load_composable_nodes_with_container)
145+
ld.add_action(load_composable_nodes_without_container)
113146

114147
return ld

ros_gz_bridge/ros_gz_bridge/actions/ros_gz_bridge.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ def __init__(
3737
bridge_name: SomeSubstitutionsType,
3838
config_file: SomeSubstitutionsType,
3939
container_name: Optional[SomeSubstitutionsType] = 'ros_gz_container',
40+
create_own_container: Optional[SomeSubstitutionsType] = 'False',
4041
namespace: Optional[SomeSubstitutionsType] = '',
41-
use_composition: Optional[SomeSubstitutionsType] = 'True',
42+
use_composition: Optional[SomeSubstitutionsType] = 'False',
4243
use_respawn: Optional[SomeSubstitutionsType] = 'False',
4344
log_level: Optional[SomeSubstitutionsType] = 'info',
4445
**kwargs
@@ -52,6 +53,7 @@ def __init__(
5253
:param: bridge_name Name of ros_gz_bridge node
5354
:param: config_file YAML config file.
5455
:param: container_name Name of container that nodes will load in if use composition.
56+
:param: create_own_container Whether to start a ROS container when using composition.
5557
:param: namespace Top-level namespace.
5658
:param: use_composition Use composed bringup if True.
5759
:param: use_respawn Whether to respawn if a node crashes (when composition is disabled).
@@ -61,6 +63,7 @@ def __init__(
6163
self.__bridge_name = bridge_name
6264
self.__config_file = config_file
6365
self.__container_name = container_name
66+
self.__create_own_container = create_own_container
6467
self.__namespace = namespace
6568
self.__use_composition = use_composition
6669
self.__use_respawn = use_respawn
@@ -83,6 +86,10 @@ def parse(cls, entity: Entity, parser: Parser):
8386
'container_name', data_type=str,
8487
optional=True)
8588

89+
create_own_container = entity.get_attr(
90+
'create_own_container', data_type=str,
91+
optional=True)
92+
8693
namespace = entity.get_attr(
8794
'namespace', data_type=str,
8895
optional=True)
@@ -111,6 +118,11 @@ def parse(cls, entity: Entity, parser: Parser):
111118
container_name = parser.parse_substitution(container_name)
112119
kwargs['container_name'] = container_name
113120

121+
if isinstance(create_own_container, str):
122+
create_own_container = \
123+
parser.parse_substitution(create_own_container)
124+
kwargs['create_own_container'] = create_own_container
125+
114126
if isinstance(namespace, str):
115127
namespace = parser.parse_substitution(namespace)
116128
kwargs['namespace'] = namespace
@@ -139,6 +151,7 @@ def execute(self, context: LaunchContext) -> Optional[List[Action]]:
139151
launch_arguments=[('bridge_name', self.__bridge_name),
140152
('config_file', self.__config_file),
141153
('container_name', self.__container_name),
154+
('create_own_container', self.__create_own_container),
142155
('namespace', self.__namespace),
143156
('use_composition', self.__use_composition),
144157
('use_respawn', self.__use_respawn),

ros_gz_sim/launch/gz_server.launch

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
<arg name="world_sdf_file" default="empty.sdf" />
33
<arg name="world_sdf_string" default="" />
44
<arg name="container_name" default="ros_gz_container" />
5-
<arg name="use_composition" default="True" />
5+
<arg name="create_own_container" default="False" />
6+
<arg name="use_composition" default="False" />
67
<gz_server
78
world_sdf_file="$(var world_sdf_file)"
89
world_sdf_string="$(var world_sdf_string)"
910
container_name="$(var container_name)"
11+
create_own_container="$(var create_own_container)"
1012
use_composition="$(var use_composition)">
1113
</gz_server>
1214
</launch>

ros_gz_sim/launch/gz_server.launch.py

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from launch.actions import DeclareLaunchArgument
1919
from launch.conditions import IfCondition
2020
from launch.substitutions import LaunchConfiguration, PythonExpression, TextSubstitution
21-
from launch_ros.actions import ComposableNodeContainer, Node
21+
from launch_ros.actions import ComposableNodeContainer, LoadComposableNodes, Node
2222
from launch_ros.descriptions import ComposableNode
2323

2424

@@ -33,8 +33,11 @@ def generate_launch_description():
3333
declare_container_name_cmd = DeclareLaunchArgument(
3434
'container_name', default_value='ros_gz_container',
3535
description='Name of container that nodes will load in if use composition',)
36+
declare_create_own_container_cmd = DeclareLaunchArgument(
37+
'create_own_container', default_value='False',
38+
description='Whether we should start our own ROS container when using composition.',)
3639
declare_use_composition_cmd = DeclareLaunchArgument(
37-
'use_composition', default_value='True',
40+
'use_composition', default_value='False',
3841
description='Use composed bringup if True')
3942

4043
load_nodes = Node(
@@ -46,8 +49,10 @@ def generate_launch_description():
4649
'world_sdf_string': LaunchConfiguration('world_sdf_string')}],
4750
)
4851

49-
load_composable_nodes = ComposableNodeContainer(
50-
condition=IfCondition(LaunchConfiguration('use_composition')),
52+
load_composable_nodes_with_container = ComposableNodeContainer(
53+
condition=IfCondition(
54+
PythonExpression([LaunchConfiguration('use_composition'), ' and ',
55+
LaunchConfiguration('create_own_container')])),
5156
name=LaunchConfiguration('container_name'),
5257
namespace='',
5358
package='rclcpp_components',
@@ -65,16 +70,35 @@ def generate_launch_description():
6570
output='screen',
6671
)
6772

73+
load_composable_nodes_without_container = LoadComposableNodes(
74+
condition=IfCondition(
75+
PythonExpression([LaunchConfiguration('use_composition'), ' and not ',
76+
LaunchConfiguration('create_own_container')])),
77+
target_container=LaunchConfiguration('container_name'),
78+
composable_node_descriptions=[
79+
ComposableNode(
80+
package='ros_gz_sim',
81+
plugin='ros_gz_sim::GzServer',
82+
name='gz_server',
83+
parameters=[{'world_sdf_file': LaunchConfiguration('world_sdf_file'),
84+
'world_sdf_string': LaunchConfiguration('world_sdf_string')}],
85+
extra_arguments=[{'use_intra_process_comms': True}],
86+
),
87+
],
88+
)
89+
6890
# Create the launch description and populate
6991
ld = LaunchDescription()
7092

7193
# Declare the launch options
7294
ld.add_action(declare_world_sdf_file_cmd)
7395
ld.add_action(declare_world_sdf_string_cmd)
7496
ld.add_action(declare_container_name_cmd)
97+
ld.add_action(declare_create_own_container_cmd)
7598
ld.add_action(declare_use_composition_cmd)
7699
# Add the actions to launch all of the gz_server nodes
77100
ld.add_action(load_nodes)
78-
ld.add_action(load_composable_nodes)
101+
ld.add_action(load_composable_nodes_with_container)
102+
ld.add_action(load_composable_nodes_without_container)
79103

80104
return ld

ros_gz_sim/launch/ros_gz_sim.launch

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
<arg name="bridge_name" />
33
<arg name="config_file" />
44
<arg name="container_name" default="ros_gz_container" />
5+
<arg name="create_own_container" default="False" />
56
<arg name="namespace" default="" />
6-
<arg name="use_composition" default="True" />
7+
<arg name="use_composition" default="False" />
78
<arg name="use_respawn" default="False" />
89
<arg name="log_level" default="info" />
910
<arg name="world_sdf_file" default="empty.sdf" />
@@ -12,12 +13,14 @@
1213
world_sdf_file="$(var world_sdf_file)"
1314
world_sdf_string="$(var world_sdf_string)"
1415
container_name="$(var container_name)"
16+
create_own_container="$(var create_own_container)"
1517
use_composition="$(var use_composition)">
1618
</gz_server>
1719
<ros_gz_bridge
1820
bridge_name="$(var bridge_name)"
1921
config_file="$(var config_file)"
2022
container_name="$(var container_name)"
23+
create_own_container="False"
2124
namespace="$(var namespace)"
2225
use_composition="$(var use_composition)"
2326
use_respawn="$(var use_respawn)"

ros_gz_sim/launch/ros_gz_sim.launch.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ def generate_launch_description():
2626
bridge_name = LaunchConfiguration('bridge_name')
2727
config_file = LaunchConfiguration('config_file')
2828
container_name = LaunchConfiguration('container_name')
29+
create_own_container = LaunchConfiguration('create_own_container')
2930
namespace = LaunchConfiguration('namespace')
3031
use_composition = LaunchConfiguration('use_composition')
3132
use_respawn = LaunchConfiguration('use_respawn')
@@ -48,12 +49,18 @@ def generate_launch_description():
4849
description='Name of container that nodes will load in if use composition',
4950
)
5051

52+
declare_create_own_container_cmd = DeclareLaunchArgument(
53+
'create_own_container',
54+
default_value='False',
55+
description='Whether we should start a ROS container when using composition.',
56+
)
57+
5158
declare_namespace_cmd = DeclareLaunchArgument(
5259
'namespace', default_value='', description='Top-level namespace'
5360
)
5461

5562
declare_use_composition_cmd = DeclareLaunchArgument(
56-
'use_composition', default_value='True', description='Use composed bringup if True'
63+
'use_composition', default_value='False', description='Use composed bringup if True'
5764
)
5865

5966
declare_use_respawn_cmd = DeclareLaunchArgument(
@@ -96,6 +103,8 @@ def generate_launch_description():
96103
'gz_server.launch.py'])]),
97104
launch_arguments=[('world_sdf_file', world_sdf_file),
98105
('world_sdf_string', world_sdf_string),
106+
('container_name', container_name),
107+
('create_own_container', create_own_container),
99108
('use_composition', use_composition), ])
100109

101110
# Create the launch description and populate
@@ -105,6 +114,7 @@ def generate_launch_description():
105114
ld.add_action(declare_bridge_name_cmd)
106115
ld.add_action(declare_config_file_cmd)
107116
ld.add_action(declare_container_name_cmd)
117+
ld.add_action(declare_create_own_container_cmd)
108118
ld.add_action(declare_namespace_cmd)
109119
ld.add_action(declare_use_composition_cmd)
110120
ld.add_action(declare_use_respawn_cmd)

ros_gz_sim/ros_gz_sim/actions/gzserver.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ def __init__(
3737
world_sdf_file: Optional[SomeSubstitutionsType] = '',
3838
world_sdf_string: Optional[SomeSubstitutionsType] = '',
3939
container_name: Optional[SomeSubstitutionsType] = 'ros_gz_container',
40-
use_composition: Optional[SomeSubstitutionsType] = 'True',
40+
create_own_container: Optional[SomeSubstitutionsType] = 'False',
41+
use_composition: Optional[SomeSubstitutionsType] = 'False',
4142
**kwargs
4243
) -> None:
4344
"""
@@ -49,12 +50,14 @@ def __init__(
4950
:param: world_sdf_file Path to the SDF world file.
5051
:param: world_sdf_string SDF world string.
5152
:param: container_name Name of container that nodes will load in if use composition.
53+
:param: create_own_container Whether to start a ROS container when using composition.
5254
:param: use_composition Use composed bringup if True.
5355
"""
5456
super().__init__(**kwargs)
5557
self.__world_sdf_file = world_sdf_file
5658
self.__world_sdf_string = world_sdf_string
5759
self.__container_name = container_name
60+
self.__create_own_container = create_own_container
5861
self.__use_composition = use_composition
5962

6063
@classmethod
@@ -74,6 +77,10 @@ def parse(cls, entity: Entity, parser: Parser):
7477
'container_name', data_type=str,
7578
optional=True)
7679

80+
create_own_container = entity.get_attr(
81+
'create_own_container', data_type=str,
82+
optional=True)
83+
7784
use_composition = entity.get_attr(
7885
'use_composition', data_type=str,
7986
optional=True)
@@ -90,6 +97,11 @@ def parse(cls, entity: Entity, parser: Parser):
9097
container_name = parser.parse_substitution(container_name)
9198
kwargs['container_name'] = container_name
9299

100+
if isinstance(create_own_container, str):
101+
create_own_container = \
102+
parser.parse_substitution(create_own_container)
103+
kwargs['create_own_container'] = create_own_container
104+
93105
if isinstance(use_composition, str):
94106
use_composition = parser.parse_substitution(use_composition)
95107
kwargs['use_composition'] = use_composition
@@ -106,6 +118,7 @@ def execute(self, context: LaunchContext) -> Optional[List[Action]]:
106118
launch_arguments=[('world_sdf_file', self.__world_sdf_file),
107119
('world_sdf_string', self.__world_sdf_string),
108120
('container_name', self.__container_name),
121+
('create_own_container', self.__create_own_container),
109122
('use_composition', self.__use_composition), ])
110123

111124
return [gz_server_description]

0 commit comments

Comments
 (0)