Main Content

Automatic Tuning of the insfilterAsync Filter

The insfilterAsync (Navigation Toolbox) object is a complex extended Kalman filter that estimates the device pose. However, manually tuning the filter or finding the optimal values for the noise parameters can be a challenging task. This example illustrates how to use the tune (Navigation Toolbox) function to optimize the filter noise parameters.

Trajectory and Sensor Setup

To illustrate the tuning process of the insfilterAsync filter, use a simple random waypoint trajectory. The imuSensor and gpsSensor objects create inputs for the filter.

% The IMU runs at 100 Hz and the GPS runs at 1 Hz.
imurate = 100;
gpsrate = 1;
decim = imurate/gpsrate;

% Create a random waypoint trajectory.
rng(1)
Npts = 4; % number of waypoints
wpPer = 5; % time between waypoints
tstart = 0;
tend = wpPer*(Npts -1);
wp = waypointTrajectory('Waypoints',5*rand(Npts,3), ...
        'TimeOfArrival',tstart:wpPer:tend, ...
        'Orientation',[quaternion.ones; randrot(Npts-1,1)], ...
        'SampleRate', imurate);

[Position,Orientation,Velocity,Acceleration,AngularVelocity] = lookupPose(...
    wp, tstart:(1/imurate):tend);

% Set up an IMU and process the trajectory.
imu = imuSensor('SampleRate',imurate);
loadparams(imu,fullfile(matlabroot, ...
    "toolbox","shared","positioning","positioningdata","generic.json"), ...
    "GenericLowCost9Axis");
[Accelerometer, Gyroscope, Magnetometer] = imu(Acceleration, ...
    AngularVelocity, Orientation);
imuData = timetable(Accelerometer,Gyroscope,Magnetometer,'SampleRate',imurate);

% Set up a GPS sensor and process the trajectory.
gps = gpsSensor('SampleRate', gpsrate,'DecayFactor',0.5, ...
    'HorizontalPositionAccuracy',1.6,'VerticalPositionAccuracy',1.6, ...
    'VelocityAccuracy',0.1);
[GPSPosition,GPSVelocity] = gps(Position(1:decim:end,:), Velocity(1:decim:end,:));
gpsData = timetable(GPSPosition,GPSVelocity,'SampleRate',gpsrate);

% Create a timetable for the tune function.
sensorData = synchronize(imuData,gpsData);

% Create a timetable capturing the ground truth pose.
groundTruth = timetable(Position,Orientation,'SampleRate',imurate);

Construct the Filter

The insfilterAsync filter fuses data from multiple sensors operating asynchronously.

filtUntuned = insfilterAsync;

Determine Filter Initial Conditions

Set the initial values for the State and StateCovariance properties based on the ground truth. Normally to obtain the initial values, you would use the first several samples of sensorData along with calibration routines. However, in this example the groundTruth is used to set the initial state for fast convergence of the filter.

idx = stateinfo(filtUntuned);
filtUntuned.State(idx.Orientation) = compact(Orientation(1));
filtUntuned.State(idx.AngularVelocity) = AngularVelocity(1,:);
filtUntuned.State(idx.Position) = Position(1,:);
filtUntuned.State(idx.Velocity) = Velocity(1,:);
filtUntuned.State(idx.Acceleration) = Acceleration(1,:);
filtUntuned.State(idx.AccelerometerBias) = imu.Accelerometer.ConstantBias;
filtUntuned.State(idx.GyroscopeBias) = imu.Gyroscope.ConstantBias;
filtUntuned.State(idx.GeomagneticFieldVector) = imu.MagneticField;
filtUntuned.State(idx.MagnetometerBias) = imu.Magnetometer.ConstantBias;
filtUntuned.StateCovariance = 1e-5*eye(numel(filtUntuned.State));

% Create a copy of the filtUntuned object for tuning later.
filtTuned = copy(filtUntuned);

Process sensorData with an Untuned Filter

Use the tunernoise function to create measurement noises which also need to be tuned. To illustrate the necessity for tuning, first use the filter with its default parameters.

