# andymuji/e architecture

> Architecture diagram of the GitHub repository andymuji/e, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-30). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/andymuji/e
- Repository: https://github.com/andymuji/e

## Overview

This repository is a ROS 2 home-robot prototype with a local operator interface. Its user-facing workflow is to save named poses, request a destination through the web console or voice, and submit a navigation goal; the navigation stack plans motion while a separate safety gate constrains it. Mapping/SLAM, simulation, location management, and run telemetry are additional capabilities. Several launch and integration modules are listed but not excerpted, so links involving them are based on README documentation rather than inspected launch code.

Main entry points: [`robot/ros2_ws/src/robot_bringup/launch/navigation.launch.py`](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_bringup/launch/navigation.launch.py) (Navigation bringup), [`robot/ros2_ws/src/robot_locations/robot_locations/location_node.py`](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_locations/robot_locations/location_node.py) (Named locations), [`robot/ros2_ws/src/robot_console/robot_console/console_node.py`](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_console/robot_console/console_node.py) (ROS console node), [`robot/ros2_ws/src/robot_voice/robot_voice/voice_node.py`](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_voice/robot_voice/voice_node.py) (Voice ROS node)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_control["Operator control"]
  node_webapp["Web control API<br/>[app.py]"]
  node_webclient["Web interface<br/>[app.js]"]
  node_console["ROS console node<br/>[console_node.py]"]
  node_goaldispatch["Goal dispatcher<br/>[goal_dispatcher.py]"]
  node_mapprovider["Map provider<br/>[map_provider.py]"]
  node_occupancy["Occupancy image<br/>[occupancy_image.py]"]
end

subgraph group_navigation["Mapping and navigation"]
  node_locations["Named locations<br/>[location_node.py]"]
  node_store[("Location store<br/>[location_store.py]")]
  node_interfaces["Pose and goal types<br/>[interfaces.py]"]
  node_slam["SLAM mapping<br/>[slam.launch.py]"]
  node_mapconvert["World-to-map conversion<br/>[world_to_map.py]"]
  node_navbringup["Navigation bringup"]
  node_planner["Grid planner<br/>[grid_planner.py]"]
  node_footprint["Robot footprint<br/>[footprint.py]"]
end

subgraph group_safety["Safety gate"]
  node_safetyadapter["Console safety adapter<br/>[safety_adapter.py]"]
  node_safetynode["Safety ROS node<br/>[safety_node.py]"]
  node_safetycontroller["Safety decisions"]
  node_distances["Obstacle distances<br/>[distances.py]"]
end

subgraph group_voice["Voice commands"]
  node_voice["Voice ROS node<br/>[voice_node.py]"]
  node_recognizer["Speech recognition<br/>[recognizer.py]"]
  node_intent["Intent parser<br/>[intent_parser.py]"]
  node_gateway["Command gateway<br/>[command_gateway.py]"]
end

subgraph group_telemetry["Run telemetry"]
  node_telemetry["Telemetry recording<br/>[record.launch.py]"]
  node_records["Run records<br/>[records.py]"]
  node_invariants["Safety invariants<br/>[invariants.py]"]
  node_report["Run report<br/>[report.py]"]
end

node_operator(("Robot operator"))

node_operator -->|"uses"| node_webclient
node_webclient -->|"requests"| node_webapp
node_webapp -->|"dispatches goals"| node_goaldispatch
node_console -->|"serves"| node_webapp
node_console -->|"provides map"| node_mapprovider
node_mapprovider -->|"renders map"| node_occupancy
node_goaldispatch -.->|"sends named goals"| node_locations
node_locations -->|"reads and writes"| node_store
node_store -->|"creates goals"| node_interfaces
node_locations -->|"publishes navigation goals"| node_navbringup
node_slam -->|"supplies saved map"| node_navbringup
node_mapconvert -.->|"converts map inputs"| node_slam
node_navbringup -->|"uses planning"| node_planner
node_navbringup -->|"configures footprint"| node_footprint
node_navbringup -->|"routes motion through"| node_safetynode
node_console -->|"controls safety"| node_safetyadapter
node_safetynode -->|"evaluates commands"| node_safetycontroller
node_safetynode -->|"checks obstacles"| node_distances
node_voice -.->|"recognizes speech"| node_recognizer
node_voice -->|"routes commands"| node_gateway
node_gateway -.->|"parses transcript"| node_intent
node_voice -->|"requests allow-listed goals"| node_locations
node_telemetry -->|"captures run data"| node_records
node_invariants -->|"checks records"| node_records
node_report -->|"summarizes checks"| node_invariants
node_report -->|"uses records"| node_records

