ros2cli

repository·rolling·Indexed 42 days ago

https://github.com/ros2/ros2cli

Standard command-line interface tools for ROS 2, providing the 'ros2' command to interact with nodes, topics, and services. Includes tools like 'ros2 doctor' (aliased as 'ros2 wtf') for system diagnosis and 'ros2 daemon' for background process management. The CLI is extensible via Python entry points using the CommandExtension class and the 'ros2cli.command' group.

Tokens
5.4K
Snippets
29
Records
35
Agent score
54%

What's inside ros2cli

  1. Extend ros2cli with new verbs

    rolling
    You can extend the ros2 CLI by adding new commands and verbs using Python entry points. This allows third-party packages to register their own functionality directly into the ros2 command hierarchy.
  2. Test multicast UDP connectivity with ros2 multicast

    rolling

    The ros2 multicast command is used to verify if multicast UDP packets can be successfully passed between two endpoints on a network. This is useful for troubleshooting network configurations that might be blocking multicast traffic.

    To perform a test:

    1. On the first machine, start a listener to wait for incoming packets: ros2 multicast receive
    2. On a second machine, send a multicast packet: ros2 multicast send

    If the network allows multicast, the first machine will output Hello World!.

    # Machine 1: Start receiving
    $ ros2 multicast receive
    
    # Machine 2: Send packet
    $ ros2 multicast send
  3. Use ros2doctor to diagnose your ROS 2 setup

    rolling

    The ros2doctor tool (also accessible via the alias ros2 wtf) examines your ROS 2 environment—including distribution, platform, and network interfaces—to identify potential issues in your system. Use it to verify that your installation and running system are configured correctly.

    ros2 doctor
    # or
    ros2 wtf
  4. Explore ros2cli commands and help

    rolling

    The ros2 command-line interface uses a hierarchical help system. You can discover available commands and detailed usage information by following these patterns:

    1. List all available commands: Use ros2 --help.
    2. Get information on a specific command: Use ros2 <command> --help.
    3. Get information on a specific verb within a command: Use ros2 <command> <verb> --help.
    # See all available commands
    ros2 --help
    
    # See usage for a specific command (e.g., topic)
    ros2 topic --help
    
    # See usage for a specific verb (e.g., topic echo)
    ros2 topic echo --help
  5. Understand how ros2cli command extensions work

    rolling

    The ros2 command is an extensible tool. It uses entry points (specifically under the ros2cli.command group) to discover and load subcommands (verbs) on demand. When you run ros2 <command>, the CLI identifies the extension associated with that command and executes its main method.

    If you are developing a new command for ros2cli, your extension must implement a main(parser, args) method that accepts the argparse.ArgumentParser instance and the parsed arguments.

  6. How CommandExtension works

    rolling

    CommandExtension is the base class for all ROS 2 CLI command plugins. It uses a plugin system to allow the ros2 tool to discover and instantiate commands dynamically.

    When a user invokes a command (e.g., ros2 <command>), the system:

    1. Identifies the entry point matching the command name.
    2. Instantiates the extension class.
    3. Calls add_arguments if it exists to configure the subparser.
    4. Calls main with the parsed arguments.

    Note that CommandExtension enforces a specific version compatibility with the ros2cli plugin system (version ^0.1).

  7. Add new checks to ros2doctor via Python entry points

    rolling

    You can extend ros2doctor by adding your own custom checks or report modules using Python entry points in your setup.py. You must register modules under two specific entry point groups:

    1. ros2doctor.checks: For the logic that performs the check.
    2. ros2doctor.report: For the logic that formats the report output.

    Example setup.py configuration:

        entry_points={
            'ros2doctor.checks': [
                'PlatformCheck = ros2doctor.api.platform:PlatformCheck',
                'NetworkCheck = ros2doctor.api.network:NetworkCheck',
            ],
            'ros2doctor.report': [
                'PlatformReport = ros2doctor.api.platform:PlatformReport',
                'NetworkReport = ros2doctor.api.network:NetworkReport',
            ],
        }
    entry_points={
        'ros2doctor.checks': [
            'PlatformCheck = ros2doctor.api.platform:PlatformCheck',
            'NetworkCheck = ros2doctor.api.network:NetworkCheck',
        ],
        'ros2doctor.report': [
            'PlatformReport = ros2doctor.api.platform:PlatformReport',
            'NetworkReport = ros2doctor.api.network:NetworkReport',
        ],
    }
  8. Configure ros2doctor report output

    rolling

    You can customize how ros2 doctor displays its findings using the following flags:

    • -r or --report: Show a report of all checked items.
    • -rf or --report-fail: Show a report containing only the failed checks.
    • -iw or --include-warnings: Treat warnings as failed checks. This can be combined with --report-fail to see all warnings and errors.
    • -ep or --exclude-packages: Exclude specific package checks from the report.
    ros2 doctor -rf -iw
  9. Add sub-parsers on demand for CLI extensions

    rolling

    The add_subparsers_on_demand function is used to dynamically build the argparse subparser tree for CLI extensions. This is critical for performance, as it ensures that only the necessary command extensions are instantiated and loaded based on the user's input.

    Parameters

    • parser: The parent argparse.ArgumentParser.
    • cli_name: The name of the CLI command (used for help titles).
    • dest: The attribute name under which the selected extension instance will be stored in the parsed args namespace.
    • group_name: The entry_point group name used to discover extensions.
    • hide_extensions: (Optional) A list of extension names to skip.
    • required: Whether the command argument is required.
    • argv: The list of command line arguments (defaults to sys.argv).

    Behavior

    • If no command is specified, it loads all first-level extensions to populate the help description.
    • If a specific command is detected in argv, it only loads that specific extension (and its recursive extensions) to minimize overhead.
    • It automatically handles argcomplete requests for shell completion.
    • It uses SuppressUsageOutput to prevent argparse from printing usage/help messages prematurely during the discovery phase.
  10. Implement a new ROS 2 CLI command extension

    rolling

    To add a new command (verb) to the ros2 CLI, you must implement the CommandExtension class. This allows your command to be discovered via entry points and integrated into the argparse hierarchy.

    Requirements

    • NAME: A property that will be automatically set to the entry point name.
    • main(self, *, parser, args): The core logic of your command. This method must be implemented and is called after arguments are parsed.
    • add_arguments(self, parser, cli_name, *, argv=None) (Optional): Use this to define the specific flags and arguments for your command using an argparse.ArgumentParser instance.

    Implementation Example

    from ros2cli.command import CommandExtension
    
    class MyCommand(CommandExtension):
        def add_arguments(self, parser, cli_name, *, argv=None):
            parser.add_argument('--my-flag', help='An example flag')
    
        def main(self, *, parser, args):
            if args.my_flag:
                print('Flag is set!')
            else:
                print('Flag is not set.')
    from ros2cli.command import CommandExtension
    
    class MyCommand(CommandExtension):
        def add_arguments(self, parser, cli_name, *, argv=None):
            parser.add_argument('--my-flag', help='An example flag')
    
        def main(self, *, parser, args):
            if args.my_flag:
                print('Flag is set!')
            else:
                print('Flag is not set.')
  11. Use ros2cli.xmlrpc.ServerProxy for XML-RPC communication

    rolling

    The ServerProxy class is used to create a client that communicates with an XML-RPC server (such as the ros2cli daemon). It allows you to call remote methods on the server as if they were local methods. This module aliases standard xmlrpc.client objects to ros2cli.xmlrpc to ensure consistent usage within the ros2cli ecosystem.

    from ros2cli.xmlrpc import ServerProxy
    
    # Example usage (conceptual):
    # proxy = ServerProxy('http://localhost:8000')
    # result = proxy.some_remote_method(arg1, arg2)
  12. Use flags for the extension-points command

    rolling

    When running ros2 extension-points, you can use the following flags to control the output:

    • --all, -a: Includes extension points that failed to be imported in the output. Failed points are prefixed with - .
    • --verbose, -v: Provides additional metadata for each extension point, such as the module name, attributes, and the EXTENSION_POINT_VERSION if available.