通过iPhone SDK测量速度

时间:2010-01-03 04:47:36

标签: iphone objective-c core-location accelerometer

我需要实现原生iPhone应用来测量手机的速度(基本上是速度计)。我知道你可以很容易地通过CoreLocation API这样做,但我担心电池消耗,因为这是一个可以一次使用长达几个小时的实时测量。我的理解是,当您主动监控来自LocationManager的事件时(即使我实际上并不关心GPS位置),这是电池密集型的。

探索的另一个明显选择是使用加速度计来尝试计算速度,但API中没有任何内容可以帮助您这样做。根据我的研究,应该可以做到这一点,但看起来非常复杂且容易出错。从加速到速度的转换可能很难开始,加上iPhone加速度计数据可能会“嘈杂”。我熟悉使用低/高通滤波等的SDK示例 - 但我没有看到任何显示计算速度的好例子。

有没有人可以分享他们的实际经验?代码太棒了,但实际上我只是想知道是否有人成功完成了这项工作(对于一个长期存在的应用程序)以及他们采取了什么方法。

编辑:我有一个使用LocationManager API的工作原型。它工作正常,但更新周期远非理想的速度实时测量。根据具体情况,有时可能需要4-5秒才能更新。以给定速度巡航往往可以正常工作,但是从用户交互的角度来看,加速/减速往往会非常严重。另外,我需要将速度提供给我正在进行的其他一些计算,而精度并不是我真正需要的。

似乎有可能基于(很少)我见过的其他应用程序,特别是gMeter声称不使用GPS但准确计算速度。我真的很惊讶没有任何参考或任何示例代码可以在任何我能找到的地方展示这一点。我意识到这很复杂,但肯定会有一些东西。

5 个答案:

答案 0 :(得分:10)

从实际的角度来看,你不会从作用在加速度计上的力获得准确的速度。

使用GPS,每隔1分钟读取一次读数,并让GPS在两者之间睡眠。

以下是一个例子:

<强> SpeedViewController.h

CLLocationManager *locManager;
CLLocationSpeed speed;
NSTimer *timer;

@property (nonantomic,retain) NSTimer *timer;

<强> SpeedViewController.m

#define kRequiredAccuracy 500.0 //meters
#define kMaxAge 10.0 //seconds

- (void)startReadingLocation {
    [locManager startUpdatingLocation];
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {

    NSTimeInterval ageInSeconds = [newLocation.timestamp timeIntervalSinceNow];

    //ensure you have an accurate and non-cached reading
    if( newLocation.horizontalAccuracy > kRequiredAccuracy || fabs(ageInSeconds) > kMaxAge )
        return;

    //get current speed    
    currentSpeed = newLocation.speed;

    //this puts the GPS to sleep, saving power
    [locManager stopUpdatingLocation]; 

    //timer fires after 60 seconds, then stops
    self.timer = [NSTimer scheduledTimerWithTimeInterval:60.0 target:self selector:@selector(timeIntervalEnded:) userInfo:nil repeats:NO];
}

//this is a wrapper method to fit the required selector signature
- (void)timeIntervalEnded:(NSTimer*)timer {
    [self startReadingLocation];
}

答案 1 :(得分:10)

由于GPS和加速度计有不同的弱点,您最好的选择可能是组合方法 - 每分钟左右从GPS获取一次测量,然后从加速度计中添加实时变化。

答案 2 :(得分:4)

加速度误差会随着时间的推移而累积。您最好的选择是从GPS获得准确的速度,可能是每分钟一次或更少:

distanceTravelled = sqrt( (position2.x-position1.x)^2 + (position2.y-position1.y)^2 )
velocity = distanceTravelled/timeBetweenGPSReadings

(其中^2表示平方

然后频繁测量加速度计:

newVelocity = oldVelocity + accelerometer*timeBetweenAccelerometerReadings

答案 3 :(得分:3)

我不确定你是否会使用加速度计来追踪速度。要做到这一点,你必须确保你捕获了每个加速度,因为任何错过的数据点都会指示错误的速度(当然,假设你能够将报告的加速度计值转换为标准单位)。因此,你必须不断地运行加速度计的东西,这本身就吸收了相当多的果汁(而且,再一次,你不能保证所有的加速度)。我建议使用CoreLocation。

答案 4 :(得分:2)

虽然我不知道iPhone API,但我确实知道有关GPS和惯性导航的知识。它可能很有用。

我使用过的GPS接收器都可以直接测量接收到的GPS信号的速度。这些测量甚至比位置数据更准确。我不知道Apple API是否提供访问权限,或者即使Apple已将其接收器配置为提供此数据。这将是获得速度测量的更有效途径。

下一条路径,假设你有加速计数据和GPS数据,就像前面提到的其他海报和评论一样。使用GPS定期校正来自加速度计数据的累积的惯性测量值在实践中非常有效。它提供了更频繁的加速度计测量和GPS测量精度的好处。通常使用卡尔曼滤波器。但考虑到所选平台的准确性和时间限制,卡尔曼滤波器可能过度,实现和运行起来更简单。

无论如何,只需要考虑一些事情。