Coder Social home page Coder Social logo

launch_ros's People

Contributors

adityapande-1995 avatar audrow avatar blast545 avatar bmarchi avatar christophebedard avatar clalancette avatar cottsay avatar dhood avatar dirk-thomas avatar esteve avatar gerkey avatar hidmic avatar ivanpauno avatar jacobperron avatar jacquelinekay avatar kenji-miyake avatar marcoag avatar methyldragon avatar mikaelarguedas avatar mjcarroll avatar mjeronimo avatar mm318 avatar nuclearsandwich avatar paudrow avatar pbaughman avatar rebecca-butler avatar rotu avatar sloretz avatar wjwwood avatar yadunund avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

launch_ros's Issues

Cleanup temporary parameter files when passing parameter dict to Node actions

Parameters can be passed to Node actions as dictionaries as of ros2/launch#138. This is done by writing a temporary parameter yaml file. The temporary file's name should be kept track of and deleted on shutdown to avoid files taking up too much space (hypothetically, in the case where nodes are set to respawn on shutdown, if there's an error that keeps restarting the node, many files could be generated (depending on how it's implemented)).

This task is a followup from https://github.com/ros2/launch/pull/138/files#diff-d78062ac1f3a77c95190e470302b7e69R188.

Error when set default_value to []

Bug report

Required Info:

  • Operating System:
    • Ubuntu 18.04
  • Installation type:
    • binaries
  • Version or commit hash:
    • eloquent

Steps to reproduce issue

    list_foo= LaunchConfiguration('list_foo')

    declare_namespace_cmd = DeclareLaunchArgument(
        'list_foo',
        default_value=[],
        description='a list')

if using an empty list as default_value an error occurs

Expected behavior

no error. since in python this is possible:
node.declare_parameter('list_foo', [], ParameterType.PARAMETER_STRING_ARRAY)

Actual behavior

error (i can post tomorrow the actual error)

regards magnglb

arguments = [--ros-args --log-level WARN] has not expected behavior

Bug report

Required Info:

  • Operating System:
    • Ubuntu 18.04
  • Installation type:
    • binaries

Steps to reproduce issue

  • making a launch file (Python) in a pkg
  • building
  • ros2 launch

`

xyz_cmd= Node(
    package=package;
    node_executable='node_executable',
    node_name=node_name'
    node_namespace = node_namespace ,
    output='screen',
    parameters = [];
    arguments = [('__log_level:=WARN')])

`
arguments = [('__log_level:=WARN')]

leads to: " [WARN] [rcl]: Found log level rule '__log_level:=WARN'. This syntax is deprecated. Use '--ros-args --log-level WARN' instead.
[joint_state_publisher-1] [WARN] [rcl]: Found log level rule '__log_level:=WARN'. This syntax is deprecated. Use '--ros-args --log-level WARN' instead."

**arguments = [(--ros-args --log-level WARN)]**
This does not work

Additional information

In the launch.py file the log-level has to be defined like that
arguments = ['--ros-args', '--log-level', 'DEBUG'],

Don't require node name to be specified if parameter dictionary passed to Node action

The node namespace is always specified when launching a Node action (defaults to /), but the node name is optional.

When parameters are passed to a Node action as a dictionary, they are written to a yaml file. Yaml files of parameters currently require the node name to be specified.

Because of this, if a dictionary of parameters is passed to a Node action, there is a requirement that the node name is also specified.

This requirement can be removed if parameters are passed individually on the command line to the node in a way that doesn't require the node's name (feature not implemented in rcl yet), or if yaml files are made to no longer require the node name.

parameter order in XML is not maintained

When a XML launch file declares parameters for a node the order of the param tags is not maintained if some use name and some use from:

normalized_params = []
params_without_from = []
for param in params:
from_attr = param.get_attr('from', optional=True)
name = param.get_attr('name', optional=True)
if from_attr is not None and name is not None:
raise RuntimeError('name and from attributes are mutually exclusive')
elif from_attr is not None:
# 'from' attribute ignores 'name' attribute,
# it's not accepted to be nested,
# and it can not have children.
normalized_params.append(parser.parse_substitution(from_attr))
continue
elif name is not None:
params_without_from.append(param)
continue
raise ValueError('param Entity should have name or from attribute')
normalized_params.append(
get_nested_dictionary_from_nested_key_value_pairs(params_without_from))

As a consequence when multiple of the param tags with different attributes set the same parameter the actually set value is unexpected since it might not be the last one.

Revisit injection of launch_ros description

Feature request

Feature description

This issue was raised as part of #97 and previously discussed in ros2/launch#208.

Both ros2 launch and ros2 test inject an included description that creates an rclpy node. This node is often useful for testing, though not always needed, and necessary to launch certain actions (e.g. LifecycleNode). The problem is that it can cause confusion and user error.

Related to testing, we end up with two types of launch test files: those that can be executed with launch_test and those that require using ros2 test. As evidenced by #97, this can lead to seemingly broken launch files, which are actually just user error (executing with launch_test instead of ros2 test).

Related to using ros2 launch, if a user decides to include the default description themselves (perhaps a rare case), they will end up starting multiple nodes with the same name. This currently results in the following warning, but may be escalated to an error in the future:

[WARN] [rcl.logging_rosout]: Publisher already registered for provided node name. If this is due to multiple nodes with the same name then all logs for that logger name will go out over the existing publisher. As soon as any node with that name is destructed it will unregister the publisher, preventing any further logs for that name from being published on the rosout topic.

I've opened this ticket to discuss alternatives to relying on the CLI tools for including launch_ros description.

Implementation considerations

Proposed solutions:

  1. Remove the injection
  • In this case, we rely on the users to provide the boiler plate for including the ROS-specific description if they need it. Example.
  • Pros:
    • rostests can be run with launch_test or ros2 test.
    • Helps avoid accidentally including the default description more than once.
  • Cons:
    • Extra boilerplate for the user.
    • Requires knowledge of which launch_ros actions require the inclusion of the default description.
  1. Only inject when necessary
  • Somehow know when an action requires the extra node provided by the default description and conditionally include it. This would require knowing when the description is already included so it is not included multiple times.
  • Pros:
    • Same as (1).
  • Cons:
    • Added complexity to launch and/or launch_ros.

I don't have any solid ideas at the moment for how to accomplish (2). But I think it makes sense in any solution that we guard against including the default description multiple times.

Namespace not pushed by `PushRosNamespace`

Bug report

Required Info:

  • Operating System:
    • Ubuntu 18.04
  • Installation type:
    • Source
  • Version or commit hash:
  • DDS implementation:
    • Fast-RTPS

Steps to reproduce issue

Given the following talker_launch.py

from launch import LaunchDescription
import launch.actions
import launch_ros.actions

def generate_launch_description():

    return LaunchDescription([
        launch_ros.actions.Node(
            package='demo_nodes_cpp',
            node_executable='talker',
            output='screen',
            node_name='talker')
    ])

And the following file with name include_launch.py that includes talker_launch.py:

from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
from launch.actions import GroupAction
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import ThisLaunchFileDir
from launch_ros.actions import PushRosNamespace


def generate_launch_description():

    return LaunchDescription([
        GroupAction([
            PushRosNamespace('talker_ns'),
            IncludeLaunchDescription(
                PythonLaunchDescriptionSource([ThisLaunchFileDir(), '/talker_launch.py']))
        ])
    ])

Expected behavior

We would expect the node name to be: /talker_ns/talker.

Actual behavior

However, it is: /talker

Additional information

But, if we provide node_namespace='' to the action in talker_launch.py, and launch include_launch.py, then the node name is /talker_ns/talker

Bad interaction between launch frontend and YAML parameters

