# Introduction to Simulating IMU Measurements

This example shows how to simulate inertial measurement unit (IMU) measurements. Sensor Fusion and Tracking Toolbox enables you to model data received from an IMU using the `imuSensor` System object. An IMU can include a combination of individual sensors, including a gyroscope, an accelerometer, and a magnetometer. You can specify properties of the individual sensors using `gyroparams`, `accelparams`, and `magparams`, respectively.

In the following plots, unless otherwise noted, only the x-axis measurements are shown.

## Contents

## Default Parameters

The default parameters for the gyroscope model simulate an ideal signal. Given a sinusoidal input, the gyroscope output should match exactly.

params = gyroparams % Generate N samples at a sampling rate of Fs with a sinusoidal frequency % of Fc. N = 1000; Fs = 100; Fc = 0.25; t = (0:(1/Fs):((N-1)/Fs)).'; acc = zeros(N, 3); angvel = zeros(N, 3); angvel(:,1) = sin(2*pi*Fc*t); imu = imuSensor('SampleRate', Fs, 'Gyroscope', params); [~, gyroData] = imu(acc, angvel); figure plot(t, angvel(:,1), '--', t, gyroData(:,1)) xlabel('Time (s)') ylabel('Angular Velocity (rad/s)') title('Ideal Gyroscope Data') legend('x (ground truth)', 'x (gyroscope)')

params = gyroparams with properties: MeasurementRange: Inf rad/s Resolution: 0 (rad/s)/LSB ConstantBias: [0 0 0] rad/s AxesMisalignment: [0 0 0] % NoiseDensity: [0 0 0] (rad/s)/√Hz BiasInstability: [0 0 0] rad/s RandomWalk: [0 0 0] (rad/s)*√Hz TemperatureBias: [0 0 0] (rad/s)/°C TemperatureScaleFactor: [0 0 0] %/°C AccelerationBias: [0 0 0] (rad/s)/(m/s²)

## Hardware Parameter Tuning

The following parameters model hardware limitations or defects. Some can be corrected through calibration.

`MeasurementRange` determines the maximum absolute value reported by the gyroscope. Larger absolute values are saturated. The effect is shown by setting the measurement range to a value smaller than the amplitude of the sinusoidal ground-truth angular velocity.

imu = imuSensor('SampleRate', Fs, 'Gyroscope', params); imu.Gyroscope.MeasurementRange = 0.5; % rad/s [~, gyroData] = imu(acc, angvel); figure plot(t, angvel(:,1), '--', t, gyroData(:,1)) xlabel('Time (s)') ylabel('Angular Velocity (rad/s)') title('Saturated Gyroscope Data') legend('x (ground truth)', 'x (gyroscope)')

`Resolution` affects the step size of the digital measurements. It is a parameter used to model the quantization effects from the analog-to-digital converter (ADC). The effect is shown by increasing the parameter to a much larger value than is typical.

imu = imuSensor('SampleRate', Fs, 'Gyroscope', params); imu.Gyroscope.Resolution = 0.5; % (rad/s)/LSB [~, gyroData] = imu(acc, angvel); figure plot(t, angvel(:,1), '--', t, gyroData(:,1)) xlabel('Time (s)') ylabel('Angular Velocity (rad/s)') title('Quantized Gyroscope Data') legend('x (ground truth)', 'x (gyroscope)')

`AxesMisalignment` is the amount of skew in the sensor axes. This skew normally occurs when the sensor is mounted to the PCB and can be corrected through calibration. The effect is shown by skewing the x-axis slightly and plotting both the x-axis and y-axis.

imu = imuSensor('SampleRate', Fs, 'Gyroscope', params); imu.Gyroscope.AxesMisalignment = [2 0 0]; % percent [~, gyroData] = imu(acc, angvel); figure plot(t, angvel(:,1:2), '--', t, gyroData(:,1:2)) xlabel('Time (s)') ylabel('Angular Velocity (rad/s)') title('Misaligned Gyroscope Data') legend('x (ground truth)', 'y (ground truth)', ... 'x (gyroscope)', 'y (gyroscope)')

`ConstantBias` occurs in sensor measurements due to hardware defects. Since this bias is not caused by environmental factors, such as temperature, it can be corrected through calibration.

imu = imuSensor('SampleRate', Fs, 'Gyroscope', params); imu.Gyroscope.ConstantBias = [0.4 0 0]; % rad/s [~, gyroData] = imu(acc, angvel); figure plot(t, angvel(:,1), '--', t, gyroData(:,1)) xlabel('Time (s)') ylabel('Angular Velocity (rad/s)') title('Biased Gyroscope Data') legend('x (ground truth)', 'x (gyroscope)')

