Main Content

tunerconfig

Fusion filter tuner configuration options

Since R2020b

Description

The tunerconfig object creates a tuner configuration for a fusion filter used to tune the filter for reduced estimation error.

Creation

Description

config = tunerconfig(filterName) creates a tunerconfig object controlling the optimization algorithm of the tune function of the fusion filter by specifying a filter name.

example

config = tunerconfig(filter) creates a tunerconfig object controlling the optimization algorithm of the tune function of the fusion filter by specifying a filter object.

example

config = tunerconfig(filterName,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, tunerconfig('imufilter','MaxIterations',3) create a tunerconfig object for the imufilter object with the a maximum of three allowed iterations.

Input Arguments

expand all

Fusion filter name, specified as one of these options:

  • 'imufilter'

  • 'ahrsfilter'

  • 'ahrs10filter'

  • 'insfilterAsync'

  • 'insfilterMARG'

  • 'insfitlerErrorState'

  • 'insfilterNonholonomic'

Properties

expand all

This property is read-only.

Class name of filter, specified as a string. Its value is one of these strings:

  • "imufilter"

  • "ahrsfilter"

  • "ahrs10filter"

  • "insfilterAsync"

  • "insfilterMARG"

  • "insfitlerErrorState"

  • "insfilterNonholonomic"

Tunable parameters, specified as an array of strings or a cell array.

  • If you want to tune all the elements in each parameter together (scaling up or down all the elements in a process noise matrix for example), then specify the property as an array of strings. Each string corresponds to a property name.

    For filter objects other than the insEKF object, this is the default option. With the default option, the property contains all the tunable parameter names as an array of strings. Each string is a tunable property name of the fusion filter.

  • If you want to tune a subset of elements for at least one noise parameter, specify it as a cell array. The number of cells is the number of parameters that you want to tune.

    • You can specify any cell element as a character vector, representing the property that you want to tune. In this case, the filter tunes all the elements in the property together.

    • You can also specify any cell element as a 1-by-2 cell array, in which the first cell is a character vector, representing the property that you want tune. The second cell in the cell array is a vector of indices, representing the elements that you want to tune in the property. These indices are column-based indices.

    This is default option for the insEKF object.

    For example, running the following:

    >> filter = insEKF;
    config = tunerconfig(filter);
    tunable = config.TunableParameters
    and you can obtain:
    tunable =
    
      1×3 cell array
    
        {1×2 cell}    {'AccelerometerNoise'}    {'GyroscopeNoise'}
    
    >> firstCell = tunable{1}
    
    firstCell =
    
      1×2 cell array
    
        {'AdditiveProcessNoise'}    {[1 15 29 43 57 71 85 99 113 127 141 155 169]}

    In the filter, the additive process noise matrix is a 13-by-13 matrices, and the column-based indices represent all the diagonal elements of the matrix.

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.

Minimum change in cost to continue tuning, specified as a nonnegative scalar. If the change in cost is smaller than the specified tolerance, the tuning process stops.

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.

Dependencies

To enable this property, set the Cost property to 'Custom'.

Output function called at each iteration, specified as a function handle. The function must use the following syntax:

stop = myOutputFcn(params,tunerValues)

params is a structure of the current best estimate of each parameter at the end of the current iteration. tunerValues is a structure containing information of the tuner configuration, sensor data, and truth data. It has these fields:

Field NameDescription
IterationIteration count of the tuner, specified as a positive integer
SensorDataSensor data input to the tune function
GroundTruthGround truth input to the tune function
Configurationtunerconfig object used for tuning
CostTuning cost at the end of the current iteration

Tip

You can use the built-in function tunerPlotPose to visualize the truth data and the estimates for most of your tuning applications. See the Visualize Tuning Results Using tunerPlotPose example for details.

Examples

collapse all

Create a tunerconfig object for the insfilterAsync object.

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

               Filter: "insfilterAsync"
    TunableParameters: ["AccelerometerNoise"    "GyroscopeNoise"    "MagnetometerNoise"    "GPSPositionNoise"    "GPSVelocityNoise"    "QuaternionNoise"    "AngularVelocityNoise"    "PositionNoise"    "VelocityNoise"    …    ] (1×14 string)
          StepForward: 1.1000
         StepBackward: 0.5000
        MaxIterations: 20
       ObjectiveLimit: 0.1000
    FunctionTolerance: 0
              Display: iter
                 Cost: RMS
            OutputFcn: []

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",ObjectiveLimit=0.03);
reset(fuse)
tune(fuse,ld.sensorData,ld.groundTruth,cfg);
    Iteration    Parameter                        Metric
    _________    _________                        ______
    1            AccelerometerNoise               0.0857
    1            GyroscopeNoise                   0.0855
    1            GyroscopeDriftNoise              0.0855
    1            LinearAccelerationNoise          0.0851
    1            LinearAccelerationDecayFactor    0.0844
    2            AccelerometerNoise               0.0844
    2            GyroscopeNoise                   0.0842
    2            GyroscopeDriftNoise              0.0842
    2            LinearAccelerationNoise          0.0840
    2            LinearAccelerationDecayFactor    0.0836
    3            AccelerometerNoise               0.0836
    3            GyroscopeNoise                   0.0834
    3            GyroscopeDriftNoise              0.0834
    3            LinearAccelerationNoise          0.0834
    3            LinearAccelerationDecayFactor    0.0831
    4            AccelerometerNoise               0.0831
    4            GyroscopeNoise                   0.0829
    4            GyroscopeDriftNoise              0.0829
    4            LinearAccelerationNoise          0.0829
    4            LinearAccelerationDecayFactor    0.0827
    5            AccelerometerNoise               0.0827
    5            GyroscopeNoise                   0.0824
    5            GyroscopeDriftNoise              0.0824
    5            LinearAccelerationNoise          0.0824
    5            LinearAccelerationDecayFactor    0.0822
    6            AccelerometerNoise               0.0822
    6            GyroscopeNoise                   0.0819
    6            GyroscopeDriftNoise              0.0819
    6            LinearAccelerationNoise          0.0819
    6            LinearAccelerationDecayFactor    0.0818
    7            AccelerometerNoise               0.0818
    7            GyroscopeNoise                   0.0814
    7            GyroscopeDriftNoise              0.0814
    7            LinearAccelerationNoise          0.0814
    7            LinearAccelerationDecayFactor    0.0813
    8            AccelerometerNoise               0.0813
    8            GyroscopeNoise                   0.0808
    8            GyroscopeDriftNoise              0.0808
    8            LinearAccelerationNoise          0.0808
    8            LinearAccelerationDecayFactor    0.0807
    9            AccelerometerNoise               0.0807
    9            GyroscopeNoise                   0.0802
    9            GyroscopeDriftNoise              0.0802
    9            LinearAccelerationNoise          0.0802
    9            LinearAccelerationDecayFactor    0.0801
    10           AccelerometerNoise               0.0801
    10           GyroscopeNoise                   0.0794
    10           GyroscopeDriftNoise              0.0794
    10           LinearAccelerationNoise          0.0794
    10           LinearAccelerationDecayFactor    0.0794
    11           AccelerometerNoise               0.0794
    11           GyroscopeNoise                   0.0785
    11           GyroscopeDriftNoise              0.0785
    11           LinearAccelerationNoise          0.0785
    11           LinearAccelerationDecayFactor    0.0785
    12           AccelerometerNoise               0.0785
    12           GyroscopeNoise                   0.0775
    12           GyroscopeDriftNoise              0.0775
    12           LinearAccelerationNoise          0.0775
    12           LinearAccelerationDecayFactor    0.0774
    13           AccelerometerNoise               0.0774
    13           GyroscopeNoise                   0.0762
    13           GyroscopeDriftNoise              0.0762
    13           LinearAccelerationNoise          0.0762
    13           LinearAccelerationDecayFactor    0.0761
    14           AccelerometerNoise               0.0761
    14           GyroscopeNoise                   0.0746
    14           GyroscopeDriftNoise              0.0746
    14           LinearAccelerationNoise          0.0746
    14           LinearAccelerationDecayFactor    0.0745
    15           AccelerometerNoise               0.0745
    15           GyroscopeNoise                   0.0727
    15           GyroscopeDriftNoise              0.0727
    15           LinearAccelerationNoise          0.0727
    15           LinearAccelerationDecayFactor    0.0726
    16           AccelerometerNoise               0.0726
    16           GyroscopeNoise                   0.0706
    16           GyroscopeDriftNoise              0.0706
    16           LinearAccelerationNoise          0.0705
    16           LinearAccelerationDecayFactor    0.0705
    17           AccelerometerNoise               0.0705
    17           GyroscopeNoise                   0.0684
    17           GyroscopeDriftNoise              0.0684
    17           LinearAccelerationNoise          0.0683
    17           LinearAccelerationDecayFactor    0.0683
    18           AccelerometerNoise               0.0683
    18           GyroscopeNoise                   0.0662
    18           GyroscopeDriftNoise              0.0662
    18           LinearAccelerationNoise          0.0662
    18           LinearAccelerationDecayFactor    0.0662
    19           AccelerometerNoise               0.0662
    19           GyroscopeNoise                   0.0644
    19           GyroscopeDriftNoise              0.0644
    19           LinearAccelerationNoise          0.0644
    19           LinearAccelerationDecayFactor    0.0644
    20           AccelerometerNoise               0.0644
    20           GyroscopeNoise                   0.0630
    20           GyroscopeDriftNoise              0.0630
    20           LinearAccelerationNoise          0.0630
    20           LinearAccelerationDecayFactor    0.0630

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 = 
4.9108
rmsTuned = sqrt(mean(dTuned.^2))
rmsTuned = 
3.6116

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)");

