Runtime configuration for Basis units and launch files: unit arguments, command-line parsing, topic templating, and launch contexts.
Basis provides a structured argument system for configuring units and launch files at runtime. Arguments are declared in YAML, parsed from the command line or launch file, and made available to the unit at construction time.
Arguments for a unit are declared in its .unit.yaml file under the args key. Each argument has a type, an optional help string, and either a default value or an optional flag.
args: string_arg: type: string help: a string argument int_arg: type: int optional_string_arg: type: string default: foobar
These correspond directly to C++ types. The type system is defined via the X_ALLOWED_ARGUMENT_TYPES macro in cpp/arguments/include/basis/arguments/argument_types.h.
CommandLineTypes is a std::variant that abstracts over three ways to supply arguments to a unit or launch file:
using CommandLineTypes = std::variant< std::vector<std::pair<std::string, std::string>>, // key-value pairs std::vector<std::string>, // argv-style strings std::pair<int, char const* const*> // raw argc + argv from main()>;
All three forms are ultimately converted to an argparse-compatible std::vector<std::string> before parsing. This lets the same argument declaration work whether arguments come from a launch file, a direct process invocation, or a test harness.
Code-generated unit classes use UnitArguments<T>::ParseArgumentsVariant() to parse a CommandLineTypes into a typed struct:
auto result = MyUnitArgs::ParseArgumentsVariant(command_line);if (!result) { // result.error() contains the parse error message}auto args = *result; // typed struct with fields per declared arg
The CreateArgumentParser() static method produces an argparse::ArgumentParser pre-populated with all declared arguments, which can be used for generating --help output.
Launch files support a Jinja2-style templating system (via the inja library). Arguments are declared in a separate YAML document at the top of the launch file, separated from the content by ---.
The first document (before ---) declares the argument schema. The second document is the launch content and may use {{ args.name }} expressions anywhere in the YAML text.
The args key must appear only in the first document. If args is detected in the content document, the launch parser will report a fatal error.
When basis launch runs, it populates a LaunchContext struct that governs process execution:
struct LaunchContext { bool sim = false; // wait for simulated time on /time topic before starting std::string process_filter; // run only this named process (used in forked child launchers) std::vector<std::string> all_args; // full original argv std::vector<std::string> launch_args; // arguments after the launch yaml path};
Unit arguments are specified under args in the process definition:
processes: navigation: units: pathfinder: {} alt_pathfinder: unit: pathfinder # reuse the same unit type with a different name args: use_experimental_algo: "1"
Each args entry is a key-value map of strings. The values are parsed according to the types declared in the unit’s .unit.yaml. If a required argument is missing or a value fails to parse, the launch will log a fatal error and stop.