succd: rewrite processing loop

This commit is contained in:
Serge Bazanski 2024-09-28 10:17:05 +02:00
parent 3d81a1f56c
commit 960be9cd23
3 changed files with 50 additions and 66 deletions

View file

@ -4,7 +4,6 @@ import (
"context"
"errors"
"fmt"
"math"
"sync"
"time"
@ -42,7 +41,9 @@ type daemonState struct {
}
piraniVolts100 ringbufferInput
piraniMbar100 pfeifferVoltsToMbar
piraniVolts3 ringbufferInput
piraniMbar3 pfeifferVoltsToMbar
rpOn bool
dpOn bool
@ -53,44 +54,6 @@ type daemonState struct {
aboveHigh thresholdOutput
}
type piraniDetection uint
const (
// piraniDetectionUnknown means the system isn't yet sure whether the pirani
// gauge is connected.
piraniDetectionUnknown piraniDetection = iota
// piraniDetectionConnected means the system assumes the pirani gauge is
// connected.
piraniDetectionConnected = iota
// piraniDetectionDisconnected means the system assumes the pirani gauge is
// disconnected.
piraniDetectionDisconnected = iota
)
func piraniVoltsToMbar(v float32) float32 {
// Per Pirani probe docs.
bar := math.Pow(10.0, float64(v)-8.5)
return float32(bar * 1000.0)
}
// piraniDetection guesses whether the pirani gauge is connected.
func (d *daemonState) piraniDetection() piraniDetection {
if !d.piraniVolts3.saturated() {
return piraniDetectionUnknown
}
mbar := piraniVoltsToMbar(d.piraniVolts3.avg)
if mbar < 4e-6 {
return piraniDetectionDisconnected
}
return piraniDetectionConnected
}
func (d *daemonState) pirani() (volts float32, mbar float32) {
volts = d.piraniVolts100.avg
mbar = piraniVoltsToMbar(volts)
return
}
func (d *daemonState) vacuumStatus() (rough, high bool) {
rough = !d.aboveRough.output
high = !d.aboveHigh.output
@ -129,51 +92,58 @@ func (d *daemon) processOnce(_ context.Context) error {
// Process pirani ringbuffers.
d.piraniVolts3.process(v)
d.piraniMbar3.process(d.piraniVolts3.avg)
d.piraniVolts100.process(v)
d.piraniMbar100.process(d.piraniVolts100.avg)
d.pumpdown.process()
d.vent.process()
_, mbar := d.daemonState.pirani()
d.aboveRough.process(float64(mbar))
d.aboveHigh.process(float64(mbar))
// Check if the pirani gauge is disconnected. Note: this will assume the
// pirani gauge is connected for the first couple of processing runs as
// samples are still being captured.
if d.piraniDetection() == piraniDetectionDisconnected {
// Unrealistic result, Pirani probe probably disconnected. Failsafe mode.
if !d.safety.failsafe {
d.safety.failsafe = true
klog.Errorf("Pirani probe seems disconnected; enabling failsafe mode")
}
} else if d.piraniDetection() == piraniDetectionConnected {
if d.safety.failsafe {
if mbar >= 1e2 {
d.safety.failsafe = false
klog.Infof("Pirani probe value (%s) is plausible again; quitting failsafe mode", formatMbar(mbar))
// Run safety checks based on small ringbuffer.
if d.piraniVolts3.saturated() {
mbar := d.piraniMbar3.mbar
if !d.safety.failsafe && mbar < 4e-6 {
// Unrealistic result, Pirani probe probably disconnected. Failsafe mode.
if !d.safety.failsafe {
d.safety.failsafe = true
klog.Errorf("Pirani probe seems disconnected; enabling failsafe mode")
}
}
}
if d.safety.failsafe && mbar > 1e2 {
d.safety.failsafe = false
klog.Infof("Pirani probe value (%s) is plausible again; quitting failsafe mode", formatMbar(mbar))
}
if mbar >= 1e-1 {
if !d.safety.highPressure {
if !d.safety.highPressure && mbar >= 1e-1 {
d.safety.highPressure = true
klog.Warningf("Pressure is too high (%s mbar); enabling diffusion pump lockout", formatMbar(mbar))
}
} else if mbar < (1e-1)-(1e-2) {
if d.safety.highPressure {
if d.safety.highPressure && mbar < (1e-1)-(1e-2) {
d.safety.highPressure = false
klog.Infof("Pressure is low enough (%s mbar) for diffusion pump operation; quitting diffusion pump lockout", formatMbar(mbar))
}
} else {
d.safety.failsafe = true
d.safety.highPressure = true
}
// Control threhold/feedback values based on main pirani ringbuffer, failing
// safe if not enough data is present.
if d.piraniVolts100.saturated() {
mbar := d.piraniMbar100.mbar
d.aboveRough.process(float64(mbar))
d.aboveHigh.process(float64(mbar))
} else {
d.aboveRough.output = true
d.aboveHigh.output = true
}
// Apply safety overrides.
if d.safety.failsafe {
d.aboveRough.output = true
d.aboveHigh.output = true
d.dpOn = false
}
if d.safety.highPressure {
d.dpOn = false
}