I am working on an accident detection algorithm on a react native application. I am using following two factors for prediction:
- Acceleration using sensor (100ms intervals averaged over 1s for data storage constraints and noise cancellation)
- Speed using gps (1s interval)
The acceleration obtained from sensor however is filled with noise because when we do very simple things with our phone like picking it up or down, A lot of acceleration is recorded which needs to be filtered out.
I also want to know what optimal interval for each of the above sensors for my use case would be considering battery usage and accuracy.
I tried filtering the acceleration by first predicting the acceleration by first calculating the difference between final and initial speed and dividing by change in timestamp. Then, comparing this predicted acceleration with observed acceleration.
const filterAccelerationNoise = (acceleration, speed) => {
const ACCELERATION_THRESHOLD = 10;
//filter acceleration data to remove noise
let noiseIndex = [];
for (let i = 0; i < acceleration.length; i++) {
let ts = acceleration[i].timestamp;
let acc = acceleration[i].value;
//find the closest data point in speed array
// can apply tenary search here
let { closestIdx, closestTs, closestSpd } = { closestIdx: -1, closestTs: Number.MAX_SAFE_INTEGER, closestSpd: null };
for (let j = 0; j < speed.length; j++) {
let diff = Math.abs(speed[j].timestamp - ts);
if (diff < Math.abs(closestTs - ts)) {
closestIdx = j;
closestTs = speed[j].timestamp;
closestSpd = speed[j].value;
}
}
console.log(closestIdx, closestTs, closestSpd);
if (closestIdx === -1) {
noiseIndex.push(i);
continue;
}
if (!nearby(ts, closestTs)) {
closestSpd = 0;
}
let initialSpeed, finalSpeed, finalTs, initialTs;
if (ts > closestTs) {
initialSpeed = closestSpd;
if (closestIdx + 1 >= speed.length) {
finalSpeed = 0;
finalTs = ts;
} else {
finalSpeed = speed[closestIdx + 1].value;
if (!nearby(speed[closestIdx + 1].timestamp, ts)) {
finalSpeed = 0;
}
finalTs = speed[closestIdx + 1].timestamp;
}
initialTs = closestTs;
}
else {
finalSpeed = closestSpd;
if (closestIdx - 1 < 0) {
initialSpeed = 0;
initialTs = ts;
} else {
initialSpeed = speed[closestIdx - 1].value;
if (!nearby(speed[closestIdx - 1].timestamp, ts)) {
initialSpeed = 0;
}
initialTs = speed[closestIdx - 1].timestamp;
}
finalTs = closestTs;
}
//compare acceleration with estimated acceleration
let estimatedAcc = (finalSpeed - initialSpeed) / (finalTs - initialTs);
if (Math.abs(estimatedAcc - acc) < ACCELERATION_THRESHOLD) {
noiseIndex.push(i);
}
}
for (let i = noiseIndex.length - 1; i >= 0; i--) {
acceleration.splice(noiseIndex[i], 1);
}
};