my application is based on GPS data and for that I'm using Fused-location-provider
.
From now and then I have seen that there's a gps jitters and some GPS coordinates are off the road. This is unacceptable. What I tried to do was to implement Kalman filter
and I did:
fun process(
newSpeed: Float,
newLatitude: Double,
newLongitude: Double,
newTimeStamp: Long,
newAccuracy: Float
) {
if (variance < 0) { // if variance < 0, object is unitialised, so initialise with current values
setState(newLatitude, newLongitude, newTimeStamp, newAccuracy)
} else { // else apply Kalman filter
val duration = newTimeStamp - timeStamp
if (duration > 0) { // time has moved on, so the uncertainty in the current position increases
variance += duration * newSpeed * newSpeed / 1000
timeStamp = newTimeStamp
}
val k = variance / (variance + newAccuracy * newAccuracy)
latitude += k * (newLatitude - latitude)
longitude += k * (newLongitude - longitude)
variance *= (1 - k)
retrieveLocation(newSpeed, longitude, latitude, duration, newAccuracy)
}
}
And I'm using it whenever I receive new location as
KalmanFilter.process(
it.newSpeed,
it.newLatitude,
it.newLongitude,
it.newTimeStamp,
it.newAccuracy
)
This helped to receive little bit more accurate results, but still - it did not fix the GPS jitter that was outside the road (see image):
Things I want to know:
- Is my kalman filter implemented correctly? Is there way to improve current solution?
- How to avoid a scenerios where coordinate is outside the road? (Something similar to snap-to-roads functionality, but as an algorithm inside app)