Figure contains an axes object. The axes object with title imufilter - Tuned vs Untuned Error, xlabel Time (s), ylabel Orientation Error (degrees) contains 2 objects of type line. These objects represent Untuned, Tuned.

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. Define the OutputFcn property as a customized function, myOutputFcn, which saves the latest tuned parameters in a MAT file.

config = tunerconfig('insfilterAsync', ...
    'MaxIterations',5, ...
    'Display','none', ...
    'OutputFcn', @myOutputFcn);
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);

Display the save parameters using the saved file.

fileObject = matfile('myfile.mat');
fileObject.params
ans = struct with fields:
         AccelerationNoise: [88.8995 88.8995 88.8995]
    AccelerometerBiasNoise: [1.0000e-07 1.0000e-07 1.0000e-07]
        AccelerometerNoise: 0.7942
      AngularVelocityNoise: [0.0089 0.0089 0.0089]
          GPSPositionNoise: 1.1664
          GPSVelocityNoise: 0.5210
    GeomagneticVectorNoise: [1.0000e-07 1.0000e-07 1.0000e-07]
        GyroscopeBiasNoise: [1.0000e-07 1.0000e-07 1.0000e-07]
            GyroscopeNoise: 0.5210
     MagnetometerBiasNoise: [1.0000e-07 1.0000e-07 1.0000e-07]
         MagnetometerNoise: 1.0128
             PositionNoise: [5.2100e-07 5.2100e-07 5.2100e-07]
           QuaternionNoise: [1.3239e-06 1.3239e-06 1.3239e-06 1.3239e-06]
         ReferenceLocation: [0 0 0]
                     State: [28×1 double]
           StateCovariance: [28×28 double]
             VelocityNoise: [6.3678e-07 6.3678e-07 6.3678e-07]

The output function

function stop = myOutputFcn(params, ~)
save('myfile.mat','params'); % overwrite the file with latest
stop = false;
end

Version History

Introduced in R2020b