Simulate the trajectory of the aircraft
scale allows you to change the mass and thrust. However, if you make the mass lower, the dynamics speed up and you may have to decrease dT.
This is set up for takeoff, straight line flight, a turn, return to the airfield, another turn and a landing.
If printFig is true, creates PDFs of the figures.
Contents
%-------------------------------------------------------------------------- % Copyright (c) 2019 Princeton Satellite Systems, Inc. % All rights reserved. %-------------------------------------------------------------------------- % Since 2019.1 %-------------------------------------------------------------------------- % Flag to print the plots printFig = false; n = 100; % Number of sim steps dT = 1; % s rTD = 180/pi; controlOn = true; vCruise = 200; % m/s vClimb = 100; % m/s hCruise = 10000; % M phiTurn = pi/16; % rad gammaClimb = pi/16; % rad dReturn = 800e3; % m tTest = 30; % How long the aircraft stays at peak Mach machTest = 3; % Peak Mach g = 9.806; % k/m^2 fSp = 16.1e-6; % kg/N/s scale = 1; % For scaling the aircraft massFuel = scale*10000; % kg
Control parameters
tauV = 100; % Time constant for velocity control (s) tauGamma = 1; % Time constant for fligh path angle control (s) segment = 1; distance = 0; time = 0; sP = struct('v',0,'t',0,'psi',0,'h',0,'d',0,'gamma',0,'phi',0,'transition','','rT',[0;0;0],'tT',0); setPoint(10) = sP; for j = 1:10 setPoint(j) = sP; end % Used for segment creation s = StdAtm(hCruise); % Set up the segments % Speed is in m/s, altitude m and psi is radians j = 1; setPoint(j).transition = 'speed'; % Takeoff setPoint(j).v = vClimb; j = j + 1; setPoint(j).transition = 'altitude'; % Climb setPoint(j).gamma = gammaClimb; setPoint(j).h = hCruise; setPoint(j).v = vClimb ; j = j + 1; setPoint(j).transition = 'speed'; % Accelerate setPoint(j).h = hCruise; setPoint(j).v = machTest*s.speedOfSound; j = j + 1; setPoint(j).transition = 'time'; % Hold speed setPoint(j).h = hCruise; setPoint(j).t = tTest; setPoint(j).v = machTest*s.speedOfSound; j = j + 1; setPoint(j).transition = 'speed'; % Decelerate setPoint(j).h = hCruise; setPoint(j).v = vCruise; j = j + 1; setPoint(j).transition = 'heading'; % Change heading setPoint(j).phi = phiTurn; setPoint(j).v = vCruise; setPoint(j).h = hCruise; setPoint(j).psi = pi; j = j + 1; setPoint(j).transition = 'distance'; % Fly until ready to turn for landing setPoint(j).h = hCruise; setPoint(j).v = vCruise; setPoint(j).d = dReturn; j = j + 1; setPoint(j).transition = 'heading'; % Turn for landing setPoint(j).phi = phiTurn; setPoint(j).v = vCruise; setPoint(j).h = hCruise; setPoint(j).psi = 2*pi; j = j + 1; setPoint(j).transition = 'altitude'; % Land setPoint(j).gamma = -gammaClimb; setPoint(j).v = vClimb; setPoint(j).h = 0; j = j + 1; setPoint(j).transition = 'speed'; % Roll to stop
Start by finding the equilibrium controls
d = RHSPointMassAircraft; d.engine = @RDEEngine; d.fSp = fSp; d.m = scale*d.m; d.s = scale*d.s; x = [0;0;0;0;0;0;massFuel];
Simulation
xPlot = zeros(length(x)+7,n); t = 0; segmentOld = 0; WaitBarManager( 'initialize', struct('nSamp',n,'name','Aircraft Simulation') ); maxX = 0; for k = 1:n if( x(6) < 0 ) x(6) = 0; end if( segment < 6 ) maxX = max([maxX x(4)]); setPoint(7).d = maxX; end if( x(6) >= 0 ) h = x(6); else h = 0; end s = StdAtm(h); d.density = s.density; % Get lift and drag for plotting [~,L,D] = RHSPointMassAircraft( x, 0, d ); % Find the specific fuel consumption [~,fSp] = ThrustConstant(x,s.density,d); d.fSp = fSp; % Plot storage xPlot(:,k) = [x;L;D;d.alpha*rTD;d.thrust;d.phi*rTD;segment;fSp]; % Out of fuel if( x(7) <= 0 ) break; end % Control the aircraft if( controlOn ) % Set point [segment, setPoint, distance, time] = Trajectory(x,t,segment,setPoint,distance, dT, time); if( segment > segmentOld ) segmentOld = segment; setPoint(segment).rT = x(4:6)/1000; setPoint(segment).tT = t/60; end % Control [d.thrust, d.alpha] = AircraftTrajectoryControl( x, d, tauGamma, tauV, setPoint(segment).v, setPoint(segment).gamma ); d.phi = setPoint(segment).phi; end WaitBarManager( 'update', k ); % Integrate x = RK4( @RHSPointMassAircraft, x, dT, 0, d ); t = t + dT; % Landed if( segment == j && x(1) < 10 ) break; end end WaitBarManager( 'close' );
Plot the results
xPlot = xPlot(:,1:k); xPlot(2,:) = xPlot(2,:)*rTD; xPlot(4:6,:) = xPlot(4:6,:)/1000; yL = {'v (m/s)' '\gamma (deg)' '\psi (deg)' 'x_e (km)' 'y_n (km)' 'h (km)' 'm_f (kg)',... 'L (N)' 'D (N)' '\alpha (deg)' 'T (N)' '\phi (deg)' 'Segment' 'f (kg/N/s)'}; [t,tL] = TimeLabel(dT*(0:(k-1))); kL = [1 3 6 12]; PlotSet( t, xPlot(kL,:), 'x label', tL, 'y label', yL(kL),... 'figure title', 'Segment Objectives' ); PlotSet( t, xPlot(1:6,:), 'x label', tL, 'y label', yL(1:6),... 'figure title', 'Aircraft State' ); PlotSet( t, xPlot(8:13,:), 'x label', tL, 'y label', yL(8:13),... 'figure title', 'Aircraft Lift, Drag and Controls' ); kL = [7 9 11 13]; PlotSet( t, xPlot(kL,:), 'x label', tL, 'y label', yL(kL),... 'figure title', 'Engine' ); PlotSet( xPlot(4,:), xPlot(5,:), 'x label', yL{4}, 'y label', yL{5},... 'figure title', 'Planar Trajectory' ); NewFig('Trajectory') plot3(xPlot(4,:),xPlot(5,:),xPlot(6,:),'linewidth',2); for j = 1:length(setPoint) s = sprintf(' %d: %4.0f min',j,setPoint(j).tT); text(setPoint(j).rT(1),setPoint(j).rT(2),setPoint(j).rT(3),s); end grid on axis image XLabelS('x (km)') YLabelS('y (km)') ZLabelS('z (km)') if( printFig ) for k = 1:6 %#ok<UNRCH> PrintFig(1,4,k,sprintf('Sim%d',k)); end end
Print out a table of the mission
k = 1; fP = {}; fP{k,1} = 'Duration'; fP{k,2} = sprintf('%12.2f min',t(end)); k = k + 1; fP{k,1} = 'Velocity cruise'; fP{k,2} = sprintf('%12.2f m/s',vCruise); k = k + 1; fP{k,1} = 'Velocity climb'; fP{k,2} = sprintf('%12.2f m/s',vClimb); k = k + 1; fP{k,1} = 'Altitude cruise'; fP{k,2} = sprintf('%12.2f m',hCruise); k = k + 1; fP{k,1} = 'Bank angle'; fP{k,2} = sprintf('%12.2f deg',phiTurn*rTD); k = k + 1; fP{k,1} = 'Climb flight path angle'; fP{k,2} = sprintf('%12.2f deg',gammaClimb*rTD); k = k + 1; fP{k,1} = 'Test Duration'; fP{k,2} = sprintf('%12.2f s',tTest); k = k + 1; fP{k,1} = 'Test Mach'; fP{k,2} = sprintf('%12.2f',machTest); k = k + 1; fP{k,1} = 'Mass Fuel'; fP{k,2} = sprintf('%12.2f kg',massFuel); k = k + 1; fP{k,1} = 'Fuel Consumed'; fP{k,2} = sprintf('%12.2f kg',massFuel-x(7)); k = k + 1; fP{k,1} = 'Dry Mass'; fP{k,2} = sprintf('%12.2f kg',d.m); k = k + 1; fP{k,1} = 'SFC'; fP{k,2} = sprintf('%12.3f kg/kN/s',fSp*1e3); k = k + 1; DisplayLatexTable(fP); CreateLatexTable(fP,'FlightParam'); Figui; %--------------------------------------
Duration 99.00 min Velocity cruise 200.00 m/s Velocity climb 100.00 m/s Altitude cruise 10000.00 m Bank angle 11.25 deg Climb flight path angle 11.25 deg Test Duration 30.00 s Test Mach 3.00 Mass Fuel 10000.00 kg Fuel Consumed 23.46 kg Dry Mass 19368.00 kg SFC 0.016 kg/kN/s