launch icon indicating copy to clipboard operation
launch copied to clipboard

Allow optional scoping for including a launchfile

Open SuperJappie08 opened this issue 1 year ago • 15 comments

Feature request

IncludeLaunchDescription is not scoped if I understand correctly. (Based on #313 #689 and the design docs)

Feature description

An extra argument for IncludeLaunchDescription action, which could enable scoping. This would prevent the leakage of arguments.

Implementation considerations

This is already possible by including into a group with forwarding set to false. Default could be false to not break the current behavior.

EDIT: I made a proof of concept package https://github.com/SuperJappie08/launch_scoped_include/, which implements this on a new action called IncludeScopedLaunchDescription

EDIT2: I can make a pull request for this if the feature is desired

SuperJappie08 avatar Oct 09 '24 14:10 SuperJappie08

@SuperJappie08 thanks for the contribution, it's definitely something that others have run into and found surprising.

I really like the idea of a new Action, like ScopedIncludeLaunchDescription or similar, and I would be in favor of including it in this repository if you want.

Also, I really appreciate you making it into a stand-alone package as a first step. It definitely helps demonstrate the idea and value, and it makes it easier for folks to try it or use it, even in older releases of ROS 2.

wjwwood avatar Feb 28 '25 21:02 wjwwood

Hi @SuperJappie08 any update on this?

alsora avatar Mar 13 '25 17:03 alsora

Hi @SuperJappie08 any update on this?

Hi,

I was initially waiting on a response from a maintainer before spending a lot of time on this because I have a tendency to spend a lot of time on the wrong things. However, some family stuff has come up recently, which required a shuffle in my priorities, so I have not had the time (yet) to start this.

I think I would be able to start this week.

SuperJappie08 avatar Mar 17 '25 09:03 SuperJappie08

it's definitely something that others have run into and found surprising.

Certainly!

So why not make this the default? Breaking changes are allowed between ROS releases.

I know breaking backward compatibility should not be considered lightly. But it's a trade-off between:

  • new developers running into this surprising feature
  • existing developers actually using this feature

The first group might actually be larger than the second.

Timple avatar Mar 17 '25 11:03 Timple

it's definitely something that others have run into and found surprising.

Certainly!

So why not make this the default? Breaking changes are allowed between ROS releases.

I know breaking backward compatibility should not be considered lightly. But it's a trade-off between:

* new developers running into this surprising feature

* existing developers actually using this feature

The first group might actually be larger than the second.

Having it as a separate action, could mean the default include action could change. But I think your point is valid, and it possibly could make sense to rename the old IncludeLaunchDescription to IncludeUnscopedLaunchDescription so the new scoped version could be the easier/shorted(/ more likely to be adopted as the default) name (IncludeLaunchDescription).

Normally, I would also cheer for backwards compatibility, but since the unscoped version feels counterintuitive to many people, it might make sense to fix it.

EDIT: Clarification

SuperJappie08 avatar Mar 17 '25 14:03 SuperJappie08

I found a fatal flaw after doing more testing on this feature with an implementation similar to my initial attempt in the package.

Currently, the 'scoped' is essentially a normal include wrapped in a scoped non-forwarding group, which only keeps the provided launch arguments. This gives essentially the expected behavior from this feature, however, since only the launch argument to the nested files are kept in systems depending on non-user set launch configurations, such as the PushRosNameSpace and SetRemap actions from launch_ros.

My initial reaction was to attempt to include launch configurations which were not defined explicitly by the child file. However, this requires a lot of rework to support multi-nesting situations.

Since not being able to do things, like name spacing a launch file, would not resolve the current non-scoping confusion behavior, I am unsure on how to continue (for now).

Does anyone have suggestions for a direction to move forward? (I will try to think of reasonable solutions as well)

EDIT: My current suggestion would be to pass all launch configurations except those explicitly defined in (recursively) included files. However, this does not seem a clear and understandable solution to users of the scoped include action

SuperJappie08 avatar Mar 18 '25 15:03 SuperJappie08

Another option could be to register overscoping launch configurations in the context, which will always be included. This could be implemented as a launch configuration, which contains the keys of the unscopable launch configurations.

SuperJappie08 avatar Mar 18 '25 16:03 SuperJappie08

I'd love to have something like this in the package (and by default!) :-)

SteveMacenski avatar Apr 29 '25 23:04 SteveMacenski

@alsora, an initial working implementation is complete (#841).

SuperJappie08 avatar May 01 '25 19:05 SuperJappie08

This gives essentially the expected behavior from this feature, however, since only the launch argument to the nested files are kept in systems depending on non-user set launch configurations, such as the PushRosNameSpace and SetRemap actions from launch_ros.

So, I think the concerns are these launch configurations:

  • ros_remaps
  • ros_namespace
  • global_params

I think a nice solution would be to have no launch configurations forwarded as done in this PR, and have a IncludeLaunchDescription (or something named a bit different to avoid confusion - like RosIncludeLaunchDescription), that inherits the ScopedIncludeLaunchDescription here, but auto-forwards the launch configurations listed above.

This can be thought of a similar concept to the launch_ros' Node class extending launch's ExecuteProcess.

ijnek avatar Jun 15 '25 23:06 ijnek

@ijnek Thank you for the input. That is an option I hadn't considered yet.

However, my concern is that a ROS specific RosIncludeLaunchDescription is less flexible, since in the current attempted implementation, other launch extensions (think a launch_system_nodes or something like a (non-existing) launch_gz) could just hook/register their own exclusions. This would make combing extensions trivial, whereas with the alternative, this would get more complex.

However, it is a balancing act, since these exclusions should not be overused and are only practical/make sense in specific situations.

I'm unsure what the best way forward would be in this case, where it's a choice between flexibility vs. simplicity.

SuperJappie08 avatar Jun 16 '25 08:06 SuperJappie08

Sorry — I completely missed your comment (https://github.com/ros2/launch/pull/841#issuecomment-2845561097) mentioning that you had already worked around this issue using global launch configurations.

Personally, I find it odd that we use launch configurations to pass ros_remaps, ros_namespace, and global_params to included launch files. While looking into launch, it seems we could instead store remapping and namespacing info in the local stack rather than using launch configurations.

https://github.com/ros2/launch/blob/820e5a2c57dafd807ea4cdf33952e87c78929ce5/launch/launch/launch_context.py#L63-L64

I’ve drafted a PR to explore this idea: https://github.com/ros2/launch_ros/pull/470.

This approach would avoid the need to track a global list of which launch configurations are meant to propagate. Let me know what you think.

ijnek avatar Jun 17 '25 02:06 ijnek

That would indeed also resolve those weird behaviors.

Personally, I'm not set to on the global exclusion list, since it is unclear in the internal API, since there are also global variables in the launch context. So naming and behavior of the global list is not very transparent in my opinion.

Currently, I'm mostly curious, why these launch_ros features use the launch configurations instead of launch context locals and why that decision was made in the first place. Because if it was a conscious decision to do it like this, there might be a valid reason we are currently missing.

EDIT: After some more looking into the launch internals, scoping local variables is rarely used, currently it is only used in the ForEach action (also tests and event internals). However, this would be easy to integrate with the scoped include. However, that would mean that ros2/launch_ros#470 does not work with the normal group action anymore.

SuperJappie08 avatar Jun 17 '25 08:06 SuperJappie08

Discussed this in ROSGraph WG today, we think this issue is important and covers a lot of confusing behavior in launch, but needs a design doc / summary pass before diving back into implementations, so that we can discuss at that level

emersonknapp avatar Nov 25 '25 18:11 emersonknapp

Discussed this in ROSGraph WG today, we think this issue is important and covers a lot of confusing behavior in launch, but needs a design doc / summary pass before diving back into implementations, so that we can discuss at that level

I will do this somewhere in the coming weeks.

SuperJappie08 avatar Nov 25 '25 18:11 SuperJappie08