Skip to content

[Feature]: Launch-time and Runtime Introspection #26

@ibrahimsel

Description

@ibrahimsel

Description

We should have a custom ROS 2 introspection daemon "MutoDaemon" that enumerates active nodes by scanning both the ROS graph and system processes (psutil). However, it misses certain nodes, particularly composable nodes that live inside containers. We also want to map each node to its PID, executable, package, and any parameters passed via -p ... in the command line. Currently, standalone nodes can be discovered by looking for --ros-args -r __node:=..., but composable nodes remain undiscovered at the OS-process level. Propose a solution to further discover composable nodes and containers. One potential solution is ros2component.api

Suggested Solution

  1. Link Nodes to Processes
    • Use Python's psutil to find active processes that contain --ros-args -r __node:=.... Record (pid, executable, package, params) for those top-level nodes.

2- Parse the Launch Description

  • Traverse in the launch description to discover what entities will arrive to runtime so that we could calculate the difference between them. This will reduce the workload on the system if the incoming LD and runtime has common nodes because composer will avoid restarting those. If not, then simply kill the difference and launch the added nodes.
  • Potential risk here is if a common node is dependent to a removed node to be active. The user needs to be careful about this
  1. Handle Edge Cases
    • In the context of discovering runtime processes:
      • Some nodes may not pass --ros-args, so we might not see __node:=... in their command line. Those remain “unknown.”
      • Some containers may not pass --ros-args -r __node:=container_name, so they also remain “unknown”

The proposed methods are somewhat heuristic and have a lot of room for improvements.

By consolidating the node graph data (including container queries) with process-based metadata (PID, executable, package, parameters), the daemon can accurately introspect both standalone and composable or other special ROS 2 nodes.

Alternatives

  1. Rely Entirely on ROS Graph

    • Skip OS-level introspection and accept that we only see node names/namespaces, not their PIDs or executables.
    • Simpler, but we lose the PID ↔ node mapping. Therefore less control over the runtime. (Which is bad for Composer's use case)
  2. Use a Single Orchestrator

    • Track node statuses in a single “supervisor” node that runs everything. That node can keep records of all processes started, storing the relevant metadata for each.
    • Requires that all nodes be launched by one orchestrator, so it may not fit more distributed setups. The Ros2LaunchParent class within the ecosystem is a strong candidate for this

Additional Context

  • ROS 2 composable nodes are meant to reduce overhead by sharing one process. Hence, we can’t uniquely match them to their own PID. This leads to difficulties in discovering them at runtime.
  • The Ros2LaunchParent class could be utilized to centralize the introspection process
  • It is necessary to write unit tests for the introspection nodes as it could get complicated pretty quickly. (TDD could be a good approach for this specific case)

Below is a high-level diagram of the above
IntrospectionArchitecture2 drawio

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions