Main Content

tunerconfig

Fusion filter tuner configuration options

Description

The tunerconfig object creates a tuner configuration for a fusion filter (insfilterAsync, ahrsfilter, or imufilter) used to tune the filter for reduced estimation error.

Creation

Description

example

config = tunnerconfig(filterName) creates a tunerconfig object controlling the optimization algorithm of the tune function of the fusion filter. The filterName input can be 'imufilter', 'ahrsfilter', or 'insfilterAsync' corresponding to the three types of fusion filters, respectively.

config = tunnerconfig(fitlerName,Name,Value) configures the created tunerconfig object properties using one or more Name,Value pair arguments. Name is a property name and Value is the corresponding value. Name must appear inside quotes. You can specify several name-value pair arguments in any order as Name1,Value1,...,NameN,ValueN. Any unspecified properties take default values.

For example, tunnerconfig('imufilter','MaxIterations',3) create a tunerconfig object for the imufilter object with the maximum number of allowed iterations equal to 3.

Inputs Arguments

expand all

Fusion filter names, specified as 'imufilter', 'ahrsfilter', or 'insfilterAsync'.

Properties

expand all

Tunable parameters, specified as an array of strings. Each string is a tunable property name of the fusion filter. By default, the property contains all the tunable parameters of a fusion filter.

Example: ["AccelerometerNoise" "GyroscopeNoise"]

Factor of a forward step, specified as a scalar larger than 1. During the tuning process, the tuner increases or decreases the noise parameters to achieve smaller estimation errors. This property specifies the ratio of parameter increase during a parameter increase step.

Factor of a backward step, specified as a scalar in the range of (0,1). During the tuning process, the tuner increases or decreases the noise parameters to achieve smaller estimation errors. This property specifies the factor of parameter decrease during a parameter decrease step.

Maximum number of iterations allowed by the tuning algorithm, specified as a positive integer.

Cost at which to stop the tuning process, specified as a positive scalar. The tuning process stops if the ObjectiveLimit is achieved before the program reaches the maximum number of iterations.

Enable showing the iteration details, specified as "iter" or "none". When specified as:

  • "iter" — The program shows the tuned parameter details in each iteration in the Command Window.

  • "none" — The program does not show any tuning information.

Metric for evaluating filter performance, specified as "RMS" or "Custom". When specified as:

  • "RMS" — The program optimizes the root-mean-squared (RMS) error between the estimate and the truth.

  • "Custom" — The program optimizes the filter performance by using a customized cost function specified by the CustomCostFcn property.

Customized cost function, specified as a function handle.

Examples

collapse all

Create a tunerconfig object for the insfilterAsync object.

config = tunerconfig('insfilterAsync')
config = 
  tunerconfig with properties:

      TunableParameters: [1×14 string]
            StepForward: 1.1000
           StepBackward: 0.5000
          MaxIterations: 20
    OptimalityTolerance: 0.1000
                Display: iter
                   Cost: RMS

Display the default tunable parameters.

config.TunableParameters
ans = 1×14 string
    "AccelerometerNoise"    "GyroscopeNoise"    "MagnetometerNoise"    "GPSPositionNoise"    "GPSVelocityNoise"    "QuaternionNoise"    "AngularVelocityNoise"    "PositionNoise"    "VelocityNoise"    "AccelerationNoise"    "GyroscopeBiasNoise"    "AccelerometerBiasNoise"    "GeomagneticVectorNoise"    "MagnetometerBiasNoise"

Load the recorded sensor data and ground truth data.

load('insfilterAsyncTuneData.mat');

Create timetables for the sensor data and the truth data.

sensorData = timetable(Accelerometer, Gyroscope, ...
    Magnetometer, GPSPosition, GPSVelocity, 'SampleRate', 100);
groundTruth = timetable(Orientation, Position, ...
    'SampleRate', 100);

Create an insfilterAsync filter object that has a few noise properties.

filter = insfilterAsync('State', initialState, ...
    'StateCovariance', initialStateCovariance, ...
    'AccelerometerBiasNoise', 1e-7, ...
    'GyroscopeBiasNoise', 1e-7, ...
    'MagnetometerBiasNoise', 1e-7, ...
    'GeomagneticVectorNoise', 1e-7);

Create a tuner configuration object for the filter. Set the maximum iterations to two. Also, set the tunable parameters as the unspecified properties.

