Compare commits
3 Commits
c464b66b27
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11d196f363 | ||
|
|
510a4233e6 | ||
|
|
26e253d030 |
@@ -883,7 +883,7 @@ _callMeasurementHandler(measurementType, value, position, context) {
|
|||||||
if (interruptible.has(sequenceName) &&
|
if (interruptible.has(sequenceName) &&
|
||||||
(currentState === "accelerating" || currentState === "decelerating")) {
|
(currentState === "accelerating" || currentState === "decelerating")) {
|
||||||
this.logger.warn(`Sequence '${sequenceName}' requested during '${currentState}'. Aborting active movement.`);
|
this.logger.warn(`Sequence '${sequenceName}' requested during '${currentState}'. Aborting active movement.`);
|
||||||
this.state.abortCurrentMovement(`${sequenceName} sequence requested`);
|
this.state.abortCurrentMovement(`${sequenceName} sequence requested`, { returnToOperational: true });
|
||||||
await this._waitForOperational(2000);
|
await this._waitForOperational(2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -967,10 +967,11 @@ _callMeasurementHandler(measurementType, value, position, context) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cFlow = this.predictFlow.y(x);
|
const rawFlow = this.predictFlow.y(x);
|
||||||
|
// Clamp: at position ≤ 0 the pump isn't rotating — physical flow is 0.
|
||||||
|
const cFlow = (x <= 0) ? 0 : Math.max(0, rawFlow);
|
||||||
this.measurements.type("flow").variant("predicted").position("downstream").value(cFlow,Date.now(),this.unitPolicy.canonical.flow);
|
this.measurements.type("flow").variant("predicted").position("downstream").value(cFlow,Date.now(),this.unitPolicy.canonical.flow);
|
||||||
this.measurements.type("flow").variant("predicted").position("atEquipment").value(cFlow,Date.now(),this.unitPolicy.canonical.flow);
|
this.measurements.type("flow").variant("predicted").position("atEquipment").value(cFlow,Date.now(),this.unitPolicy.canonical.flow);
|
||||||
//this.logger.debug(`Calculated flow: ${cFlow} for pressure: ${this.getMeasuredPressure()} and position: ${x}`);
|
|
||||||
return cFlow;
|
return cFlow;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -991,10 +992,9 @@ _callMeasurementHandler(measurementType, value, position, context) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//this.predictPower.currentX = x; Decrepated
|
const rawPower = this.predictPower.y(x);
|
||||||
const cPower = this.predictPower.y(x);
|
const cPower = (x <= 0) ? 0 : Math.max(0, rawPower);
|
||||||
this.measurements.type("power").variant("predicted").position('atEquipment').value(cPower, Date.now(), this.unitPolicy.canonical.power);
|
this.measurements.type("power").variant("predicted").position('atEquipment').value(cPower, Date.now(), this.unitPolicy.canonical.power);
|
||||||
//this.logger.debug(`Calculated power: ${cPower} for pressure: ${this.getMeasuredPressure()} and position: ${x}`);
|
|
||||||
return cPower;
|
return cPower;
|
||||||
}
|
}
|
||||||
// If no curve data is available, log a warning and return 0
|
// If no curve data is available, log a warning and return 0
|
||||||
|
|||||||
@@ -48,7 +48,12 @@ test('predictions use initialized medium pressure and not the minimum-pressure f
|
|||||||
assert.equal(pressureStatus.initialized, true);
|
assert.equal(pressureStatus.initialized, true);
|
||||||
assert.equal(pressureStatus.hasDifferential, true);
|
assert.equal(pressureStatus.hasDifferential, true);
|
||||||
|
|
||||||
const expectedDiff = (mediumDownstreamMbar - mediumUpstreamMbar) * 100; // mbar -> Pa canonical
|
const rawDiff = (mediumDownstreamMbar - mediumUpstreamMbar) * 100; // mbar -> Pa = 40000
|
||||||
assert.equal(Math.round(machine.predictFlow.fDimension), expectedDiff);
|
// fDimension is clamped to [fValues.min, fValues.max]. The H05K curve's
|
||||||
|
// minimum pressure slice is 70000 Pa (700 mbar). A 40000 Pa differential
|
||||||
|
// is below the curve minimum, so it gets clamped to 70000.
|
||||||
|
const curveMinPressure = 70000;
|
||||||
|
const expected = Math.max(rawDiff, curveMinPressure);
|
||||||
|
assert.equal(Math.round(machine.predictFlow.fDimension), expected);
|
||||||
assert.ok(machine.predictFlow.fDimension > 0);
|
assert.ok(machine.predictFlow.fDimension > 0);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -14,7 +14,10 @@ test('pressure initialization combinations are handled explicitly', () => {
|
|||||||
assert.equal(status.source, null);
|
assert.equal(status.source, null);
|
||||||
const noPressureValue = machine.getMeasuredPressure();
|
const noPressureValue = machine.getMeasuredPressure();
|
||||||
assert.equal(noPressureValue, 0);
|
assert.equal(noPressureValue, 0);
|
||||||
assert.ok(machine.predictFlow.fDimension <= 1);
|
// With no pressure injected, fDimension is clamped to the curve minimum
|
||||||
|
// (70000 Pa for H05K). Previously a schema default at pressure "1" made
|
||||||
|
// fValues.min=1 — that was a data-poisoning bug, now fixed.
|
||||||
|
assert.ok(machine.predictFlow.fDimension >= 70000);
|
||||||
|
|
||||||
// upstream only
|
// upstream only
|
||||||
machine = createMachine();
|
machine = createMachine();
|
||||||
@@ -44,9 +47,11 @@ test('pressure initialization combinations are handled explicitly', () => {
|
|||||||
assert.equal(Math.round(downstreamValue), downstreamOnly * 100);
|
assert.equal(Math.round(downstreamValue), downstreamOnly * 100);
|
||||||
assert.equal(Math.round(machine.predictFlow.fDimension), downstreamOnly * 100);
|
assert.equal(Math.round(machine.predictFlow.fDimension), downstreamOnly * 100);
|
||||||
|
|
||||||
// downstream and upstream
|
// downstream and upstream — pick values whose differential (Pa) is above
|
||||||
|
// the curve's minimum pressure slice (70000 Pa = 700 mbar for H05K).
|
||||||
|
// 200 mbar upstream + 1100 mbar downstream → diff = 900 mbar = 90000 Pa.
|
||||||
machine = createMachine();
|
machine = createMachine();
|
||||||
const upstream = 700;
|
const upstream = 200;
|
||||||
const downstream = 1100;
|
const downstream = 1100;
|
||||||
machine.measurements.type('pressure').variant('measured').position('upstream').value(upstream, Date.now(), 'mbar');
|
machine.measurements.type('pressure').variant('measured').position('upstream').value(upstream, Date.now(), 'mbar');
|
||||||
machine.measurements.type('pressure').variant('measured').position('downstream').value(downstream, Date.now(), 'mbar');
|
machine.measurements.type('pressure').variant('measured').position('downstream').value(downstream, Date.now(), 'mbar');
|
||||||
|
|||||||
@@ -14,11 +14,16 @@ test('execSequence startup reaches operational with zero transition times', asyn
|
|||||||
|
|
||||||
test('execMovement constrains controller position to safe bounds in operational state', async () => {
|
test('execMovement constrains controller position to safe bounds in operational state', async () => {
|
||||||
const machine = new Machine(makeMachineConfig(), makeStateConfig({ state: { current: 'operational' } }));
|
const machine = new Machine(makeMachineConfig(), makeStateConfig({ state: { current: 'operational' } }));
|
||||||
const { max } = machine._resolveSetpointBounds();
|
const { min, max } = machine._resolveSetpointBounds();
|
||||||
|
|
||||||
|
// Test upper constraint: setpoint above max gets clamped to max
|
||||||
|
await machine.handleInput('parent', 'execMovement', max + 50);
|
||||||
|
let pos = machine.state.getCurrentPosition();
|
||||||
|
assert.equal(pos, max, `setpoint above max should be clamped to ${max}`);
|
||||||
|
|
||||||
|
// Test that a valid setpoint within bounds is applied as-is
|
||||||
await machine.handleInput('parent', 'execMovement', 10);
|
await machine.handleInput('parent', 'execMovement', 10);
|
||||||
|
pos = machine.state.getCurrentPosition();
|
||||||
const pos = machine.state.getCurrentPosition();
|
assert.equal(pos, 10, 'setpoint within bounds should be applied as-is');
|
||||||
assert.ok(pos <= max);
|
assert.ok(pos >= min && pos <= max);
|
||||||
assert.equal(pos, max);
|
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user