-
Notifications
You must be signed in to change notification settings - Fork 139
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add ability to define and pass launch arguments to launch files (#123)
* add self descriptions for substitutions * add tracebacks back to the output by default * add new actions for declaring launch arguments * new method on LaunchDescription which gets all declared arguments within * add ability to pass arguments when including a launch description * add description for local variables used in Node action * fix bug in Node action * cleanup error reporting in Node action * use launch arguments in examples * add ability to show and pass launch arguments on the command line * fix python 3.5 support * add accessor for the Condition of an Action Signed-off-by: William Woodall <william@osrfoundation.org> * do not automatically push/pop configs when including Signed-off-by: William Woodall <william@osrfoundation.org> * small refactor to get the launch file location Signed-off-by: William Woodall <william@osrfoundation.org> * improve ability to detect declared arguments across launch file includes Signed-off-by: William Woodall <william@osrfoundation.org> * add tests for the new DeclareLaunchArgument action Signed-off-by: William Woodall <william@osrfoundation.org> * test new features of IncludeLaunchDescription Signed-off-by: William Woodall <william@osrfoundation.org> * test new features of LaunchDescription class Signed-off-by: William Woodall <william@osrfoundation.org> * remove unused imports Signed-off-by: William Woodall <william@osrfoundation.org> * improve output when showing arguments of a launch file Signed-off-by: William Woodall <william@osrfoundation.org> * fix the return type of LaunchService.run() Signed-off-by: William Woodall <william@osrfoundation.org> * fix the checking for the asyncio event loop for the case where it is not set Signed-off-by: William Woodall <william@osrfoundation.org> * typo Signed-off-by: William Woodall <william@osrfoundation.org> * restart event loop to allow proper shutdown when there's an unhandled exception Signed-off-by: William Woodall <william@osrfoundation.org> * ExecuteProcess: unregister event handlers if rest of setup fails The event handlers need to be setup before the other lines, but are invalid if setup does not complete successfully. * only put traceback in debug logging
- Loading branch information
Showing
29 changed files
with
729 additions
and
93 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
# 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. | ||
|
||
"""Module for the DeclareLaunchArgument action.""" | ||
|
||
import logging | ||
from typing import List | ||
from typing import Optional | ||
from typing import Text | ||
|
||
from ..action import Action | ||
from ..launch_context import LaunchContext | ||
from ..some_substitutions_type import SomeSubstitutionsType | ||
from ..substitution import Substitution | ||
from ..utilities import normalize_to_list_of_substitutions | ||
from ..utilities import perform_substitutions | ||
|
||
_logger = logging.getLogger('launch.actions.DeclareLaunchArgument') | ||
|
||
|
||
class DeclareLaunchArgument(Action): | ||
""" | ||
Action that declares a new launch argument. | ||
A launch arguments are stored in a "launch configuration" of the same name. | ||
See :py:class:`launch.actions.SetLaunchConfiguration` and | ||
:py:class:`launch.substitutions.LaunchConfiguration`. | ||
Any launch arguments declared within a :py:class:`launch.LaunchDescription` | ||
will be exposed as arguments when that launch description is included, e.g. | ||
as additional parameters in the | ||
:py:class:`launch.actions.IncludeLaunchDescription` action or as | ||
command-line arguments when launched with ``ros2 launch ...``. | ||
In addition to the name, which is also where the argument result is stored, | ||
launch arguments may have a default value and a description. | ||
If a default value is given, then the argument becomes optional and the | ||
default value is placed in the launch configuration instead. | ||
If no default value is given and no value is given when including the | ||
launch description, then an error occurs. | ||
The default value may use Substitutions, but the name and description can | ||
only be Text, since they need a meaningful value before launching, e.g. | ||
when listing the command-line arguments. | ||
Note that declaring a launch argument needs to be in a part of the launch | ||
description that is describable without launching. | ||
For example, if you declare a launch argument with this action from within | ||
a condition group or as a callback to an event handler, then it may not be | ||
possible for a tool like ``ros2 launch`` to know about the argument before | ||
launching the launch description. | ||
In such cases, the argument will not be visible on the command line but | ||
may raise an exception if that argument is not satisfied once visited (and | ||
has no default value). | ||
Put another way, the post-condition of this action being visited is either | ||
that a launch configuration of the same name is set with a value or an | ||
exception is raised because none is set and there is no default value. | ||
However, the pre-condition does not guarantee that the argument was visible | ||
if behind condition or situational inclusions. | ||
""" | ||
|
||
def __init__( | ||
self, | ||
name: Text, | ||
*, | ||
default_value: Optional[SomeSubstitutionsType] = None, | ||
description: Text = 'no description given', | ||
**kwargs | ||
) -> None: | ||
"""Constructor.""" | ||
super().__init__(**kwargs) | ||
self.__name = name | ||
if default_value is None: | ||
self.__default_value = default_value | ||
else: | ||
self.__default_value = normalize_to_list_of_substitutions(default_value) | ||
self.__description = description | ||
|
||
# This is used later to determine if this launch argument will be | ||
# conditionally visited. | ||
# Its value will be read and set at different times and so the value | ||
# may change depending at different times based on the context. | ||
self._conditionally_included = False | ||
|
||
@property | ||
def name(self) -> Text: | ||
"""Getter for self.__name.""" | ||
return self.__name | ||
|
||
@property | ||
def default_value(self) -> Optional[List[Substitution]]: | ||
"""Getter for self.__default_value.""" | ||
return self.__default_value | ||
|
||
@property | ||
def description(self) -> Text: | ||
"""Getter for self.__description.""" | ||
return self.__description | ||
|
||
def execute(self, context: LaunchContext): | ||
"""Execute the action.""" | ||
if self.name not in context.launch_configurations: | ||
if self.default_value is None: | ||
# Argument not already set and no default value given, error. | ||
_logger.error( | ||
"Required launch argument '{}' (description: '{}') was not provided" | ||
.format(self.name, self.description) | ||
) | ||
raise RuntimeError( | ||
"Required launch argument '{}' was not provided.".format(self.name)) | ||
context.launch_configurations[self.name] = \ | ||
perform_substitutions(context, self.default_value) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.