Wrong speed and course from CLLocationManager when using kCLLocationAccuracyBestForNavigation - ios

Sometimes I get strange values for speed and course in didUpdateToLocation. This probably started when I changed the desiredAccuracy setting from kCLLocationAccuracyBest to kCLLocationAccuracyBestForNavigation. The course could drift up to 90 degrees. Another problem is that the speed sometimes is set to 0 if the device is perfectly still(even if the boat/car is moving). I don't know if the problems are related or not.
I can confirm this behavior on several devices both ipad2 and ipad3.
Has anyone experienced anything similar?
/Martin

I just tried an experiment with this, using a new iPhone with iOS 7.02. I could not replicate your issues. Specifically, I was using the delegate method didUpdateLocations,
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
since didUpdateToLocation has been deprecated since iOS6. I don't know that the locations array is any different than the newLocation returned in the deprecated method.
I tried it both walking and driving, and got good results. Yes, the course will bounce around, and is not as instantly accurate as the compass heading, but I didn't see it vary as much as 90 degrees while moving, nor did I see speed at zero.
If you have poor signal from GPS or even WiFi, or if you are moving then you can see that kind of behavior. Maybe this is not the sort of answer you were hoping for, but as it's been over a month, I thought I'd related my experience even though it does not confirm yours.
I could post a code snippet if that would be helpful.

Related

CLLocationManager desiredAccuracy of kCLLocationAccuracyHundredMeters causes location updates to be very infrequent

I am attempting to use location accuracy of kCLLocationAccuracyHundredMeters for my standard location updates in my application, which seem to work relatively well for a bit, but every once in a while I will receive a 10 minute gap between updates (while driving around multiple miles in different directions) which seems out of character for the setting. Here are the settings on my location manager. Also I am only using foreground location updates so for these tests I had the screen on the entire time and app always in foreground.
self.locManager = [[CLLocationManager alloc] init];
self.locManager.delegate = self;
self.locManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
self.locManager.distanceFilter = 15;
I tried out kCLLocationAccuracyBest with the same other settings and I get perfect measurements throughout my drive, but I don't need that accurate of a location. I assumed the hundred meter accuracy would still give relatively consistent updates with less accuracy, which is what we are looking for.
Is this just a side effect of working with the kCLLocationAccuracyHundredMeters setting vs kCLLocationAccuracyBest?
Tested on an iPhone 6s : 11.0.2 and iPhone 7Plus : 11.0.3
Any help is appreciated, thanks!
EDIT:
I should clarify I did setup logging in the CLLocationManager delegate methods listed below, but never received any callbacks / logs.
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error;
- (void)locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(nullable NSError *)error;
- (void)locationManagerDidPauseLocationUpdates:(CLLocationManager *)manager;
- (void)locationManagerDidResumeLocationUpdates:(CLLocationManager *)manager;
When you ask for kCLLocationAccuracyHundredMeters iPhone does not use GPS at all and relies on cell towers and wifi access points for triangulation. That means iPhone updates location with the frequency of wifi scans, which is far from continuous. If you are getting away from areas with wifi coverage, cell towers become your only source and you might start getting location updates only when switching between cell towers.
To cut it short:
setting accuracy tells iOS which hardware to use,
distance filter tells iOS how far to move before waking up CPU with new data

Use only GPS for iOS device location

I need to know if the GPS device component of my users is healthy, so i want to get the location ONLY by the GPS and NOT form wifi or surrounding antennas.
I'm forcing my users to close their wifi before this operation so i definitely know that the received signal is not from the wifi (because its possible).
I tried to work with the CLLocationManager and CLLocation's horizontalAccuracy.
some people say that when the horizontalAccuracy is lower than 160 it means we have a good GPS strength, but its not perfect at all..
I also tried to create an array of [CLLocation] after calling [locationManager startUpdatingLocation], and than i saw that when i'm in a place like a basement(with no GPS signal), my array's count was lower that a situation with signal because the updates frequency is lower.. but this is not a perfect solution either..
I just want to be sure that the GPS component is definitely working and the location that i get is from the GPS.
so, any solution please?

Filtering GPS jitter when standing still?

