我正在尝试为CLbeacons建立地理围栏,如下所示: 一个&GT;任何能够检测到精度<= 2.5米距离的信标。
现在,当我将信标放置在大约7米的距离时,两者都会被检测到。更令人震惊的是,信标的准确度有时会达到15.70米(通过运行Airlocate应用程序检查),这种情况随机发生,从而无法构建地理围栏。
我尝试应用自定义公式计算信标距离double accuracy = (0.89976) * pow(ratio,7.7095) + 0.111;
double ratio = rssi*1.0/txPower;
,但由于未提供CLbeacons的txPower,因此该函数依赖于我提供静态值为txPower。
任何人都可以指导如何构建这些CLBeacons的地理围栏吗?
答案 0 :(得分:0)
你是正确的,因为信标的准确度值可以在短时间内大幅波动。我处理这个问题的方式(我们有类似的需要确定何时将设备返回到基本位置)是两种方法的组合:首先,我们调整iBeacons的功能以降低它们以便执行didDetermineState:委托调用进入和离开信标的范围不会被多次调用。其次,我的iBeacon模型跟踪范围内任何信标的准确性并将其平均化。这样,有人走在设备和信标之间,或者用户以特定的方式转动设备,不会导致精度值的巨大波动,从而弄乱你的逻辑。
我不相信Apple希望开发人员将iBeacons用作室内地理位置。它的地理围栏方面是简单地调整发射功率,以便您可以获得设备何时可以检测到信号的通知。可以使用准确度,但它是如此不准确,应谨慎使用。
有一位开发人员声称开发了一种使用iBeacons进行室内定位的算法,但我没有使用它。此外,如果可以达到任何精度水平,我觉得Apple会将它用于室内定位功能,但事实并非如此。
以下是我使用的一些代码:
这是我的自定义MyBeacon类:
@interface MyBeacon()
@property NSMutableDictionary *accuracyHistory;
@end
@implementation MyBeacon
- (id) init
{
self = [super init];
if (self!=nil) {
self.accuracyHistory = [[NSMutableDictionary alloc] init];
}
return self;
}
- (void) addAccuracyValue:(CGFloat)rangeValue forDate:(NSDate *)rangeDateTime
{
[self removeOldRangeHistoryItems];
[self.accuracyHistory setObject:[NSNumber numberWithFloat:rangeValue] forKey:rangeDateTime];
}
- (double) getBeaconAverageAccuracy
{
[self removeOldRangeHistoryItems];
if( self.accuracyHistory.count == 0 )
{
return -1;
}
CGFloat sumRangeVals = 0.0;
int numRangeVals = 0;
for(NSDate *accuracyDateTime in self.accuracyHistory) {
NSNumber *curValue = [self.accuracyHistory objectForKey:accuracyDateTime];
if( [curValue floatValue] >= 0.0 )
{
sumRangeVals += [curValue floatValue];
numRangeVals++;
}
else // let's toy with giving unknown readings a value of 30.
{
sumRangeVals += 30;
numRangeVals++;
}
}
CGFloat averageRangeVal = sumRangeVals / numRangeVals;
return averageRangeVal;
}
- (void) removeOldRangeHistoryItems
{
NSMutableArray *keysToDelete = [[NSMutableArray alloc] init];
for(NSDate *accuracyDateTime in self.accuracyHistory) {
// remove anything older than 10 seconds.
if( [accuracyDateTime timeIntervalSinceNow] < -10.0 )
{
[keysToDelete addObject:accuracyDateTime];
}
}
for( NSDate *key in keysToDelete )
{
[self.accuracyHistory removeObjectForKey:key];
}
}
@end