-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Provides a simple rolling average hysteresis.
- Loading branch information
1 parent
5e21011
commit 473deda
Showing
1 changed file
with
51 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} | ||
} |