In [1]:
from __future__ import division, print_function
from math import pi
from IPython.display import HTML, display

In [ ]:

Blah ...


In [ ]:

Inertial Measure Unit Error

Noise is the unwanted signal generated from internal electronics that interferes with measurement of the desired signal. The noise level will determine the minimum sensor output that is distinguishable from the background noise of the sensor or noise floor. Rate-noise density is specified in rms milli-g/rt-Hz (accelerometer) and rms dps/rt-Hz (gyro) and is a common spec used to quantify sensor white noise output for a given sensor bandwidth.

$$ Noise_{RMS} = NoiseDensity_{RMS} * \sqrt{Bandwidth} \\ Bandwidth = frequency - 3dB * K_{Filter} $$

where $K_{Filter}$ is 1.57 (1st order), 1.11 (2nd order), or 1.05 (3rd order).

In general, velocity, position, or pitch-or-roll error from the accelerometer or gyro white noise will be smaller than the other described noise sources (such as bias or scale-factor error).


In [21]:
# this is just a helper function to automagically build pretty tables for us
def makeTable(data):
    """
    move to jupyter_tools
    """
    return HTML(
    '<table><tr>{}</tr></table>'.format(
        '</tr><tr>'.join(
            '<td>{}</td>'.format('</td><td>'.join(str(_) for _ in row)) for row in data)
        )
     )

Accelerometer

Accelerometers measure gravity and inertial forces placed on our system. To estimate system-level velocity and position errors from accelerometer noise:

$$ VelocityError = Noise_{accel} * gravity * time \\ PositionError = \frac{1}{2} * Noise_{accel} * gravity * time^2 $$

In [39]:
def accel_vel_error(n):
    err = ['vel (m/s)']
    for t in [1, 10, 60, 3600]:
        e = n*9.81*t
        err.append(e)
    return err

def accel_pos_error(n):
    err = ['pos (m)']
    for t in [1, 10, 60, 3600]:
        e = 1/2*n*9.81*t**2
        err.append(e)
    return err

In [41]:
verr = accel_vel_error(300e-6)  # 300 ug/sqr(Hz) from MPU-9250 sensor
perr = accel_pos_error(300e-6)
data = [['', '1 sec', '10 sec', '60 sec', '3600 sec'], verr, perr]
table = makeTable(data)
display(table)


1 sec10 sec60 sec3600 sec
vel (m/s)0.0029430.029430.1765810.5948
pos (m)0.00147150.147155.297419070.64

Gyro

Gyro noise creates orientation angle errors for an INS or AHRS, which again negatively affect the projection of the gravity vector and results in velocity and position error. To estimate system-level velocity and position errors from gyro noise:

$$ VelocityError = \frac{1}{2} * Noise_{gyro} * \frac{\pi}{180} * gravity * time^2 \\ PositionError = \frac{1}{6} * Noise_{gyro} * \frac{\pi}{180} * gravity * time^3 $$

In [32]:
def gyro_vel_error(n):
    err = ['vel (m/s)']
    for t in [1, 10, 60, 3600]:
        e = 1/2*n*pi/180*9.81*t**2
        err.append(e)
    return err

def gyro_pos_error(n):
    err = ['pos (m)']
    for t in [1, 10, 60, 3600]:
        e = 1/6*n*pi/180*9.81*t**3
        err.append(e)
    return err

In [36]:
verr = gyro_vel_error(0.01)  # gyro noise from mpu-9250 sensor
perr = gyro_pos_error(0.01)

In [34]:
data = [['', '1 sec', '10 sec', '60 sec', '3600 sec'], verr, perr]
table = makeTable(data)
display(table)


1 sec10 sec60 sec3600 sec
vel (m/s)0.0008560839981030.08560839981033.0819023931711094.8486154
pos (m)0.0002853613327010.28536133270161.638047863413313818.3385

Conclusion

We always want to pick IMU's with small noise errors, but gyro error effect the system more than any other error term. Thus, low noise and high ADC bits on the gyros are what you look for.


In [ ]:


In [ ]: