Skip to content

[Proposal] Enhanced CLI Arg System: tyro Integration and Explicit Node Parameter Overrides #44

Description

@TomCC7

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions