Skip to content

Commit

Permalink
Create Hysteresis utility class
Browse files Browse the repository at this point in the history
Provides a simple rolling average hysteresis.
  • Loading branch information
Gigabyte5671 committed Sep 4, 2023
1 parent 5e21011 commit 473deda
Showing 1 changed file with 51 additions and 0 deletions.
51 changes: 51 additions & 0 deletions src/modules/utility/hysteresis.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* The default number of points to sample from.
*/
const defaultLength = 10;

/**
* A rolling average hysteresis.
* @param getter A function to retrieve new values.
* @param length `(Optional)` The number of points to sample the rolling average from.
* @param threshold `(Optional)` The snapping threshold. New values with a delta greater than this threshold will cause the output to snap to said new value.
*/
export class Hysteresis {
private getter;
private history;
private length;
private threshold;

constructor(getter: () => number, length = defaultLength, threshold?: number) {
this.getter = getter;
this.history = new Array<number>();
this.length = length;
this.threshold = threshold;

const value = getter();
for (let i = 0; i < this.length; i++) {
this.history.push(value);
}
}

/**
* @returns The value from the getter with hysteresis smoothing applied.
*/
public get(): number {
const value = this.getter();
this.history.shift();
this.history.push(value);
const average = this.history.reduce((a, b) => a + b) / this.length;
if (typeof this.threshold === "number" && Math.abs(value - this.history[this.history.length - 2]) > this.threshold) {
this.history = this.history.fill(value);
return value;
}
return average;
}

/**
* @returns The value from the getter **without** hysteresis smoothing applied.
*/
public getInstant(): number {
return this.getter();
}
}

0 comments on commit 473deda

Please sign in to comment.