4.6 KiB
BATL CARLA Dashboard Architecture
This document outlines the architecture, data flow, and inner workings of the BATL CARLA Dashboard (GUI Orchestrator). It is designed to be easily digestible for both human maintainers and AI assistants iterating on the codebase.
1. High-Level Overview
The BATL CARLA Dashboard is a web-based GUI that replaces manual CLI interactions. It allows users to:
- Select scenarios intuitively.
- Override configuration parameters (frames, weather, etc.).
- Spawn the simulation as a background process.
- Stream real-time standard output (stdout) directly from the simulation to the browser.
The system is split into three main layers:
- Frontend (Browser): HTML/CSS/JavaScript located in
dashboard/templatesanddashboard/static. - Backend (Web Server): A Flask application defined in
dashboard/app.py. - Execution Engine (CLI Pipeline): The pre-existing
run.batwrapper andsrc/main.pyPython script.
2. Component Breakdown
A. The Launcher (dashboard.bat)
This simple batch script is the entry point for the user. It activates the appropriate Python environment and executes dashboard/app.py, launching the Flask development server on port 5000.
B. The Web Server (dashboard/app.py)
Flask acts as the bridge between the user's browser HTTP requests and the host operating system's command line.
- API Endpoints: It serves
/api/configand/api/scenario_params/<name>to dynamically inform the UI about available scenarios, config limits, and tunable parameters. - Process Orchestration: When a user clicks "Run" on the UI, the frontend sends a
POSTrequest to/api/runcontaining the selected options. Flask parses this JSON payload and heavily formats a CLI command array.
C. The Frontend (dashboard/static/app.js)
The JavaScript logic handles state management. It:
- Fetches scenarios on load and populates dropdowns.
- Intercepts the "Run" form submission to prevent page reloads.
- Opens a standard Server-Sent Events (SSE) connection via the built-in
EventSourceAPI to receive real-time text streams from Flask.
3. How the Dashboard Interacts with run.bat
The most critical interface in this architecture is how Flask triggers and monitors the underlying CARLA simulation.
When the /api/run endpoint is hit:
-
Command Construction: Flask builds the command array. A payload of
{"scenario": "showcase", "frames": 50}translates to the equivalent of typing:cmd.exe /c run.bat showcase --frames 50 -
Subprocess Spawning: Flask leverages Python's
subprocess.Popento spawn a detached child process running the constructed command.cwd=PROJECT_ROOT: Ensuresrun.batis executed contextually from the root workspace so relative imports insidesrc/main.pydo not break.stdout=subprocess.PIPE/stderr=subprocess.STDOUT: Captures both standard and error console outputs, merging them into a single pipe that Flask can read dynamically.
-
Stream Unbuffering (Crucial Step): By default, Python buffers stdout when piping it to another program, causing massive delays (the GUI appears to "freeze"). To fix this, Flask injects
env["PYTHONUNBUFFERED"] = "1"into the sub-environment, andrun.batalso callsset PYTHONUNBUFFERED=1. This forces the downstream Python simulation (src/main.pyand its dependencies) to emit logs instantly, allowing real-time progress bar renders in the GUI console. -
Event Streaming (Yield): Instead of waiting for the process to return an exit code, Flask uses a specific Python generator (
def generate():) paired with a standardResponse(mimetype="text/event-stream"). Asprocess.stdout.readline()pulls new text from the unbuffered stream, Flask yields it to the browser wrapped indata: ... \n\nsyntax. The JS EventSource catches these fragments and appends them to the<div id="console">log box.
4. Extension Guidelines for AI
When asked to extend the Dashboard, observe the following patterns:
- Adding new CLI flags: Update the
POST /api/runpayload parser inapp.py, extend thecmd.extend()builder, and add the corresponding HTML<input>inindex.html. - Adding new data streams: The SSE generator currently pipes raw text. To parse structured data (like active ego speed) for live graphs, consider formatting the intermediate Python prints as JSON and having
app.jsparse theevent.datapayload conditionally. - Pathing: Remember that
app.pylives in a sub-folder. Operations manipulating the CARLA simulation must be rooted up two levels using thePROJECT_ROOTpointer established in the file.