config = tunerconfig('insfilterAsync','MaxIterations',8);
config.TunableParameters = setdiff(config.TunableParameters, ...
    {'GeomagneticVectorNoise', 'AccelerometerBiasNoise', ...
    'GyroscopeBiasNoise', 'MagnetometerBiasNoise'});
config.TunableParameters
ans = 1×10 string
    "AccelerationNoise"    "AccelerometerNoise"    "AngularVelocityNoise"    "GPSPositionNoise"    "GPSVelocityNoise"    "GyroscopeNoise"    "MagnetometerNoise"    "PositionNoise"    "QuaternionNoise"    "VelocityNoise"

Use the tuner noise function to obtain a set of initial sensor noises used in the filter.

measNoise = tunernoise('insfilterAsync')
measNoise = struct with fields:
    AccelerometerNoise: 1
        GyroscopeNoise: 1
     MagnetometerNoise: 1
      GPSPositionNoise: 1
      GPSVelocityNoise: 1

Tune the filter and obtain the tuned parameters.

tunedParams = tune(filter,measNoise,sensorData,groundTruth,config);
    Iteration    Parameter               Metric
    _________    _________               ______
    1            AccelerationNoise       2.1345
    1            AccelerometerNoise      2.1264
    1            AngularVelocityNoise    1.9659
    1            GPSPositionNoise        1.9341
    1            GPSVelocityNoise        1.8420
    1            GyroscopeNoise          1.7589
    1            MagnetometerNoise       1.7362
    1            PositionNoise           1.7362
    1            QuaternionNoise         1.7218
    1            VelocityNoise           1.7218
    2            AccelerationNoise       1.7190
    2            AccelerometerNoise      1.7170
    2            AngularVelocityNoise    1.6045
    2            GPSPositionNoise        1.5948
    2            GPSVelocityNoise        1.5323
    2            GyroscopeNoise          1.4803
    2            MagnetometerNoise       1.4703
    2            PositionNoise           1.4703
    2            QuaternionNoise         1.4632
    2            VelocityNoise           1.4632
    3            AccelerationNoise       1.4596
    3            AccelerometerNoise      1.4548
    3            AngularVelocityNoise    1.3923
    3            GPSPositionNoise        1.3810
    3            GPSVelocityNoise        1.3322
    3            GyroscopeNoise          1.2998
    3            MagnetometerNoise       1.2976
    3            PositionNoise           1.2976
    3            QuaternionNoise         1.2943
    3            VelocityNoise           1.2943
    4            AccelerationNoise       1.2906
    4            AccelerometerNoise      1.2836
    4            AngularVelocityNoise    1.2491
    4            GPSPositionNoise        1.2258
    4            GPSVelocityNoise        1.1880
    4            GyroscopeNoise          1.1701
    4            MagnetometerNoise       1.1698
    4            PositionNoise           1.1698
    4            QuaternionNoise         1.1688
    4            VelocityNoise           1.1688
    5            AccelerationNoise       1.1650
    5            AccelerometerNoise      1.1569
    5            AngularVelocityNoise    1.1454
    5            GPSPositionNoise        1.1100
    5            GPSVelocityNoise        1.0778
    5            GyroscopeNoise          1.0709
    5            MagnetometerNoise       1.0675
    5            PositionNoise           1.0675
    5            QuaternionNoise         1.0669
    5            VelocityNoise           1.0669
    6            AccelerationNoise       1.0634
    6            AccelerometerNoise      1.0549
    6            AngularVelocityNoise    1.0549
    6            GPSPositionNoise        1.0180
    6            GPSVelocityNoise        0.9866
    6            GyroscopeNoise          0.9810
    6            MagnetometerNoise       0.9775
    6            PositionNoise           0.9775
    6            QuaternionNoise         0.9768
    6            VelocityNoise           0.9768
    7            AccelerationNoise       0.9735
    7            AccelerometerNoise      0.9652
    7            AngularVelocityNoise    0.9652
    7            GPSPositionNoise        0.9283
    7            GPSVelocityNoise        0.8997
    7            GyroscopeNoise          0.8947
    7            MagnetometerNoise       0.8920
    7            PositionNoise           0.8920
    7            QuaternionNoise         0.8912
    7            VelocityNoise           0.8912
    8            AccelerationNoise       0.8885
    8            AccelerometerNoise      0.8811
    8            AngularVelocityNoise    0.8807
    8            GPSPositionNoise        0.8479
    8            GPSVelocityNoise        0.8238
    8            GyroscopeNoise          0.8165
    8            MagnetometerNoise       0.8165
    8            PositionNoise           0.8165
    8            QuaternionNoise         0.8159
    8            VelocityNoise           0.8159

