Skip to content

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

Open

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

  1. changed the title [-][Proposal] Enhanced CLI Arg System: Support for Node-Specific Overrides and Tyro Integration[/-] [+][Proposal] Enhanced CLI Arg System: tyro Integration and Explicit Node Parameter Overrides[/+] on Dec 19, 2025
  2. ndahn commented on Dec 25, 2025

    @ndahn
    Collaborator

    Hey, thank you so much for the nice feedback and suggestions!

    I can definitely see a use case for passing node parameters directly. I like the smart approach using dot notation and can have a go at it sometime in the future unless you want to provide a PR :)

    On the other hand, I feel very reluctant to change the argument parsing framework. From a cursory glance tyro seems like a nice alternative, but I already know that click works and supports all the features I want, including layered auto completion for various shells. Getting the CLI part to the current state and reliability was a non-trivial task. I am still open for discussion, but unless there are some very good reasons I think I will stick with click for the time being.

  3. TomCC7 commented on Dec 25, 2025

    @TomCC7
    Author

    Thanks for the feedback! I'll see if I can provide a PR on passing node parameter if I get a chance 😄

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