automatic tuning of the insfilterasync filter -pg电子麻将胡了
the (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 (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 4.5898
1 gyroscopenoise 4.5694
1 magnetometernoise 4.5481
1 gpspositionnoise 4.4737
1 gpsvelocitynoise 4.2984
1 quaternionnoise 4.2984
1 angularvelocitynoise 3.9668
1 positionnoise 3.9668
1 velocitynoise 3.9668
1 accelerationnoise 3.9556
1 gyroscopebiasnoise 3.9556
1 accelerometerbiasnoise 3.9511
1 geomagneticvectornoise 3.9511
1 magnetometerbiasnoise 3.9360
2 accelerometernoise 3.9360
2 gyroscopenoise 3.9360
2 magnetometernoise 3.9064
2 gpspositionnoise 3.9064
2 gpsvelocitynoise 3.7129
2 quaternionnoise 3.7122
2 angularvelocitynoise 3.0116
2 positionnoise 3.0116
2 velocitynoise 3.0116
2 accelerationnoise 2.9850
2 gyroscopebiasnoise 2.9850
2 accelerometerbiasnoise 2.9824
2 geomagneticvectornoise 2.9824
2 magnetometerbiasnoise 2.9821
3 accelerometernoise 2.9821
3 gyroscopenoise 2.9613
3 magnetometernoise 2.9432
3 gpspositionnoise 2.9432
3 gpsvelocitynoise 2.8373
3 quaternionnoise 2.8369
3 angularvelocitynoise 2.6993
3 positionnoise 2.6993
3 velocitynoise 2.6993
3 accelerationnoise 2.6993
3 gyroscopebiasnoise 2.6993
3 accelerometerbiasnoise 2.6971
3 geomagneticvectornoise 2.6971
3 magnetometerbiasnoise 2.6955
4 accelerometernoise 2.6941
4 gyroscopenoise 2.6797
4 magnetometernoise 2.6676
4 gpspositionnoise 2.6626
4 gpsvelocitynoise 2.5530
4 quaternionnoise 2.5530
4 angularvelocitynoise 2.4285
4 positionnoise 2.4285
4 velocitynoise 2.4285
4 accelerationnoise 2.4232
4 gyroscopebiasnoise 2.4232
4 accelerometerbiasnoise 2.4217
4 geomagneticvectornoise 2.4217
4 magnetometerbiasnoise 2.4023
5 accelerometernoise 2.4019
5 gyroscopenoise 2.3900
5 magnetometernoise 2.3900
5 gpspositionnoise 2.3887
5 gpsvelocitynoise 2.2986
5 quaternionnoise 2.2986
5 angularvelocitynoise 2.1945
5 positionnoise 2.1945
5 velocitynoise 2.1945
5 accelerationnoise 2.1863
5 gyroscopebiasnoise 2.1863
5 accelerometerbiasnoise 2.1856
5 geomagneticvectornoise 2.1856
5 magnetometerbiasnoise 2.1615
6 accelerometernoise 2.1613
6 gyroscopenoise 2.1393
6 magnetometernoise 2.1199
6 gpspositionnoise 2.1112
6 gpsvelocitynoise 2.0140
6 quaternionnoise 2.0140
6 angularvelocitynoise 1.9288
6 positionnoise 1.9288
6 velocitynoise 1.9288
6 accelerationnoise 1.9242
6 gyroscopebiasnoise 1.9242
6 accelerometerbiasnoise 1.9216
6 geomagneticvectornoise 1.9216
6 magnetometerbiasnoise 1.9054
7 accelerometernoise 1.9047
7 gyroscopenoise 1.8887
7 magnetometernoise 1.8820
7 gpspositionnoise 1.8803
7 gpsvelocitynoise 1.7713
7 quaternionnoise 1.7712
7 angularvelocitynoise 1.7145
7 positionnoise 1.7145
7 velocitynoise 1.7145
7 accelerationnoise 1.7122
7 gyroscopebiasnoise 1.7122
7 accelerometerbiasnoise 1.7112
7 geomagneticvectornoise 1.7112
7 magnetometerbiasnoise 1.6873
8 accelerometernoise 1.6853
8 gyroscopenoise 1.6790
8 magnetometernoise 1.6694
8 gpspositionnoise 1.6565
8 gpsvelocitynoise 1.5700
8 quaternionnoise 1.5676
8 angularvelocitynoise 1.5366
8 positionnoise 1.5366
8 velocitynoise 1.5366
8 accelerationnoise 1.5366
8 gyroscopebiasnoise 1.5366
8 accelerometerbiasnoise 1.5353
8 geomagneticvectornoise 1.5337
8 magnetometerbiasnoise 1.5166
9 accelerometernoise 1.5129
9 gyroscopenoise 1.5117
9 magnetometernoise 1.5114
9 gpspositionnoise 1.4953
9 gpsvelocitynoise 1.4106
9 quaternionnoise 1.4106
9 angularvelocitynoise 1.3742
9 positionnoise 1.3742
9 velocitynoise 1.3742
9 accelerationnoise 1.3731
9 gyroscopebiasnoise 1.3731
9 accelerometerbiasnoise 1.3715
9 geomagneticvectornoise 1.3715
9 magnetometerbiasnoise 1.3576
10 accelerometernoise 1.3528
10 gyroscopenoise 1.3528
10 magnetometernoise 1.3510
10 gpspositionnoise 1.3322
10 gpsvelocitynoise 1.2512
10 quaternionnoise 1.2512
10 angularvelocitynoise 1.2507
10 positionnoise 1.2507
10 velocitynoise 1.2507
10 accelerationnoise 1.2497
10 gyroscopebiasnoise 1.2497
10 accelerometerbiasnoise 1.2480
10 geomagneticvectornoise 1.2480
10 magnetometerbiasnoise 1.2301
11 accelerometernoise 1.2233
11 gyroscopenoise 1.2222
11 magnetometernoise 1.2220
11 gpspositionnoise 1.2008
11 gpsvelocitynoise 1.1043
11 quaternionnoise 1.1043
11 angularvelocitynoise 1.1038
11 positionnoise 1.1038
11 velocitynoise 1.1038
11 accelerationnoise 1.1028
11 gyroscopebiasnoise 1.1028
11 accelerometerbiasnoise 1.1013
11 geomagneticvectornoise 1.1013
11 magnetometerbiasnoise 1.0867
12 accelerometernoise 1.0782
12 gyroscopenoise 1.0767
12 magnetometernoise 1.0733
12 gpspositionnoise 1.0505
12 gpsvelocitynoise 0.9564
12 quaternionnoise 0.9563
12 angularvelocitynoise 0.9563
12 positionnoise 0.9563
12 velocitynoise 0.9563
12 accelerationnoise 0.9550
12 gyroscopebiasnoise 0.9550
12 accelerometerbiasnoise 0.9534
12 geomagneticvectornoise 0.9534
12 magnetometerbiasnoise 0.9402
13 accelerometernoise 0.9303
13 gyroscopenoise 0.9291
13 magnetometernoise 0.9269
13 gpspositionnoise 0.9036
13 gpsvelocitynoise 0.8072
13 quaternionnoise 0.8071
13 angularvelocitynoise 0.8071
13 positionnoise 0.8071
13 velocitynoise 0.8071
13 accelerationnoise 0.8065
13 gyroscopebiasnoise 0.8065
13 accelerometerbiasnoise 0.8052
13 geomagneticvectornoise 0.8052
13 magnetometerbiasnoise 0.7901
14 accelerometernoise 0.7806
14 gyroscopenoise 0.7806
14 magnetometernoise 0.7768
14 gpspositionnoise 0.7547
14 gpsvelocitynoise 0.6932
14 quaternionnoise 0.6930
14 angularvelocitynoise 0.6923
14 positionnoise 0.6923
14 velocitynoise 0.6923
14 accelerationnoise 0.6906
14 gyroscopebiasnoise 0.6906
14 accelerometerbiasnoise 0.6896
14 geomagneticvectornoise 0.6896
14 magnetometerbiasnoise 0.6801
15 accelerometernoise 0.6704
15 gyroscopenoise 0.6676
15 magnetometernoise 0.6653
15 gpspositionnoise 0.6469
15 gpsvelocitynoise 0.6047
15 quaternionnoise 0.6047
15 angularvelocitynoise 0.6037
15 positionnoise 0.6037
15 velocitynoise 0.6037
15 accelerationnoise 0.6019
15 gyroscopebiasnoise 0.6019
15 accelerometerbiasnoise 0.6015
15 geomagneticvectornoise 0.6015
15 magnetometerbiasnoise 0.5913
[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');

% orientation error figure; plot(t, rad2deg(dist(orientation, orienttunedest)), ... t, rad2deg(dist(orientation, orientuntunedest))); title('orientation error'); ylabel('degrees'); legend('tuned', 'untuned');
