function* eventGenerator() {
let normalizedRate = 0;
let events = 0;
const pid = new PID(normalizedRate, setpoint, Kp, Ki, Kd, "reverse");
pid.setMode("auto");
let lastEventMs = Date.now();
let lastTime = Date.now();
let output = 0;
while (true) {
const zeroes = Math.floor(Math.random() * maxRandomZeroes);
pid.setInput((normalizedRate * 1000) / windowSizeMs);
do {} while (!pid.compute());
output = pid.getOutput();
const currentMs = Date.now();
if (currentMs - lastTime >= timeBetweenEvents) {
lastTime = currentMs;
const period = currentMs - lastEventMs;
lastEventMs = currentMs;
const normalizedFreq = windowSizeMs / period;
const alpha = Math.min(1, 1 / normalizedFreq);
if (zeroes >= output) {
normalizedRate = alpha * normalizedFreq + (1 - alpha) * normalizedRate;
events++;
} else {
normalizedRate = (1 - alpha) * normalizedRate;
}
}
yield {
rate: (normalizedRate * 1000) / windowSizeMs,
minPow: Math.floor(output),
events,
zeroes
};
}
}