Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Measuring velocity via iPhone SDK

I need to implement a native iPhone app to measure the velocity of the phone (basically a speedometer). I know that you can do so via the CoreLocation API fairly easily, but I am concerned about battery consumption since this is to be a real-time measurement that could be used for up to a couple of hours at a time. My understanding is that while you are actively monitoring for events from the LocationManager (even though I don't actually care about GPS location) it is battery-intensive.

The other obvious option to explore would be using the accelerometers to try and calculate speed, but there is nothing in the API to help you do so. Based on my research, it should be possible to do this, but seems extremely complicated and error-prone. Translating from acceleration to velocity can be tricky to begin with, plus the iPhone accelerometer data can be "noisy". I'm familiar with the SDK example that demonstrates using low/high pass filtering, etc. -- but I have not seen a good example anywhere that shows calculating velocity.

Does anyone have any real-world experience with this they can share? Code would be fantastic, but really I just want to know if anyone has successfully done this (for a long-lived app) and what approach they took.

EDIT: I've got a working prototype that uses the LocationManager API. It works OK, but the update cycle is far from ideal for a real-time measurement of velocity. Depending on circumstances, it can take up to 4-5 seconds sometimes to update. Cruising at a given speed tends to work OK, but accel/decel tend to lag very badly from a user interaction standpoint. Also, I need to feed velocity into some other calculations that I'm doing and the precision is not really what I need.

It seems possible based on (very few) other apps I've seen, notably gMeter which claims to make no use of GPS but calculates velocity accurately. I'm really surprised there are no references or any sample code that demonstrates this anywhere that I can find. I realize it's complex, but surely there's something out there.

like image 741
Brian Moeskau Avatar asked Jan 03 '10 04:01

Brian Moeskau


People also ask

How does iPhone measure velocity?

SpeedClock uses the camera to detect and analyze motion, and a reference distance to calculate the speed of an object. Define the distance to the object of interest, hold the iPhone still and let the object pass across the the screen. The speed is displayed automatically.

Can iPhone tell you your speed?

GPS - Speed Tracker uses the iPhone's built-in GPS system to show your current, maximum/top and average speed, as well as the heading direction, total distance, trip time and altitude in a single screen. This app is perfect for car driving/racing and biking.

Is there an accelerometer in iPhone?

All iOS devices have a three-axis accelerometer, which delivers acceleration values in each of the three axes shown in Figure 1. The values reported by the accelerometers are measured in increments of the gravitational acceleration, with the value 1.

How accurate is iPhone accelerometer?

The coefficient of variation was less than 3% at velocities from 30°/s to 120°/s and less than 7% at 150°/s. Conclusions: The app was highly accurate and precise.


2 Answers

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.

like image 53
Tom Clarkson Avatar answered Nov 10 '22 03:11

Tom Clarkson


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];
}
like image 40
bentford Avatar answered Nov 10 '22 03:11

bentford