我正在尝试为CLbeacons建立一个地理围栏,它是这样的: a>任何其精度<= 2.5米距离应该被检测到的信标。
现在,当我将信标放置在相距约7米的地方时,两个信标都会被检测到。更令人震惊的是,有时信标的精度会达到15.70米(通过运行Airlocate应用程序进行检查),这是随机发生的,从而使地理围栏无法构建。
我尝试应用自定义公式来计算double ratio = rssi*1.0/txPower;中的信标距离double accuracy = (0.89976) * pow(ratio,7.7095) + 0.111;,但由于没有提供CLbeacons的txPower,因此该函数依赖于我提供的静态值txPower。
那么,谁能指导一下这些CLBeacons的地理围栏应该如何构建?
发布于 2014-08-11 23:34:10
您是正确的,因为信标的精确值可能在短时间内急剧波动。我处理这个问题的方法(我们有类似的需求来确定设备何时返回基址)是两种方法的组合:首先,我们调整iBeacons的电源以降低它们,这样didDetermineState: delegate调用就不会因为进入和离开信标的范围而被多次调用。其次,我的iBeacon模型跟踪范围内任何信标的精度,并将它们平均。这样,有人走在设备和信标之间,或者用户以特定的方式转动设备,就不会导致精确值的巨大波动,从而扰乱您的逻辑。
我不相信苹果有意让开发者使用iBeacons作为室内地理定位。它的地理隔离方面是简单地调整发射功率,以便当您的设备可以检测到信号或无法检测到信号时,您可以得到通知。精度是可以使用的,但它太不准确了,所以应该谨慎使用。
有一个开发人员声称已经开发了一种使用iBeacons进行室内定位的算法,但我没有使用它的经验。此外,如果它可以达到任何水平的准确性,我认为苹果将使用它的室内定位功能,但他们不是。
下面是我使用的一些代码:
下面是我的自定义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 https://stackoverflow.com/questions/25244458
复制相似问题