I thought for sure that there would have been a duplicate question somewhere on the site that answers this question, but I can't find one, so here's a quick description of the method.
- Put your IMU in a known starting position and orientation (position + orientation = "pose").
- Capture IMU accelerometer and gyroscope readings.
- Use numeric integration on the gyroscope output (
angle += gyroReading*deltaTime
) to get the current orientation of the IMU.
- Use the current orientation of the IMU to construct a rotation matrix that will transform the accelerometer readings from the IMU "body frame" of reference to the "world frame" of reference.
- Use numeric integration on the transformed accelerometer output (
speed += xfmAccelerometerReading*deltaTime
) to get the current speed of the IMU in the world frame.
- Use numeric integration on the world-frame speed (
position += speed*deltaTime
, or position += speed*deltaTime + 0.5*xfmAccelerometerReading*deltaTime*deltaTime
) to get the current position of the IMU in the world frame.
- GOTO: 2.
This is the most simplistic way of using an IMU output to get position. All sensors have a bias, though, so when you integrate the output you're left with a drift on the speed, position, and orientation estimates (important because they are estimates and not measurements).
You can use the gravitational "down" vector (the only sustainable long-term acceleration) to correct any drift on your x/y rotations. You can use a magnetometer/compass to correct any drift on your z rotation. You can use GPS to correct position drift.
I am a huge fan of the Madgwick filter and plug it every chance I get - it's free, open-source, outperforms the Kalman filter, and it's probably already written for you. It will take accelerometer, gyro, and magnetometer readings and give you the outputs.