Measuring velocity via iPhone SDK

天涯浪子 提交于 2019-11-28 16:35:29

Since the GPS and accelerometer have different weaknesses, your best option is probably a combined approach - Get a measurement from the GPS every minute or so, then add realtime changes from the accelerometer.

From a practical standpoint, you are not going get accurate velocity from forces acting on the accelerometer.

Use the GPS with readings taken at 1 minute intervals and put the GPS to sleep inbetween.

Here is an example:

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];
}

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

I'm not sure you'll get very far trying to track velocity using the accelerometer. To do this, you'd have to make sure you captured EVERY acceleration, since any missed data points would indicate the wrong velocity (this is assuming, of course, you're able to convert the reported accelerometer values into standard units). Thus, you'd have to constantly run the accelerometer stuff, which sucks quite a bit of juice in itself (and, again, you won't be guaranteed all accelerations). I'd recommend using CoreLocation.

While I don't know the iPhone API, I do know something about GPS and inertial navigation. It might be useful.

The GPS receivers I have worked with can all provide a direct measurement of velocity from the GPS signals they receive. These measurements are more accurate than position data even. I don't know if the Apple API provides access, or even if apple has configured their receiver to provide this data. This would be the more efficient route to getting a velocity measurement.

The next path, given that you have accelerometer data and GPS data is to combine them as mentioned earlier by other posters and comments. Using the GPS to periodically correct the accumulated intertial measurement from the accelerometer data works very well in practice. It provides the benefit of more frequent accelerometer measurements, and the accuracy of the GPS measurements. A Kalman filter is commonly used. But given the accuracy and timing limits of your chosen platform a kalman filter may be overkill and something simpler to implement and run should work fine.

Anyway, just some things to think about.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!