Fuse the sensor data using the tuned filter.

dt = seconds(diff(groundTruth.Time));
N = size(sensorData,1);
qEst = quaternion.zeros(N,1);
posEst = zeros(N,3);
% Iterate the filter for prediction and correction using sensor data.
for ii=1:N
    if ii ~= 1
        predict(filter, dt(ii-1));
    end
    if all(~isnan(Accelerometer(ii,:)))
        fuseaccel(filter,Accelerometer(ii,:), ...
            tunedParams.AccelerometerNoise);
    end
    if all(~isnan(Gyroscope(ii,:)))
        fusegyro(filter, Gyroscope(ii,:), ...
            tunedParams.GyroscopeNoise);
    end
    if all(~isnan(Magnetometer(ii,1)))
        fusemag(filter, Magnetometer(ii,:), ...
            tunedParams.MagnetometerNoise);
    end
    if all(~isnan(GPSPosition(ii,1)))
        fusegps(filter, GPSPosition(ii,:), ...
            tunedParams.GPSPositionNoise, GPSVelocity(ii,:), ...
            tunedParams.GPSVelocityNoise);
    end
    [posEst(ii,:), qEst(ii,:)] = pose(filter);
end

Compute the RMS errors.

orientationError = rad2deg(dist(qEst, Orientation));
rmsorientationError = sqrt(mean(orientationError.^2))
rmsorientationError = 2.7801
positionError = sqrt(sum((posEst - Position).^2, 2));
rmspositionError = sqrt(mean( positionError.^2))
rmspositionError = 0.5966

Visualize the results.

figure();
t = (0:N-1)./ groundTruth.Properties.SampleRate;
subplot(2,1,1)
plot(t, positionError, 'b');
title("Tuned insfilterAsync" + newline + "Euclidean Distance Position Error")
xlabel('Time (s)');
ylabel('Position Error (meters)')
subplot(2,1,2)
plot(t, orientationError, 'b');
title("Orientation Error")
xlabel('Time (s)');
ylabel('Orientation Error (degrees)');

Load recorded sensor data and ground truth data.

ld = load('imufilterTuneData.mat');
qTrue = ld.groundTruth.Orientation; % true orientation

Create an imufilter object and fuse the filter with the sensor data.

fuse = imufilter;
qEstUntuned = fuse(ld.sensorData.Accelerometer, ...
    ld.sensorData.Gyroscope);

Create a tunerconfig object and tune the imufilter to improve the orientation estimate.

