didEnterRegion called with larger radius (iOS) - ios

I want didEnterRegion to be called with much precision, but I wasn't able to do so. Here is what I have done: I used the best values of distanceFilter and desiredAccuracy (most precise GPS settings according to Apple) and have a destination CLCircularRegion (Subclass of CLRegion).
self.locationManager.distanceFilter = kCLLocationAccuracyBestForNavigation;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
#property (nonatomic, strong) CLCircularRegion *Destination;
self.Destination = [[CLCircularRegion alloc] initWithCenter:CLLocationCoordinate2DMake(43.907691, -69.963158) radius:5 identifier:#"Destination"];
[self.locationManager startMonitoringForRegion:self.Destination];
The problem is when I am like 150m away from this destination, didEnterRegion gets called. Also around similar distance away didExitRegion gets called. I want didEnter and didExit region to be called when I am 5 m away, not 150m away, as I have specified with initiation of CLCircularRegion. Does anyone have a solution? Precision is what I need, and 150m instead of 5m is too inaccurate for me. Thanks ton -
(I used iPhone 4S to Test)

While in theory accuracies of 5m are possible with the current GPS+ technical gear, it may be that Apple prevents such accuracy for region monitoring for various reasons.
One is that they always want a good user experience and the 5m accuracy you want is within the accuracy range you will often get from the GPS readings. Thus leaving such a small region could also be on account of lower accuracy readings while the user is still within the region. Apple does cover up for such errors by setting thresholds for posting regionEnter or regionExit notifications. From Apple documentation:
When testing your region monitoring code in iOS Simulator or on a device, realize that region events may not happen immediately after a region boundary is crossed. To prevent spurious notifications, iOS doesn’t deliver region notifications until certain threshold conditions are met. Specifically, the user’s location must cross the region boundary, move away from the boundary by a minimum distance, and remain at that minimum distance for at least 20 seconds before the notifications are reported.
The specific threshold distances are determined by the hardware and the location technologies that are currently available. For example, if Wi-Fi is disabled, region monitoring is significantly less accurate. However, for testing purposes, you can assume that the minimum distance is approximately 200 meters
Nevertheless since you can ask for high accuracy readings Apple should also take that into account. The alternative might be - as you commented - to use didUpdateLocation: and determine if inside or outside the region. That way you could include a test for location accuracy and only accept an exit/entry when horizontal accuracy is good enough.

Related

How to achieve a more accurate distance from device to Beacon?

I am sorry if this has been asked in one way shape or another. I have started working with beacons, and in Xcode (Swift) - using CoreLocation. I really need a more accurate determination between the device and a beacon though. So far I have been using the standard proximity region values (Far, Near, and Immediate), however this just isn't cutting it at all. It seems far too unstable for the solution I am looking for - which is a simple one at best.
My scenario;
I need to display notifications, adverts, images etc to the users device when they are approximately 4 meters away from the beacon. This sounds simple enough, but when I found out that the only real solutions there are for beacons are those aforementioned proximity regions, I started to get worried because I need to only display to devices that are 3-5 meters away, no more.
I am aware of the accuracy property of the CLBeacon class, however Apple state it should not be used for accurate positioning of beacons, which I believe is what I am trying to achieve.
Is there a solution to this? Any help is appreciated!
Thanks,
Olly
There are limitations of physics when it comes to estimating distance with Bluetooth radio signals. Radio noise, signal reflections, and obstructions all affect the ability to estimate distance based on radio signal strength. It's OK to use beacons for estimating distance, but you must set your expectations appropriately.
Apple's algorithms in CoreLocation take a running average of the measured signal strength over 20 seconds or so, then come up with a distance estimate in meters that is put into the CLBeacon accuracy field. The results of this field are then used to come up with the proximity field. (0.5 meters or less means immediate, 0.5-3 meters means near, etc.)
When Apple recommends against using the accuracy field, it is simply trying to protect you against unrealistic expectations. This will never be an exact estimate in meters. Best results will come with a phone out of a pocket, with no obstructions between the beacon and the phone, and the phone relatively stationary. Under best conditions, you might expect to get distance estimates of +/- 1 meter at close distances of 3 meters or less. The further you get away, the more variation you will see.
You have to decide if this is good enough for your use case. If you can control the beacons there are a few things you can do to make the results as good as possible:
Turn the beacon transmitter power setting up as high as possible. This gives you a higher signal to noise ratio, hence better distance estimates.
Turn the advertising rate up as high as possible. This gives you more statistical samples, hence better distance estimates.
Place your beacons in locations where there will be as few obstructions as possible.
Always calibrate your beacon after making the changes like above. Calibration involves measuring the signal level at 1 meter and storing this as a calibration constant inside the beacon. Consult your beacon manufacturer instructions for details of how to do this calibration.

Exact coordinates from ios app

I'm creating a tracking application and ios application is the front end to gather the coordinates. Issue is my ios application is not giving the exact path followed. Im using this code to gather coordinates
locationMgr.desiredAccuracy = kCLLocationAccuracyBestForNavigation
locationMgr.delegate = self
//locationMgr.allowDeferredLocationUpdatesUntilTraveled(1.0, timeout:100)
locationMgr.requestWhenInUseAuthorization()
locationMgr.pausesLocationUpdatesAutomatically=false
locationMgr.distanceFilter=1
locationMgr.startUpdatingLocation()
I'm using coordinates gathered upto 8th decimal point such as 34.98776555
but Out put is not straight one that I followed. Please help
GPS Positioning typically has an accuracy of 1-5 meters. There are additional factors that can reduce the accuracy further.
As per the excerpt from the following website : How Accurate is the GPS on my Smart Phone?
For any GPS to work the antennae needs a clear view of the sky. Users of smart phones will frequently be in “urban canyons” or indoors. This is where WiFi and cellular network positioning become necessary. Both of these methods are used by smart phones as indoor positioning systems. The phone will use a hybrid approach, using all three methods to locate you. These other two technologies aren’t nearly as accurate as A-GPS, but can still locate you sufficiently to find the closest vanilla latte!
Generally WiFi positioning is more accurate than cellular network
positioning. It uses wireless access points and measures the
intensity of the received signal from one or more networks to find the
position. Interestingly it doesn’t require your device to be WiFi
enabled to work.
Cellular network positioning triangulates your position based off of
nearby cell phone towers. Phone companies have precise locations for
their cell towers, which when combined with signal strength can be
used to approximate your location. Both of these techniques are
dependent on overlapping signals from either access points and
cellular towers. Therefore they’re more accurate in urban settings.
CLLocationManger has an attribute called horizontalAccuracy which you can use to ignore points if they aren't accurate enough as per your requirements.
public func locationManager(manager: CLLocationManager, didUpdateToLocation newLocation: CLLocation, fromLocation oldLocation: CLLocation){
print(newLocation.coordinate.latitude)
print(newLocation.coordinate.longitude)
print(newLocation.horizontalAccuracy)
}
A GPS point which is off by just 1-2 meters will cause that point to get plotted off the road. From my experience getting pinpoint accuracy will be difficult and there is nothing that can be done about it.

Estimating distance to iBeacon on iOS

I'm trying to estimate the distance from an iOS device to an iBeacon. I am aware that distance estimation is not super accurate, and I am also aware of this formula:
https://electronics.stackexchange.com/questions/83354/calculate-distance-from-rssi
I have found, through some research, that an iBeacon's BLE advertisement in fact contains data that represents the calibration value. That is to say, the RSSI determined at 1 meter away is actually broadcast by the beacon for all to see.
Now, I think the iOS must internally use this information to determine the Near, Far, Immediate, and Unknown categorizations of distance but I am not aware of any way to access this 1-meter RSSI directly.
My question is simply: Is there a way to get the distance estimate between an iOS device and a beacon WITHOUT having the 1-meter calibration value saved on the iOS device beforehand?
Some people say that the 'accuracy' field of the CLBeacon class is, in fact, the distance measurement to the beacon. The documentation does not support this statement, here's what it says:
accuracy The accuracy of the proximity value, measured in meters from
the beacon. (read-only)
#property (readonly, nonatomic) CLLocationAccuracy accuracy;
Discussion Indicates the one sigma horizontal accuracy in meters. Use
this property to differentiate between beacons with the same proximity
value. Do not use it to identify a precise location for the beacon.
Accuracy values may fluctuate due to RF interference.
A negative value in this property signifies that the actual accuracy
could not be determined.
There is a new iBeacon Document released by Apple on June 2, 2014 that states:
When building an application that uses either GPS or
beacon, it is important to consider this accuracy. The values
reported by the Core Location objects (the
horizontalAccuracy property in the CLLocation class, or
the accuracy property in the CLBeacon class) indicate this
level of uncertainty, or the margin of error. Both are
measured in meters. The higher the value, the lower the
certainty of the position of the device or beacon. Keep in
mind that depending on the physical surroundings a low
accuracy may not be possible.
I suspect that's Apple's 'confidence' metric when reading their CLProximity values. I interpret that as obtaining something like:
CLProximityNear with an accuracy value of 5; Apple pinpoints your position within a 5m margin of error.
The general sentiment I'm getting from my general analysis of sources is that using beacon technology for distance approximation is probably not the strength of the technology.
EDIT: Chaise Hocking from Shine Technologies in Melbourne has an insightful blog post that has some experiments and results regarding the accuracy property.
Is there a way to get the distance estimate between an iOS device and a beacon WITHOUT having the 1-meter calibration value saved on the iOS device beforehand?
YES, you simply read the CLBeacon accuracy field as you suspected. This is an estimate of the distance to the beacon in meters.
This estimate uses an undocumented calculation that is based on the RSSI measurements (likely a 30 second running average, perhaps discarding outliers) combined with the 1-meter RSSI calibration value embedded in the iBeacon advertisement. A port of this calculation to Android is shown here.
And, no, there is no way to read the calibration value from an app. It is obscured by iOS, which disallows seeing the details of iBeacon Bluetooth LE advertisements. See here for a detailed explanation.

Beacon Proximity: Is this still a issue from Apple API reference.

We are having a issue with iBeacons.
App makes wrong guess sometimes as to which proximity region its in before eventually correcting itself. It sometimes shows Far when the Proximity is Near. And then later it flips back to Near.
The problem actually occurs when we need to fire an event when we are in the Near/Far/Immediate region. This doest happen in that way. App is likely to lose range of beacons for brief instances.
Are there any other way to solve this Issue.
It is normal for the Proximity estimate to fluctuate with radio noise, but your experience sounds extreme. What iBeacon brand are you using?
Make sure you are using an iBeacon with as fast enough transmission rate. Different iBeacons transmit advertisements at different frequencies from 30 times per second to once per second or less. Generally, faster transmission rates give you less noisy distance estimates because they give iOS more radio signal strength measurements to work with.
If an iBeacon transmits less than once per sec, you may get intermittent exit/entry events.
For your testing, Try an iOS-based iBeacon like Locate for iBeacon or EZBeacon to see if it helps. It is known to transmit 30x per second.
The proximity issue can be effected by advertising frequency as David has already said. The reason for this is that iOS takes an average of the RSSI readings overtime and uses these to find a final value, if you hold an iOS device in an ideal location, (i.e. clear line of site to the beacon) the result settles down over a few seconds of holding the device still. Apple describes the averaging as: "This value is the average RSSI value of the samples received since the range of the beacon was last reported to your app."
However a bigger factor can be fluctuations in the environment, the RSSI will change dramatically if an obstruction appears between the iBeacon and the iOS device, if the iBeacon and iOS device are both at a low level, this could be a person walking past. I have published some initial results using Estimote iBeacons that show changes in distance based on the device operator rotating 360 degrees. A distance change of +/- 2m is not an uncommon change in this circumstance and could result in the behaviour you observed if the iOS device is near the proximity region boundary.
This is Wojtek Borowicz, I'm a community evangelist at Estimote.
Calculating the exact proximity of a Beacon is based solely on the radio waves it’s broadcasting an is really hard. You encounter factors like multipath propagation, wave diffraction, absorption or interference. That’s exactly why iBeacon standard does not try to calculate the exact distance between a Beacon and the receiving device. Instead, it uses a value called RSSI (received signal strength indicator), which allows to estimate the proximity based on signal power. For calibration purposes, there’s also included a metric called Measured Power - but it’s nothing more than just RSSI measured 1 meter away from the Beacon. Even calibrated, RSSI might fluctuate heavily, due to the factors mentioned above.
The stability of the Beacon’s signal is also based on two main factors. One of them is advertising interval (frequency - the lower, the better signal) and broadcasting power (the higher the better signal). Improving them will allow for much better proximity reading, but will also strongly affect battery life.

What is CoreLocation's Region Monitoring system defined cushion?

I'm using the simulator to test region monitoring. Using CoreLocation with region monitoring and the Freeway Drive test location path in the Simulator (Debug > Location > Freeway Drive) I'm able to simulate, at least visually the path of the Freeway Drive as it intersects with various overlays. Those overlays are converted to regions and monitored as soon as I start monitoring the user's location. Anyway, this doesn't seem to work very well. The regions represented by my overlays don't cause didEnter/didExit events when you "think" they would. The regions seem to be much wider in size than the distances I specified. I'm guess this is because of the cushion the system applies.
Apple's Region Monitoring documentation states that:
The system does not report boundary crossings until the boundary plus a system-defined cushion distance is exceeded. This cushion value prevents the system from generating numerous entered and exited events in quick succession while the user is traveling close the edge of the boundary.
The docs don't seem to state what this cushion is, exactly. Nor how it is calculated. Does anyone know what the system defined cushion is?
I think it's 200m. At the bottom of the Region Monitoring documentation there's a paragraph that loosely explains how to test:
When testing your region monitoring code in iOS Simulator or on a device, realize that region events may not happen immediately after a region boundary is crossed. To prevent spurious notifications, iOS does not deliver region notifications until certain threshold conditions are met. Specifically, the user’s location must cross the region boundary and move away from that boundary by a minimum distance and remain at that minimum distance for at least 20 seconds before the notifications are reported.
The specific threshold distances are determined by the hardware and the location technologies that are currently available. For example, if Wi-Fi is disabled, region monitoring is significantly less accurate. However, for testing purposes, you can assume that the minimum distance is approximately 200 meters.

Resources