aggregate_error_stackup — SPEC
Purpose
Aggregate per-layer surface-height error CSVs from the print loop's state_dir into a unified 3D "pancake stackup" visualization. The plot reveals how the proportional controller's corrections reduce error over successive layers.
Domain context
Each layer of a WAAM print produces a CSV (L{N}.csv) with columns X, Y, Z, err_mm mapping every robot pose sample to its measured surface-height error. Individually these are viewed as single-layer 3D plots (robot path vs error surface). This module stacks all available layers into one interactive Plotly scene so the operator can visually confirm that error magnitudes diminish as the build progresses — i.e., the proportional controller is converging.
Type signatures
type LayerCSV = FilePath -- state_dir/L{N}.csv with columns X, Y, Z, err_mm
type AggregateHTML = FilePath -- interactive Plotly 3D stackup
type SummaryCSV = FilePath -- per-layer error statistics
-- Core pipeline
discover_layers :: StateDir -> [(LayerNumber, LayerCSV)]
load_layer :: LayerCSV -> DataFrame -- X, Y, Z, err_mm
compute_stats :: DataFrame -> LayerStats -- mean_abs, rms, max_abs, n_samples
build_stackup :: [(LayerNumber, DataFrame)] -> PlotlyFigure
build_trend :: [LayerStats] -> PlotlyFigure
aggregate_error_stackup :: StateDir -> (AggregateHTML, SummaryCSV)
Inputs
Per-layer error CSVs
Files L{N}.csv in the state directory produced by map_surface_err_to_xyz_pos.py (Step 2 of the print loop).
X,Y,Z,err_mm
12.2021,47.3637,43.2479,4.0644
10.7972,47.6810,43.2649,4.0644
...
Discovery: glob state_dir/L*.csv, extract layer number N from filename.
Optional: job state JSON
{state_dir}/{job_name}_state.json — if present, used to extract nominal Z heights per layer. Otherwise, Z is inferred from the CSV data (median Z per layer).
Outputs
1. Aggregate 3D HTML (stackup.html)
A Plotly Scatter3d figure with two traces per layer:
| Trace | Color | Description |
|---|---|---|
| Robot path | black → grey gradient by layer | Actual X, Y, Z from poses |
| Error surface | colorscale by err_mm | X, Y, Z + err_mm — shows deviations |
All layers rendered simultaneously in a single 3D scene. The Z axis naturally separates layers by their physical height. A dropdown/slider allows toggling individual layers on/off.
Layout:
- Title:
"WAAM Aggregate Error Stackup — {state_dir.name}" - Scene: aspect mode "data", axis labels X/Y/Z in mm
- Legend groups by layer number
2. Error trend subplot (embedded in same HTML)
A secondary 2D subplot (below the 3D scene) charting per-layer error statistics vs layer number:
| Series | Metric |
|---|---|
| RMS error | sqrt(mean(err_mm²)) |
| Mean | err |
| Max | err |
X-axis: layer number. Y-axis: error magnitude (mm). If the controller is working, these curves should trend downward.
3. Summary CSV (stackup_summary.csv)
layer,nominal_z,n_samples,mean_abs_err,rms_err,max_abs_err,std_err
19,63.8,1842,0.312,0.418,1.204,0.278
20,65.9,1910,0.287,0.391,1.103,0.266
...
Algorithm
1. Discover: glob state_dir/L*.csv, sort by layer number
2. For each CSV:
a. Load into numpy arrays (X, Y, Z, err_mm)
b. Compute statistics: n, mean_abs, rms, max_abs, std
c. Build error surface: Z_err = Z + err_mm
3. Build 3D figure:
a. For each layer, add robot-path trace (X, Y, Z) with layer-indexed color
b. For each layer, add error-surface trace (X, Y, Z_err) colored by err_mm
c. Add updatemenus for layer toggle
4. Build 2D trend subplot with error statistics over layer progression
5. Combine into single HTML with subplots
6. Write summary CSV
CLI interface
uv run python aggregate_error_stackup.py <state_dir> [options]
| Flag | Default | Purpose |
|---|---|---|
| Positional 1 | — | Path to the state directory containing L*.csv files |
-o, --output | <state_dir>/stackup.html | Output HTML path |
--summary | <state_dir>/stackup_summary.csv | Output summary CSV path |
--title | auto from dir name | Plot title |
--layers | all discovered | Comma-separated layer numbers to include (e.g. 19,20,21) |
--no-trend | false | Omit the 2D error trend subplot |
Dependencies
numpy— array operations and statisticsplotly— interactive 3D + 2D visualization- Standard library:
csv,pathlib,argparse,re
Constraints
- CSV files must follow
L{N}.csvnaming convention. - At least two layers must be present for the trend plot to be meaningful.
- Large layer counts (>50) may require trace simplification (downsampling) for browser performance.