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

LaunchConfiguration is not read from ComposableNode when included inside a group action #114

Closed
jacobperron opened this issue Jan 16, 2020 · 5 comments · Fixed by #170
Closed
Assignees
Labels
bug Something isn't working

Comments

@jacobperron
Copy link
Member

Bug report

Required Info:

  • Operating System:
    • Ubuntu 18.04
  • Installation type:
    • source
  • Version or commit hash:
  • DDS implementation:
    • N/A
  • Client library (if applicable):
    • N/A

Steps to reproduce issue

Create the following two launch files:

foo.launch.xml

<launch>
  <group>
    <include file='bar.launch.py'>
    </include>
  </group>
</launch>

bar.launch.py

import launch
import launch_ros


def generate_launch_description():
    return launch.LaunchDescription([
        launch.actions.DeclareLaunchArgument(name='bar_arg', default_value='True'),
        launch_ros.actions.ComposableNodeContainer(
            package='rclcpp_components', node_executable='component_container',
            node_name='my_container', node_namespace='',
            composable_node_descriptions=[
                launch_ros.descriptions.ComposableNode(
                    package='demo_nodes_cpp',
                    node_plugin='demo_nodes_cpp::Talker',
                    parameters=[{'use_sim_time': launch.substitutions.LaunchConfiguration('bar_arg')}]
                ),
            ]
        ),
        # launch_ros.actions.Node(
        #     name='talker', package='demo_nodes_cpp', node_executable='talker', output='screen',
        #     parameters=[{'use_sim_time': launch.substitutions.LaunchConfiguration('bar_arg')}]),
    ])

Launch foo.launch.xml:

ros2 launch foo.launch.xml

Expected behavior

No launch errors.

Actual behavior

Launch error:

[INFO] [launch]: All log files can be found below /home/jacob/.ros/log/2020-01-16-13-53-42-380127-warner-9368
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [component_container-1]: process started with pid [9379]
[ERROR] [launch]: Caught exception in launch (see debug for traceback): launch configuration 'bar_arg' does not exist
[INFO] [component_container-1]: sending signal 'SIGINT' to process[component_container-1]
[INFO] [component_container-1]: process has finished cleanly [pid 9379]
Debug output
[DEBUG] [launch.launch_context]: emitting event synchronously: 'launch.events.IncludeLaunchDescription'
[DEBUG] [launch.launch_context]: emitting event synchronously: 'launch.events.IncludeLaunchDescription'
[INFO] [launch]: All log files can be found below /home/jacob/.ros/log/2020-01-16-13-54-08-734132-warner-9451
[INFO] [launch]: Default logging verbosity is set to DEBUG
[DEBUG] [launch]: processing event: ''
[DEBUG] [launch]: processing event: '' ✓ ''
[DEBUG] [launch]: processing event: ''
[DEBUG] [launch]: processing event: '' ✓ ''
[INFO] [component_container-1]: process started with pid [9462]
[DEBUG] [launch.launch_context]: emitting event: 'launch.events.process.ProcessStarted'
[DEBUG] [launch]: processing event: ''
[DEBUG] [launch]: processing event: '' ✓ ''
Executing () created at /usr/lib/python3.6/asyncio/queues.py:74> took 0.252 seconds
[DEBUG] [launch]: Traceback (most recent call last):
  File "/opt/ros/eloquent/lib/python3.6/site-packages/launch/launch_service.py", line 381, in run_async
    await process_one_event_task
  File "/usr/lib/python3.6/asyncio/coroutines.py", line 126, in send
    return self.gen.send(value)
  File "/opt/ros/eloquent/lib/python3.6/site-packages/launch/launch_service.py", line 291, in _process_one_event
    await self.__process_event(next_event)
  File "/usr/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
    return self.gen.send(None)
  File "/opt/ros/eloquent/lib/python3.6/site-packages/launch/launch_service.py", line 311, in __process_event
    visit_all_entities_and_collect_futures(entity, self.__context))
  File "/opt/ros/eloquent/lib/python3.6/site-packages/launch/utilities/visit_all_entities_and_collect_futures_impl.py", line 38, in visit_all_entities_and_collect_futures
    sub_entities = entity.visit(context)
  File "/opt/ros/eloquent/lib/python3.6/site-packages/launch/action.py", line 108, in visit
    return self.execute(context)
  File "/opt/ros/eloquent/lib/python3.6/site-packages/launch_ros/actions/load_composable_nodes.py", line 171, in execute
    self._load_in_sequence(self.__composable_node_descriptions, context)
  File "/opt/ros/eloquent/lib/python3.6/site-packages/launch_ros/actions/load_composable_nodes.py", line 151, in _load_in_sequence
    self._load_node(next_composable_node_description, context)
  File "/opt/ros/eloquent/lib/python3.6/site-packages/launch_ros/actions/load_composable_nodes.py", line 114, in _load_node
    context, composable_node_description.parameters
  File "/opt/ros/eloquent/lib/python3.6/site-packages/launch_ros/utilities/evaluate_parameters.py", line 145, in evaluate_parameters
    output_params.append(evaluate_parameter_dict(context, param))
  File "/opt/ros/eloquent/lib/python3.6/site-packages/launch_ros/utilities/evaluate_parameters.py", line 69, in evaluate_parameter_dict
    evaluated_value = perform_substitutions(context, list(value))
  File "/opt/ros/eloquent/lib/python3.6/site-packages/launch/utilities/perform_substitutions_impl.py", line 26, in perform_substitutions
    return ''.join([context.perform_substitution(sub) for sub in subs])
  File "/opt/ros/eloquent/lib/python3.6/site-packages/launch/utilities/perform_substitutions_impl.py", line 26, in 
    return ''.join([context.perform_substitution(sub) for sub in subs])
  File "/opt/ros/eloquent/lib/python3.6/site-packages/launch/launch_context.py", line 184, in perform_substitution
    return substitution.perform(self)
  File "/opt/ros/eloquent/lib/python3.6/site-packages/launch/substitutions/launch_configuration.py", line 99, in perform
    "launch configuration '{}' does not exist".format(expanded_variable_name))
