Hauptinhalt

Diese Seite wurde mithilfe maschineller Übersetzung übersetzt. Klicken Sie hier, um die neueste Version auf Englisch zu sehen.

IMU- und GPS-Fusion für die Trägheitsnavigation

Dieses Beispiel zeigt, wie Sie einen IMU + GPS-Fusionsalgorithmus erstellen können, der für unbemannte Luftfahrzeuge (UAVs) oder Quadcopter geeignet ist.

In diesem Beispiel werden Beschleunigungsmesser, Gyroskope, Magnetometer und GPS verwendet, um die Ausrichtung und Position eines UAV zu bestimmen.

Simulationsaufbau

Stellen Sie die Abtastraten ein. In einem typischen System laufen der Beschleunigungsmesser und das Gyroskop mit relativ hohen Abtastraten. Die Komplexität der Verarbeitung der Daten dieser Sensoren im Fusionsalgorithmus ist relativ gering. Im Gegensatz dazu arbeiten das GPS und in manchen Fällen auch das Magnetometer mit relativ niedrigen Abtastraten, und die mit ihrer Verarbeitung verbundene Komplexität ist hoch. Bei diesem Fusionsalgorithmus werden die Magnetometer- und GPS-Samples zusammen mit derselben niedrigen Rate und die Beschleunigungsmesser- und Gyroskop-Samples zusammen mit derselben hohen Rate verarbeitet.

Um diese Konfiguration zu simulieren, werden die IMU (Beschleunigungsmesser, Gyroskop und Magnetometer) mit 160 Hz und das GPS mit 1 Hz abgetastet. Da nur eine von 160 Abtastungen des Magnetometers an den Fusionsalgorithmus weitergegeben wird, könnte die Abtastung des Magnetometers in einem realen System mit einer viel geringeren Rate erfolgen.

imuFs = 160;
gpsFs = 1;

% Define where on the Earth this simulated scenario takes place using the
% latitude, longitude and altitude.
refloc = [42.2825 -72.3430 53.0352];


% Validate that the |gpsFs| divides |imuFs|. This allows the sensor sample 
% rates to be simulated using a nested for loop without complex sample rate
% matching.

imuSamplesPerGPS = (imuFs/gpsFs);
assert(imuSamplesPerGPS == fix(imuSamplesPerGPS), ...
    'GPS sampling rate must be an integer factor of IMU sampling rate.');

Fusion Filter

Erstellen Sie den Filter, um IMU- und GPS-Messungen zu kombinieren. Der Fusionsfilter verwendet einen erweiterten Kalman-Filter, um Ausrichtung (als Quaternion), Geschwindigkeit, Position, Sensorverzerrungen und den geomagnetischen Vektor zu verfolgen.

Dieses insfilterMARG verfügt über einige Methoden zur Verarbeitung von Sensordaten, darunter predict, fusemag und fusegps. Die Methode predict verwendet die Beschleunigungsmesser- und Gyroskopproben der IMU als Eingaben. Rufen Sie die Methode predict jedes Mal auf, wenn der Beschleunigungsmesser und das Gyroskop abgetastet werden. Diese Methode sagt die Zustände auf Grundlage des Beschleunigungsmessers und des Gyroskops einen Zeitschritt im Voraus voraus. Hier wird die Fehlerkovarianz des erweiterten Kalman-Filters aktualisiert.

Die Methode fusegps verwendet GPS-Samples als Eingabe. Diese Methode aktualisiert die Filterzustände basierend auf GPS-Samples, indem sie einen Kalman-Gewinn berechnet, der die verschiedenen Sensoreingaben entsprechend ihrer Unsicherheit gewichtet. Auch hier wird eine Fehlerkovarianz aktualisiert, diesmal ebenfalls unter Verwendung der Kalman-Verstärkung.

Die fusemag-Methode ist ähnlich, aktualisiert jedoch die Zustände, die Kalman-Verstärkung und die Fehlerkovarianz basierend auf den Magnetometerproben.

