Main Content

tune

Tune insfilterAsync parameters to reduce estimation error

Since R2020b

Description

tunedMeasureNoise = tune(filter,measureNoise,sensorData,groundTruth) adjusts the properties of the insfilterAsync filter object, filter, and measurement noises to reduce the root-mean-squared (RMS) state estimation error between the fused sensor data and the ground truth. The function also returns the tuned measurement noise, tunedMeasureNoise. The function uses the property values in the filter and the measurement noise provided in the measureNoise structure as the initial estimate for the optimization algorithm.

example

tunedMeasureNoise = tune(___,config) specifies the tuning configuration based on a tunerconfig object, config.

Examples

collapse all

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

Input Arguments

collapse all

Filter object, specified as an insfilterAsync object.

Measurement noise, specified as a structure. The function uses the measurement noise input as the initial guess for tuning the measurement noise. The structure must contain these fields:

Field nameDescription
AccelerometerNoiseVariance of accelerometer noise, specified as a scalar in (m/s2)2
GyroscopeNoiseVariance of gyroscope noise, specified as a scalar in (rad/s)2
MagnetometerNoiseVariance of magnetometer noise, specified as a scalar in (μT)2
GPSPositionNoiseVariance of GPS position noise, specified as a scalar in m2
GPSVelocityNoiseVariance of GPS velocity noise, specified as a scalar in (m/s)2

Sensor data, specified as a timetable. In each row, the time and sensor data is specified as:

  • Time — Time at which the data is obtained, specified as a scalar in seconds.

  • Accelerometer — Accelerometer data, specified as a 1-by-3 vector of scalars in m2/s.

  • Gyroscope — Gyroscope data, specified as a 1-by-3 vector of scalars in rad/s.

  • Magnetometer — Magnetometer data, specified as a 1-by-3 vector of scalars in μT.

  • GPSPosition — GPS position data, specified as a 1-by-3 vector of latitude in degrees, longitude in degrees, and altitude in meters.

  • GPSVelocity — GPS velocity data, specified as a 1-by-3 vector of scalars in m/s.

If a sensor does not produce measurements, specify the corresponding entry as NaN. If you set the Cost property of the tuner configuration input, config, to Custom, then you can use other data types for the sensorData input based on your choice.

Ground truth data, specified as a timetable. In each row, the table can optionally contain any of these variables:

  • Orientation — Orientation from the navigation frame to the body frame, specified as a quaternion or a 3-by-3 rotation matrix.

  • AngularVelocity — Angular velocity in body frame, specified as a 1-by-3 vector of scalars in rad/s.

  • Position — Position in navigation frame, specified as a 1-by-3 vector of scalars in meters.

  • Velocity — Velocity in navigation frame, specified as a 1-by-3 vector of scalars in m/s.

  • Acceleration — Acceleration in navigation frame, specified as a 1-by-3 vector of scalars in m2/s.

  • AccelerometerBias — Accelerometer delta angle bias in body frame, specified as a 1-by-3 vector of scalars in m2/s.

  • GyroscopeBias — Gyroscope delta angle bias in body frame, specified as a 1-by-3 vector of scalars in rad/s.

  • GeomagneticFieldVector — Geomagnetic field vector in navigation frame, specified as a 1-by-3 vector of scalars.

  • MagnetometerBias — Magnetometer bias in body frame, specified as a 1-by-3 vector of scalars in μT.

The function processes each row of the sensorData and groundTruth tables sequentially to calculate the state estimate and RMS error from the ground truth. State variables not present in groundTruth input are ignored for the comparison. The sensorData and the groundTruth tables must have the same time steps.

If you set the Cost property of the tuner configuration input, config, to Custom, then you can use other data types for the groundTruth input based on your choice.

Tuner configuration, specified as a tunerconfig object.

Output Arguments

collapse all

Tuned measurement noise, returned as a structure. The structure contains these fields.

Field nameDescription
AccelerometerNoiseVariance of accelerometer noise, specified as a scalar in (m2/s)2
GyroscopeNoiseVariance of gyroscope noise, specified as a scalar in (rad/s)2
MagnetometerNoiseVariance of magnetometer noise, specified as a scalar in (μT)2
GPSPositionNoiseVariance of GPS position noise, specified as a scalar in m2
GPSVelocityNoiseVariance of GPS velocity noise, specified as a scalar in (m/s)2

References

[1] Abbeel, P., Coates, A., Montemerlo, M., Ng, A.Y. and Thrun, S. Discriminative Training of Kalman Filters. In Robotics: Science and systems, Vol. 2, pp. 1, 2005.

Version History

Introduced in R2020b