通过iPhone SDK测量速度

12
我需要实现一个原生的iPhone应用程序来测量手机的速度(基本上是一个速度计)。我知道你可以通过CoreLocation API相当容易地实现,但我担心电池消耗,因为这是实时测量,可能会连续使用几个小时。我的理解是,虽然您正在积极监视LocationManager中的事件(即使我实际上并不关心GPS位置),但它会消耗电池。
另一个明显的选择是使用加速计尝试计算速度,但API中没有任何帮助您这样做的内容。根据我的研究,应该可以做到这一点,但似乎非常复杂和容易出错。从加速度到速度的转换本来就很棘手,再加上iPhone加速度计数据可能会产生“噪声”。我熟悉演示使用低/高通滤波等的SDK示例--但我还没有看到任何很好的示例显示如何计算速度。
有人有任何实际经验可以分享吗?代码将是很棒的,但我只想知道是否有人已成功完成此操作(对于长寿命的应用程序)以及他们采取的方法。
编辑:我有一个使用LocationManager API的工作原型。它运行良好,但更新周期远非测量速度的实时测量的理想选择。根据情况,有时需要花费4-5秒钟才能更新。以给定速度巡航往往可以正常工作,但加速/减速往往从用户交互的角度严重滞后。此外,我需要将速度输入到我正在进行的其他计算中,精度并不是我所需要的。

根据我看到的其他应用程序(非常少),例如gMeter,它声称不使用GPS但可以准确计算速度,这似乎是可能的。我真的很惊讶,我找不到任何参考资料或演示此功能的示例代码。我知道这很复杂,但肯定有一些东西存在。


嗨,我对你在这方面取得的任何成功都很感兴趣。我目前正在研究如何使用iPhone 4的加速度计/陀螺仪数据以及GPS数据,在GPS更新之间绘制惯性导航路线。 - Jerceratops
5个回答

10

就实际情况而言,从作用于加速度计的力中得到准确的速度是不可能的。

使用每1分钟进行读数的GPS,并在其间使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];
}

谢谢提供示例。实际上,对于我来说,这必须是近乎实时的测量。如果以每秒或每两秒更新间隔进行操作,我仍然担心功耗问题。您是否在真实世界的应用程序中完成过此操作? - Brian Moeskau
我没有真实世界的证据来证明这确实可以节省电力。理论上,每次读取后关闭几秒钟的GPS应该会显著减少功耗。 - bentford
  • (void)locationManager 中缺少“{”。
- Malte Onken
1
我看到的问题是关闭收音机意味着在它唤醒后约十秒钟内会得到相当不准确的结果,进一步加剧了这个问题。获取卫星所使用的额外电力可能很容易超过关闭40秒左右所节省的任何电力。 - Kendall Helmstetter Gelner

10

由于GPS和加速度计各自具有不同的缺点,您最好采用综合方法-每隔一分钟从GPS获取一次测量值,然后添加来自加速度计的实时变化。


是的,基于我读过的有关仅在长距离上使用加速度会导致误差累积的内容,这就是我一直在考虑的方法。但是我仍然在努力将加速度正确转换为速度。 - Brian Moeskau

4

加速度误差会随着时间的推移而累积。最好的方法是从GPS中获取准确的速度,可能每分钟或更短一次:

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

(其中^2表示平方)

然后频繁地对加速度计进行测量:

newVelocity = oldVelocity + accelerometer*timeBetweenAccelerometerReadings

3

我不确定您是否可以使用加速度计追踪速度。要做到这一点,您必须确保捕获每个加速度,因为任何遗漏的数据点都会导致错误的速度(假设当然,您能够将报告的加速度计值转换为标准单位)。因此,您必须不断运行加速度计,这本身就会消耗大量的电力(而且,再次强调,您无法保证所有加速度)。我建议使用CoreLocation。


听起来像我读过的加速度->速度,尽管我的印象是iPhone使用的内部天线来处理卫星/蜂窝信号比加速计消耗更多的能量(它们几乎总是开着的吧?) - Brian Moeskau

2

虽然我不了解iPhone API,但我对GPS和惯性导航有一定了解。这可能会很有用。

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

下一个路径是,鉴于您拥有加速度计数据和GPS数据,可以像其他帖子和评论中提到的那样将它们结合起来。在实践中,使用GPS定期校正加速度计数据累积的惯性测量非常有效。它提供了更频繁的加速度计测量和GPS测量的准确性。通常使用卡尔曼滤波器。但考虑到您选择平台的准确性和时间限制,卡尔曼滤波器可能过于复杂,实现和运行简单的方法也应该能够正常工作。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接