Both launch XML and YAML frontends currently coexist with the YAML parsing of substitution text in Node parameters. This has caused us issues in the past (e.g. ros2/launch#226 (comment)), forcing additional quotes as escape mechanisms. At the time we deemed this as a situation we'd rarely find in the field.


Well, as you can see in RobotWebTools/rosbridge_suite#433, specifically on commit RobotWebTools/rosbridge_suite@d466c89, it's not as rare as we thought.

There, I'm forced to surround a * with two ' on each side.

  • Why a * needs this? Because it's later used as a Node parameter and parameters are parsed as YAML, that parses that * as a malformed alias (see PyYAML documentation about aliases).

  • Why two '? The inner pair prevents * from being parsed as a YAML alias, and the outer pair is removed by the frontend for consistency -- otherwise one has to remember that some values given in e.g. XML are parsed using YAML under the hood and some are not.

IMHO the deeper, unresolved issue that #31 partially addressed is that Substitutions in launch are always text and it is up to the receiving end to do any additional parsing, opening the door to things like this.

Release 'launch_testing_ros' to Crystal

Feature description

There's a great potential on the testing framework that would be great to have in Crystal as well, specially for testing packages released for multiple distro versions (in this case, considering Crystal as well)

Implementation considerations

I guess it would be as simple as doing a bloom release for Crystal, unless the API doesn't allow it or requires backporting other changes.

@wjwwood @sloretz thanks in advance!

roslaunch fails reading yaml file

I working with ROS2 Dashing on Ubuntu Bionic. I want to pass parameters to a node with a yaml file.

While I was looking for a solution, I came across a solution for ROS2 crystal on this post https://stackoverflow.com/questions/53917469/how-to-launch-a-node-with-a-parameter-in-ros2.

Unfortunately, that does not seem to work under ROS2 dashing. I created a fork of the ROS2 realsense driver (https://github.com/AndreasAZiegler/ros2_intel_realsense/tree/serial_no_param/realsense_ros2_camera) and my goal is to be able to pass the serial number via a parameter. With

ros2 run realsense_ros2_camera realsense_ros2_camera  __params:=/paht/to/config/parameters.yaml

passing the parameter works fine but when I start the node with the launch python file

ros2 launch realsense_ros2_camera ros2_intel_realsense.launch.py

it ignores the parameter. The path to the parameters.yaml is correct (I print it in the launch python script).

Output a warning when launching multiple nodes with the same name

Feature request

Node name uniqueness is not enforced in ROS2. It seems to be uncertain whether-or-when it will be so. In the meantime, there is a lot of user confusion that can happen around having multiple nodes with the same name, since much of ROS2 assumes they are uniquely named.

One user-helping mitigation we can introduce is: Within a single invocation of ros2 launch, log a warning message for duplicate node names before actually starting them. This will highlight one source of duplicate node names.

Limitations:

  • this does nothing to help in separately-launched launchfiles (e.g. other robots on the network or separate shells)
  • this probably can't introspect the default names if users do not specify a node name on the Node action

Implementation considerations

I'm not yet familiar enough with this code to understand how to implement. I assume at some point launch has a fully substituted flattened list of things to start, at which point we'd have all the node names expanded out and can detect duplicates.

lifecycle_node causing launch to hang at shutdown

Bug report

Required Info:

  • Operating System:
    • Ubuntu 18.04 -->
  • Installation type:
    • Source
  • Version or commit hash:
    • Launch: c644dfa8e1f1433e200b76eb52ba22f392838f48
    • Launch Ros: 84cdecd
  • DDS implementation:
    • Fast-RTPS

I'm not sure if this issue is launch or launch_ros related. I've got another issue open here: ros2/launch#359

It appears that a lifecycle_node can deadlock with the launch service when shutting down. Both the launch service and the lifecycle_node are waiting on the launch service's _process_one_event to return. I'm looking for tips for how to continue debugging this.

Steps to reproduce issue

I can get this to happen by running ros2 test lifecycle/test/test_lifecycle.py in a loop. Eventually the test will hang after the active tests and before the post-shutdown tests run.

I can determine that launch_testing is stuck in self._launch_service.run()

I can determine the launch service is stuck here

Furthermore, I can print some information about what's in the entity_futures list:

    <Task pending coro=<LaunchService._process_one_event() running at /home/pete.baughman/gc/apex_ws/build/launch/launch/launch_service.py:286> wait_for=<Future
 pending cb=[Task._wakeup()] created at /usr/lib/python3.6/asyncio/base_events.py:295> created at /home/pete.baughman/gc/apex_ws/build/launch/launch/launch_service.py:355>
      [
        <FrameSummary file /home/pete.baughman/gc/apex_ws/build/launch/launch/launch_service.py, line 414 in run>,
        <FrameSummary file /usr/lib/python3.6/asyncio/base_events.py, line 471 in run_until_complete>,
        <FrameSummary file /usr/lib/python3.6/asyncio/base_events.py, line 438 in run_forever>,
        <FrameSummary file /usr/lib/python3.6/asyncio/base_events.py, line 1451 in _run_once>,
        <FrameSummary file /usr/lib/python3.6/asyncio/events.py, line 145 in _run>,
        <FrameSummary file /usr/lib/python3.6/asyncio/tasks.py, line 261 in _wakeup>,
        <FrameSummary file /usr/lib/python3.6/asyncio/tasks.py, line 180 in _step>,
        <FrameSummary file /home/pete.baughman/gc/apex_ws/build/launch/launch/launch_service.py, line 355 in run_async>
      ]
    <Future pending cb=[_chain_future.<locals>._call_check_cancel() at /usr/lib/python3.6/asyncio/futures.py:403] created at /usr/lib/python3.6/asyncio/base_events.py:295>
      [
        <FrameSummary file /usr/lib/python3.6/asyncio/tasks.py, line 180 in _step>,
        <FrameSummary file /home/pete.baughman/gc/apex_ws/build/launch/launch/launch_service.py, line 287 in _process_one_event>,
        <FrameSummary file /home/pete.baughman/gc/apex_ws/build/launch/launch/launch_service.py, line 307 in __process_event>,
        <FrameSummary file /home/pete.baughman/gc/apex_ws/build/launch/launch/utilities/visit_all_entities_and_collect_futures_impl.py, line 38 in visit_all_entities_and_collect_futures>,
        <FrameSummary file /home/pete.baughman/gc/apex_ws/build/launch/launch/action.py, line 89 in visit>,
        <FrameSummary file /home/pete.baughman/gc/apex_ws/build/launch/launch/actions/opaque_function.py, line 75 in execute>,
        <FrameSummary file /home/pete.baughman/gc/apex_ws/build/launch_ros/launch_ros/actions/lifecycle_node.py, line 101 in _on_change_state_event>,
        <FrameSummary file /usr/lib/python3.6/asyncio/base_events.py, line 655 in run_in_executor>,
        <FrameSummary file /usr/lib/python3.6/asyncio/futures.py, line 431 in wrap_future>,
        <FrameSummary file /usr/lib/python3.6/asyncio/base_events.py, line 295 in create_future>
      ]

I'm not so good at asyncio futures, but it looks like I've got one task pending that was created here and another future in the event queue that came from a launch_ros/actions/lifecycle_node that's also waiting for _process_one_event in the launch_service.

Does any of this look familiar to anybody? Any tips for how to continue debugging this hang?

talker_listener_launch_test example is broken

Trying to run this launch test:

python3 -m launch_testing.launch_test src/ros2/launch_ros/launch_testing_ros/test/examples/talker_listener_launch_test.py

Yields:

Traceback (most recent call last):
  File "src/ros2/launch_ros/launch_testing_ros/test/examples/talker_listener_launch_test.py", line 72, in test_talker_transmits
    node = launch_context.locals.launch_ros_node
  File "build/launch/launch/launch_context.py", line 137, in __getattr__
    ', '.join(_dict.keys())
AttributeError: context.locals does not contain attribute 'launch_ros_node', it contains: []

[ros2launch] Optional 'package_name' when full path is provided

Feature request

Feature description

Ability to call launch omitting the package_name argument given that the launch file full path is provided.

E.g.

$ ros2 launch ./my_launch.launch.py

Beside mimicking roslaunch, this feature comes handy when one wants to run a launch file that is not in a proper ROS package. Even more so since launch files are now Python scripts.

Implementation considerations

I do not know about the difficulties here, there seems to be a somewhat related todo comment tho.

Node action failing with 'env' argument

Bug report

  • Operating System:
    • Ubuntu 18.04
  • Installation type:
    • From source
  • Version or commit hash:
    • launch_ros(#448846d9361f39bdde94d1a41679abac3a1e124a)
  • DDS implementation:
    • fast-rtps
  • Client library (if applicable):
    • rclcpp

Steps to reproduce issue

This is a modified version of launch_ros/examples/pub_sub_launch.py here.

# Copyright 2018 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Launch a talker and a listener."""

import os
import sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))  # noqa
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', 'launch'))  # noqa

from launch import LaunchDescription
from launch import LaunchIntrospector
from launch import LaunchService

from launch_ros import get_default_launch_description
import launch_ros.actions


def main(argv=sys.argv[1:]):
    """Main."""
    ld = LaunchDescription([
        launch_ros.actions.Node(
            package='demo_nodes_cpp', node_executable='talker', output='screen',
            env={'asd': '1'},
            remappings=[('chatter', 'my_chatter')]),
        launch_ros.actions.Node(
            package='demo_nodes_cpp', node_executable='listener', output='screen',
            remappings=[('chatter', 'my_chatter')]),
    ])

    print('Starting introspection of launch description...')
    print('')

    print(LaunchIntrospector().format_launch_description(ld))

    print('')
    print('Starting launch of launch description...')
    print('')

    # ls = LaunchService(debug=True)
    ls = LaunchService()
    ls.include_launch_description(get_default_launch_description())
    ls.include_launch_description(ld)
    return ls.run()


if __name__ == '__main__':
    main()

This line has been added to the original file:

            env={'asd': '1'},

Expected behavior

It should work as the original example.

Actual behavior

It fails to find the rmw implementation:

Starting introspection of launch description...

<launch.launch_description.LaunchDescription object at 0x7fcf4cfff3c8>
├── ExecuteProcess(cmd=[ExecInPkg(pkg='demo_nodes_cpp', exec='talker'), LocalVar('remapping 1')], cwd=None, env={'asd': '1'}, shell=False)
└── ExecuteProcess(cmd=[ExecInPkg(pkg='demo_nodes_cpp', exec='listener'), LocalVar('remapping 1')], cwd=None, env=None, shell=False)

Starting launch of launch description...

[INFO] [launch]: All log files can be found below /home/ivanpauno/.ros/log/2019-04-11-16-24-06-965421-71c1584df2a2-5104
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [talker-1]: process started with pid [5113]
[INFO] [listener-2]: process started with pid [5114]
[talker-1] terminate called after throwing an instance of 'rclcpp::exceptions::RCLError'
[talker-1]   what():  failed to initialized rcl init options: failed to find shared library of rmw implementation. Searched rmw_fastrtps_cpp, at /home/ivanpauno/ros2_ws/src/ros2/rmw_implementation/rmw_implementation/src/functions.cpp:129, at /home/ivanpauno/ros2_ws/src/ros2/rcl/rcl/src/rcl/init_options.c:55
[ERROR] [talker-1]: process has died [pid 5113, exit code -6, cmd '/home/ivanpauno/ros2_ws/install/demo_nodes_cpp/lib/demo_nodes_cpp/talker chatter:=my_chatter'].

Create `PushRemapping`

Feature request

Feature description

In the spirit of PushRosNamespace, a PushRemapping action would add a remapping to be applied to all Nodes within the scope.

It solves the problem of applying the same remapping (possibly conditioned) to multiple nodes (on possibly on different launch descriptions).

Implementation considerations

This involves creating a PushRemapping, perhaps passing tuples of remappings to it. Which then get added to the context's launch configurations. It involves also extending the Node action, particularly perform_substitutions to add the remappings on the context.

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

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.

Trying to launch a lifecycle node with launch_ros.actions.Node fails silently

Passing a lifecycle node executable to a launch_ros.actions.Node fails rather silently as in the below example. The mistake is hard to spot and should throw an obvious error pointing out the mistake (in this case that node_executable lifecycle_talker does not spin a lifecycle node).

from launch import LaunchDescription
from launch_ros.actions import Node


def generate_launch_description():
    return LaunchDescription([
        Node(package='lifecycle', node_executable='lifecycle_talker',
             node_name='lc_talker', output='screen'),
        Node(package='lifecycle', node_executable='lifecycle_listener', output='screen'),
        Node(package='lifecycle', node_executable='lifecycle_service_client', output='screen')
    ])

[INFO] [lifecycle_talker-1]: process started with pid [30809]
[INFO] [lifecycle_listener-2]: process started with pid [30810]
[INFO] [lifecycle_service_client-3]: process started with pid [30811]
[lifecycle_service_client-3] [ERROR] [lc_client]: Service /lc_talker/change_state is not available.
[INFO] [lifecycle_service_client-3]: process has finished cleanly [pid 30811]

test_launch_ros tests fail when using nightly docker image

Bug report

Required Info:

  • Operating System:
    • Ubuntu 16.04
  • Installation type:
    • Mostly binaries. launch_ros built from source
  • Version or commit hash:
    • launch_ros: 93b242c
    • Nightly docker image ed821d8fbcf3 (yesterday)
    • Nightly docker image 0f21b27cbc11 (today)
  • DDS implementation:
    • N/A
  • Client library (if applicable):
    • N/A

Steps to reproduce issue

pete@pete-VirtualBox:~$ docker pull osrf/ros2:nightly
pete@pete-VirtualBox:~$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
osrf/ros2           nightly             0f21b27cbc11        23 minutes ago      3.62GB
. . . 
pete@pete-VirtualBox:~$ docker run --rm -it -v ~/launch_ros:/launch_ros osrf/ros2:nightly

root@1b2a1736429f:/# cd launch_ros/
root@1b2a1736429f:/launch_ros# colcon build
root@1b2a1736429f:/launch_ros# colcon test
Starting >>> launch_ros
Finished <<< launch_ros [4.76s]          
Starting >>> launch_testing_ros
Starting >>> ros2launch
Starting >>> test_launch_ros                                  
Finished <<< ros2launch [3.88s]                               
Finished <<< test_launch_ros [5.58s]    [ with test failures ]
Finished <<< launch_testing_ros [11.5s]            
                      
Summary: 4 packages finished [16.7s]
  1 package had test failures: test_launch_ros
root@1b2a1736429f:/launch_ros# colcon test-result --verbose
. . .
[ERROR] [launch]: Caught exception in launch (see debug for traceback): package 'demo_nodes_py' found at '/opt/ros/foxy', but libexec directory '/opt/ros/foxy/lib/demo_nodes_py' does not exist

Expected behavior

These tests should pass, I'm running them unmodified

Actual behavior

It looks like something is wrong with how demo_nodes_py is used or maybe built

Additional information

Maybe this is helpful:

root@1b2a1736429f:/launch_ros# find /opt -iname demo_nodes_py
/opt/ros/foxy/lib/python3.6/site-packages/demo_nodes_py
/opt/ros/foxy/share/demo_nodes_py
/opt/ros/foxy/share/colcon-core/packages/demo_nodes_py
/opt/ros/foxy/share/ament_index/resource_index/packages/demo_nodes_py

It looks like the correct path might be /opt/ros/foxy/lib/python3.6/site-packages/demo_nodes_py instead of /opt/ros/foxy/lib/demo_nodes_py?

Invalid keyword argument

Bug report

Required Info:

  • Operating System:
    • Ubuntu 18.04
    • Jenkins build farm - multiple systems (linux, osx, etc)
  • Installation type:
    • source
  • Version or commit hash:

Build farm test link

Steps to reproduce issue

Check out a clean workspace

colcon build --packages-up-to test_launch_ros
colcon test --packages-up-to test_launch_ros

Expected behavior

test/test_launch_ros/frontend/test_node_frontend.py passes

Actual behavior

TypeError: parse_substitution() got an unexpected keyword argument 'optional'

Add a way of grouping remapping rules and parameters

Feature request

Feature description

We don't have a SetRemapping action.
It could be useful, is the same remapping has to be applied in many nodes.

Implementation considerations

We could store them in the LaunchContext. The group action will do its magic for limiting their scope.

Previous discussion: ros2/ros2_documentation#302 (comment)


We could do something similar for parameters.
But it won't set a global parameter, as in ROS 1, but it'll set the same parameter in each node in the scope.

Previous discussion:
ros2/ros2_documentation#302 (comment)

launch file should interpret LaunchConfiguration values as yaml

Bug report

Required Info:

  • Operating System:
    • OSX, but should apply to all
  • Installation type:
    • source
  • Version or commit hash:
    • HEAD

Steps to reproduce issue

It is currently not trivial to set a boolean parameter via a launch file.

    return LaunchDescription([
        DeclareLaunchArgument(
            'use_sim_time',
            default_value='True',
            description='Use simulation (Gazebo) clock if true'),

        Node(
            package='robot_state_publisher',
            node_executable='robot_state_publisher',
            node_name='robot_state_publisher',
            output='screen',
            parameters=[{'use_sim_time': LaunchConfiguration('use_sim_time')}],
            arguments=[urdf])
    ])

Expected behavior

Robot state publisher sets the boolean parameter use_sim_time to true

Actual behavior

Robot state publisher complains that parameter use_sim_time is a string

Additional information

A workaround for this to work is to use IfConditions and UnlessConditions.

    return LaunchDescription([
        DeclareLaunchArgument(
            'use_sim_time',
            default_value='True',
            description='Use simulation (Gazebo) clock if true'),

        Node(
            package='robot_state_publisher',
            node_executable='robot_state_publisher',
            node_name='robot_state_publisher',
            output='screen',
            parameters=[{'use_sim_time': True}],
            arguments=[urdf],
            condition=IfCondition(LaunchConfiguration('use_sim_time'))),

        Node(
            package='robot_state_publisher',
            node_executable='robot_state_publisher',
            node_name='robot_state_publisher',
            output='screen',
            parameters=[{'use_sim_time': False}],
            arguments=[urdf],
            condition=UnlessCondition(LaunchConfiguration('use_sim_time')))
    ])

Standalone Component Action

Feature request

Feature description

Add a launch action that will allow for a single component to be loaded into a component container. This would be a simplified representation or alias to the larger component actions.

Make OnStateTransition work with the new ComposableNode descriptions

Feature request

Feature description

In Dashing, the ComposableNodeContainer action and the corresponding ComposableNode description were introduced. A ComposableNode description also takes a managed node (aka lifecycle node). However, configuring and activating a lifecycle node by a ComposableNode description (instead of a LifecycleNode action) fails:

on_inactive_node_B_handler = launch.actions.RegisterEventHandler(
        launch_ros.event_handlers.OnStateTransition(
            target_lifecycle_node=node_B,
            goal_state='inactive',
            entities=[configure_node_A]))

> Caught exception in launch (see debug for traceback): OnStateTransition 
  requires a 'LifecycleNode' action as the target

Using a matcher is also not possible but gives an exception.

on_inactive_node_B_handler = launch.actions.RegisterEventHandler(
        launch_ros.event_handlers.OnStateTransition(
            matcher=launch_ros.events.lifecycle.matches_node_name("/example/node_B"),
            goal_state='inactive',
            entities=[configure_node_A]))

> ... return lambda action: action.node_name == node_name
  AttributeError: 'Shutdown' object has no attribute 'node_name'

When calling matches_action with a ComposableNode description is simply does nothing:

    configure_node_B = launch.actions.EmitEvent(
        event=launch_ros.events.lifecycle.ChangeState(
            lifecycle_node_matcher=launch.events.matchers.matches_action(node_B),
            transition_id=lifecycle_msgs.msg.Transition.TRANSITION_CONFIGURE,
        )
    )

Probably, the whole matching and event system for lifecycle action and events has to be extended for ComposbleNode descriptions.

As a starting for experiments, you may use the damped_pendulum_with_transport_delay_as_composed_node.launch.py of the fmi_adapter_examples package, cf. https://github.com/boschresearch/fmi_adapter_ros2/blob/0.1.5/fmi_adapter_examples/launch/damped_pendulum_with_transport_delay_as_composed_node.launch.py and remove comments in lines 90 to 103 and 106 to 108.

Can't launch node with empty args

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

<launch>
  <!-- Fails -->
  <!--node
    pkg="demo_nodes_cpp"
    exec="listener"
    output="screen"
    name="demo_listener_1">
  </node-->
  
  <!-- Fails -->
  <!--node
    pkg="demo_nodes_cpp"
    exec="listener_2"
    output="screen"
    name="demo_listener"
    args="">
  </node-->

  <!-- Succeeds with dummy args -->
  <node
    pkg="demo_nodes_cpp"
    exec="listener"
    output="screen"
    name="demo_listener_3"
    args="foo">
  </node>
</launch>

Uncomment the node tags in the above launch file (one at a time) and launch.

Expected behavior

All nodes in the example launch successfully.

Actual behavior

The first two nodes fail to launch.

The first with the error:

AttributeError: Attribute args of type <class 'str'> not found in Entity node

And the second with the error:

lark.exceptions.ParseError: Unexpected end of input! Expecting a terminal of: [Terminal('DOLLAR'), Terminal('UNQUOTED_STRING'), Terminal('DOLLAR')]

Launch composable C++ nodes

Feature request

This is a feature request for launching multiple composable nodes into the same process. The acceptance criteria for this ticket is limited to launching dynamically composable rclcpp non-lifecycle nodes into a container process.

Feature description

launch_ros must pass arguments to the composable nodes where "arguments" means:

  • the information that can be passed via the command line of any rcl based node
    • parameters
    • remap rules
    • node name
    • namespace
    • log level
  • information that is specific to the client library rclcpp
    • use_intra_process_comms
    • start_parameter_services

An exception is use_global_arguments which should always be false so a composed node is not affected by arguments passed to the container process.

Arguments does not include environment variables like RMW_IMPLEMENTATION which apply to the whole container process.

PRs

  • OnProcessStart ros2/launch#171
  • Reusable type checking for remap rules ros2/launch#173
  • Reusable type checking for parameters ros2/launch#192
  • launch_ros.ComposableNode, launch_ros.actions.LoadComposableNodes, launch_ros.actions.ComposableNodeContainer plus examples from #9

Implementation considerations

launch_ros

See slide 8 of https://roscon.ros.org/2018/presentations/ROSCon2018_launch.pdf

        ExecuteComposableNodeProcess(
            package='rclcpp_components', container_executable='rclcpp_node_container', output='screen',
            composable_node_descriptions=[
                ComposableNodeDescription(
                    package_name='demo_nodes_cpp', node_plugin_name='talker',
                    name='my_talker'),
                ComposableNodeDescription(
                    package_name='demo_nodes_cpp', node_plugin_name='listener'
                    name='my_listener')
            ]
        )

ExecuteComposableNodeProcess should start a container executable with a defined API. This allows a user to create a custom container process (e.g. create a container with a custom executor). The API may be a config file and/or a ROS API. The acceptance criteria for this ticket is limited to a ROS service API that can load and unload composable nodes (see also ros2/rcl_interfaces#60).

rclcpp

There must be a new ROS package (rclcpp_components?) with a container process for rclcpp nodes. The acceptance criteria for this task is to be able to use either a single threaded executor or multithreaded executor in a container process. For example, this could be two container processes, or one with a CLI argument to choose the executor.

Launching a composable node requires a common API for constructing a node.
One option is to mimic ROS 1 nodelets which required a default constructor on the node and had an init() member function to initialize the nodes with parameters.
Another option is having a constructor with one argument and and a factory class to call it.
Regardless this task should require ros2/rclcpp#492 so there is one object NodeArguments/NodeOptions so new arguments to a node don't require changing the signature of a function.

CMake API

This ticket includes creating a CMake API for creating a composable node. This API should

  • call add_library(... SHARED ..)
  • optionally add_executable() with a generated main()
  • register the composable node with pluginlib

Provide Documentation on how to use XML API

Feature request

Feature description

Provide an example on how to use the XML API, i.e., if I have a launch file, how can I get it running? Do I need to create a package, do I need to add it in package.xml whatsoever...

Especially since the release of Eloquent Elusor, the launch system became way more practical (imho) and is one of the great features of ROS1. Nonetheless, I struggle to get it running. I already asked on answers.ros, receiving no answer.

Implementation considerations

Tab autocomplete to only list launch files in package when package is specified

Bug report

When using the ros2 launch CLI, tab autocomplete for pwd files persists even after a valid package name is specified in the first argument. This makes it annoying to use the CLI in busy directories, particularly when you'd just like to check for the available launch files in the package specified.

Required Info:

  • Operating System:
    • Ubuntu 18.04
  • Installation type:
    • binaries:
  • Version or commit hash:
    • ros-eloquent-launch/bionic,now 0.9.6-1bionic.20200121.220323 amd64

Expected behavior

ros2 launch foo<TAB TAB>
should enumerate all packages and files in PWD that start with the string foo

ros2 launch foo bar<TAB TAB>
should enumerate only launch files in package foo that start with the string bar

Actual behavior

Instead, available launch file names are interleaved among the long list of files in the pwd, even though they would be invalid inputs given such paths do not exist in the package's launch folder.

Additional information

Such plagues me when invoking ros2 launch from a freshly spawned shell in my busy ~/ directory.


Feature request

Perhaps add args such as --package, -p, --launchfile, -l, --file, -f to hint the autocomplete?

Feature description

ros2 launch -p foo<TAB TAB>
should enumerate only packages that start with the string foo

ros2 launch -f foo<TAB TAB>
should autocomplete file paths that start with the string foo

ros2 launch -p foo -l bar<TAB TAB>
should autocomplete launch file names that exist in package foo that start with the string bar

Implementation considerations

Perhaps keep the existing positional package+launchfile args, and introduce a --file, -f arg when wishing to autocomplete general file paths?

Allow LifecycleNodes to be added to ComposableNodeContainers

Feature request

Feature description

Allow launch_ros.actions.ComposableNodeContainer to contain launch_ros.actions.LifecycleNode objects which are also registered as Composable Nodes. It is possible to register an rclcpp::LifecycleNode as a Comoposable node (see example here) but it is not possible in launch_ros right now to both reference these nodes as LifecycleNode objects (to allow functions like state transitions) and also combine them into a ComposableNodeContainer.

secondary launch adding components into running containers

For modularity the user might want to split a launch file into separate files which are started independently. One example would be a base_launch.py file which gets started once and a dev_launch.py file which contains stuff which the developer iterates on which is being started / stopped repeatedly.

For nodes running in separate processes these launch files can be started independently. What is not supported at the moment is for both launch files to contribute components into the same process. E.g. the second launch file want to inject a component into a process which was started by the first launch file.

The goal would be to support this use case within launch.

[xml frontend] Can't launch node without name attribute

Bug report

Required Info:

  • Operating System:
    • Ubuntu bionic
  • Installation type:
    • source
  • Version or commit hash:
    • master
  • DDS implementation:
    • Fast-RTPS
  • Client library (if applicable):
    • N/A

Steps to reproduce issue

Save the following as test.launch.xml

<?xml version="1.0"?>
<launch>
  <node pkg="demo_nodes_cpp" exec="talker" output="screen" args=" ">
  </node>
</launch>

Run it with

ros2 launch --debug test.launch.xml 

Expected behavior

Node would successfully launch using whatever name is its default.

Actual behavior

An exception is raised.

traceback
$ ros2 launch --debug tf2_ros_py/src/mypkg/launch/test.launch.xml 
[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/sloretz/.ros/log/2019-08-29-14-21-16-169948-87cee88a3136-25020
[INFO] [launch]: Default logging verbosity is set to DEBUG
[DEBUG] [launch]: processing event: '<launch.events.include_launch_description.IncludeLaunchDescription object at 0x7f768f3ae4e0>'
[DEBUG] [launch]: processing event: '<launch.events.include_launch_description.IncludeLaunchDescription object at 0x7f768f3ae4e0>' ✓ '<launch.event_handlers.on_include_launch_description.OnIncludeLaunchDescription object at 0x7f7684a17358>'
[DEBUG] [launch]: processing event: '<launch.events.include_launch_description.IncludeLaunchDescription object at 0x7f768032ddd8>'
[DEBUG] [launch]: processing event: '<launch.events.include_launch_description.IncludeLaunchDescription object at 0x7f768032ddd8>' ✓ '<launch.event_handlers.on_include_launch_description.OnIncludeLaunchDescription object at 0x7f7684a17358>'
[DEBUG] [launch]: Traceback (most recent call last):
  File "/home/sloretz/workspaces/ros2-dev0/build/launch/launch/launch_description_sources/any_launch_file_utilities.py", line 53, in get_launch_description_from_any_launch_file
    return loader(launch_file_path)
  File "/home/sloretz/workspaces/ros2-dev0/build/launch/launch/launch_description_sources/frontend_launch_file_utilities.py", line 35, in get_launch_description_from_frontend_launch_file
    return parser.parse_description(root_entity)
  File "/home/sloretz/workspaces/ros2-dev0/build/launch/launch/frontend/parser.py", line 102, in parse_description
    actions = [self.parse_action(child) for child in entity.children]
  File "/home/sloretz/workspaces/ros2-dev0/build/launch/launch/frontend/parser.py", line 102, in <listcomp>
    actions = [self.parse_action(child) for child in entity.children]
  File "/home/sloretz/workspaces/ros2-dev0/build/launch/launch/frontend/parser.py", line 85, in parse_action
    return instantiate_action(entity, self)
  File "/home/sloretz/workspaces/ros2-dev0/build/launch/launch/frontend/expose.py", line 38, in instantiate_action
    action_type, kwargs = action_parse_methods[entity.type_name](entity, parser)
  File "/home/sloretz/workspaces/ros2-dev0/build/launch_ros/launch_ros/actions/node.py", line 234, in parse
    kwargs['node_name'] = kwargs['name']
KeyError: 'name'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/sloretz/workspaces/ros2-dev0/build/launch/launch/launch_service.py", line 377, 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 "/home/sloretz/workspaces/ros2-dev0/build/launch/launch/launch_service.py", line 287, 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 "/home/sloretz/workspaces/ros2-dev0/build/launch/launch/launch_service.py", line 307, in __process_event
    visit_all_entities_and_collect_futures(entity, self.__context))
  File "/home/sloretz/workspaces/ros2-dev0/build/launch/launch/utilities/visit_all_entities_and_collect_futures_impl.py", line 45, in visit_all_entities_and_collect_futures
    futures_to_return += visit_all_entities_and_collect_futures(sub_entity, context)
  File "/home/sloretz/workspaces/ros2-dev0/build/launch/launch/utilities/visit_all_entities_and_collect_futures_impl.py", line 45, in visit_all_entities_and_collect_futures
    futures_to_return += visit_all_entities_and_collect_futures(sub_entity, context)
  File "/home/sloretz/workspaces/ros2-dev0/build/launch/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 "/home/sloretz/workspaces/ros2-dev0/build/launch/launch/action.py", line 112, in visit
    return self.execute(context)
  File "/home/sloretz/workspaces/ros2-dev0/build/launch/launch/actions/include_launch_description.py", line 128, in execute
    launch_description = self.__launch_description_source.get_launch_description(context)
  File "/home/sloretz/workspaces/ros2-dev0/build/launch/launch/launch_description_source.py", line 84, in get_launch_description
    self._get_launch_description(self.__expanded_location)
  File "/home/sloretz/workspaces/ros2-dev0/build/launch/launch/launch_description_sources/any_launch_description_source.py", line 53, in _get_launch_description
    return get_launch_description_from_any_launch_file(location)
  File "/home/sloretz/workspaces/ros2-dev0/build/launch/launch/launch_description_sources/any_launch_file_utilities.py", line 56, in get_launch_description_from_any_launch_file
    raise InvalidLaunchFileError(extension, likely_errors=exceptions)
launch.invalid_launch_file_error.InvalidLaunchFileError: Caught exception when trying to load file of format [{}]:

[ERROR] [launch]: Caught exception in launch (see debug for traceback): Caught exception when trying to load file of format [{}]:
[DEBUG] [launch.launch_context]: emitting event: 'launch.events.Shutdown'
[DEBUG] [launch]: processing event: '<launch.events.shutdown.Shutdown object at 0x7f768032d5c0>'
[DEBUG] [launch]: processing event: '<launch.events.shutdown.Shutdown object at 0x7f768032d5c0>' ✓ '<launch.event_handlers.on_shutdown.OnShutdown object at 0x7f767c0ecba8>'
^C[WARNING] [launch]: user interrupted with ctrl-c (SIGINT)
[DEBUG] [launch]: processing event: '<launch.events.shutdown.Shutdown object at 0x7f768032d5c0>' ✓ '<launch.event_handlers.on_shutdown.OnShutdown object at 0x7f768f41e4a8>'
Executing <Task finished coro=<LaunchService._process_one_event() done, defined at /home/sloretz/workspaces/ros2-dev0/build/launch/launch/launch_service.py:285> result=None created at /home/sloretz/workspaces/ros2-dev0/build/launch/launch/launch_service.py:355> took 0.998 seconds

Additional information

The launch file works fine if I add a name attribute.

<?xml version="1.0"?>
<launch>
  <node pkg="demo_nodes_cpp" exec="talker" output="screen" name="demo_talker" args=" ">
  </node>
</launch>

Similar to #53, but with a different attribute on the node tag.

Can't use launch argument for node output

Bug report

Required Info:

  • Operating System:
    • Ubuntu 18.04
  • Installation type:
    • From apt

Steps to reproduce issue

Using a launch file like:

import launch
import launch_ros.actions

#Argument names
NODE_NAME = "node_name"
OUTPUT = "output"

def generate_launch_description():
  ld = launch.LaunchDescription([
    launch.actions.DeclareLaunchArgument(
      NODE_NAME,
      default_value="node_name",
    ),
    launch.actions.DeclareLaunchArgument(
      OUTPUT,
      default_value="screen"
    ),
 ])
  node = launch_ros.actions.Node(
      package="package_name",
      node_executable="executable_name",
      output=launch.substitutions.LaunchConfiguration(OUTPUT),
      node_name=launch.substitutions.LaunchConfiguration(NODE_NAME),
  )
  ld.add_action(node)
  return ld

Then run:

ros2 launch example_launch.py

Expected behavior

I would expect the output to default to 'screen', but be settable from the cli with output:=log or from another launch file that includes this one.

Actual behavior

Launch fails with message

[ERROR] [launch]: Caught exception in launch (see debug for traceback): <launch.substitutions.launch_configuration.LaunchConfiguration object at 0x7f5f04242ac8> is not a valid output configuration

Additional information


Feature request

Feature description

Implementation considerations

Is it possible to support set node options in launch file?

I have two ComposableNode in launch.py and execute them in a single process. However, there is not any performance improvement compared with running them in two processes respectively, in terms of latency and throughput(measured by ros2 topic delay and ros2 topic hz). Is it expected?
After the observation, I would like to make them run in a single process with memory zero-copy. As far as I know, it can be set by intra_process_comm of rclcpp::NodeOptions, but I don't know how to make it in launch file. Anyone can help?

Can't write launch tests with composable nodes

Bug report

Required Info:

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

Steps to reproduce issue

Example launch test file:

import sys 
import unittest

from launch import LaunchDescription
from launch.actions import OpaqueFunction

from launch_ros.actions import ComposableNodeContainer
from launch_ros.descriptions import ComposableNode

import pytest


@pytest.mark.rostest
def generate_test_description(ready_fn):

    return LaunchDescription([
        ComposableNodeContainer(
            package='rclcpp_components',
            node_executable='component_container',
            node_name='my_node_container',
            node_namespace='',
            composable_node_descriptions=[
                ComposableNode(
                    package='composition',
                    node_plugin='composition::Talker'
                )
            ],
            output='screen'
        ),
        OpaqueFunction(function=lambda context: ready_fn()),
    ])  


class TestMyNode(unittest.TestCase):

    def test_something(self):
        print('We do not see this message', file=sys.stderr)

Expected behavior

The tests runs and passes without errors.

Actual behavior

Different runtime errors depending how you run the test.

launch_test
[INFO] [launch]: All log files can be found below /home/jacob/.ros/log/2019-12-16-17-23-38-303988-warner-30644
[INFO] [launch]: Default logging verbosity is set to INFO
test_something (example_launch_test.TestMyNode) ... We do not see this message
ok

Ran 1 test in 0.000s

OK
[INFO] [component_container-1]: process started with pid [30649]
[ERROR] [launch]: Caught exception in launch (see debug for traceback): context.locals does not contain attribute 'launch_ros_node', it contains: [event]
[INFO] [component_container-1]: sending signal 'SIGINT' to process[component_container-1]
[ERROR] [component_container-1]: process has died [pid 30649, exit code -2, cmd '/opt/ros/eloquent/lib/rclcpp_components/component_container --ros-args -r __node:=my_node_container'].


Ran 0 tests in 0.000s

OK

ros2 test
[INFO] [launch]: All log files can be found below /home/jacob/.ros/log/2019-12-16-17-21-29-265673-warner-30543
[INFO] [launch]: Default logging verbosity is set to INFO
test_something (example_launch_test.TestMyNode) ... We do not see this message
ok

Ran 1 test in 0.000s

OK
Task exception was never retrieved
future: <Task finished coro=<LaunchService._process_one_event() done, defined at /opt/ros/eloquent/lib/python3.6/site-packages/launch/launch_service.py:289> exception=RuntimeError('Signal event received before subprocess transport available.',)>
Traceback (most recent call last):
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 "/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/actions/opaque_function.py", line 75, in execute
return self.__function(context, *self.__args, **self.__kwargs)
File "/opt/ros/eloquent/lib/python3.6/site-packages/launch/actions/execute_process.py", line 383, in __on_signal_process_event
raise RuntimeError('Signal event received before subprocess transport available.')
RuntimeError: Signal event received before subprocess transport available.
[INFO] [component_container-1]: process started with pid [30555]
Task exception was never retrieved
future: <Task finished coro=<LaunchService._process_one_event() done, defined at /opt/ros/eloquent/lib/python3.6/site-packages/launch/launch_service.py:289> exception=InvalidHandle('Tried to use a handle that has been destroyed.',)>
Traceback (most recent call last):
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 "/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 167, in execute
self.__target_container.node_name
File "/opt/ros/eloquent/lib/python3.6/site-packages/rclpy/node.py", line 1201, in create_client
with self.handle as node_capsule:
File "/opt/ros/eloquent/lib/python3.6/site-packages/rclpy/handle.py", line 150, in enter
return self._get_capsule()
File "/opt/ros/eloquent/lib/python3.6/site-packages/rclpy/handle.py", line 132, in _get_capsule
raise InvalidHandle('Tried to use a handle that has been destroyed.')
rclpy.handle.InvalidHandle: Tried to use a handle that has been destroyed.
[ERROR] [component_container-1]: process[component_container-1] failed to terminate '5' seconds after receiving 'SIGINT', escalating to 'SIGTERM'
[INFO] [component_container-1]: sending signal 'SIGTERM' to process[component_container-1]
[ERROR] [component_container-1]: process has died [pid 30555, exit code -15, cmd '/opt/ros/eloquent/lib/rclcpp_components/component_container --ros-args -r __node:=my_node_container'].


Ran 0 tests in 0.000s

OK

Additional information

The first error (running with launch_test) is because launch_ros_node is not added to the launch context, which LoadComposableNode action assumes exists:

self.__rclpy_load_node_client = context.locals.launch_ros_node.create_client(
composition_interfaces.srv.LoadNode, '{}/_container/load_node'.format(
self.__final_target_container_name
)
)

This is closely related to #97.

I'm not sure about the second error.

LoadComposableNodes action blocks previous actions

Bug report

In particular, it would be really convenient to be able to start a node container just before some actions to load components into it. Maybe not a bug, but certainly a big usability improvement.

Required Info:

  • Operating System:
    • Ubuntu 18.04
  • Installation type:
    • source
  • Version or commit hash:
  • DDS implementation:
    • Fast-RTPS

Steps to reproduce issue

Launch the following launch file:

from launch import LaunchDescription
from launch_ros.actions import ComposableNodeContainer
from launch_ros.actions import LoadComposableNodes
from launch_ros.descriptions import ComposableNode


def generate_launch_description():
    return LaunchDescription([
        ComposableNodeContainer(
           package='rclcpp_components', node_executable='component_container',
           node_name='my_container', node_namespace=''
        ),  
        LoadComposableNodes(
            composable_node_descriptions=[
                ComposableNode(
                    package='composition',
                    node_plugin='composition::Talker'
                )
            ],  
            target_container='my_container'
        ),  
    ])

Expected behavior

A container node starts and the composition talker component is loaded.

Actual behavior

The container does not start and so the LoadComposableNodes

Additional information

I understand that the LoadComposableNodes action is blocking until the service is available. But my intuition says that since the ComposableNodeContainer action appears first, it should be started before the loading action starts.

After talking with @wjwwood, it sounds like we should update the implementation of LoadComposableNodes so it waits for the service in a separate thread so that it doesn't block the asyncio loop.

Namespace defined on rclcpp::node is not applied

Bug report

Required Info:

  • Operating System:
    • Ubuntu 18.04
  • Installation type:
    • Source
  • Version or commit hash:
  • DDS implementation:
    • Fast-RTPS
  • Client library (if applicable):
    • rclcpp

Steps to reproduce issue

Given the following modified MinimalTimer node from ROS2 example package.

#include <chrono>
#include <memory>

#include "rclcpp/rclcpp.hpp"

using namespace std::chrono_literals;

class MinimalTimer : public rclcpp::Node
{
public:
  MinimalTimer()
  : Node("minimal_timer", "timer_ns")
  {
    RCLCPP_INFO(this->get_logger(), "The namespace is %s", this->get_namespace());

    timer_ = create_wall_timer(
      500ms, std::bind(&MinimalTimer::timer_callback, this));
  }

private:
  void timer_callback()
  {
    RCLCPP_INFO(this->get_logger(), "Hello, world!");
  }
  rclcpp::TimerBase::SharedPtr timer_;
};

int main(int argc, char * argv[])
{
  rclcpp::init(argc, argv);
  rclcpp::spin(std::make_shared<MinimalTimer>());
  rclcpp::shutdown();
  return 0;
}

and the following timer_launch.py

from launch import LaunchDescription
import launch.actions
import launch.substitutions
import launch_ros.actions


def generate_launch_description():
    """Launch a talker and a listener."""
    return LaunchDescription([
        launch_ros.actions.Node(
            package='examples_rclcpp_minimal_timer',
            node_executable='timer_member_function',
            output='screen')
    ])

Expected behavior

If launching using timer_launch.py we expect the node name to be /timer_ns/minimal_timer as a namespace parameter was passed to the node constructor.

Actual behavior

However, it is /minimal_timer.

Additional information

Running the executable does yield the expected node name.

Passing argument to launch file yields wrong RCL warning

Bug report

I am receiving a misleading/wrong warning when trying to pass arguments to the ros2 launch command.

Required Info:

  • Operating System:
    • OSX
  • Installation type:
    • Eloquent source
  • Client library (if applicable):
    • rcl ?

Steps to reproduce issue

Given a launch file with any LaunchArgument

    launch_description = LaunchDescription([
        DeclareLaunchArgument(
            'my_argument',
            default_value = 'some_default',
            description = 'some description'),

Then launching the launch file as follows:

ros2 launch my_launchfile.launch.py my_argument:=some_custom_value

Expected behavior

Launch file started without any complains and launch argument successfully remapped.

Actual behavior

[WARN] [rcl]: Found remap rule 'my_argument:=some_custom_value'. This syntax is deprecated. Use '--ros-args --remap my_argument:=some_custom_value' instead.

Similarly, when using the proposed syntax, the substitution does not take place.

Please feel free to transfer to ticket to a more appropriate repo if applicable.

Node action failing with some special parameters

Bug report

  • Operating System:
    • Ubuntu 18.04
  • Installation type:
    • From source
  • Version or commit hash:
    • launch_ros(#448846d9361f39bdde94d1a41679abac3a1e124a)
  • DDS implementation:
    • fast-rtps
  • Client library (if applicable):
    • rclcpp

Steps to reproduce issue

This is a modified version of launch_ros/examples/pub_sub_launch.py here.

# Copyright 2018 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Launch a talker and a listener."""

import os
import sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))  # noqa
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', 'launch'))  # noqa

from launch import LaunchDescription
from launch import LaunchIntrospector
from launch import LaunchService

from launch_ros import get_default_launch_description
import launch_ros.actions


def main(argv=sys.argv[1:]):
    """Main."""
    ld = LaunchDescription([
        launch_ros.actions.Node(
            package='demo_nodes_cpp', node_executable='talker', output='screen',
            node_name='my_node',
            parameters=[{'a': 1, 'b': 'a', 'c': ['list', 'of', 'stuff']}],
            remappings=[('chatter', 'my_chatter')]),
        launch_ros.actions.Node(
            package='demo_nodes_cpp', node_executable='listener', output='screen',
            remappings=[('chatter', 'my_chatter')]),
    ])

    print('Starting introspection of launch description...')
    print('')

    print(LaunchIntrospector().format_launch_description(ld))

    print('')
    print('Starting launch of launch description...')
    print('')

    # ls = LaunchService(debug=True)
    ls = LaunchService()
    ls.include_launch_description(get_default_launch_description())
    ls.include_launch_description(ld)
    return ls.run()


if __name__ == '__main__':
    main()

I only added:

            node_name='my_node',
            parameters=[{'a': 1, 'b': 'a', 'c': ['list', 'of', 'stuff']}],

Expected behavior

It should work as the original example.

Actual behavior

It fails when loading parameters.

Starting introspection of launch description...

<launch.launch_description.LaunchDescription object at 0x7fe2636a25c0>
├── ExecuteProcess(cmd=[ExecInPkg(pkg='demo_nodes_cpp', exec='talker'), LocalVar('node name'), LocalVar('parameter 1'), LocalVar('remapping 1')], cwd=None, env=None, shell=False)
└── ExecuteProcess(cmd=[ExecInPkg(pkg='demo_nodes_cpp', exec='listener'), LocalVar('remapping 1')], cwd=None, env=None, shell=False)

Starting launch of launch description...

[INFO] [launch]: All log files can be found below /home/ivanpauno/.ros/log/2019-04-11-15-07-37-242126-71c1584df2a2-4887
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [talker-1]: process started with pid [4896]
[INFO] [listener-2]: process started with pid [4897]
[talker-1] terminate called after throwing an instance of 'std::runtime_error'
[talker-1]   what():  Failed to parse parameters from file '/tmp/launch_params_au9d6q_k': Sequence should be of same type. Value type 'bool' do not belong at line_num 8, at /home/ivanpauno/ros2_ws/src/ros2/rcl/rcl_yaml_param_parser/src/parser.c:891
[ERROR] [talker-1]: process has died [pid 4896, exit code -6, cmd '/home/ivanpauno/ros2_ws/install/demo_nodes_cpp/lib/demo_nodes_cpp/talker __node:=my_node __params:=/tmp/launch_params_au9d6q_k chatter:=my_chatter'].

Content of /tmp/launch_params_au9d6q_k

ivanpauno@71c1584df2a2:~/ros2_ws/src/ros2/launch_ros/launch_ros/examples$ cat /tmp/launch_params_au9d6q_k
/:
  my_node:
    ros__parameters:
      a: 1
      b: a
      c: !!python/tuple
      - list
      - of
      - stuff

Additional information

If I change the parameter arg to:

            parameters=[{'a': 1, 'b': 'a', 'c': ['a', 'b', 'c']}],

It works. Generated parameters file:

/:
  my_node:
    ros__parameters:
      a: 1
      b: a
      c: !!python/tuple
      - a
      - b
      - c

Numbers inside the 'c' list also work well, like ['10', '1', '2'].

As far as I've seen, the problem appears when one of the parameters is a list of strings, and one of the list items is more that one character long.

Node constructor annotations are too opaque

Bug report

Required Info:

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

Steps to reproduce issue

import launch_ros
help(launch_ros.actions.LifecycleNode)

Or use an IDE that shows type annotation information and view the annotation info for the LifecycleNode class.

Expected behavior

Help will show useful information about the required arguments to the LifecycleNode constructor (as well as other related constructions like Node, ExecuteProcess, Action)

Actual behavior

Only the information for the node_name argument and an opaque **kwargs argument is given, as well as an unapologetic caveat.

image

class LifecycleNode(launch_ros.actions.node.Node)
 |  Action that executes a ROS lifecycle node.
 |  
 |  Method resolution order:
 |      LifecycleNode
 |      launch_ros.actions.node.Node
 |      launch.actions.execute_process.ExecuteProcess
 |      launch.action.Action
 |      launch.launch_description_entity.LaunchDescriptionEntity
 |      builtins.object
 |  
 |  Methods defined here:
 |  
 |  __init__(self, *, node_name:str, **kwargs) -> None
 |      Construct a LifecycleNode action.
 |      
 |      Almost all of the arguments are passed to :class:`Node` and eventually
 |      to :class:`launch.actions.ExecuteProcess`, so see the documentation of
 |      those classes for additional details.
 |      
 |      This action additionally emits some event(s) in certain circumstances:
 |      
 |      - :class:`launch.events.lifecycle.StateTransition`:
 |      
 |          - this event is emitted when a message is published to the
 |            "/<node_name>/transition_event" topic, indicating the lifecycle
 |            node represented by this action changed state
 |      
 |      This action also handles some events related to lifecycle:
 |      
 |      - :class:`launch.events.lifecycle.ChangeState`
 |      
 |        - this event can be targeted to a single lifecycle node, or more than
 |          one, or even all lifecycle nodes, and it requests the targeted nodes
 |          to change state, see its documentation for more details.
 |  

Additional information

This could be fixed with the either use of the merge_args library or the metaprogramming techniques described by its author here: https://chriswarrick.com/blog/2018/09/20/python-hackery-merging-signatures-of-two-python-functions/

[ros2launch] Making `launch-prefix` easily accessible

Feature request

Feature description

The launch-prefix option comes handy when debugging/profiling, however it is not 'easily' accessible as of now, I am referring to this example. This scheme offers a fine granularity as which node should benefit what prefix, however sometimes one may simply want to launch an entire launch file under a given prefix.
Given that the run verb provides a --prefix option, the launch verb could similarly provide a --launch-prefix option.

Implementation considerations

One possible implementation boils down to including the desired launch file in a LaunchDescription which sets the launch configuration appropriately, something similar to this script.

Cannot launch example

I am trying to write launch file for python package, and for some reason I am not able to build the package correctly to use with the launch file. So I tried the tutorial, and I am seeing the same issue. I don't know if I am missing something, or just doing it incorrectly.
This might be related to build, and maybe i should open a ticket there?

Bug report

Required Info:

  • Operating System:
    • Ubuntu 18.04
  • Installation type:
    • source
  • DDS implementation:
    • Fast-RTPS

Steps to reproduce issue

  • Download launch_ros and build, then source
  • In terminal:
    ros2 launch ros2launch ros2launch example.launch.py
    OR
    ros2 launch launch_ros pub_sub_launch.py

Expected behavior

Launches example

Actual behavior

file 'example.launch.py' was not found in the share directory of package 'ros2launch' which is at '/home/yathartha/Desktop/test/install/ros2launch/share/ros2launch'

And similarly:

file 'pub_sub_launch.py' was not found in the share directory of package 'launch_ros' which is at '/home/yathartha/Desktop/test/install/launch_ros/share/launch_ros'

[launch_ros] node_name overrides for a multi-node rclpy process

Feature description

A means of setting node_name overrides for a multi-node rclpy process such as that given in ros2/launch#204.

Implementation considerations

This also brings into question the naming of the class launch_ros.actions.Node since it currently can launch a multi-node process. Perhaps that should fail on trying to launch a multi-node process and for that, use a launch_ros.actions.MultiNode action.

Note: This is a different problem to the composable node launch. Here the nodes are brought into the same process via ... the process, not the launcher. I suspect the same situation would arise linking two c++ classes with nodes and instantiating them in the same application.

Command substitution: special characters inside XML comments causes launch to fail

Bug report

Required Info:

  • Operating System:
    • Ubuntu 18.04
  • Installation type:
    • from source
  • Version or commit hash:
    • 4333910ba41977f3ab9867082c86a8698ada3a16

Specifically, I've noticed that colons (:) and tab characters are not working.

Steps to reproduce issue

I ran into this issue trying to pass a URDF from xacro to robot_state_publisher, like the example here. For some reason, if the URDF/xacro file contains a colon (:) or a tab character inside of an XML comment, then launch fails.

Here's my example URDF file foo.urdf:

<?xml version="1.0" ?>
<robot>
  <!--: -->
</robot>

And my launch file:

<launch>
  <node pkg="demo_nodes_cpp" exec="talker" output="screen">
    <param name="foo" value="$(command 'cat foo.urdf')" />
  </node>
</launch>

Expected behavior

The launch file succeeds and we see the talker node chatting.

Actual behavior

Error:

[ERROR] [launch]: Caught exception in launch (see debug for traceback): mapping values are not allowed here
  in "<unicode string>", line 3, column 7:
      <!--: -->
          ^

Additional information

The error seems to specifically occur if there is a colon followed by a space. E.g. making the following change works fine:

-      <!--: -->
+      <!--:-->

Replacing the colcon with a tab character also triggers the same error:

[ERROR] [launch]: Caught exception in launch (see debug for traceback): while scanning for the next token
found character '\t' that cannot start any token
  in "<unicode string>", line 3, column 7:
      <!--	-->
          ^

yaml file passed to launch file doesn't take effect

Required Info:

  • Operating System:
    • Ubuntu18.04
  • Installation type:
    • source
  • Version or commit hash:
  • DDS implementation:
    • fast-rtps
  • Client library (if applicable):
    • rclcpp

Steps to reproduce issue

Pass the yaml file to launch.py, but it doesn't take effect.

Expected behavior

Actual behavior

Additional information

  • launch file
import os
import launch
from launch_ros.actions import ComposableNodeContainer
from launch_ros.descriptions import ComposableNode

def generate_launch_description():
    param_file_path = /my/file/path
    container = ComposableNodeContainer(
            node_name='my_container',
            node_namespace='',
            package='rclcpp_components',
            node_executable='component_container',
            composable_node_descriptions=[
                ComposableNode(
                    package='my_package',
                    node_plugin='namespace::Class',
                    node_name='my_node',
                    parameters=[param_file_path],),
            ],
            output='screen',
    )

    return launch.LaunchDescription([container])
  • yaml file:
my_node:
  ros__parameters:
    enabled_param1: true
    enabled_param2: true

ros2 launch crashes on list-valued parameter when used with Composable Nodes

In trying to use launch_ros with composable nodes, I got a hard crash trying to process a parameter file. The syntax that it choked on is not even used by my composable node, but it looks like to_parameters_list crashed the entire launch file nonetheless.

Debug output of ros2 launch with crash trace:

[DEBUG] [launch.launch_context]: emitting event synchronously: 'launch.events.process.ProcessStderr'
[DEBUG] [launch]: processing event: '<launch.events.process.process_started.ProcessStarted object at 0x7f391403b668>'
[DEBUG] [launch]: processing event: '<launch.events.process.process_started.ProcessStarted object at 0x7f391403b668>' ✓ '<launch.event_handlers.on_process_start.OnProcessStart object at 0x7f391410a748>'
/opt/ros/master/install/lib/python3.6/site-packages/launch_ros/utilities/to_parameters_list.py:49: YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details.
  context, normalize_parameter_dict(yaml.load(f))
Executing <Handle <TaskWakeupMethWrapper object at 0x7f39140b23a8>(<Future finis...events.py:295>) created at /usr/lib/python3.6/asyncio/queues.py:74> took 1.263 seconds
[DEBUG] [launch.launch_context]: emitting event synchronously: 'launch.events.process.ProcessStdout'
[DEBUG] [launch.launch_context]: emitting event synchronously: 'launch.events.process.ProcessStderr'
[DEBUG] [launch.launch_context]: emitting event synchronously: 'launch.events.process.ProcessStdout'
[DEBUG] [launch]: Traceback (most recent call last):
  File "/opt/ros/master/install/lib/python3.6/site-packages/launch/launch_service.py", line 350, in run
    self.__loop_from_run_thread.run_until_complete(run_loop_task)
  File "/usr/lib/python3.6/asyncio/base_events.py", line 484, in run_until_complete
    return future.result()
  File "/opt/ros/master/install/lib/python3.6/site-packages/launch/launch_service.py", line 240, in __run_loop
    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/master/install/lib/python3.6/site-packages/launch/launch_service.py", line 177, 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/master/install/lib/python3.6/site-packages/launch/launch_service.py", line 197, in __process_event
    visit_all_entities_and_collect_futures(entity, self.__context))
  File "/opt/ros/master/install/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/master/install/lib/python3.6/site-packages/launch/action.py", line 60, in visit
    return cast(Optional[List[LaunchDescriptionEntity]], self.execute(context))
  File "/opt/ros/master/install/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/master/install/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/master/install/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/master/install/lib/python3.6/site-packages/launch_ros/utilities/to_parameters_list.py", line 60, in to_parameters_list
    raise RuntimeError('invalid parameter value {}'.format(repr(value)))
RuntimeError: invalid parameter value (-7, -34, -47)

Relevant part of parameter file hardware.yaml:

bno055_driver:
  ros__parameters:
    port: /dev/imu
    frame_id: imu_link
    frequency: 30.0
    self_manage: true
    use_magnetometer: false

    angular_velocity_stdev: 0.01
    linear_acceleration_stdev: 0.0015
    magnetic_field_stdev: 0.0000005
    orientation_stdev: 0.000001
    # these calibration values need to be determined on a per-device basis.
    calibration/accelerometer_offset: [-7, -34, -47]
    calibration/magnetometer_offset: [275, -193, -104]
    calibration/gyroscope_offset: [-3, -3, -1]
    calibration/accelerometer_radius: 1000
    calibration/magnetometer_radius: 842

Relevant part of launch file hardware.launch.py:

from pathlib import Path

from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch_ros.actions import Node, ComposableNodeContainer
from launch_ros.descriptions import ComposableNode

def generate_launch_description():
    hardware_config = Path(get_package_share_directory('openrover_demo'), 'config', 'hardware.yaml')
    assert hardware_config.is_file()

    return LaunchDescription([
        ComposableNodeContainer(
            node_name='container',
            node_namespace='openrover',
            package='rclcpp_components',
            node_executable='component_container',
            composable_node_descriptions=[
                ComposableNode(package='openrover_core', node_plugin="openrover::Rover",
                               node_namespace='/openrover',
                               node_name='driver', parameters=[hardware_config]),
                ComposableNode(package='openrover_core', node_plugin="openrover::RoverSerial",
                               node_namespace='/openrover',
                               node_name='serial', parameters=[hardware_config]),
            ]),
        Node(
            package='bno055_driver',
            node_executable='bno055_driver',
            output='screen',
            parameters=[hardware_config]
        )
    ])

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.