12

我需要实现一个原生 iPhone 应用程序来测量手机的速度(基本上是一个速度计)。我知道你可以很容易地通过 CoreLocation API 做到这一点,但我担心电池消耗,因为这是一个实时测量,一次最多可以使用几个小时。我的理解是,虽然您正在积极监视来自 LocationManager 的事件(即使我实际上并不关心 GPS 位置),但它是电池密集型的。

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

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

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

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

4

5 回答 5

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];
}
于 2010-01-03T05:11:29.570 回答
10

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

于 2010-01-13T03:04:09.727 回答
4

The error in the acceleration will accumulate over time. Your best bet is to get an accurate velocity from the GPS, maybe once a minute or less:

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

(where ^2 means squared)

Then take frequent measurements of the accelerometer:

newVelocity = oldVelocity + accelerometer*timeBetweenAccelerometerReadings
于 2010-01-13T21:31:09.130 回答
3

我不确定您是否会尝试使用加速度计跟踪速度。为此,您必须确保捕获了每个加速度,因为任何丢失的数据点都会指示错误的速度(当然,这是假设您能够将报告的加速度计值转换为标准单位)。因此,你必须不断地运行加速度计的东西,它本身就吸了很多汁液(同样,你不能保证所有的加速度)。我建议使用 CoreLocation。

于 2010-01-03T05:10:35.890 回答
2

虽然我不知道 iPhone API,但我对 GPS 和惯性导航有所了解。它可能有用。

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

下一条路径,假设你有加速度计数据和 GPS 数据,就像前面其他海报和评论中提到的那样将它们结合起来。在实践中,使用 GPS 定期校正加速度计数据的累积惯性测量值非常有效。它提供了更频繁的加速度计测量的好处,以及 GPS 测量的准确性。通常使用卡尔曼滤波器。但是考虑到您选择的平台的准确性和时间限制,卡尔曼滤波器可能是多余的,并且更容易实现和运行的东西应该可以正常工作。

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

于 2010-01-19T17:29:39.857 回答