src/simulation/simulator.js random-walk generator (was simulateInput inline)
src/calibration/calibrator.js calibrate + isStable + evaluateRepeatability,
using generalFunctions/stats. NB: isStable
tautology preserved verbatim — see
OPEN_QUESTIONS.md 2026-05-10 for the bug.
src/commands/ registry + handlers (canonical names from start)
CONTRACT.md inputs/outputs/events surface
77 basic tests pass (62 pre-refactor + 15 new across the three new files).
specificClass.js / nodeClass.js untouched — integration is P3 wave 2.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
61 lines
2.0 KiB
JavaScript
61 lines
2.0 KiB
JavaScript
/**
|
|
* Simulator — random-walk driver for the measurement input.
|
|
*
|
|
* Lifted verbatim from Measurement.simulateInput. The orchestrator decides
|
|
* what to do with the returned value (originally written to `inputValue`),
|
|
* so this module owns nothing but the walk and its bounds.
|
|
*/
|
|
class Simulator {
|
|
constructor({ config, logger } = {}) {
|
|
if (!config || !config.scaling) {
|
|
throw new Error('Simulator requires { config.scaling }');
|
|
}
|
|
this.config = config;
|
|
this.logger = logger || { warn() {}, info() {}, debug() {}, error() {} };
|
|
|
|
const s = config.scaling;
|
|
this.inputRange = Math.abs(s.inputMax - s.inputMin);
|
|
this.processRange = Math.abs(s.absMax - s.absMin);
|
|
this.simValue = 0;
|
|
}
|
|
|
|
step() {
|
|
const s = this.config.scaling;
|
|
const sign = Math.random() < 0.5 ? -1 : 1;
|
|
let maxStep;
|
|
|
|
if (s.enabled) {
|
|
// Step size scales with the live input window; fall back to 1 so a
|
|
// collapsed range still wanders instead of freezing at zero.
|
|
maxStep = this.inputRange > 0 ? this.inputRange * 0.05 : 1;
|
|
if (this.simValue < s.inputMin || this.simValue > s.inputMax) {
|
|
this.logger.warn(`Simulated value ${this.simValue} is outside of input range constraining between min=${s.inputMin} and max=${s.inputMax}`);
|
|
this.simValue = _constrain(this.simValue, s.inputMin, s.inputMax);
|
|
}
|
|
} else {
|
|
maxStep = this.processRange > 0 ? this.processRange * 0.05 : 1;
|
|
if (this.simValue < s.absMin || this.simValue > s.absMax) {
|
|
this.logger.warn(`Simulated value ${this.simValue} is outside of abs range constraining between min=${s.absMin} and max=${s.absMax}`);
|
|
this.simValue = _constrain(this.simValue, s.absMin, s.absMax);
|
|
}
|
|
}
|
|
|
|
this.simValue += sign * Math.random() * maxStep;
|
|
return this.simValue;
|
|
}
|
|
|
|
reset() {
|
|
this.simValue = 0;
|
|
}
|
|
|
|
get current() {
|
|
return this.simValue;
|
|
}
|
|
}
|
|
|
|
function _constrain(v, lo, hi) {
|
|
return Math.min(Math.max(v, lo), hi);
|
|
}
|
|
|
|
module.exports = Simulator;
|