Obwohl insfilterMARG Beschleunigungsmesser- und Gyroskopproben als Eingaben verwendet, werden diese integriert, um jeweils Deltageschwindigkeiten und Deltawinkel zu berechnen. Der Filter verfolgt die Vorspannung des Magnetometers und diese integrierten Signale.

fusionfilt = insfilterMARG;
fusionfilt.IMUSampleRate = imuFs;
fusionfilt.ReferenceLocation = refloc;

UAV-Flugbahn

Dieses Beispiel verwendet eine gespeicherte, von einem UAV aufgezeichnete Flugbahn als Grundwahrheit. Diese Flugbahn wird mehreren Sensorsimulatoren zugeführt, um simulierte Datenströme von Beschleunigungsmesser, Gyroskop, Magnetometer und GPS zu berechnen.

% Load the "ground truth" UAV trajectory.
load LoggedQuadcopter.mat trajData;
trajOrient = trajData.Orientation;
trajVel = trajData.Velocity;
trajPos = trajData.Position;
trajAcc = trajData.Acceleration;
trajAngVel = trajData.AngularVelocity;

% Initialize the random number generator used in the simulation of sensor
% noise.
rng(1)

GPS-Sensor

Richten Sie das GPS auf die angegebene Abtastrate und den angegebenen Referenzort ein. Die anderen Parameter steuern die Art des Rauschens im Ausgangssignal.

gps = gpsSensor('UpdateRate', gpsFs);
gps.ReferenceLocation = refloc;     
gps.DecayFactor = 0.5;              % Random walk noise parameter 
gps.HorizontalPositionAccuracy = 1.6;   
gps.VerticalPositionAccuracy =  1.6;
gps.VelocityAccuracy = 0.1;

IMU-Sensoren

Normalerweise verwendet ein UAV einen integrierten MARG-Sensor (Magnetic, Angular Rate, Gravity) zur Lagebestimmung. Um einen MARG-Sensor zu modellieren, definieren Sie ein IMU-Sensormodell, das einen Beschleunigungsmesser, ein Gyroskop und ein Magnetometer enthält. In einer realen Anwendung könnten die drei Sensoren aus einem einzigen integrierten Schaltkreis oder aus separaten Schaltkreisen stammen. Die hier eingestellten Eigenschaftswerte sind typisch für kostengünstige MEMS-Sensoren.

imu = imuSensor('accel-gyro-mag', 'SampleRate', imuFs);
imu.MagneticField = [19.5281 -5.0741 48.0067];

% Accelerometer
imu.Accelerometer.MeasurementRange =  19.6133;
imu.Accelerometer.Resolution = 0.0023928;
imu.Accelerometer.ConstantBias = 0.19;
imu.Accelerometer.NoiseDensity = 0.0012356;

% Gyroscope
imu.Gyroscope.MeasurementRange = deg2rad(250);
imu.Gyroscope.Resolution = deg2rad(0.0625);
imu.Gyroscope.ConstantBias = deg2rad(3.125);
imu.Gyroscope.AxesMisalignment = 1.5;
imu.Gyroscope.NoiseDensity = deg2rad(0.025);

% Magnetometer
imu.Magnetometer.MeasurementRange = 1000;
imu.Magnetometer.Resolution = 0.1;
imu.Magnetometer.ConstantBias = 100;
imu.Magnetometer.NoiseDensity = 0.3/ sqrt(50);

Initialisieren Sie den Zustandsvektor des insfilterMARG

Das insfilterMARG verfolgt die Pose-Zustände in einem 22-Element-Vektor. Die Zustände sind:

     State                           Units        State Vector Index
 Orientation as a quaternion                      1:4
 Position (NED)                      m            5:7
 Velocity (NED)                      m/s          8:10 
 Delta Angle Bias (XYZ)              rad          11:13
 Delta Velocity Bias (XYZ)           m/s          14:16
 Geomagnetic Field Vector (NED)      uT           17:19
 Magnetometer Bias (XYZ)             uT           20:22

