Simple sim using a CAD model of the spacecraft to view the attitude.

Demonstrates control design using PIDMIMO, the Disturbances function, rigid body attitude dynamics with FRB, orbit dynamics with FOrbCart, and integration using RK4. The CAD model is viewed using DrawSCPlugIn.

Use the flags to turn on or off the disturbances and 3D viewing. If 3D viewing is off the demo concludes with a quaternion animation. ------------------------------------------------------------------------ See also DrawSCPlanPlugIn, PIDMIMO, AU2Q, AnimQ, QLVLH, QMult, QPose, Constant, NPlot, Plot2D, Plot3D, TimeGUI, RK4, JD2000, El2RV, Disturbances, SunV1, DrawSCPlugIn, Accel ------------------------------------------------------------------------

Contents

%-------------------------------------------------------------------------------
%  Copyright 2003, 2006 Princeton Satellite Systems, Inc. All rights reserved.
%-------------------------------------------------------------------------------
%  Since version 5.5 (2003)
%  2016.1: update integration to use function handles
%-------------------------------------------------------------------------------

Global for the TimeGUI

%------------------------
global simulationAction
simulationAction = ' ';
clear e;

Flags - take values 0 or 1

%---------------------------
use3DGraphics   = 1;
useDisturbances = 1;

Constants

%----------
degToRad = pi/180;
radToDeg = 180/pi;

Spacecraft model

%-----------------
g = load('XYZSat');
ShowCAD( g );

The control sampling period and the simulation integration time step

%---------------------------------------------------------------------
tSamp       = 0.5;

Number of sim steps

%--------------------
nSim        = 300;

Initial conditions

%-------------------
%                 q         w
x1         = [[1;0;0;0];[0;0;0]];
el         = [Constant('earth radius mean')+15000 45*pi/180 0 0 0 0];
[r,v]      = El2RV(el);
x2         = [r;v];

dTSim      = tSamp;
mET        = 0;
jD         = JD2000;
roll       = 0;
pitch      = 0;
yaw        = 0;

Initialize the 3D window

%-------------------------
g(1).body(1).bHinge.q = x1(1:4);
g(1).rECI             = r;
g(1).qLVLH            = QLVLH( r, v );
g(1).name             = 'XYZSat';
if( use3DGraphics )
  tag3DWindow = DrawSCPlugIn( 'initialize', g, [], [], 'Earth', jD );
