Test a star sensor attitude determination system with gyros.
dT is the time step for the attitude determination system. You can numerically integrate with a smaller time step by setting nInt > 1.
------------------------------------------------------------------------- See also StellarAttDetEKF, StarDataGeneration, StarSensor and RandSC -------------------------------------------------------------------------
Contents
%-------------------------------------------------------------------------- % Copyright (c) 2016 Princeton Satellite Systems, Inc. % All rights reserved. %-------------------------------------------------------------------------- % Since version 2017.1 % Version 2018.1 Added RIG noise to the simulation. %--------------------------------------------------------------------------
Always have the same random numbers
Comment this out to test with different numbers each run
rng(0); % Constants degToRad = pi/180; % User inputs fOV = 30*degToRad; fScale = 1; nStars = 1000; rIGNoise1Sigma = 0.001; % rad qBToS = [cos(pi/4); 0; sin(pi/4); 0]; uS = [0 0 1]'; nPixels = 1024; angRes = 5*fOV/nPixels; options = StarIDPyramid; options.pixelMapScale = fScale; nInt = 2; % The number of integration steps per estimation step inr = [1000 0 0;0 2000 0; 0 0 2000]; invInr = inv(inr); torque = zeros(3,1); uRIG = eye(3); % Rate integrating gyro vectors nSim = 100; dT = 0.5; % Time step (sec) % Attitude determination system initialization b = zeros(3,1); % Initial bias estimate p = diag([0.01 0.01 0.01 0.001 0.001 0.001]); % Covariance matrix Q = 0.01*eye(6); % Plant noise matrix r = 0.0001; % Noise for a star measurement q = QUnit([1;0.1;0.2;0.2]); % Initial estimate
Initial state
q0 = [1;0;0;0]; bias = [0.01; 0.03; -0.04]; wo = 0; % 0.01 omega = [wo;0;0]; intRate = dT*(omega + bias); x = [q0;omega;intRate;bias]; % True state nRWRIG = zeros(3,1); nBRIG = zeros(3,1); nORIG = zeros(3,1); betaRIG = zeros(3,1); xRIGOld = zeros(3,1); % Set up the simulation t = 0; x(1:4) = QUnit(x(1:4)); % Set up arrays for plotting angInc = zeros(3,1); xPlot = zeros(13,nSim); qPlot = zeros( 4,nSim); bPlot = zeros( 3,nSim); aPlot = zeros( 3,nSim); tPlot = zeros( 1,nSim); qEPlot = zeros( 4,nSim); sDPlot = zeros( 1,nSim); qErrPlot = zeros( 4,nSim); % Create a random star catalog [starMatrix,starCatalog] = RandSC(nStars,2); dStarData = StarDataGeneration( starCatalog, fOV*sqrt(2), angRes ); starData = struct('starMatrix',dStarData.starMatrix,'starID',[],'uMeas',[],'uCatalog',[]);
StarDataGeneration: Eliminating stars that cannot be separated based on the input angular resolution. StarDataGeneration: 2 stars will be eliminated that are too close to other stars. 998 stars will be in the reduced catalog.
Run the simulation
dTInt = dT/nInt; for i = 1:nSim % Attitude Determination starSensorData = StarSensor( x(1:4), qBToS, uS, starMatrix, fOV, fScale ); [angInc, xRIGOld] = RIGOut( x(8:10), xRIGOld, nORIG ); angInc = angInc + rIGNoise1Sigma*randn(3,1); % Star identification if( ~isempty(starSensorData) ) starMeas.pixelIntensity = starSensorData(1,:); starMeas.pixelLocation = starSensorData(2:3,:); [starData.starID,starData.uMeas,starData.uCatalog] = StarIDPyramid( starMeas, dStarData, options ); else starData.starID = []; starData.uMeas = []; starData.uCatalog = []; end % Plotting bPlot(:,i) = b; xPlot(:,i) = x; aPlot(:,i) = angInc; tPlot(i) = t; qEPlot(:,i) = q; sDPlot(:,i) = length(starData.starID); qErrPlot(:,i) = QMult(QPose(q),x(1:4)); % The extended Kalman Filter [q, b, p] = StellarAttDetEKF(angInc,q,dT,b,p,Q,r,qBToS,starSensorData,starData,fScale); % Simulation for k = 1:nInt x = RK4( @FRBwRIG, x, dTInt, t, inr, invInr, torque, uRIG, nRWRIG, nBRIG, betaRIG ); t = t + dTInt; end end
Plot results
[tPlot, tLbl] = TimeLabl(tPlot); yLbl = {'True' 'Estimated'}; Plot2D( tPlot, [xPlot(1:4,:);qEPlot],tLbl,yLbl,'EKF: Quaternion', 'lin',{'1:4' '5:8'}) yLbl = {'x (rad/s)' 'y (rad/s)' 'z (rad/s)'}; Plot2D( tPlot, [xPlot(11:13,:);bPlot],tLbl,yLbl,'EKF: Bias','lin', {'[1 4]' '[2 5]' '[3 6]'}) legend('True', 'Estimated') yLbl = {'Rates' 'Integrated Rates' 'Biases' 'Ang Increments'}; Plot2D( tPlot, [xPlot(5:13,:);aPlot],tLbl,yLbl,'EKF: Rate States', 'lin',{'1:3' '4:6' '7:9' '10:12'}) yLbl = {'Bias Error' 'Q Error' '# Stars'}; Plot2D( tPlot, [xPlot(11:13,:)-bPlot;qErrPlot;sDPlot],tLbl,yLbl,'EKF: Estimation Errors','lin',{'1:3' '5:7' '8'}) %--------------------------------------