我正在使用罗盘标题来旋转MKMapView。旋转有点生涩,所以我试图像iPhone上的谷歌地图那样过滤它(或者似乎做了一些诡计)。
我正在尝试使用移动平均公式来过滤iphone指南针的读数,但它在359和0之间的交叉处失败,因为它从35x开始向后平均到0并导致地图在接近时向后旋转从西边向北。
任何想法最好的方法是过滤这些数据,使其从359回到零,并维持滚动平均值。
代码在这里:
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {
static float xd=0;
static float k = 0.22;
// Moving average formula
xd = k * xd + (1.0 - k) * newHeading.magneticHeading;
NSLog(@"%0.2f : %0.2f", newHeading.magneticHeading, xd);
[map setTransform:CGAffineTransformMakeRotation((-1 * xd * M_PI) /180)];}
感谢您的帮助
答案 0 :(得分:4)
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)heading
{
int newHeading;
int queuecount;
newHeading = heading.trueHeading;
[queue addObject:[NSNumber numberWithInt:newHeading]];
if([queue count] > 10) [queue removeObjectAtIndex:0];
queuecount = [queue count];
NSEnumerator *e = [queue objectEnumerator];
NSNumber *sum;
int oldd = 0 , newd, average =0;
BOOL firstLoop = YES;
while ((sum = [e nextObject]))
{
newd = [sum intValue];
if(firstLoop) {oldd = newd;firstLoop=NO;}
if((newd +180) < oldd)
{
newd +=360; oldd = newd;
average = average + newd;
continue;
}
if((newd - 180) > oldd)
{
newd -=360;oldd = newd;
average = average + newd;
continue;
}
average = average + newd;
oldd = newd;
}
average = (average / queuecount) % 360;
[map setTransform:CGAffineTransformMakeRotation((-1 * average * M_PI) /180)];
}
答案 1 :(得分:2)
如果之前的移动平均线和新标题的差异超过180度,则将360添加到较小的值。然后在存储新移动平均线时由360修改。所以(没有精确的数学):
HDG MA
350 350
355 353
0 356 (because 353 - 0 > 180 so adjusted HDG is 360)
5 359 (likewise)
10 2 (likewise, then 362 is new MA, mod 360 to normalize)
350 356 (because 2 - 350 < -180 so adjusted MA is 362)
我希望这是有效的,并且比Averaging angles中描述的三角方法更有效(感谢Mark Ransom提到它)。
答案 2 :(得分:0)
我只想添加我的d0n发布的代码版本,并进行一些调整。
我的代码是Arduino的C代码所以我没有使用库(例如我得到没有abs函数的绝对值)...
这个帖子对我很有帮助。谢谢D0n和John ......
int Robot::getHeadingAverage() {
// setup
int lastReading = 0;
int newReading = 0;
int totalHeadings = 0;
int avgHeading = 0;
// loop through all the readings
for(int i=0; i<totalHeadingReadings; i++) {
// get the reading
newReading = headings[i];
// make sure we have an old reading
if(i==0) {
lastReading = newReading;
}
if((newReading + 180) < lastReading) {
newReading = newReading + 360;
}
if((newReading - 180) > lastReading) {
newReading = newReading - 360;
}
lastReading = newReading;
totalHeadings = totalHeadings + newReading;
}
// get the average and make sure we do not end up over 360
avgHeading = (totalHeadings / totalHeadingReadings) % 360;
// check for negative value
if(avgHeading < 0) {
avgHeading = -1 * avgHeading;
}
return avgHeading;
}
答案 3 :(得分:0)
最后,这对我有用。
libname out 'C:\users\den\Desktop\' ;
proc copy inlib=work outlib=out ;
select export_project;
run;