UNPKG

mind-ar

Version:

web augmented reality framework

71 lines (55 loc) 1.6 kB
// Ref: https://jaantollander.com/post/noise-filtering-using-one-euro-filter/#mjx-eqn%3A1 const smoothingFactor = (te, cutoff) => { const r = 2 * Math.PI * cutoff * te; return r / (r+1); } const exponentialSmoothing = (a, x, xPrev) => { return a * x + (1 - a) * xPrev; } class OneEuroFilter { constructor({minCutOff, beta}) { this.minCutOff = minCutOff; this.beta = beta; this.dCutOff = 0.001; // period in milliseconds, so default to 0.001 = 1Hz this.xPrev = null; this.dxPrev = null; this.tPrev = null; this.initialized = false; } reset() { this.initialized = false; } filter(t, x) { if (!this.initialized) { this.initialized = true; this.xPrev = x; this.dxPrev = x.map(() => 0); this.tPrev = t; return x; } const {xPrev, tPrev, dxPrev} = this; //console.log("filter", x, xPrev, x.map((xx, i) => x[i] - xPrev[i])); const te = t - tPrev; const ad = smoothingFactor(te, this.dCutOff); const dx = []; const dxHat = []; const xHat = []; for (let i = 0; i < x.length; i++) { // The filtered derivative of the signal. dx[i] = (x[i] - xPrev[i]) / te; dxHat[i] = exponentialSmoothing(ad, dx[i], dxPrev[i]); // The filtered signal const cutOff = this.minCutOff + this.beta * Math.abs(dxHat[i]); const a = smoothingFactor(te, cutOff); xHat[i] = exponentialSmoothing(a, x[i], xPrev[i]); } // update prev this.xPrev = xHat; this.dxPrev = dxHat; this.tPrev = t; return xHat; } } export { OneEuroFilter }