aggregate_error_stackup — SPEC
aggregate_error_stackup — SPEC
Section titled “aggregate_error_stackup — SPEC”Purpose
Section titled “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
Section titled “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
Section titled “Type signatures”type LayerCSV = FilePath -- state_dir/L{N}.csv with columns X, Y, Z, err_mmtype AggregateHTML = FilePath -- interactive Plotly 3D stackuptype SummaryCSV = FilePath -- per-layer error statistics
-- Core pipelinediscover_layers :: StateDir -> [(LayerNumber, LayerCSV)]load_layer :: LayerCSV -> DataFrame -- X, Y, Z, err_mmcompute_stats :: DataFrame -> LayerStats -- mean_abs, rms, max_abs, n_samplesbuild_stackup :: [(LayerNumber, DataFrame)] -> PlotlyFigurebuild_trend :: [LayerStats] -> PlotlyFigure
aggregate_error_stackup :: StateDir -> (AggregateHTML, SummaryCSV)Inputs
Section titled “Inputs”Per-layer error CSVs
Section titled “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_mm12.2021,47.3637,43.2479,4.064410.7972,47.6810,43.2649,4.0644...Discovery: glob state_dir/L*.csv, extract layer number N from filename.
Optional: job state JSON
Section titled “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
Section titled “Outputs”1. Aggregate 3D HTML (stackup.html)
Section titled “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)
Section titled “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)
Section titled “3. Summary CSV (stackup_summary.csv)”layer,nominal_z,n_samples,mean_abs_err,rms_err,max_abs_err,std_err19,63.8,1842,0.312,0.418,1.204,0.27820,65.9,1910,0.287,0.391,1.103,0.266...Algorithm
Section titled “Algorithm”1. Discover: glob state_dir/L*.csv, sort by layer number2. 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_mm3. 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 toggle4. Build 2D trend subplot with error statistics over layer progression5. Combine into single HTML with subplots6. Write summary CSVCLI interface
Section titled “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
Section titled “Dependencies”numpy— array operations and statisticsplotly— interactive 3D + 2D visualization- Standard library:
csv,pathlib,argparse,re
Constraints
Section titled “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.