Die Ground Truth wird zur Initialisierung der Filterzustände verwendet, sodass der Filter schnell zu guten Antworten konvergiert.

% Initialize the states of the filter 

initstate = zeros(22,1);
initstate(1:4) = compact( meanrot(trajOrient(1:100))); 
initstate(5:7) = mean( trajPos(1:100,:), 1);
initstate(8:10) = mean( trajVel(1:100,:), 1);
initstate(11:13) =  imu.Gyroscope.ConstantBias./imuFs;
initstate(14:16) =  imu.Accelerometer.ConstantBias./imuFs;
initstate(17:19) =  imu.MagneticField;
initstate(20:22) = imu.Magnetometer.ConstantBias;

fusionfilt.State = initstate;

Initialisieren Sie die Varianzen von insfilterMARG

Die insfilterMARG-Messgeräusche beschreiben, wie viel Rauschen die Sensorwerte verfälscht. Diese Werte basieren auf den Parametern imuSensor und gpsSensor.

Das Prozessrauschen beschreibt, wie gut die Filtergleichungen die Zustandsentwicklung beschreiben. Prozessgeräusche werden empirisch durch Parameter-Sweepen ermittelt, um die Positions- und Orientierungsschätzungen des Filters gemeinsam zu optimieren.

% Measurement noises
Rmag = 0.0862; % Magnetometer measurement noise
Rvel = 0.0051; % GPS Velocity measurement noise
Rpos = 5.169; % GPS Position measurement noise

% Process noises
fusionfilt.AccelerometerBiasNoise =  0.010716; 
fusionfilt.AccelerometerNoise = 9.7785; 
fusionfilt.GyroscopeBiasNoise = 1.3436e-14; 
fusionfilt.GyroscopeNoise =  0.00016528; 
fusionfilt.MagnetometerBiasNoise = 2.189e-11;
fusionfilt.GeomagneticVectorNoise = 7.67e-13;

% Initial error covariance
fusionfilt.StateCovariance = 1e-9*eye(22);

Bereiche initialisieren

Der HelperScrollingPlotter-Bereich ermöglicht die Darstellung von Variablen im Zeitverlauf. Es wird hier verwendet, um Posenfehler zu verfolgen. Der HelperPoseViewer-Bereich ermöglicht eine 3D-Visualisierung der Filterschätzung und der Ground-Truth-Pose. Die Zielfernrohre können die Simulation verlangsamen. Um einen Bereich zu deaktivieren, setzen Sie die entsprechende logische Variable auf false.

useErrScope = true;  % Turn on the streaming error plot
usePoseView = true;  % Turn on the 3-D pose viewer

if useErrScope
    errscope = HelperScrollingPlotter(...
        'NumInputs', 4, ...
        'TimeSpan', 10, ...
        'SampleRate', imuFs, ...
        'YLabel', {'degrees', ...
        'meters', ...
        'meters', ...
        'meters'}, ...
        'Title', {'Quaternion Distance', ...
        'Position X Error', ...
        'Position Y Error', ...
        'Position Z Error'}, ...
        'YLimits', ...
        [ -3, 3
        -2, 2
        -2 2
        -2 2]);
end

if usePoseView
    posescope = HelperPoseViewer(...
        'XPositionLimits', [-15 15], ...
        'YPositionLimits', [-15, 15], ...
        'ZPositionLimits', [-10 10]);
end

Simulationsschleife

Die Hauptsimulationsschleife ist eine While-Schleife mit einer verschachtelten For-Schleife. Die While-Schleife wird bei gpsFs ausgeführt, was der GPS-Abtastrate entspricht. Die verschachtelte For-Schleife wird bei imuFs ausgeführt, was der IMU-Abtastrate entspricht. Die Oszilloskope werden mit der IMU-Abtastrate aktualisiert.

% Loop setup - |trajData| has about 142 seconds of recorded data.
secondsToSimulate = 50; % simulate about 50 seconds
numsamples = secondsToSimulate*imuFs;

