title: How to calculate speed and distance from acceleration in iOS
body: <p>Okay, this is an odd one - and the question has been asked before in various guises and always closed out with the opinion that a) it won't be accurate and b) that it will get less accurate with time.</p>
  
  <p>I understand this - but I'm doing an experiment to see whether that accuracy can be boosted at all by taking into account other evidential sources (for example, if a map has been plotted in advance then the direction of travel from the compass combined with the route could provide another evidence source).</p>
  
  <p>The problem is that my code is clearly rubbish - so I'd welcome your opinion.  I suspect that this might be a brown paper bag error!</p>
  
  <p>My <strong>ViewController.h</strong> looks like this:</p>
  
  <pre><code>#import &lt;UIKit/UIKit.h&gt;
  
  @interface ViewController : UIViewController &lt;UIAccelerometerDelegate&gt; {
  
      UIAccelerometer *accelerometer;
  
      long last_speed;
      long distance_travelled;
  
      long lastAccel;
      long long lastTime;
  
      IBOutlet UITextField* speedView;
      IBOutlet UITextField* distanceView;
  }
  
  @end
  </code></pre>
  
  <p>And my <strong>ViewController.m</strong> looks like this:</p>
  
  <pre><code>#import "ViewController.h"
  
  @implementation ViewController
  
  - (void)viewDidLoad {
      [super viewDidLoad];
      // Do any additional setup after loading the view, typically from a nib.
      lastAccel = 0;
      last_speed = 0;
      distance_travelled = 0;
      lastTime = (long)(NSTimeInterval)([NSDate.date timeIntervalSince1970] * 1000.0);
  
      accelerometer = UIAccelerometer.sharedAccelerometer;
      accelerometer.updateInterval = 0.1;
      accelerometer.delegate = self;
  }
  
  - (void)accelerometer:(UIAccelerometer *)meter
          didAccelerate:(UIAcceleration *)acceleration
  {
      long long currentTime = (long)(NSTimeInterval)([NSDate.date timeIntervalSince1970] * 1000.0);
      long long deltaTime = currentTime - lastTime;
      lastTime = currentTime;
  
      long accel_x = acceleration.x;
      long accel_y = acceleration.y;
      long accel_z = acceleration.z;
  
      long integrated_acceleration = sqrtl(accel_x*accel_x + accel_y*accel_y + accel_z*accel_z);
  
      long average_acceleration = (lastAccel + integrated_acceleration) / 2;
  
      long speed = last_speed + (average_acceleration * deltaTime);
      long average_speed = (speed + last_speed) / 2;
      distance_travelled = distance_travelled + (average_speed * deltaTime);
  
      last_speed = speed;
      lastAccel = integrated_acceleration;
  
      [speedView setText:[NSString stringWithFormat:@"%ld", speed]];
      [distanceView setText:[NSString stringWithFormat:@"%ld", distance_travelled]];
  }
  
  @end
  </code></pre>
  
  <p>When the code is run, the speed and the distance keep going up continually, and deceleration (me slowing down) is never taken into account - so even when I stop, speed and distance keep going up.</p>
  
  <p>Even by the standards of 'this will be a bit inaccurate' that's taking it too far!</p>
  
  <p>All thoughts and opinions gratefully received (well almost - I <em>know</em> that it won't be accurate!)</p>