From 03947cd94cd6ee624684b7126cb5590b94879637 Mon Sep 17 00:00:00 2001 From: ScottW514 Date: Sun, 16 Aug 2026 16:09:07 -0400 Subject: [PATCH] bench: run flow_sampler.py from the installed bench tools, not /data The dev image installs the bench tools under /usr/share/forgetest/bench/, so flow_matrix.py and flow_warm_validate.py invoke the board-side sampler from there instead of a hand-copied /data/flow_sampler.py; the README follows. Bench-tool path change only, no machine behavior involved. --- scripts/bench/README.md | 11 ++++++----- scripts/bench/flow_matrix.py | 2 +- scripts/bench/flow_warm_validate.py | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/scripts/bench/README.md b/scripts/bench/README.md index e625b88..fa368f3 100644 --- a/scripts/bench/README.md +++ b/scripts/bench/README.md @@ -29,13 +29,13 @@ to go through a WSL distro from Windows). | `pacing_test.py` | Protocol-loop pacing check (runs on the board, dry motion): idle and parked-in-Hold states are coarse-paced, active motion is tight-paced, and a feed-hold/resume mid-move preserves position with no feeder starve. | | `fan_test.py` | Fan/coolant bench (Windows-side): snapshots fan PWMs/tachs/temps, drives M8 → cut fans, M9 → cooldown → idle, verifying via tach readbacks. | | `flow_characterize.py` | Coolant flow characterization using the factory temperature curve: baseline → flow → no-flow → recovery, printing the ΔT bands and their separation. Takes the heater duty as an argument (`flow_characterize.py 30`); aborts if downstream passes 45 °C. | -| `flow_matrix.py` | **The flow-detection design matrix** (with `flow_sampler.py`, which lives on the board at `/data/`): duty × duration × flow/no-flow, every run from a common cooled baseline, interleaved repeats. One heating trace yields the metric at every candidate duration, so cost and precision come from the same 60 runs. Prints a cost table, a precision table (mean±sd, worst-case margin, d′) and a ranked shortlist. Env: `FM_DUTIES`, `FM_REPEATS`, `FM_RESULTS`. | +| `flow_matrix.py` | **The flow-detection design matrix** (with `flow_sampler.py`, run on the board from `/usr/share/forgetest/bench/`): duty × duration × flow/no-flow, every run from a common cooled baseline, interleaved repeats. One heating trace yields the metric at every candidate duration, so cost and precision come from the same 60 runs. Prints a cost table, a precision table (mean±sd, worst-case margin, d′) and a ranked shortlist. Env: `FM_DUTIES`, `FM_REPEATS`, `FM_RESULTS`. | | `flow_sustained.py` | Long-run test of the real re-check cadence via M8: counts verdicts/false faults and tracks whether the loop accumulates heat. | | `flow_warm_validate.py` | Runs the real check from a heater-warmed baseline. Note the ceiling: 100 % duty pushes the downstream sensor past 50 °C in 30 s while the bulk barely moves, so warm-loop validation above ~23 °C needs the laser, not the heater. | | `flow_recheck_char.py` | Characterizes short in-run re-checks and the differential metric; shows why over-temp cannot see a stopped pump and why passive warming trends are ambiguous. | | `flow_confirm_drill.py` | Coolant flow suspicion/confirmation drill (runs on the board): one continuous M8 session walks the verdict state machine through real pump-off transients — verified → SUSPECT (+ immediate re-check) → cleared → SUSPECT → FAULT (consecutive) → recovered — printing PASS/FAIL per transition. Leaves the machine idle (M9, pump on, heater off). | | `flow_escalate_drill.py` | Coolant starved-re-check escalation drill (runs on the board against a controller started with a short confirmation budget): with the pump off the job-start check reads SUSPECT, the stagnant loop cannot pass the settle gate inside the budget, and the driver must escalate to FAULT. PASS/FAIL, leaves the machine idle. | -| `flow_sampler.py` | Board-side coolant sampler used by the flow tools (`flow_sampler.py `, prints `elapsed,raw_down,raw_up`); kept on the board at `/data/` so cadence does not depend on ssh latency. | +| `flow_sampler.py` | Board-side coolant sampler used by the flow tools (`flow_sampler.py `, prints `elapsed,raw_down,raw_up`); run on the board (dev image: `/usr/share/forgetest/bench/`) so cadence does not depend on ssh latency. | | `temp_calibrate.py` | Coolant temperature spot-check helper (`watch` / `point ` / `fit`) — pairs a measured temperature with averaged raw ADC readings and fits a per-machine line to sanity-check the factory curve against a thermometer. | | `build-glowforge.sh` | Cross-compiles **grblHAL-glowforge** (the canonical driver repo, `../../../grblHAL-glowforge`) in the Yocto build environment, borrowing the recipe toolchain. Run: `bash /build-glowforge.sh` (from Windows, launch it through the WSL distro from PowerShell; Git Bash mangles /mnt/c paths). Env: `FF_SRC_TOP`, `FF_BUILD_TOP`. This is the production controller build. | | `build-forgectrl.sh` | Cross-compiles **forgectrl** (the canonical control-daemon repo, `../../../forgectrl`) the same way, borrowing the toolchain from the forgectrl recipe workdir (regenerate with `bitbake forgectrl` after a clean). | @@ -83,9 +83,10 @@ the threshold set at the balanced midpoint of the two bands (14.4 °C). baselines (`flow_warm_results.json`). To reproduce on another machine: set `GF_HOST` (and `GF_SSH` if ssh needs a -wrapper), copy `flow_sampler.py` to `/data/` on the board, and run -`flow_matrix.py` (env `FM_DUTIES`, `FM_REPEATS`, `FM_RESULTS`; ~1.6 h for -the full matrix, the controller is stopped for the duration). The same +wrapper), boot the dev image (it installs `flow_sampler.py` under +`/usr/share/forgetest/bench/`), and run `flow_matrix.py` (env `FM_DUTIES`, +`FM_REPEATS`, `FM_RESULTS`; ~1.6 h for the full matrix, the controller is +stopped for the duration). The same derivation is also built into forgectrl as the panel's Diagnostics → **flow-calibrate** tool (3 trials per case at the operating point, reports both bands and a recommended threshold; the bench value it recommends diff --git a/scripts/bench/flow_matrix.py b/scripts/bench/flow_matrix.py index 6b2a048..d7850d4 100644 --- a/scripts/bench/flow_matrix.py +++ b/scripts/bench/flow_matrix.py @@ -118,7 +118,7 @@ def run_case(duty, flow, log): time.sleep(3) d0, u0 = temps() heater(duty) - raw = board('python3 /data/flow_sampler.py %d %.1f' % (RUN_S, SAMPLE_IV), + raw = board('python3 /usr/share/forgetest/bench/flow_sampler.py %d %.1f' % (RUN_S, SAMPLE_IV), timeout=RUN_S + 60) heater(0) pump(True) diff --git a/scripts/bench/flow_warm_validate.py b/scripts/bench/flow_warm_validate.py index 7a11cfc..3832d48 100644 --- a/scripts/bench/flow_warm_validate.py +++ b/scripts/bench/flow_warm_validate.py @@ -135,7 +135,7 @@ def check(flow, log): time.sleep(3) d0, u0 = temps() heater(DUTY) - raw = board('python3 /data/flow_sampler.py %d 1.0' % CHECK_S, timeout=CHECK_S + 60) + raw = board('python3 /usr/share/forgetest/bench/flow_sampler.py %d 1.0' % CHECK_S, timeout=CHECK_S + 60) heater(0) pump(True)