end
                       ALim: [0 2]
                   ALimMode: 'auto'
                 AlphaScale: 'linear'
                   Alphamap: [1×64 double]
          AmbientLightColor: [1 1 1]
               BeingDeleted: off
                        Box: off
                   BoxStyle: 'back'
                 BusyAction: 'queue'
              ButtonDownFcn: ''
                       CLim: [0 255]
                   CLimMode: 'auto'
             CameraPosition: [5.2777e+06 2.945e+07 -3.0611e-11]
         CameraPositionMode: 'manual'
               CameraTarget: [3.7698e+06 2.1036e+07 1.3086e-09]
           CameraTargetMode: 'manual'
             CameraUpVector: [0.69602 -0.12473 0.70711]
         CameraUpVectorMode: 'manual'
            CameraViewAngle: 30
        CameraViewAngleMode: 'manual'
                   Children: [6×1 Graphics]
                   Clipping: on
              ClippingStyle: '3dbox'
                      Color: [0 0 0]
                 ColorOrder: [7×3 double]
            ColorOrderIndex: 1
                 ColorScale: 'linear'
                   Colormap: [256×3 double]
                ContextMenu: [0×0 GraphicsPlaceholder]
                  CreateFcn: ''
               CurrentPoint: [2×3 double]
            DataAspectRatio: [1 1 1]
        DataAspectRatioMode: 'manual'
                  DeleteFcn: ''
                  FontAngle: 'normal'
                   FontName: 'Helvetica'
                   FontSize: 10
               FontSizeMode: 'auto'
              FontSmoothing: on
                  FontUnits: 'points'
                 FontWeight: 'normal'
                  GridAlpha: 0.15
              GridAlphaMode: 'auto'
                  GridColor: [0.15 0.15 0.15]
              GridColorMode: 'auto'
              GridLineStyle: '-'
           HandleVisibility: 'on'
                    HitTest: on
              InnerPosition: [0 0 340 340]
               Interactions: [1×1 matlab.graphics.interaction.interface.DefaultAxesInteractionSet]
              Interruptible: on
    LabelFontSizeMultiplier: 1.1
                      Layer: 'bottom'
                     Layout: [0×0 matlab.ui.layout.LayoutOptions]
                     Legend: [0×0 GraphicsPlaceholder]
             LineStyleOrder: '-'
        LineStyleOrderIndex: 1
                  LineWidth: 0.5
             MinorGridAlpha: 0.25
         MinorGridAlphaMode: 'auto'
             MinorGridColor: [0.1 0.1 0.1]
         MinorGridColorMode: 'auto'
         MinorGridLineStyle: ':'
                   NextPlot: 'replace'
            NextSeriesIndex: 1
              OuterPosition: [-44.2 -37.4 416.5 402.9]
                     Parent: [1×1 Figure]
              PickableParts: 'visible'
         PlotBoxAspectRatio: [1 2.2317 1]
     PlotBoxAspectRatioMode: 'manual'
                   Position: [0 0 340 340]
         PositionConstraint: 'innerposition'
                 Projection: 'perspective'
                   Selected: off
         SelectionHighlight: on
                 SortMethod: 'depth'
                        Tag: 'Spacecraft'
                    TickDir: 'out'
                TickDirMode: 'auto'
       TickLabelInterpreter: 'tex'
                 TickLength: [0.01 0.025]
                 TightInset: [0 0 0 0]
                      Title: [1×1 Text]
    TitleFontSizeMultiplier: 1.1
            TitleFontWeight: 'bold'
                    Toolbar: [1×1 AxesToolbar]
                       Type: 'axes'
                      Units: 'pixels'
                   UserData: []
                       View: [138.25 0]
                    Visible: off
                      XAxis: [1×1 NumericRuler]
              XAxisLocation: 'bottom'
                     XColor: [0.15 0.15 0.15]
                 XColorMode: 'auto'
                       XDir: 'normal'
                      XGrid: on
                     XLabel: [1×1 Text]
                       XLim: [-6378100 6378100]
                   XLimMode: 'auto'
                 XMinorGrid: off
                 XMinorTick: off
                     XScale: 'linear'
                      XTick: [1×7 double]
                 XTickLabel: {7×1 cell}
             XTickLabelMode: 'auto'
         XTickLabelRotation: 0
                  XTickMode: 'auto'
                      YAxis: [1×1 NumericRuler]
              YAxisLocation: 'left'
                     YColor: [0.15 0.15 0.15]
                 YColorMode: 'auto'
                       YDir: 'normal'
                      YGrid: on
                     YLabel: [1×1 Text]
                       YLim: [-6378100 2.2089e+07]
                   YLimMode: 'auto'
                 YMinorGrid: off
                 YMinorTick: off
                     YScale: 'linear'
                      YTick: [-5000000 0 5000000 10000000 15000000 20000000]
                 YTickLabel: {6×1 cell}
             YTickLabelMode: 'auto'
         YTickLabelRotation: 0
                  YTickMode: 'auto'
                      ZAxis: [1×1 NumericRuler]
                     ZColor: [0.15 0.15 0.15]
                 ZColorMode: 'auto'
                       ZDir: 'normal'
                      ZGrid: on
                     ZLabel: [1×1 Text]
                       ZLim: [-6378100 6378100]
                   ZLimMode: 'auto'
                 ZMinorGrid: off
                 ZMinorTick: off
                     ZScale: 'linear'
                      ZTick: [1×7 double]
                 ZTickLabel: {7×1 cell}
             ZTickLabelMode: 'auto'
         ZTickLabelRotation: 0
                  ZTickMode: 'auto'

Plot every nPMax steps

%-----------------------
nP          = 0;
kP          = 0;
nPMax       = 1;
nPlot       = nSim/nPMax;

Plotting arrays

%----------------
x1Plot      = zeros( 7,nPlot );
x2Plot      = zeros( 6,nPlot );
tPlot       = zeros( 1,nPlot );
TPlot       = zeros( 3,nPlot );
FPlot       = zeros( 3,nPlot );

Print the time to go message every nTTGo steps

%------------------------------------------------
nTTGo       = 1000;

Spacecraft Inertias

-------------------

inr         = g.mass.inertia; % can change inertia here
invInr      = inv(inr);
tDist       = [0;0;0]; % can add disturbances using this variable

Design the control loops

%-------------------------
inr          = 1;   % inertia
zeta         = 1;   % damping ratio
omega        = 0.1; % natural frequency
tauInt       = 100; % integrator time constant
omegaR       = 1;   % derivative term roll-off frequency
[a, b, c, d, k] = PIDMIMO( inr, zeta, omega, tauInt, omegaR, tSamp, 'Delta' );

Initialize the control system

%------------------------------
xRoll      = [0;0];
xPitch     = [0;0];
xYaw       = [0;0];
qTarget    = AU2Q( 30*pi/180, [1;0;0] ); % 30 degree rotation

Initialize the time display