I am working on an iOS app with tracking. I have implemented Kalman smoothing in order to present a pleasing path. This is working pretty well at this point.
I am having a bit of trouble dealing with the user-not-moving case though. When the user IS moving we get very good reads back from the CLLocation Manager. And even when a reading is a bit off the Kalman algorithm takes care of it.
When standing still the CLLocation Manager delegate is still receiving "accurate" locations. They have good accuracy, not an unbelievable speed. Looking at the screen with human eyes it's clear that the user is standing still with all these points just scattered around. Some points very close and a few of them far out.
I have tried setting the CLLocationManager property pausesLocationUpdatesAutomatically but it doesn't seem to be working that well. It doesn't always stop when it should and there have been difficulty restarting the tracking again as the antennas are powered down.
So I'm looking to keep the tracking on the whole time but I want to filter out the jitter in post processing. So I determine programmatically that the user is stopped and discard (or ignore) all locations until the user is moving again.
I'm not really sure how to go about this, what algorithm is appropriate to achieve something like this?

CLRegion hidden buffer?

After coming across this question, I am concerned that there will not be an answer to the question, but I will hope, anyways.
I have setup a few geofences (most small and one large). I am using the simulator and I have outputted the radius of the large CLRegion and it tells me that the radius is 10881.98m around a certain coordinate, but when I simulate the geolocation to 11281.86m away from that same certain coordinate, it does not trigger the locationManager:didExitRegion: delegate method for the large region.
While the large region will not trigger locationManager:didExitRegion:, I have confirmed that the smaller regions will trigger the delegate method every time. Is there a reason why this is not firing? Is there a distance buffer around a region? Is it documented somewhere?
Any help would be great.
EDIT: From testing, I need to cut down the radius by around 45.28% in order to have the geofence trigger. Obviously this is not a great solution, as it is very imprecise and it goes against the whole idea of geofencing.
My guess is that this is an issue unique to the simulator. While CLRegion does not technically have a buffer or padding, the OS takes substantially longer to determine you have physically left the geofence area. On fences of that size, I would image it could take longer. On smaller regions, 100-200M, I've seen it take several minutes of driving, but easily 300-400M before triggering an event. From what the Apple Engineer told me at WWDC 2013, the OS takes its time in determining that you left. It is also harder for the system to determine you left because of its reliance on cell tower triangulation and known wifi networks. It needs to go well beyond the known networks before it can safely trigger the exit event.
I know it isn't an exact answer, but hopefully you'll understand a bit more how they work under the hood and what Apple's expectation of them is. Good luck.

why did didupdatelocation be called when device is not moved

i use CLLocation for a app that record people's trace in map view when they are running or walking ,but i found when my device is still (not moved) ,the
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations is also get called frequently ?
currently ,my locationmanager's desiredAccuracy is 10 meters and distanceFilter is 10.
how to deal with this situation? I have tried use big distancefilter value(like 150) ,but I found if i do this, then i can't record exactly when people is running or walking
GPS is not exact. You can move around a few feet and get the same location. Or you can sit still and get told you have moved a few feet.
You might be able to combine measurements from the accelerometer to determine if you have really moved but this would only work if the device was sitting on a table not moving.
Have you called stopUpdatingLocation after the initial startUpdatingLocation? It will keep updating location if you do not call it.
How does system know whether or not you have actually moved? It MUST fetch your location to find out. The more accurate your desired accuracy is, the more vigorously and frequently it would look. By vigorous I mean if it's suppose to use cell-tower information then it would look into more cell-towers to better triangulate. Or simply put it, the interval between its fetches would be smaller. Concluding: OS would fetch data even if you don't move.
Additionally to triangulate your position the OS (depending on your desiredAccuracy and previous movements) would use a mix of GPS, wifi, Cell-tower. And because someone may all of sudden turn off/on their wifi, or satellite that you were using to get your location has moved a bit or the satellites have changed, or a cell-tower signal may become more or less accurate due to its bandwidth limitations then your calculated location may change which triggers a callback if it's more than your distanceFilter. ( I don't believe you get callbacks for less than your distanceFilter, but I may be wrong) This likely means your distanceFilter is set to very small number which depending on your business requirements may or may not be a good choice. Concluding: your location is never ever 100% accurate
The result of periodical fetching, possibility of error and small distanceFilters lead to possible incorrect locationChanges.

Resources