launch.substitutions.substitution_failure.SubstitutionFailure: launch configuration 'bar_arg' does not exist

[ERROR] [launch]: Caught exception in launch (see debug for traceback): launch configuration 'bar_arg' does not exist
[DEBUG] [launch.launch_context]: emitting event: 'launch.events.Shutdown'
[DEBUG] [launch]: processing event: '<launch.events.shutdown.Shutdown object at 0x7fb51d289c88>'
[DEBUG] [launch]: processing event: '<launch.events.shutdown.Shutdown object at 0x7fb51d289c88>' ✓ '<launch.event_handlers.on_shutdown.OnShutdown object at 0x7fb51d2965f8>'
[DEBUG] [launch.launch_context]: emitting event synchronously: 'launch.events.process.SignalProcess'
[DEBUG] [launch]: processing event: '<launch.events.shutdown.Shutdown object at 0x7fb51d289c88>' ✓ '<launch.event_handlers.on_shutdown.OnShutdown object at 0x7fb5204265c0>'
[DEBUG] [launch]: processing event: '<launch.events.shutdown.Shutdown object at 0x7fb51d289c88>' ✓ '<launch.event_handlers.on_shutdown.OnShutdown object at 0x7fb52dde0e10>'
Executing <Task finished coro=<LaunchService._process_one_event() done, defined at /opt/ros/eloquent/lib/python3.6/site-packages/launch/launch_service.py:289> result=None created at /opt/ros/eloquent/lib/python3.6/site-packages/launch/launch_service.py:359> took 0.743 seconds
[DEBUG] [launch]: processing event: '<launch.events.process.signal_process.SignalProcess object at 0x7fb51d343748>'
[DEBUG] [launch]: processing event: '<launch.events.process.signal_process.SignalProcess object at 0x7fb51d343748>' ✓ '<launch.event_handler.EventHandler object at 0x7fb51d296908>'
[INFO] [component_container-1]: sending signal 'SIGINT' to process[component_container-1]
[DEBUG] [launch.launch_context]: emitting event synchronously: 'launch.events.process.ProcessStdout'
[DEBUG] [launch]: processing event: '<launch.events.process.process_stdout.ProcessStdout object at 0x7fb52041cf28>'
[DEBUG] [launch]: processing event: '<launch.events.process.process_stdout.ProcessStdout object at 0x7fb52041cf28>' ✓ '<launch.event_handlers.on_process_io.OnProcessIO object at 0x7fb51d2965c0>'
[INFO] [component_container-1]: process has finished cleanly [pid 9462]
[DEBUG] [launch.launch_context]: emitting event: 'launch.events.process.ProcessExited'
[DEBUG] [launch]: processing event: '<launch.events.process.process_exited.ProcessExited object at 0x7fb52041cdd8>'
[DEBUG] [launch]: processing event: '<launch.events.process.process_exited.ProcessExited object at 0x7fb52041cdd8>' ✓ '<launch.event_handlers.on_process_exit.OnProcessExit object at 0x7fb51d296518>'
[DEBUG] [launch]: processing event: '<launch.events.process.process_exited.ProcessExited object at 0x7fb52041cdd8>' ✓ '<launch.event_handlers.on_process_exit.OnProcessExit object at 0x7fb51d296630>'

