ros2 / launch

Tools for launching multiple processes and for writing tests involving multiple processes.
Apache License 2.0
124 stars 139 forks source link

Allow conditional substitutions #290

Open ryanewel opened 5 years ago

ryanewel commented 5 years ago

Feature request

Feature description

Add a conditional to a substitution so that a substitution only takes place if a value was provided. See https://answers.ros.org/question/314903/ros2-optionally-launch-node-with-no-arguments/ for some discussion.

chapulina commented 5 years ago

We'd also like this for gazebo_ros_pkgs. We currently have a hacky workaround on this PR using PythonExpression.

ivanpauno commented 5 years ago

I don't like the idea of a conditional substitution returning None when the condition is False, as described in https://answers.ros.org/question/314903/ros2-optionally-launch-node-with-no-arguments/. IMO, it adds complexity, and that's not the source of the problem.


https://answers.ros.org/question/314903/ros2-optionally-launch-node-with-no-arguments/

Something similar as described in https://github.com/ros2/launch/issues/263 will solve the issue. Here the problem is not the need of conditional substitutions, but that the representation chosen for arguments is not good enough.


We'd also like this for gazebo_ros_pkgs. We currently have a hacky workaround on this PR using PythonExpression.

This can be solved by using SetLaunchConfiguration. e.g. this could be replaced with:

SetLaunchConfiguration('version-arg', '--version', if=LaunchConfiguration('version'))

and then instead of _command('version'), do:

LaunchConfiguration('version-arg', default=''),

We could have a "ternary-if" substitution too, like:

class ConditionalSubstitution(Substitution):
    def __init__(self, condition, true_value, else_value):
        ...

Which I agree, it would be nice to have it.


There are other cases where it's difficult to conditionally add an extra "entity". e.g.: parameters and environment variables.

IMO, the problem here is again the representation chosen for them: https://github.com/ros2/launch/blob/0007307e4f5ad26b0531ca7265965d09482c5d68/launch/launch/actions/execute_process.py#L92

If we would have a class for representing an environment variable:

class EnvironmentVariable: # Nothing to do with launch.substitutions.EnvironmentVariable
    def __init__(self, name, value, *, condition):
        ...

ExecuteProcess could take an Iterable[Union[EnvironmentVariable, THE_DICT_ABOVE]] instead of just a dict.

A similar solution is possible for parameters.

AlexKaravaev commented 2 years ago

Is there any update on this? Would find this pretty useful too.

asasine commented 2 years ago

Another similar idea I've had is to conditionally include substitutions in the parameters kwarg for a launch_ros.actions.Node. This will allow us to include YAML config files as parameters if they exist, otherwise skip them.

Our current solution employs a custom substitution to write empty YAML files to the temp directory. It would be excellent if we could provide a simple condition to a path such that the path is skipped when the node/process is later executed.

nachovizzo commented 1 year ago

Any update on this? Anyone who managed to setup an "optional" argument in ROS2?

russkel commented 1 year ago

Another similar idea I've had is to conditionally include substitutions in the parameters kwarg for a launch_ros.actions.Node. This will allow us to include YAML config files as parameters if they exist, otherwise skip them.

Our current solution employs a custom substitution to write empty YAML files to the temp directory. It would be excellent if we could provide a simple condition to a path such that the path is skipped when the node/process is later executed.

Have a look at SetParametersFromFile.

slim71 commented 1 year ago

What about being able to call a launch file with no arguments from CLI? This is what I've thought of for now

spawn_x = LaunchConfiguration("spawn_x", default='0.0')
spawn_x_argument = DeclareLaunchArgument(
        name="spawn_x",
        default_value="0.0",
        description="Position along x-axis",
    )

but a conditional way to add an argument would be great. What I'm doing seems a bit redundant, since I have to specify a default in both the LaunchConfiguration and in the DeclareLaunchArgument...