mn = tunernoise('insfilterAsync');
[posUntunedEst, orientUntunedEst] = fuse(filtUntuned, sensorData, mn);

Tune the Filter and Process sensorData

Use the tune function to minimize the root mean squared (RMS) error between the groundTruth and state estimates.

cfg = tunerconfig(class(filtTuned),'MaxIterations',15,'StepForward',1.1);
tunedmn = tune(filtTuned,mn,sensorData,groundTruth,cfg);
    Iteration    Parameter                 Metric
    _________    _________                 ______
    1            AccelerometerNoise        3.9157
    1            GyroscopeNoise            3.9157
    1            MagnetometerNoise         3.8618
    1            GPSPositionNoise          3.8162
    1            GPSVelocityNoise          3.6551
    1            QuaternionNoise           3.6522
    1            AngularVelocityNoise      3.4632
    1            PositionNoise             3.4632
    1            VelocityNoise             3.4632
    1            AccelerationNoise         3.4420
    1            GyroscopeBiasNoise        3.4420
    1            AccelerometerBiasNoise    3.4389
    1            GeomagneticVectorNoise    3.4389
    1            MagnetometerBiasNoise     3.4389
    2            AccelerometerNoise        3.4389
    2            GyroscopeNoise            3.4389
    2            MagnetometerNoise         3.3792
    2            GPSPositionNoise          3.3792
    2            GPSVelocityNoise          3.2526
    2            QuaternionNoise           3.2506
    2            AngularVelocityNoise      2.6514
    2            PositionNoise             2.6514
    2            VelocityNoise             2.6514
    2            AccelerationNoise         2.6514
    2            GyroscopeBiasNoise        2.6514
    2            AccelerometerBiasNoise    2.6496
    2            GeomagneticVectorNoise    2.6496
    2            MagnetometerBiasNoise     2.6386
    3            AccelerometerNoise        2.6351
    3            GyroscopeNoise            2.6351
    3            MagnetometerNoise         2.6165
    3            GPSPositionNoise          2.6165
    3            GPSVelocityNoise          2.5219
    3            QuaternionNoise           2.4994
    3            AngularVelocityNoise      2.4183
    3            PositionNoise             2.4183
    3            VelocityNoise             2.4183
    3            AccelerationNoise         2.4032
    3            GyroscopeBiasNoise        2.4032
    3            AccelerometerBiasNoise    2.3922
    3            GeomagneticVectorNoise    2.3922
    3            MagnetometerBiasNoise     2.3922
    4            AccelerometerNoise        2.3888
    4            GyroscopeNoise            2.3888
    4            MagnetometerNoise         2.3888
    4            GPSPositionNoise          2.3888
    4            GPSVelocityNoise          2.2745
    4            QuaternionNoise           2.2641
    4            AngularVelocityNoise      2.1749
    4            PositionNoise             2.1749
    4            VelocityNoise             2.1749
    4            AccelerationNoise         2.1628
    4            GyroscopeBiasNoise        2.1628
    4            AccelerometerBiasNoise    2.1624
    4            GeomagneticVectorNoise    2.1624
    4            MagnetometerBiasNoise     2.1589
    5            AccelerometerNoise        2.1587
    5            GyroscopeNoise            2.1587
    5            MagnetometerNoise         2.1587
    5            GPSPositionNoise          2.1573
    5            GPSVelocityNoise          2.0520
    5            QuaternionNoise           2.0518
    5            AngularVelocityNoise      2.0044
    5            PositionNoise             2.0044
    5            VelocityNoise             2.0044
    5            AccelerationNoise         2.0013
    5            GyroscopeBiasNoise        2.0013
    5            AccelerometerBiasNoise    1.9900
    5            GeomagneticVectorNoise    1.9900
    5            MagnetometerBiasNoise     1.9900
    6            AccelerometerNoise        1.9893
    6            GyroscopeNoise            1.9893
    6            MagnetometerNoise         1.9893
    6            GPSPositionNoise          1.9893
    6            GPSVelocityNoise          1.8894
    6            QuaternionNoise           1.8894
    6            AngularVelocityNoise      1.8273
    6            PositionNoise             1.8273
    6            VelocityNoise             1.8273
    6            AccelerationNoise         1.8189
    6            GyroscopeBiasNoise        1.8189
    6            AccelerometerBiasNoise    1.8189
    6            GeomagneticVectorNoise    1.8188
    6            MagnetometerBiasNoise     1.8188
    7            AccelerometerNoise        1.8188
    7            GyroscopeNoise            1.8188
    7            MagnetometerNoise         1.8177
    7            GPSPositionNoise          1.8157
    7            GPSVelocityNoise          1.7122
    7            QuaternionNoise           1.7122
    7            AngularVelocityNoise      1.6420
    7            PositionNoise             1.6420
    7            VelocityNoise             1.6420
    7            AccelerationNoise         1.6420
    7            GyroscopeBiasNoise        1.6420
    7            AccelerometerBiasNoise    1.6412
    7            GeomagneticVectorNoise    1.6412
    7            MagnetometerBiasNoise     1.6412
    8            AccelerometerNoise        1.6412
    8            GyroscopeNoise            1.6411
    8            MagnetometerNoise         1.6411
    8            GPSPositionNoise          1.6383
    8            GPSVelocityNoise          1.5216
    8            QuaternionNoise           1.5216
    8            AngularVelocityNoise      1.5004
    8            PositionNoise             1.5004
    8            VelocityNoise             1.5004
    8            AccelerationNoise         1.5000
    8            GyroscopeBiasNoise        1.5000
    8            AccelerometerBiasNoise    1.5000
    8            GeomagneticVectorNoise    1.5000
    8            MagnetometerBiasNoise     1.4998
    9            AccelerometerNoise        1.4998
    9            GyroscopeNoise            1.4998
    9            MagnetometerNoise         1.4998
    9            GPSPositionNoise          1.4998
    9            GPSVelocityNoise          1.4106
    9            QuaternionNoise           1.4106
    9            AngularVelocityNoise      1.3916
    9            PositionNoise             1.3916
    9            VelocityNoise             1.3916
    9            AccelerationNoise         1.3916
    9            GyroscopeBiasNoise        1.3916
    9            AccelerometerBiasNoise    1.3911
    9            GeomagneticVectorNoise    1.3911
    9            MagnetometerBiasNoise     1.3911
    10           AccelerometerNoise        1.3911
    10           GyroscopeNoise            1.3910
    10           MagnetometerNoise         1.3910
    10           GPSPositionNoise          1.3892
    10           GPSVelocityNoise          1.2977
    10           QuaternionNoise           1.2977
    10           AngularVelocityNoise      1.2977
    10           PositionNoise             1.2977
    10           VelocityNoise             1.2977
    10           AccelerationNoise         1.2975
    10           GyroscopeBiasNoise        1.2975
    10           AccelerometerBiasNoise    1.2975
    10           GeomagneticVectorNoise    1.2975
    10           MagnetometerBiasNoise     1.2974
    11           AccelerometerNoise        1.2973
    11           GyroscopeNoise            1.2973
    11           MagnetometerNoise         1.2973
    11           GPSPositionNoise          1.2973
    11           GPSVelocityNoise          1.2031
    11           QuaternionNoise           1.2030
    11           AngularVelocityNoise      1.1998
    11           PositionNoise             1.1998
    11           VelocityNoise             1.1998
    11           AccelerationNoise         1.1998
    11           GyroscopeBiasNoise        1.1998
    11           AccelerometerBiasNoise    1.1995
    11           GeomagneticVectorNoise    1.1995
    11           MagnetometerBiasNoise     1.1994
    12           AccelerometerNoise        1.1993
    12           GyroscopeNoise            1.1992
    12           MagnetometerNoise         1.1992
    12           GPSPositionNoise          1.1982
    12           GPSVelocityNoise          1.1009
    12           QuaternionNoise           1.1008
    12           AngularVelocityNoise      1.0972
    12           PositionNoise             1.0972
    12           VelocityNoise             1.0972
    12           AccelerationNoise         1.0972
    12           GyroscopeBiasNoise        1.0972
    12           AccelerometerBiasNoise    1.0968
    12           GeomagneticVectorNoise    1.0968
    12           MagnetometerBiasNoise     1.0967
    13           AccelerometerNoise        1.0966
    13           GyroscopeNoise            1.0965
    13           MagnetometerNoise         1.0965
    13           GPSPositionNoise          1.0955
    13           GPSVelocityNoise          0.9830
    13           QuaternionNoise           0.9829
    13           AngularVelocityNoise      0.9829
    13           PositionNoise             0.9829
    13           VelocityNoise             0.9829
    13           AccelerationNoise         0.9829
    13           GyroscopeBiasNoise        0.9829
    13           AccelerometerBiasNoise    0.9825
    13           GeomagneticVectorNoise    0.9825
    13           MagnetometerBiasNoise     0.9824
    14           AccelerometerNoise        0.9822
    14           GyroscopeNoise            0.9822
    14           MagnetometerNoise         0.9822
    14           GPSPositionNoise          0.9812
    14           GPSVelocityNoise          0.8868
    14           QuaternionNoise           0.8867
    14           AngularVelocityNoise      0.8816
    14           PositionNoise             0.8816
    14           VelocityNoise             0.8816
    14           AccelerationNoise         0.8815
    14           GyroscopeBiasNoise        0.8815
    14           AccelerometerBiasNoise    0.8812
    14           GeomagneticVectorNoise    0.8812
    14           MagnetometerBiasNoise     0.8811
    15           AccelerometerNoise        0.8809
    15           GyroscopeNoise            0.8809
    15           MagnetometerNoise         0.8809
    15           GPSPositionNoise          0.8799
    15           GPSVelocityNoise          0.7916
    15           QuaternionNoise           0.7916
    15           AngularVelocityNoise      0.7916
    15           PositionNoise             0.7916
    15           VelocityNoise             0.7916
    15           AccelerationNoise         0.7916
    15           GyroscopeBiasNoise        0.7916
    15           AccelerometerBiasNoise    0.7913
    15           GeomagneticVectorNoise    0.7913
    15           MagnetometerBiasNoise     0.7913
