代码之家  ›  专栏  ›  技术社区  ›  Brian Moeskau

通过iphonesdk测量速度

  •  12
  • Brian Moeskau  · 技术社区  · 16 年前

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

    有没有人有任何现实经验可以分享?代码将是美妙的,但我真的只想知道是否有人成功地做到了这一点(对于一个长寿命的应用程序),以及他们采取了什么方法。

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

    这似乎是有可能的,因为我看到的其他应用(很少),尤其是 gMeter 它声称不使用GPS,但精确计算速度。我真的很惊讶,在我能找到的任何地方都没有引用或任何示例代码来演示这一点。我意识到这很复杂,但肯定有一些东西。

    5 回复  |  直到 16 年前
        1
  •  10
  •   Tom Clarkson    16 年前

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

        2
  •  10
  •   bentford Marko Hlebar    15 年前

    从实际的角度来看,通过作用在加速计上的力无法获得准确的速度。

    使用GPS,每隔1分钟读取一次读数,并将GPS置于其间休眠。

    以下是一个例子:

    CLLocationManager *locManager;
    CLLocationSpeed speed;
    NSTimer *timer;
    
    @property (nonantomic,retain) NSTimer *timer;
    

    #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];
    }
    
        3
  •  4
  •   BlueRaja - Danny Pflughoeft    16 年前

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

    (在哪里 ^2 方法 )

    然后频繁测量加速计:

    newVelocity = oldVelocity + accelerometer*timeBetweenAccelerometerReadings
    
        4
  •  3
  •   Ben Gottlieb    16 年前

    我不确定你用加速度计跟踪速度会走多远。为此,您必须确保捕捉到每个加速度,因为任何丢失的数据点都会指示错误的速度(当然,这是假设您能够将报告的加速度计值转换为标准单位)。因此,您必须不断运行加速计,它本身会吸很多果汁(而且,您也不能保证所有的加速度)。我建议使用CoreLocation。

        5
  •  2
  •   Steve Roe    16 年前

    虽然我不知道iphoneapi,但我知道一些关于GPS和惯性导航的知识。这可能有用。

    我使用过的GPS接收机都可以根据接收到的GPS信号直接测量速度。这些测量甚至比位置数据更精确。我不知道苹果API是否提供访问,甚至苹果是否配置了接收器来提供这些数据。这将是获得速度测量的更有效途径。

    下一个途径是,考虑到您有加速度计数据和GPS数据,将它们结合起来,正如前面其他海报和评论所提到的那样。利用GPS对加速度计数据中累积的惯性测量值进行定期修正,在实践中效果良好。它提供了更频繁的加速计测量的好处,以及GPS测量的准确性。通常使用卡尔曼滤波器。但是,考虑到所选平台的精度和时间限制,卡尔曼滤波器可能过于致命,一些更简单的实现和运行方法应该可以很好地工作。