aggregate_error_stackup

-- Multi-layer error aggregation and trend visualization.
aggregate_error_stackup :: StateDir -> (AggregateHTML, SummaryCSV)
-- Reads all L{N}.csv files from the print loop state directory,
-- stacks them into a unified 3D Plotly scene at their physical Z heights,
-- and charts error statistics over time.

Post-print analysis tool that aggregates per-layer surface-height error data from the WAAM print loop into a single interactive visualization. The 3D "pancake stackup" shows every layer's robot path alongside its error surface at the correct Z height, while a 2D trend chart below confirms that the proportional controller is reducing error over time.

Usage

# from ros2_ws/lib/control/aggregate_error_stackup/
uv run python aggregate_error_stackup.py /path/to/STATE/ERR/job_dir/

This reads all L*.csv files in the directory and produces:

  • stackup.html — interactive 3D + 2D Plotly visualization
  • stackup_summary.csv — per-layer error statistics table

Serve for remote viewing

The output HTML is self-contained. To view from another machine on the same Tailscale / LAN:

cd /path/to/STATE/ERR/job_dir/
python3 -m http.server 8080 --bind 0.0.0.0
# browse to http://<robot-host>:8080/stackup.html

Options

positional arguments:
  state_dir             Directory containing L*.csv error maps

options:
  -o, --output          Output HTML path (default: <state_dir>/stackup.html)
  --summary             Output summary CSV (default: <state_dir>/stackup_summary.csv)
  --title               Custom plot title
  --layers              Comma-separated layer subset (e.g. 19,20,21,22)
  --no-trend            Omit the 2D error-trend subplot

Examples

# Full stackup of all layers
uv run python aggregate_error_stackup.py \
    /home/r76/PhotogrammetryWAAM/STATE/ERR/mayorvase_LH2.1_40x_-20y/

# Only layers 40-60 with custom title
uv run python aggregate_error_stackup.py \
    /home/r76/PhotogrammetryWAAM/STATE/ERR/mayorvase_LH2.1_40x_-20y/ \
    --layers 40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60 \
    --title "Mayor Vase — Layers 40–60"

# Stackup without trend chart
uv run python aggregate_error_stackup.py \
    ~/PhotogrammetryWAAM/STATE/ERR/mayorvase_LH2.1_40x_-20y/ \
    --no-trend

What it shows

3D Stackup (top)

Every layer is plotted at its physical Z height. Two traces per layer:

TraceVisualData
Robot pathCool→warm colored line (blue=early, red=late)X, Y, Z from L{N}.csv
Error surfaceRed-Yellow-Green colorscale by error magnitudeX, Y, Z + err_mm

Layers are toggle-able via the legend. "Show All" / "Hide All" buttons allow quick comparison.

Error Trend (bottom)

Per-layer statistics plotted against layer number:

SeriesMetricHealthy trend
RMS errorsqrt(mean(err²))Decreasing
Meanerr
Maxerr

A downward slope confirms the proportional controller is converging.

Integration with the print loop

This tool is designed as Step 4 — a post-hoc analysis that runs after layers have been printed. It reads the same state_dir that the print_loop orchestrator writes to:

print_loop (Steps 1-3)          aggregate_error_stackup (Step 4)
        │                                     │
        ▼                                     ▼
  state_dir/                            state_dir/
  ├── L19.csv                           ├── stackup.html        ← NEW
  ├── L19.html                          ├── stackup_summary.csv ← NEW
  ├── L20.csv                           ├── L19.csv
  ├── L20.html                          ├── L19.html
  ├── ...                               ├── ...
  └── mayor_1_state.json                └── mayor_1_state.json

Run it at any point during or after a print job to see accumulated progress.

Files

FilePurpose
aggregate_error_stackup.pyMain CLI script
pyproject.tomluv project definition
SPEC.mdFull specification

Full specification (../spec/)