cfg = tunerconfig('imufilter');
tune(fuse, ld.sensorData, ld.groundTruth, cfg);
    Iteration    Parameter                        Metric
    _________    _________                        ______
    1            AccelerometerNoise               0.1149
    1            GyroscopeNoise                   0.1146
    1            GyroscopeDriftNoise              0.1146
    1            LinearAccelerationNoise          0.1122
    1            LinearAccelerationDecayFactor    0.1103
    2            AccelerometerNoise               0.1102
    2            GyroscopeNoise                   0.1098
    2            GyroscopeDriftNoise              0.1098
    2            LinearAccelerationNoise          0.1070
    2            LinearAccelerationDecayFactor    0.1053
    3            AccelerometerNoise               0.1053
    3            GyroscopeNoise                   0.1048
    3            GyroscopeDriftNoise              0.1048
    3            LinearAccelerationNoise          0.1016
    3            LinearAccelerationDecayFactor    0.1002
    4            AccelerometerNoise               0.1001
    4            GyroscopeNoise                   0.0996
    4            GyroscopeDriftNoise              0.0996
    4            LinearAccelerationNoise          0.0962
    4            LinearAccelerationDecayFactor    0.0950
    5            AccelerometerNoise               0.0950
    5            GyroscopeNoise                   0.0943
    5            GyroscopeDriftNoise              0.0943
    5            LinearAccelerationNoise          0.0910
    5            LinearAccelerationDecayFactor    0.0901
    6            AccelerometerNoise               0.0900
    6            GyroscopeNoise                   0.0893
    6            GyroscopeDriftNoise              0.0893
    6            LinearAccelerationNoise          0.0862
    6            LinearAccelerationDecayFactor    0.0855
    7            AccelerometerNoise               0.0855
    7            GyroscopeNoise                   0.0848
    7            GyroscopeDriftNoise              0.0848
    7            LinearAccelerationNoise          0.0822
    7            LinearAccelerationDecayFactor    0.0818
    8            AccelerometerNoise               0.0817
    8            GyroscopeNoise                   0.0811
    8            GyroscopeDriftNoise              0.0811
    8            LinearAccelerationNoise          0.0791
    8            LinearAccelerationDecayFactor    0.0789
    9            AccelerometerNoise               0.0788
    9            GyroscopeNoise                   0.0782
    9            GyroscopeDriftNoise              0.0782
    9            LinearAccelerationNoise          0.0769
    9            LinearAccelerationDecayFactor    0.0768
    10           AccelerometerNoise               0.0768
    10           GyroscopeNoise                   0.0762
    10           GyroscopeDriftNoise              0.0762
    10           LinearAccelerationNoise          0.0754
    10           LinearAccelerationDecayFactor    0.0753
    11           AccelerometerNoise               0.0753
    11           GyroscopeNoise                   0.0747
    11           GyroscopeDriftNoise              0.0747
    11           LinearAccelerationNoise          0.0741
    11           LinearAccelerationDecayFactor    0.0740
    12           AccelerometerNoise               0.0740
    12           GyroscopeNoise                   0.0734
    12           GyroscopeDriftNoise              0.0734
    12           LinearAccelerationNoise          0.0728
    12           LinearAccelerationDecayFactor    0.0728
    13           AccelerometerNoise               0.0728
    13           GyroscopeNoise                   0.0721
    13           GyroscopeDriftNoise              0.0721
    13           LinearAccelerationNoise          0.0715
    13           LinearAccelerationDecayFactor    0.0715
    14           AccelerometerNoise               0.0715
    14           GyroscopeNoise                   0.0706
    14           GyroscopeDriftNoise              0.0706
    14           LinearAccelerationNoise          0.0700
    14           LinearAccelerationDecayFactor    0.0700
    15           AccelerometerNoise               0.0700
    15           GyroscopeNoise                   0.0690
    15           GyroscopeDriftNoise              0.0690
    15           LinearAccelerationNoise          0.0684
    15           LinearAccelerationDecayFactor    0.0684
    16           AccelerometerNoise               0.0684
    16           GyroscopeNoise                   0.0672
    16           GyroscopeDriftNoise              0.0672
    16           LinearAccelerationNoise          0.0668
    16           LinearAccelerationDecayFactor    0.0667
    17           AccelerometerNoise               0.0667
    17           GyroscopeNoise                   0.0655
    17           GyroscopeDriftNoise              0.0655
    17           LinearAccelerationNoise          0.0654
    17           LinearAccelerationDecayFactor    0.0654
    18           AccelerometerNoise               0.0654
    18           GyroscopeNoise                   0.0641
    18           GyroscopeDriftNoise              0.0641
    18           LinearAccelerationNoise          0.0640
    18           LinearAccelerationDecayFactor    0.0639
    19           AccelerometerNoise               0.0639
    19           GyroscopeNoise                   0.0627
    19           GyroscopeDriftNoise              0.0627
    19           LinearAccelerationNoise          0.0627
    19           LinearAccelerationDecayFactor    0.0624
    20           AccelerometerNoise               0.0624
    20           GyroscopeNoise                   0.0614
    20           GyroscopeDriftNoise              0.0614
    20           LinearAccelerationNoise          0.0613
    20           LinearAccelerationDecayFactor    0.0613

Fuse the sensor data again using the tuned filter.

qEstTuned = fuse(ld.sensorData.Accelerometer, ...
    ld.sensorData.Gyroscope);

Compare the tuned and untuned filter RMS error performances.

dUntuned = rad2deg(dist(qEstUntuned, qTrue));
dTuned = rad2deg(dist(qEstTuned, qTrue));
rmsUntuned = sqrt(mean(dUntuned.^2))
rmsUntuned = 6.5864
rmsTuned = sqrt(mean(dTuned.^2))
rmsTuned = 3.5098

Visualize the results.

N = numel(dUntuned);
t = (0:N-1)./ fuse.SampleRate;
plot(t, dUntuned, 'r', t, dTuned, 'b');
legend('Untuned', 'Tuned');
title('imufilter - Tuned vs Untuned Error')
xlabel('Time (s)');
ylabel('Orientation Error (degrees)');

Introduced in R2020b