loopBound = floor(numsamples);
loopBound = floor(loopBound/imuFs)*imuFs; % ensure enough IMU Samples

% Log data for final metric computation.
pqorient = quaternion.zeros(loopBound,1);
pqpos = zeros(loopBound,3);

fcnt = 1;

while(fcnt <=loopBound)
    % |predict| loop at IMU update frequency.
    for ff=1:imuSamplesPerGPS
        % Simulate the IMU data from the current pose.
        [accel, gyro, mag] = imu(trajAcc(fcnt,:), trajAngVel(fcnt, :), ...
            trajOrient(fcnt));
        
        % Use the |predict| method to estimate the filter state based
        % on the simulated accelerometer and gyroscope signals.
        predict(fusionfilt, accel, gyro);
        
        % Acquire the current estimate of the filter states.
        [fusedPos, fusedOrient] = pose(fusionfilt);
        
        % Save the position and orientation for post processing.
        pqorient(fcnt) = fusedOrient;
        pqpos(fcnt,:) = fusedPos;
        
        % Compute the errors and plot.
        if useErrScope
            orientErr = rad2deg(dist(fusedOrient, ...
                trajOrient(fcnt) ));
            posErr = fusedPos - trajPos(fcnt,:); 
            errscope(orientErr, posErr(1), posErr(2), posErr(3));
        end
        
        % Update the pose viewer.
        if usePoseView
            posescope(pqpos(fcnt,:), pqorient(fcnt),  trajPos(fcnt,:), ...
                trajOrient(fcnt,:) );
        end
        fcnt = fcnt + 1;
    end
    
    % This next step happens at the GPS sample rate.
    % Simulate the GPS output based on the current pose.
    [lla, gpsvel] = gps( trajPos(fcnt,:), trajVel(fcnt,:) );
    
    % Correct the filter states based on the GPS data and magnetic
    % field measurements.
    fusegps(fusionfilt, lla, Rpos, gpsvel, Rvel);
    fusemag(fusionfilt, mag, Rmag);
 
end

Figure Scrolling Plotter contains 4 axes objects. Axes object 1 with title Position Z Error, xlabel Time (s), ylabel meters contains an object of type line. Axes object 2 with title Position Y Error, xlabel Time (s), ylabel meters contains an object of type line. Axes object 3 with title Position X Error, xlabel Time (s), ylabel meters contains an object of type line. Axes object 4 with title Quaternion Distance, xlabel Time (s), ylabel degrees contains an object of type line.

MATLAB figure

Berechnung der Fehlermetrik

Positions- und Orientierungsschätzungen wurden während der gesamten Simulation protokolliert. Berechnen Sie nun den mittleren quadrierten Fehler von Ende zu Ende für Position und Ausrichtung.

posd = pqpos(1:loopBound,:) - trajPos( 1:loopBound, :);

% For orientation, quaternion distance is a much better alternative to
% subtracting Euler angles, which have discontinuities. The quaternion
% distance can be computed with the |dist| function, which gives the
% angular difference in orientation in radians. Convert to degrees
% for display in the command window. 

quatd = rad2deg(dist(pqorient(1:loopBound), trajOrient(1:loopBound)) );

% Display RMS errors in the command window.
fprintf('\n\nEnd-to-End Simulation Position RMS Error\n');
End-to-End Simulation Position RMS Error
msep = sqrt(mean(posd.^2));
fprintf('\tX: %.2f , Y: %.2f, Z: %.2f   (meters)\n\n',msep(1), ...
    msep(2), msep(3));
	X: 0.50 , Y: 0.79, Z: 0.65   (meters)
fprintf('End-to-End Quaternion Distance RMS Error (degrees) \n');
End-to-End Quaternion Distance RMS Error (degrees) 
fprintf('\t%.2f (degrees)\n\n', sqrt(mean(quatd.^2)));
	1.45 (degrees)