## Random Noise Parameter Tuning

The following parameters model random noise in sensor measurements. More information on these parameters can be found in the Inertial Sensor Noise Analysis Using Allan Variance example.

`NoiseDensity` is the amount of white noise in the sensor measurement. It is sometimes called angle random walk for gyroscopes or velocity random walk for accelerometers.

rng('default') imu = imuSensor('SampleRate', Fs, 'Gyroscope', params); imu.Gyroscope.NoiseDensity = 1.25e-2; % (rad/s)/sqrt(Hz) [~, gyroData] = imu(acc, angvel); figure plot(t, angvel(:,1), '--', t, gyroData(:,1)) xlabel('Time (s)') ylabel('Angular Velocity (rad/s)') title('White Noise Gyroscope Data') legend('x (ground truth)', 'x (gyroscope)')

`BiasInstability` is the amount of pink or flicker noise in the sensor measurement.

imu = imuSensor('SampleRate', Fs, 'Gyroscope', params); imu.Gyroscope.BiasInstability = 2.0e-2; % rad/s [~, gyroData] = imu(acc, angvel); figure plot(t, angvel(:,1), '--', t, gyroData(:,1)) xlabel('Time (s)') ylabel('Angular Velocity (rad/s)') title('Bias Instability Gyroscope Data') legend('x (ground truth)', 'x (gyroscope)')

`RandomWalk` is the amount of Brownian noise in the sensor measurement. It is sometimes called rate random walk for gyroscopes or acceleration random walk for accelerometers.

imu = imuSensor('SampleRate', Fs, 'Gyroscope', params); imu.Gyroscope.RandomWalk = 9.1e-2; % (rad/s)*sqrt(Hz) [~, gyroData] = imu(acc, angvel); figure plot(t, angvel(:,1), '--', t, gyroData(:,1)) xlabel('Time (s)') ylabel('Angular Velocity (rad/s)') title('Random Walk Gyroscope Data') legend('x (ground truth)', 'x (gyroscope)')

## Environmental Parameter Tuning

The following parameters model noise that arises from changes to the environment of the sensor.

`TemperatureBias` is the bias added to sensor measurements due to temperature difference from the default operating temperature. Most sensor datasheets list the default operating temperature as 25 degrees Celsius. This bias is shown by setting the parameter to a non-zero value and setting the operating temperature to a value above 25 degrees Celsius.

imu = imuSensor('SampleRate', Fs, 'Gyroscope', params); imu.Gyroscope.TemperatureBias = 0.06; % (rad/s)/(degrees C) imu.Temperature = 35; [~, gyroData] = imu(acc, angvel); figure plot(t, angvel(:,1), '--', t, gyroData(:,1)) xlabel('Time (s)') ylabel('Angular Velocity (rad/s)') title('Temperature-Biased Gyroscope Data') legend('x (ground truth)', 'x (gyroscope)')

`TemperatureScaleFactor` is the error in the sensor scale factor due to changes in the operating temperature. This causes errors in the scaling of the measurement, meaning smaller ideal values have less error than larger values. This error is shown by linearly increasing the temperature.

imu = imuSensor('SampleRate', Fs, 'Gyroscope', params); imu.Gyroscope.TemperatureScaleFactor = 3.2; % %/(degrees C) standardTemperature = 25; % degrees C temperatureSlope = 2; % (degrees C)/s temperature = temperatureSlope*t + standardTemperature; gyroData = zeros(N, 3); for i = 1:N imu.Temperature = temperature(i); [~, gyroData(i,:)] = imu(acc(i,:), angvel(i,:)); end figure plot(t, angvel(:,1), '--', t, gyroData(:,1)) xlabel('Time (s)') ylabel('Angular Velocity (rad/s)') title('Temperature-Scaled Gyroscope Data') legend('x (ground truth)', 'x (gyroscope)')

`AccelerationBias` is the bias added to the gyroscope measurement due to linear accelerations. This parameter is specific to the gyroscope. This bias is shown by setting the parameter to a non-zero value and using a non-zero input acceleration.

imu = imuSensor('SampleRate', Fs, 'Gyroscope', params); imu.Gyroscope.AccelerationBias = 0.3; % (rad/s)/(m/s^2) acc(:,1) = 1; [~, gyroData] = imu(acc, angvel); figure plot(t, angvel(:,1), '--', t, gyroData(:,1)) xlabel('Time (s)') ylabel('Angular Velocity (rad/s)') title('Acceleration-Biased Gyroscope Data') legend('x (ground truth)', 'x (gyroscope)')