%----------------------------
[ ratioRealTime, tToGoMem ] =  TimeGUI( nSim, 0, [], 0, tSamp, 'XYZ Demo Sim' );

Initialize disturbances

%------------------------
e           = Disturbances('defaults');
e.s         = 1367*SunV1( jD, x2(1:3) ); % Watts/m^2
e.shadow    = 0;
e.units     = 'm';
e.planet    = 'Earth';
e.mu        = 3.986014e5;
e.computeAero = 1;
if( useDisturbances )
    hD = Disturbances( 'init', g, e );
end

Run the simulation

%-------------------
for k = 1:nSim

  % Display the status message
  %---------------------------
  [ ratioRealTime, tToGoMem ] = TimeGUI( nSim, k, tToGoMem, ratioRealTime, tSamp );

  % ---------------------------
  % The Attitude Control System
  % ---------------------------

  % The attitude control loops
  % --------------------------
  % torque = AttitudeControlLaw( params );

  qTargetToBody = QPose( QMult( QPose(x1(1:4)), qTarget ) );

  % Small angle convention
  %-----------------------
  angleError = -2*qTargetToBody(2:4);

  % Controller blocks, delta format. Each axis uses the same gains.
  %----------------------------------------------------------------
  accel    = zeros(3,1);
  accel(1) =          c*xRoll  + d*angleError(1);
  xRoll    = xRoll  + a*xRoll  + b*angleError(1);

  accel(2) =          c*xPitch + d*angleError(2);
  xPitch   = xPitch + a*xPitch + b*angleError(2);

  accel(3) =         c*xYaw   + d*angleError(3);
  xYaw     = xYaw  + a*xYaw   + b*angleError(3);

  torque = -g.mass.inertia*accel;

  % May add force here
  %-------------------
  force = [0;0;0];

  % -------------
  % Disturbances
  % -------------
  g = SetCADQuaternion( g, x1(1:4) );
  if( useDisturbances )
    % Use disturbances model (uses CAD model)
    e.r         = x2(1:3);
    e.v         = x2(4:6);
    [f,t]       = Disturbances('run',g,e,hD);
    fDist = f.total/1000; % to kN from N
    tDist = t.total;      % already in Nm
  else
    % Alternatively, add periodic disturbance (faster)
    tDist = [1;0;0.5]*1e-3*sin(0.0011*mET);
    fDist = [0;0;0];
  end

  % -------------------------------
  % Update the equations of motion
  % -------------------------------
  x1       = RK4(@FRB,x1,dTSim,mET,inr,invInr,torque+tDist);
  x2       = RK4(@FOrbCart,x2,dTSim,jD,[force+fDist]/g.mass.mass);
  mET      = mET + dTSim;
  jD       = jD + dTSim/86400;

  % --------------------
  % Update the graphics
  % --------------------
  if( use3DGraphics )
    g(1) = SetCADState( g(1), x2(1:3), x2(4:6) );
    DrawSCPlugIn( 'update spacecraft', tag3DWindow, g, jD );
  end

  % Plotting
  % --------
  if (nP == 0)
    kP           = kP + 1;
    x1Plot(:,kP) = x1;
  	x2Plot(:,kP) = x2;
    tPlot(:,kP)  = mET;
    TPlot(:,kP)  = torque;
    FPlot(:,kP)  = force;
    nP           = nPMax - 1;
  else
    nP           = nP - 1;
  end

  % Time control
  %-------------
  switch simulationAction
    case 'pause'
      pause
      simulationAction = ' ';
    case 'stop'
      return;
    case 'plot'
      break;
  end

end

Plot results

TimeGUI('close');

j = 1:kP;

tPlot = tPlot(j);

Plot2D(tPlot,x1Plot( 1:4,j),'Time (sec)',['Q_s';'Q_x';'Q_y';'Q_z'],'Quaternion')
Plot2D(tPlot,x1Plot( 5:7,j),'Time (sec)',['\omega_x';'\omega_y';'\omega_z'],'Body Rates')
Plot2D(tPlot,x2Plot( 1:3,j),'Time (sec)',['X';'Y';'Z'],'Position (km)')
Plot2D(tPlot,x2Plot( 4:6,j),'Time (sec)',['V_x';'V_y';'V_z'],'Velocity (km/s)')
Plot2D(tPlot,TPlot(:,j),'Time (sec)',['T_x';'T_y';'T_z'],'Applied Torque (Nm)')

if( ~use3DGraphics )
    % Post-animate quaternion and orbit
    %----------------------------------
    Plot3D(x2Plot( 1:3,j),'x (km)','y','z','Orbit',6371)
    AnimQ( x1Plot( 1:4,:), 2 );
end


%--------------------------------------