First off, I want to say that better_launch is a fantastic improvement over the standard ROS 2 launch system. The synchronous execution model and Pythonic API make it infinitely more usable and readable. I'm really enjoying the direction this project is taking!
I have some ideas to further improve the CLI argument system, though they are a bit opinionated, so I wanted to open a discussion before attempting a PR.
The Proposal
I would like to improve the CLI argument parsing in two main directions:
1. Support for Node-Specific Parameter Overrides
I want to enable overwriting parameters for specific nodes directly from the command line without needing to manually expose every single one as a top-level function argument.
I see two ways to handle this syntax and would like your opinion on which fits the better_launch philosophy better:
- The Explicit Approach: A dedicated flag similar to standard ROS 2 patterns, e.g.,
--node_parameter <node_name> <param_name> <value>. This is verbose but very clear and avoids namespace collisions with top-level arguments.
- The "Tyro/Pythonic" Approach: Using dot-notation to access nested namespaces directly, e.g.,
--node_name.ns1.param value. This is cleaner to type but requires the argument parser to be "smart" about node structures.
2. Migrate to tyro for CLI Construction
I suggest moving from the current click-based approach to tyro.
- Why?
tyro is designed to generate CLIs from type-annotated Python objects (functions, dataclasses). It naturally supports the nested structures mentioned above.
- Benefit: It avoids the "simplistic" feel of standard
click interfaces when dealing with complex configs and provides robust static analysis and autocompletion out of the box.
Example Usage with Tyro
If we went with tyro, we could structure launch configurations using dataclasses, which tyro would automatically unroll into CLI args:
from dataclasses import dataclass
import tyro
@dataclass
class SimConfig:
enabled: bool = True
rate: float = 100.0
@launch_this
def main(
sim: SimConfig,
# ... other args
):
# ... usage
This effectively gives us the "dot notation" (e.g., --sim.enabled) for free for top-level args. The discussion is then whether we extend this automatically to node parameters or keep node overrides behind an explicit flag.
Discussion Points
- Explicit vs. Implicit: Do you prefer the safety of an explicit
--node_parameter flag, or the brevity of automatic node.param resolution?
- Dependency: Is introducing
tyro (a lightweight but new dependency) acceptable for this feature set?
I'd love to hear your thoughts on this! If this sounds like a good direction, I'd be happy to take a crack at drafting an implementation.
First off, I want to say that
better_launchis a fantastic improvement over the standard ROS 2 launch system. The synchronous execution model and Pythonic API make it infinitely more usable and readable. I'm really enjoying the direction this project is taking!I have some ideas to further improve the CLI argument system, though they are a bit opinionated, so I wanted to open a discussion before attempting a PR.
The Proposal
I would like to improve the CLI argument parsing in two main directions:
1. Support for Node-Specific Parameter Overrides
I want to enable overwriting parameters for specific nodes directly from the command line without needing to manually expose every single one as a top-level function argument.
I see two ways to handle this syntax and would like your opinion on which fits the
better_launchphilosophy better:--node_parameter <node_name> <param_name> <value>. This is verbose but very clear and avoids namespace collisions with top-level arguments.--node_name.ns1.param value. This is cleaner to type but requires the argument parser to be "smart" about node structures.2. Migrate to
tyrofor CLI ConstructionI suggest moving from the current
click-based approach to tyro.tyrois designed to generate CLIs from type-annotated Python objects (functions, dataclasses). It naturally supports the nested structures mentioned above.clickinterfaces when dealing with complex configs and provides robust static analysis and autocompletion out of the box.Example Usage with Tyro
If we went with
tyro, we could structure launch configurations using dataclasses, whichtyrowould automatically unroll into CLI args:This effectively gives us the "dot notation" (e.g.,
--sim.enabled) for free for top-level args. The discussion is then whether we extend this automatically to node parameters or keep node overrides behind an explicit flag.Discussion Points
--node_parameterflag, or the brevity of automaticnode.paramresolution?tyro(a lightweight but new dependency) acceptable for this feature set?I'd love to hear your thoughts on this! If this sounds like a good direction, I'd be happy to take a crack at drafting an implementation.