click node_webapp "https://github.com/andymuji/e/blob/main/web_ui/app.py"
click node_webclient "https://github.com/andymuji/e/blob/main/web_ui/web/app.js"
click node_console "https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_console/robot_console/console_node.py"
click node_goaldispatch "https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_console/robot_console/goal_dispatcher.py"
click node_mapprovider "https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_console/robot_console/map_provider.py"
click node_occupancy "https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_console/robot_console/occupancy_image.py"
click node_locations "https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_locations/robot_locations/location_node.py"
click node_store "https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_locations/robot_locations/location_store.py"
click node_interfaces "https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_core/robot_core/interfaces.py"
click node_slam "https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_bringup/launch/slam.launch.py"
click node_mapconvert "https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_bringup/robot_bringup/world_to_map.py"
click node_navbringup "https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_bringup/launch/navigation.launch.py"
click node_planner "https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_navigation/robot_navigation/grid_planner.py"
click node_footprint "https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_navigation/robot_navigation/footprint.py"
click node_safetyadapter "https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_console/robot_console/safety_adapter.py"
click node_safetynode "https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_safety/robot_safety/safety_node.py"
click node_safetycontroller "https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_safety/robot_safety/safety_controller.py"
click node_distances "https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_safety/robot_safety/distances.py"
click node_voice "https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_voice/robot_voice/voice_node.py"
click node_recognizer "https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_voice/robot_voice/recognizer.py"
click node_intent "https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_voice/robot_voice/intent_parser.py"
click node_gateway "https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_voice/robot_voice/command_gateway.py"
click node_telemetry "https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_telemetry/launch/record.launch.py"
click node_records "https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_telemetry/robot_telemetry/records.py"
click node_invariants "https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_telemetry/robot_telemetry/invariants.py"
click node_report "https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_telemetry/robot_telemetry/report.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_webapp,node_webclient,node_console,node_goaldispatch,node_mapprovider,node_occupancy toneBlue
class node_locations,node_store,node_interfaces,node_slam,node_mapconvert,node_navbringup,node_planner,node_footprint toneAmber
class node_safetyadapter,node_safetynode,node_safetycontroller,node_distances toneMint
class node_voice,node_recognizer,node_intent,node_gateway toneRose
class node_telemetry,node_records,node_invariants,node_report,node_operator toneIndigo
```

## Components

### Operator control

- [Web control API](https://github.com/andymuji/e/blob/main/web_ui/app.py): `web_ui/app.py`
- [Web interface](https://github.com/andymuji/e/blob/main/web_ui/web/app.js): `web_ui/web/app.js`
- [ROS console node](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_console/robot_console/console_node.py): `robot/ros2_ws/src/robot_console/robot_console/console_node.py`
- [Goal dispatcher](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_console/robot_console/goal_dispatcher.py): `robot/ros2_ws/src/robot_console/robot_console/goal_dispatcher.py`
- [Map provider](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_console/robot_console/map_provider.py): `robot/ros2_ws/src/robot_console/robot_console/map_provider.py`
- [Occupancy image](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_console/robot_console/occupancy_image.py): `robot/ros2_ws/src/robot_console/robot_console/occupancy_image.py`

### Mapping and navigation

- [Named locations](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_locations/robot_locations/location_node.py): `robot/ros2_ws/src/robot_locations/robot_locations/location_node.py`
- [Location store](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_locations/robot_locations/location_store.py): `robot/ros2_ws/src/robot_locations/robot_locations/location_store.py`
- [Pose and goal types](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_core/robot_core/interfaces.py): `robot/ros2_ws/src/robot_core/robot_core/interfaces.py`
- [SLAM mapping](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_bringup/launch/slam.launch.py): `robot/ros2_ws/src/robot_bringup/launch/slam.launch.py`
- [World-to-map conversion](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_bringup/robot_bringup/world_to_map.py): `robot/ros2_ws/src/robot_bringup/robot_bringup/world_to_map.py`
- [Navigation bringup](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_bringup/launch/navigation.launch.py): `robot/ros2_ws/src/robot_bringup/launch/navigation.launch.py`
- [Grid planner](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_navigation/robot_navigation/grid_planner.py): `robot/ros2_ws/src/robot_navigation/robot_navigation/grid_planner.py`
- [Robot footprint](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_navigation/robot_navigation/footprint.py): `robot/ros2_ws/src/robot_navigation/robot_navigation/footprint.py`

### Safety gate

- [Console safety adapter](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_console/robot_console/safety_adapter.py): `robot/ros2_ws/src/robot_console/robot_console/safety_adapter.py`
- [Safety ROS node](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_safety/robot_safety/safety_node.py): `robot/ros2_ws/src/robot_safety/robot_safety/safety_node.py`
- [Safety decisions](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_safety/robot_safety/safety_controller.py): `robot/ros2_ws/src/robot_safety/robot_safety/safety_controller.py`
- [Obstacle distances](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_safety/robot_safety/distances.py): `robot/ros2_ws/src/robot_safety/robot_safety/distances.py`

### Voice commands

- [Voice ROS node](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_voice/robot_voice/voice_node.py): `robot/ros2_ws/src/robot_voice/robot_voice/voice_node.py`
- [Speech recognition](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_voice/robot_voice/recognizer.py): `robot/ros2_ws/src/robot_voice/robot_voice/recognizer.py`
- [Intent parser](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_voice/robot_voice/intent_parser.py): `robot/ros2_ws/src/robot_voice/robot_voice/intent_parser.py`
- [Command gateway](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_voice/robot_voice/command_gateway.py): `robot/ros2_ws/src/robot_voice/robot_voice/command_gateway.py`

### Run telemetry

- [Telemetry recording](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_telemetry/launch/record.launch.py): `robot/ros2_ws/src/robot_telemetry/launch/record.launch.py`
- [Run records](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_telemetry/robot_telemetry/records.py): `robot/ros2_ws/src/robot_telemetry/robot_telemetry/records.py`
- [Safety invariants](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_telemetry/robot_telemetry/invariants.py): `robot/ros2_ws/src/robot_telemetry/robot_telemetry/invariants.py`
- [Run report](https://github.com/andymuji/e/blob/main/robot/ros2_ws/src/robot_telemetry/robot_telemetry/report.py): `robot/ros2_ws/src/robot_telemetry/robot_telemetry/report.py`

### Other components

- **Robot operator**

## Connections

- Robot operator → Web interface: uses
- Web interface → Web control API: requests
- Web control API → Goal dispatcher: dispatches goals (evidence: `web_ui/app.py`)
- ROS console node → Web control API: serves (evidence: `robot/ros2_ws/src/robot_console/robot_console/console_node.py`)
- ROS console node → Map provider: provides map (evidence: `robot/ros2_ws/src/robot_console/robot_console/console_node.py`)
- Map provider → Occupancy image: renders map (evidence: `robot/ros2_ws/src/robot_console/robot_console/map_provider.py`)
- Goal dispatcher → Named locations: sends named goals
- Named locations → Location store: reads and writes (evidence: `robot/ros2_ws/src/robot_locations/robot_locations/location_node.py`)
- Location store → Pose and goal types: creates goals (evidence: `robot/ros2_ws/src/robot_locations/robot_locations/location_store.py`)
- Named locations → Navigation bringup: publishes navigation goals (evidence: `robot/ros2_ws/src/robot_locations/robot_locations/location_node.py`)
- SLAM mapping → Navigation bringup: supplies saved map
- World-to-map conversion → SLAM mapping: converts map inputs
- Navigation bringup → Grid planner: uses planning
- Navigation bringup → Robot footprint: configures footprint
- Navigation bringup → Safety ROS node: routes motion through
- ROS console node → Console safety adapter: controls safety (evidence: `robot/ros2_ws/src/robot_console/robot_console/console_node.py`)
- Safety ROS node → Safety decisions: evaluates commands (evidence: `robot/ros2_ws/src/robot_safety/robot_safety/safety_node.py`)
- Safety ROS node → Obstacle distances: checks obstacles
- Voice ROS node → Speech recognition: recognizes speech
- Voice ROS node → Command gateway: routes commands (evidence: `robot/ros2_ws/src/robot_voice/robot_voice/voice_node.py`)
- Command gateway → Intent parser: parses transcript
- Voice ROS node → Named locations: requests allow-listed goals
- Telemetry recording → Run records: captures run data (evidence: `robot/ros2_ws/src/robot_telemetry/robot_telemetry/records.py`)
- Safety invariants → Run records: checks records (evidence: `robot/ros2_ws/src/robot_telemetry/robot_telemetry/invariants.py`)
- Run report → Safety invariants: summarizes checks (evidence: `robot/ros2_ws/src/robot_telemetry/robot_telemetry/report.py`)
- Run report → Run records: uses records (evidence: `robot/ros2_ws/src/robot_telemetry/robot_telemetry/report.py`)
