UNPKG

kalman-filter

Version:

Kalman filter (and Extended Kalman Filter) Multi-dimensional implementation in Javascript

89 lines (71 loc) 2.38 kB
const {diag} = require('simple-linalg'); /** *Creates a dynamic model, considering the null in order to make the predictions * @param {Array.<Number>} staticCovariance * @param {ObservationConfig} observation * @returns {DynamicConfig} */ const constantSpeedDynamic = function ({staticCovariance, avSpeed, center}, observation) { const observationDimension = observation.observedProjection[0].length; const dimension = 2 * observationDimension; if ((center) === undefined) { throw (new TypeError('Center must be defined')); } if (center.length !== observationDimension) { throw (new TypeError(`Center size should be ${observationDimension}`)); } if (avSpeed.length !== observationDimension) { throw (new TypeError(`avSpeed size should be ${observationDimension}`)); } const initCov = diag(center.map(c => c * c / 3).concat(avSpeed.map(c => c * c / 3))); const init = { mean: center.map(c => [c]).concat(center.map(() => [0])), covariance: initCov, index: -1, }; const transition = ({getTime, index, previousCorrected}) => { const dT = getTime(index) - getTime(previousCorrected.index); if (typeof (dT) !== 'number' || Number.isNaN(dT)) { throw (new TypeError(`dT (${dT}) should be a number`)); } // Example is : // [ // [1, 0, dT, 0], // [0, 1, 0, dT], // [0, 0, 1, 0], // [0, 0, 0, 1] // ]; // constant speed usual matrix // create identity matrix const mat = diag(center.map(() => 1).concat(center.map(() => 1))); // Then add dT for (let i = 0; i < observationDimension; i++) { mat[i][observationDimension + i] = dT; } if (Number.isNaN(mat[0][2])) { throw (new TypeError('nan mat')); } return mat; }; const covariance = ({index, previousCorrected, getTime}) => { const dT = getTime(index) - getTime(previousCorrected.index); if (typeof (dT) !== 'number') { throw (new TypeError(`dT (${dT}) should be a number`)); } // State is (x, y, vx, vy) const sqrt = Math.sqrt(dT); if (Number.isNaN(sqrt)) { console.log({lastPreviousIndex: previousCorrected.index, index}); console.log(dT, previousCorrected.index, index, getTime(index), getTime(previousCorrected.index)); throw (new Error('Sqrt(dT) is NaN')); } return diag(staticCovariance.map(v => v * sqrt)); }; return { init, dimension, transition, covariance, }; }; module.exports = constantSpeedDynamic;