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

Extra parameter to start a container #616

Merged
merged 10 commits into from
Oct 14, 2024
4 changes: 3 additions & 1 deletion ros_gz_bridge/launch/ros_gz_bridge.launch
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@
<arg name="bridge_name" />
<arg name="config_file" />
<arg name="container_name" default="ros_gz_container" />
<arg name="create_own_container" default="False" />
<arg name="namespace" default="" />
<arg name="use_composition" default="True" />
<arg name="use_composition" default="False" />
<arg name="use_respawn" default="False" />
<arg name="log_level" default="info" />
<ros_gz_bridge
bridge_name="$(var bridge_name)"
config_file="$(var config_file)"
container_name="$(var container_name)"
create_own_container="$(var create_own_container)"
namespace="$(var namespace)"
use_composition="$(var use_composition)"
use_respawn="$(var use_respawn)"
Expand Down
39 changes: 34 additions & 5 deletions ros_gz_bridge/launch/ros_gz_bridge.launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from launch.actions import DeclareLaunchArgument, GroupAction
from launch.conditions import IfCondition
from launch.substitutions import LaunchConfiguration, PythonExpression
from launch_ros.actions import LoadComposableNodes, Node
from launch_ros.actions import ComposableNodeContainer, LoadComposableNodes, Node
from launch_ros.descriptions import ComposableNode


Expand All @@ -27,6 +27,7 @@ def generate_launch_description():
bridge_name = LaunchConfiguration('bridge_name')
config_file = LaunchConfiguration('config_file')
container_name = LaunchConfiguration('container_name')
create_own_container = LaunchConfiguration('create_own_container')
namespace = LaunchConfiguration('namespace')
use_composition = LaunchConfiguration('use_composition')
use_respawn = LaunchConfiguration('use_respawn')
Expand All @@ -46,12 +47,18 @@ def generate_launch_description():
description='Name of container that nodes will load in if use composition',
)

declare_create_own_container_cmd = DeclareLaunchArgument(
'create_own_container',
default_value='False',
description='Whether to start a ROS container when using composition',
caguero marked this conversation as resolved.
Show resolved Hide resolved
)

declare_namespace_cmd = DeclareLaunchArgument(
'namespace', default_value='', description='Top-level namespace'
)

declare_use_composition_cmd = DeclareLaunchArgument(
'use_composition', default_value='True', description='Use composed bringup if True'
'use_composition', default_value='False', description='Use composed bringup if True'
)

declare_use_respawn_cmd = DeclareLaunchArgument(
Expand Down Expand Up @@ -81,8 +88,27 @@ def generate_launch_description():
],
)

load_composable_nodes = LoadComposableNodes(
condition=IfCondition(use_composition),
load_composable_nodes_with_container = ComposableNodeContainer(
condition=IfCondition(PythonExpression([use_composition, ' and ', create_own_container])),
name=LaunchConfiguration('container_name'),
namespace='',
package='rclcpp_components',
executable='component_container',
composable_node_descriptions=[
ComposableNode(
package='ros_gz_bridge',
plugin='ros_gz_bridge::RosGzBridge',
name=bridge_name,
namespace=namespace,
parameters=[{'config_file': config_file}],
extra_arguments=[{'use_intra_process_comms': True}],
),
],
output='screen',
)

load_composable_nodes_without_container = LoadComposableNodes(
condition=IfCondition(PythonExpression([use_composition, ' and not ', create_own_container])),
target_container=container_name,
composable_node_descriptions=[
ComposableNode(
Expand All @@ -94,6 +120,7 @@ def generate_launch_description():
extra_arguments=[{'use_intra_process_comms': True}],
),
],
output='screen',
)

# Create the launch description and populate
Expand All @@ -103,12 +130,14 @@ def generate_launch_description():
ld.add_action(declare_bridge_name_cmd)
ld.add_action(declare_config_file_cmd)
ld.add_action(declare_container_name_cmd)
ld.add_action(declare_create_own_container_cmd)
ld.add_action(declare_namespace_cmd)
ld.add_action(declare_use_composition_cmd)
ld.add_action(declare_use_respawn_cmd)
ld.add_action(declare_log_level_cmd)
# Add the actions to launch all of the bridge nodes
ld.add_action(load_nodes)
ld.add_action(load_composable_nodes)
ld.add_action(load_composable_nodes_with_container)
ld.add_action(load_composable_nodes_without_container)

return ld
14 changes: 13 additions & 1 deletion ros_gz_bridge/ros_gz_bridge/actions/ros_gz_bridge.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ def __init__(
bridge_name: SomeSubstitutionsType,
config_file: SomeSubstitutionsType,
container_name: Optional[SomeSubstitutionsType] = 'ros_gz_container',
create_own_container: Optional[SomeSubstitutionsType] = 'False',
namespace: Optional[SomeSubstitutionsType] = '',
use_composition: Optional[SomeSubstitutionsType] = 'True',
use_composition: Optional[SomeSubstitutionsType] = 'False',
use_respawn: Optional[SomeSubstitutionsType] = 'False',
log_level: Optional[SomeSubstitutionsType] = 'info',
**kwargs
Expand All @@ -52,6 +53,7 @@ def __init__(
:param: bridge_name Name of ros_gz_bridge node
:param: config_file YAML config file.
:param: container_name Name of container that nodes will load in if use composition.
:param: create_own_container Whether to start a ROS container when using composition.
:param: namespace Top-level namespace.
:param: use_composition Use composed bringup if True.
:param: use_respawn Whether to respawn if a node crashes (when composition is disabled).
Expand All @@ -61,6 +63,7 @@ def __init__(
self.__bridge_name = bridge_name
self.__config_file = config_file
self.__container_name = container_name
self.__create_own_container = create_own_container
self.__namespace = namespace
self.__use_composition = use_composition
self.__use_respawn = use_respawn
Expand All @@ -83,6 +86,10 @@ def parse(cls, entity: Entity, parser: Parser):
'container_name', data_type=str,
optional=True)

create_own_container = entity.get_attr(
'create_own_container', data_type=str,
optional=True)

namespace = entity.get_attr(
'namespace', data_type=str,
optional=True)
Expand Down Expand Up @@ -111,6 +118,10 @@ def parse(cls, entity: Entity, parser: Parser):
container_name = parser.parse_substitution(container_name)
kwargs['container_name'] = container_name

if isinstance(create_own_container, str):
create_own_container = parser.parse_substitution(create_own_container)
kwargs['create_own_container'] = create_own_container

if isinstance(namespace, str):
namespace = parser.parse_substitution(namespace)
kwargs['namespace'] = namespace
Expand Down Expand Up @@ -139,6 +150,7 @@ def execute(self, context: LaunchContext) -> Optional[List[Action]]:
launch_arguments=[('bridge_name', self.__bridge_name),
('config_file', self.__config_file),
('container_name', self.__container_name),
('create_own_container', self.__create_own_container),
('namespace', self.__namespace),
('use_composition', self.__use_composition),
('use_respawn', self.__use_respawn),
Expand Down
Loading