Additional information

If we remove the <group> tag in foo.launch.xml, then there is no issue.

If we use a Node action instead of a composable node, then there is no issue.

@jacobperron jacobperron added the bug Something isn't working label Jan 16, 2020
@wjwwood
Copy link
Member

wjwwood commented Jan 17, 2020

Maybe you need to use the scoped argument for the GroupAction? I need to look in more detail at why you are using the group, but I guess the scope option needs to be flipped or the scope mechanism has a bug in it or something.

@wjwwood
Copy link
Member

wjwwood commented Jan 17, 2020

Maybe it has to do with the delayed evaluation of the substitution? I'm not sure...

@wjwwood
Copy link
Member

wjwwood commented Jan 17, 2020

I think since the load of the composable nodes is done asynchronously (with an event handler) the group has already ended and undone the scope:

composable_node_descriptions=self.__composable_node_descriptions,

I'm not sure how to fix this, a few options:

  • perform the substitutions in ComposableNodeContainer::execute() before registering the event
  • change how the containers are loaded to avoid the delay in evaluating the substitutions (i.e. do not use an event)
  • store the launch config state and make sure it is used for the evaluation in the event handler (sort of like lambda capture or something)

@jrgnicho
Copy link

jrgnicho commented May 6, 2020

Also experiencing the same issue with ComposableNodeContainer where my python launch file looks like this

def generate_launch_description():
   
    container =  ComposableNodeContainer(
            node_name= 'perception',
            node_namespace= launch.substitutions.LaunchConfiguration('global_ns'),
            package= 'rclcpp_components',
            node_executable = 'component_container',
            composable_node_descriptions = [
                ComposableNode(
                package='crs_perception',
                node_plugin='crs_perception::LocalizeToPart',
                node_name='part_localization',
                node_namespace = launch.substitutions.LaunchConfiguration('global_ns')),
                ],
            output = 'screen'
        )    
    
    return launch.LaunchDescription([
        launch.actions.DeclareLaunchArgument('global_ns', default_value = ['/my_ns']),
        container])

It runs fine when I call it from the command line
but when I call it from an xml launch file

	    <include file="$(find-pkg-share crs_application)/launch/perception.launch.py">
	    	<arg name="global_ns" value="$(var group_ns)"/>
	    </include>

It errors out saying that the launch configuration 'global_ns' does not exist. Removing the argument has no effect either

jacobperron added a commit that referenced this issue Aug 10, 2020
Fixes #114.

Due to the asynchronous nature of the LoadComposableNodes action, an event handler causes the launch configuration is popped if ComposableNodeContainer appears inside a group or include action.
It seems to me we can simply return the load node action, which will get executed after the ComposableNodeContainer action. The use of an event handler is vestigial of a refactoring done in #16, and doesn't appear to be necessary.

Signed-off-by: Jacob Perron <jacob@openrobotics.org>
jacobperron added a commit that referenced this issue Aug 10, 2020
Fixes #114.

Due to the asynchronous nature of the LoadComposableNodes action, an event handler causes the launch configuration is popped if ComposableNodeContainer appears inside a group or include action.
It seems to me we can simply return the load node action, which will get executed after the ComposableNodeContainer action. The use of an event handler is vestigial of a refactoring done in #16, and doesn't appear to be necessary.

Signed-off-by: Jacob Perron <jacob@openrobotics.org>
jacobperron added a commit that referenced this issue Aug 11, 2020
Fixes #114.

Due to the asynchronous nature of the LoadComposableNodes action, an event handler causes the launch configuration is popped if ComposableNodeContainer appears inside a group or include action.
It seems to me we can simply return the load node action, which will get executed after the ComposableNodeContainer action. The use of an event handler is vestigial of a refactoring done in #16, and doesn't appear to be necessary.

Signed-off-by: Jacob Perron <jacob@openrobotics.org>
@jacobperron
Copy link
Member Author

I did some investigation and I can confirm the launch configuration dropped by the event handler:

RegisterEventHandler(
event_handler=OnProcessStart(
target_action=self,
on_start=[
LoadComposableNodes(
composable_node_descriptions=self.__composable_node_descriptions,
target_container=self
)
]
)
)

