How to get accurate speed from accelerometer on iOS?

3.3k views Asked by At

I would need very accurate speed for my app, even when the user is only walking. I tried using the GPS, it works well but not for speeds that low. So my question is, could I use the accelerometer to get some more accurate values? If yes, how would I do that?

4

There are 4 answers

3
matt On

could I use the accelerometer to get some more accurate values

No, the accelerometer cannot tell you anything about speed. Acceleration and speed are very different things. Indeed, during motion with a constant speed, there is no acceleration (except gravity and similar side effects). You could travel at the speed of light and experience no acceleration (if you could travel at the speed of light).

4
casillas On

I do not think you will get something from accelerometer. Accelerometer only returns you motion (x,y,z). I do not know how you could able to get speed out of that, unless you will do some linear modelling algorithm that requires heavy research, that could be a Ph.D topic I guess.

I propose the following implementation.

- (id) init
{
    self = [super init];
    if (self != nil) {
        self.manager = [[CLLocationManager alloc] init];
        self.manager.delegate = self;
        [self.manager startUpdatingLocation];
    }
    return self;
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    NSLog(@"Speed = %f", newLocation.speed);
}

or you could use directly CMPedometer class which I believe that class developed exactly for physical activity applications. I have recently used that class and I am quite satisfied.

import CoreMotion

let lengthFormatter = NSLengthFormatter()
let pedometer = CMPedometer()
pedometer.startPedometerUpdatesFromDate(NSDate(), withHandler: { data, error in
if !error {
    println("Steps Taken: \(data.numberOfSteps)")

    var distance = data.distance.doubleValue
    println("Distance: \(lengthFormatter.stringFromMeters(distance))")

    var time = data.endDate.timeIntervalSinceDate(data.startDate)
    var speed = distance / time
    println("Speed: \(lengthFormatter.stringFromMeters(speed)) / s")
}
})
0
zaph On

It really isn't possible to get a decent speed estimate from the Accelerometer. That even if you start with the device at rest and end with it at rest and alsoo using the gyroscope.

Averaging the GPS location is probably the best, possibly a moving average of some sort.

0
AlexWien On

I already have answerded similar question many times. The apporach with the accelerometer will not work well for more than some seconds. The cause is the dramatic accuracy loss due double integration. This is well explained in a Goole Talk "Sensor Fusioning" video.

What you can do, for low GPS speed:
A bit simplified:
1. Take locations evry 5 seconds, 2. calculate distance between fix(i-5) and fix(i), 3. calcuate time difference,

and cacluate then the speed in m/s by distanceMeters / timeDeltaSeconds

An advanced solution would use a time window of let's say 5 seconds, and this evaluation window will move 1 step further every second, using the same 3 calculation steps as above