[posTunedEst, orientTunedEst] = fuse(filtTuned,sensorData,tunedmn);

Compare Tuned vs Untuned Filter

Plot the position estimates from the tuned and untuned filters along with the ground truth positions. Then, plot the orientation error (quaternion distance) in degrees for both tuned and untuned filters. The tuned filter estimates the position and orientation better than the untuned filter.

% Position error
figure;
t = sensorData.Time;
subplot(3,1,1);
plot(t, [posTunedEst(:,1) posUntunedEst(:,1) Position(:,1)]);
title('Position');
ylabel('X-axis');
legend('Tuned', 'Untuned', 'Truth');
subplot(3,1,2);
plot(t, [posTunedEst(:,2) posUntunedEst(:,2) Position(:,2)]);
ylabel('Y-axis');
subplot(3,1,3);
plot(t, [posTunedEst(:,3) posUntunedEst(:,3) Position(:,3)]);
ylabel('Z-axis');

Figure contains 3 axes objects. Axes object 1 with title Position, ylabel X-axis contains 3 objects of type line. These objects represent Tuned, Untuned, Truth. Axes object 2 with ylabel Y-axis contains 3 objects of type line. Axes object 3 with ylabel Z-axis contains 3 objects of type line.

% Orientation Error
figure;
plot(t, rad2deg(dist(Orientation, orientTunedEst)), ...
    t, rad2deg(dist(Orientation, orientUntunedEst)));
title('Orientation Error');
ylabel('Degrees');
legend('Tuned', 'Untuned');

Figure contains an axes object. The axes object with title Orientation Error, ylabel Degrees contains 2 objects of type line. These objects represent Tuned, Untuned.