Open leonardoayres opened 4 years ago
Hi @leonardoayres , I have been experiencing this lately. But only when I am not in the move. If I stop in a position for a while, I most often get a spike far away from where I am. But I am still trying to analyse the problem to understand what that might be.
Exactly. I'm considering start to use some kind of accelerometer monitoring to guarantee that i'm on the move before start to track the positions.
What's the platform? Android or iOS?
Android.
I haven't tested on iOS yet.
Same here, Android. Should be able to do a test on an IPad today.
What accuracy are you using? Navigation
is the must accurate parameter. If your are getting this behavior with Navigation
accuracy then there should be some problem. Please provide any information you can (Android version, device, logs, codes ....), so I can simulate the situation for further investigation;
I already tried with HIGH and LOW.
Now i completely removed the accuracy and the "spikes" occured less; but they still there.
I'll try to make a demo...but as i'm using google maps, who test it must provide ones key.
I am actually using only Navigation accuracy, because no other works for me. I think there is an issue open on that, but I can't find it. Up to now, the issues were found on Android 10 on Google Pixel 3a.
Here is an Android 10 with a Xiaomi Mi9T.
I am actually using only Navigation accuracy, because no other works for me. I think there is an issue open on that, but I can't find it.
Yes I'm aware of the issue you are referring to, and I Think that issue is related to this. I will try to find an Android 10 device and test on that. This might be a platform specific issue, because I don't have this problem on my Android 8 device.
Good to know @mehdok , I will try on an android 9 to see if that is different. I guess I will be able to better test in the weekend. Testing location services is always a mess :-)
Found an article that talks about "cleaning noise" of the GPS data. Looks like the scenario that we are facing.
@leonardoayres Really interesting, does this solve your problem?
I haven't applied yet. Have to take off the rust of my math skills and see if my code can be changed without more surprises |-]
There is another simple solution for getting rid of gps noise, just turn your phone in 8 shape several times, then open your app and let me know if it works. If this problem caused by gps noise this method will solve it;
I added some testresults to issue #76 in order to not pollute this issue to much.
Guys,
I've found an implementation of a Kalman filter and converted to Dart:
import 'dart:math' as Math;
// Original code by Paul Doust (https://stackoverflow.com/users/2110762/stochastically)
class KalmanLatLong {
final double _minAccuracy = 1;
double _qMetresPerSecond;
double _timeStampMilliseconds;
double _lat;
double _lng;
double _variance; // P matrix. Negative means object uninitialised. NB: units irrelevant, as long as same units used throughout
KalmanLatLong(double qMetresPerSecond) {
this._qMetresPerSecond = qMetresPerSecond;
this._variance = -1;
}
double get timeStamp {
return this._timeStampMilliseconds;
}
double get latitude {
return this._lat;
}
double get longitude {
return this._lng;
}
double get accuracy {
return Math.sqrt(this._variance);
}
void setState(double lat, double lng, double accuracy, double timeStampMilliseconds) {
this._lat = lat;
this._lng = lng;
this._variance = accuracy * accuracy;
this._timeStampMilliseconds = timeStampMilliseconds;
}
///
/// Kalman filter processing for lattitude and longitude.
///
/// latMeasurement: New measurement of lattidude.
///
/// lngMeasurement: New measurement of longitude.
///
/// accuracy: Measurement of 1 standard deviation error in metres.
///
/// timeStampMilliseconds: Time of measurement.
///
/// returns: new state.
///
void process(double latMeasurement, double lngMeasurement, double accuracy, double timeStampMilliseconds) {
if (accuracy < this._minAccuracy) accuracy = this._minAccuracy;
if (this._variance < 0) {
// if variance < 0, object is unitialised, so initialise with current values
this._timeStampMilliseconds = timeStampMilliseconds;
this._lat = latMeasurement;
this._lng = lngMeasurement;
this._variance = accuracy * accuracy;
} else {
// else apply Kalman filter methodology
double timeIncMilliseconds = timeStampMilliseconds - this._timeStampMilliseconds;
if (timeIncMilliseconds > 0) {
// time has moved on, so the uncertainty in the current position increases
this._variance += timeIncMilliseconds * this._qMetresPerSecond * this._qMetresPerSecond / 1000;
this._timeStampMilliseconds = timeStampMilliseconds;
// TO DO: USE VELOCITY INFORMATION HERE TO GET A BETTER ESTIMATE OF CURRENT POSITION
}
// Kalman gain matrix K = Covarariance * Inverse(Covariance + MeasurementVariance)
// NB: because K is dimensionless, it doesn't matter that variance has different units to lat and lng
double K = this._variance / (this._variance + accuracy * accuracy);
// apply K
this._lat += K * (latMeasurement - this._lat);
this._lng += K * (lngMeasurement - this._lng);
// new Covarariance matrix is (IdentityMatrix - K) * Covarariance
this._variance = (1 - K) * this._variance;
}
}
}
Usage:
import '<the file with the implementation above>';
...
// the parameter represents the distanteInterval em m/s. Some say that 3 is the sweet spot, i haven't tried yet.
KalmanLatLong filter = KalmanLatLong(2);
...
// on the code where you update your position, apply...
filter.process(position.latitude, position.longitude, position.accuracy, position.time);
<your method for position update>(filter.latitude, filter.longitude);
Hope it helps.
Hi @leonardoayres , from the link I can't find where the original implementation is. Could you link it please. If this works you might want to create a flutter package for this, it would be great to have accessible and upgradable once improved :-)
@moovida The original code is from this link: https://stackoverflow.com/questions/1134579/smooth-gps-data
I think if it is relevant for anything, it could be added to the current background_locator package. There is already to many packages for the same problem :-)
You might be right. I will try to apply it to a set of logs I have to see how well if makes things. And a dynamic parameter will be necessary, since the decay speed seems to be very depending on the different speed (i.e. car vs walking vs bike). If you do some test it would be great if you could share some tests. :-)
Hi @leonardoayres , did you try to use the Kalman filter? This morning I made a quick copy-paste to have a test, since I had to walk mountainside. The result is as if nothing happened:
Clearly it is identified that this is an Android 10 issue of this library, but it still should have done some smoothing.
Hi @moovida,
My need of background locator is for a software that i'm responsible for on my job. My experience with the background_locator in Foreground use (using wakelock package to keep the screen active) was terrible; too much track spikes. However, for background running, it was ok (go figure, right?).
So, i've made an hybrid: Location package for Foreground (active) tracking and Background_Locator for background (paused) tracking. I've implemented the aproach on the didChangeAppLifecycleState
to manage the App lifecycle.
The Kalman filter was applied for both listeners (Location and Background_Locator) and generates a smoothest path, far from perfect, but better.
Currently i'm testing an implemetation with flutter_background_geolocation (from Transistor Software) and so far, so good.
@leonardoayres Do you have any idea on what Q value range does the kalman filter work best in a scenario of a moving vehicle?
I'm thinking of using the accelerometer of the device for estimating an appropriate Q value, as the device might not always be in motion and vice versa.
I don't know is my problem same issue what written here but when I am watching my app, location is jumping all the time and there may be spikes which may be kilometers long no matter is my app in foreground or is it running in background. I am using latest version and accuracy is Navigation (in android). At the same time when checking route from Google Maps Timeline, route looks quite nice there.
Kalman filter might not solve the issue when the noise is too much. We have sometimes gotten noise where the position is ~ 1Km away from the actual position. But it would be better if its included in the plugin itself. It seems iOS does a lot of post-processing as well, that's why their graph is smoother
I don't know if somebody else is facing this:
I tryed to use the BackgroundLocator to replace the Location plugin because of the background tracking aspect , but when using it "live", in active state, sometimes the tracking move my Marker to an aleatory position (a good amount of feets away) and then back to my position.
I'm drawing polylines when using the plugin; guys, my path looks like a heartbeat graph, with zigs and zags instead a straight line.
Have somebody experienced something like this with this package?