Looking through the commit history, the whole event handler strategy for loading seems vestigial; it was originally used in the LoadComposableNodes action, but since moved to the container action (see #16). I don't think it is necessary to use an event and we can simply return the load node action. See #170 for proposed fix.

jacobperron added a commit that referenced this issue Aug 17, 2020
Fixes #114.

Due to the asynchronous nature of the LoadComposableNodes action, an event handler causes the launch configuration is popped if ComposableNodeContainer appears inside a group or include action.
It seems to me we can simply return the load node action, which will get executed after the ComposableNodeContainer action. The use of an event handler is vestigial of a refactoring done in #16, and doesn't appear to be necessary.

Signed-off-by: Jacob Perron <jacob@openrobotics.org>
jacobperron added a commit that referenced this issue Nov 19, 2020
Fixes #114.

Due to the asynchronous nature of the LoadComposableNodes action, an event handler causes the launch configuration is popped if ComposableNodeContainer appears inside a group or include action.
It seems to me we can simply return the load node action, which will get executed after the ComposableNodeContainer action. The use of an event handler is vestigial of a refactoring done in #16, and doesn't appear to be necessary.

Signed-off-by: Jacob Perron <jacob@openrobotics.org>
jacobperron added a commit that referenced this issue Nov 19, 2020
Fixes #114.

Due to the asynchronous nature of the LoadComposableNodes action, an event handler causes the launch configuration is popped if ComposableNodeContainer appears inside a group or include action.
It seems to me we can simply return the load node action, which will get executed after the ComposableNodeContainer action. The use of an event handler is vestigial of a refactoring done in #16, and doesn't appear to be necessary.

Signed-off-by: Jacob Perron <jacob@openrobotics.org>
jacobperron added a commit that referenced this issue Nov 19, 2020
Fixes #114.

Due to the asynchronous nature of the LoadComposableNodes action, an event handler causes the launch configuration is popped if ComposableNodeContainer appears inside a group or include action.
It seems to me we can simply return the load node action, which will get executed after the ComposableNodeContainer action. The use of an event handler is vestigial of a refactoring done in #16, and doesn't appear to be necessary.

Signed-off-by: Jacob Perron <jacob@openrobotics.org>
jacobperron added a commit that referenced this issue Nov 19, 2020
Fixes #114.

Due to the asynchronous nature of the LoadComposableNodes action, an event handler causes the launch configuration is popped if ComposableNodeContainer appears inside a group or include action.
It seems to me we can simply return the load node action, which will get executed after the ComposableNodeContainer action. The use of an event handler is vestigial of a refactoring done in #16, and doesn't appear to be necessary.

Signed-off-by: Jacob Perron <jacob@openrobotics.org>
jacobperron added a commit that referenced this issue Nov 19, 2020
Fixes #114.

Due to the asynchronous nature of the LoadComposableNodes action, an event handler causes the launch configuration is popped if ComposableNodeContainer appears inside a group or include action.
It seems to me we can simply return the load node action, which will get executed after the ComposableNodeContainer action. The use of an event handler is vestigial of a refactoring done in #16, and doesn't appear to be necessary.

Signed-off-by: Jacob Perron <jacob@openrobotics.org>
jacobperron added a commit that referenced this issue Nov 19, 2020
Fixes #114.

Due to the asynchronous nature of the LoadComposableNodes action, an event handler causes the launch configuration is popped if ComposableNodeContainer appears inside a group or include action.
It seems to me we can simply return the load node action, which will get executed after the ComposableNodeContainer action. The use of an event handler is vestigial of a refactoring done in #16, and doesn't appear to be necessary.

Signed-off-by: Jacob Perron <jacob@openrobotics.org>
jacobperron added a commit that referenced this issue Nov 20, 2020
Fixes #114.

Due to the asynchronous nature of the LoadComposableNodes action, an event handler causes the launch configuration is popped if ComposableNodeContainer appears inside a group or include action.
It seems to me we can simply return the load node action, which will get executed after the ComposableNodeContainer action. The use of an event handler is vestigial of a refactoring done in #16, and doesn't appear to be necessary.

Signed-off-by: Jacob Perron <jacob@openrobotics.org>
jacobperron added a commit that referenced this issue Nov 30, 2020
Fixes #114.

Due to the asynchronous nature of the LoadComposableNodes action, an event handler causes the launch configuration is popped if ComposableNodeContainer appears inside a group or include action.
It seems to me we can simply return the load node action, which will get executed after the ComposableNodeContainer action. The use of an event handler is vestigial of a refactoring done in #16, and doesn't appear to be necessary.

Signed-off-by: Jacob Perron <jacob@openrobotics.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants