Simulate raising to graveyard orbit from GEO.
This is a low-fidelity model with a specular sail using EarthGuidance and FOrbCart. Integration is with RK45 (variable integration timestep). The simulation is run three times, for three different sail areas. The spacecraft bus is 1730 kg (a Lockheed A2100AX bus). The largest sail modeled can achieve over 5 km SMA change per month. You can also run the sail perfectly sun-pointing for comparison. Plots: (1) Planar view of orbit (2) Elements for the last orbit (3) Control angles (for the last orbit) (4) Average change in elements each orbit (5) Perigree radius (6) Acceleration in LVLH frame (for last orbit)
Since version 7. ------------------------------------------------------------------------- See also Cone, NPlot, Plot2D, TimeLabl, Cross, Dot, RK4, Unit, JD2000, El2RV, RV2El, Eclipse, SunV1, Accel, ConeClockToU, UToConeClock, delta, EarthGuidance -------------------------------------------------------------------------
Contents
%------------------------------------------------------------------------------- % Copyright (c) 2006 Princeton Satellite Systems, Inc. % All rights reserved. %-------------------------------------------------------------------------------
Constants
mu = 398600.44; % Earth cLight = 3e8; % m/s flux = 1367; % W/m2 m2km = 0.001;
Set up the parameters.
Area OR mass can be a vector, not both.
%---------------------------------------- Asail = [40 100 200]; % m2 arealDensity = 0.025; % g/m2 mSC = [1730]; % kg % Number of sim steps and duration %--------------------------------- nOrbits = 30; nPPO = 50; dOrbits = 40; % delta points between 3D plotting % Initial conditions %------------------- SMA = 42167; % 6378+1000; % inc = 0; jD0 = JD2000; % eclipse will be seen for JD2000+90, equinox on 79 % Control method (see EarthGuidance) %----------------------------------- method = 'sma'; % Results % 50 m square sail at 25 g/m2, 1730 kg bus, 3500 km/year with on/off % 50 m square sail and 25 g/m2, 1730 kg bus, 649.018358 km/year with on/30*
Simulation initialization
el0 = [SMA inc 0 0 0 0]; nSim = nOrbits*nPPO; dT = Period(SMA)/nPPO; % Number of separate cases mSail = Asail*arealDensity; % kg mass = mSail + mSC; mSim = length(mass); [r0,v0] = El2RV( el0, [], mu ); % Plotting arrays %---------------- dPlot = PlotArrays('init',{mSim nPPO}); dPlot = PlotArrays('add',dPlot,'sma',SMA); dPlot = PlotArrays('add',dPlot,'nEclipse',0); dPlot = PlotArrays('add',dPlot,'inc',0); dPlot = PlotArrays('add',dPlot,'ecc',0); dPlot = PlotArrays('add',dPlot,'r',0); dPlot = PlotArrays('add',dPlot,'t',0); dPlot = PlotArrays('add',dPlot,'acc',0); dPlot = PlotArrays('add',dPlot,'cone',0); dPlot = PlotArrays('add',dPlot,'clock',0); dPlot = PlotArrays('add',dPlot,'accLVLH',[0;0;0]); dAvg = PlotArrays('init',{mSim nOrbits}); dAvg = PlotArrays('add',dAvg,'sma',SMA); dAvg = PlotArrays('add',dAvg,'inc',0); dAvg = PlotArrays('add',dAvg,'ecc',0); dAvg = PlotArrays('add',dAvg,'t',0); dAvg = PlotArrays('add',dAvg,'apogee',0); dAvg = PlotArrays('add',dAvg,'perigee',0); dAvg = PlotArrays('add',dAvg,'r',0); xPlot = zeros(6,nPPO); % Global for the time interface %------------------------------ global simulationAction simulationAction = ' '; d = struct; d.method = method; [rP, vP] = RVFromKepler( el0 ); Plot3D(rP) hold on
Run the simulation(s)
%---------------------- for j = 1:mSim % Assume specular sail %--------------------- acc0 = 2*Asail(j)*flux/cLight/mass(j)*m2km; x = [r0;v0]; jD = jD0; disp('-----------------------------') disp(['Simulation ' num2str(j) ' of ' num2str(mSim)]) disp('-----------------------------') kS = 1; kO = 1; h = dT; for k = 1:nSim % Local variables %---------------- r = x(1:3); v = x(4:6); % Display the status message %--------------------------- if floor(k/nSim*10) == kS disp(['Sim is ' num2str(kS) '0% finished.']) kS = kS+1; end % Control %-------- % First determine sail unit vector. [uS, rS] = SunV1( jD ); if 1 % use EarthGuidance to compute an optimal angle d.method = method; [q,alphaG,deltaG] = EarthGuidance( 0, [r;v], d, struct('uSun',uS) ); else % switch based on angle between sun projection in orbit plane and r hHat = Unit(Cross(r,v)); sunProj = Cross( hHat, Cross(uS,hHat) ); cosTheta = Unit(sunProj)'*Unit(v); if cosTheta > 0 % receding from sun alphaG = pi/2; % off: pi/2 deltaG = 0; else % approaching sun alphaG = 0; deltaG = 0; end end u = ConeClockToU( alphaG, deltaG, r, v, uS ); % Check for eclipses (not common in GEO) [n, eclipseType] = Eclipse( r, rS*uS ); % Compute the acceleration accel = n*acc0*cos(alphaG); aExt = -accel*u; % Plotting %--------- varNames = {'r' 'nEclipse' 'acc' 'cone' 'clock' 'sma' 'inc' 'ecc'}; el = RV2El( r, v, mu )'; dPlot = PlotArrays('logmulti',dPlot,varNames,{j kO},... {Mag(r) n accel alphaG deltaG el(1) el(2)*180/pi el(5)}); q = QLVLH( r, v ); dPlot = PlotArrays('log',dPlot,'accLVLH',{j kO},QForm(q,aExt)); xPlot(:,kO) = x; % Integrate the trajectory %------------------------- %x = RK4( 'FOrbCart', x, dT, 0, aExt, mu ); [x, h] = RK45( 'FOrbCart', x, h, dT, dT/200, 1e-8, 0, aExt, mu ); jD = jD + dT/86400; if rem(k,nPPO) == 0 % Compute averages over each day kO = 0; iD = floor(k/nPPO); smaLog = PlotArrays('get',dPlot,'sma'); smaAvg = mean(smaLog(j,:)); dAvg = PlotArrays('log',dAvg,'sma',{j iD},smaAvg); eccLog = PlotArrays('get',dPlot,'ecc'); dAvg = PlotArrays('log',dAvg,'ecc',{j iD},mean(eccLog(j,:))); incLog = PlotArrays('get',dPlot,'inc'); dAvg = PlotArrays('log',dAvg,'ecc',{j iD},mean(incLog(j,:))); dAvg = PlotArrays('log',dAvg,'perigee',{j iD},mean(smaLog(j,:).*(1-eccLog(j,:)))); dAvg = PlotArrays('log',dAvg,'apogee',{j iD},mean(smaLog(j,:).*(1+eccLog(j,:)))); dAvg = PlotArrays('log',dAvg,'t',{j iD},dT*k); % Compute a new dT since orbit period will increase dT = Period(smaAvg)/nPPO; if (rem(iD,dOrbits) == 0 && mSim == 1) % add orbit to plot plot3(xPlot(1,:),xPlot(2,:),xPlot(3,:)) end end kO = kO + 1; end end % Finish orbit plot axis equal; view(0,90)
----------------------------- Simulation 1 of 3 ----------------------------- Sim is 10% finished. Sim is 20% finished. Sim is 30% finished. Sim is 40% finished. Sim is 50% finished. Sim is 60% finished. Sim is 70% finished. Sim is 80% finished. Sim is 90% finished. Sim is 100% finished. ----------------------------- Simulation 2 of 3 ----------------------------- Sim is 10% finished. Sim is 20% finished. Sim is 30% finished. Sim is 40% finished. Sim is 50% finished. Sim is 60% finished. Sim is 70% finished. Sim is 80% finished. Sim is 90% finished. Sim is 100% finished. ----------------------------- Simulation 3 of 3 ----------------------------- Sim is 10% finished. Sim is 20% finished. Sim is 30% finished. Sim is 40% finished. Sim is 50% finished. Sim is 60% finished. Sim is 70% finished. Sim is 80% finished. Sim is 90% finished. Sim is 100% finished.
Plot the results
%----------------- [t, tL] = TimeLabl( (0:(nPPO-1))*dT ); mET = cumsum(dAvg.t.data')'; [mT, mL] = TimeLabl(mET); tPlot = [(0:(nPPO-1))/nPPO]; tL = 'Orbit Fraction'; Plot2D(tPlot,[dPlot.sma.data;dPlot.inc.data;dPlot.ecc.data],... tL,{'a' 'i (deg)' 'e'},'Elements for Last Orbit','lin',... {[1:mSim],[1:mSim]+mSim,[1:mSim]+2*mSim}); %Plot2D(t,aPlot,tL,'SMA (km)', 'SemiMajor Axis Change with Sail Length (m)') %legend(num2str(sqrt(Asail)',3)) hF = Plot2D(tPlot,[dPlot.cone.data;dPlot.clock.data;dPlot.acc.data*1e6],... tL,{'\alpha' '\delta' 'accel (mm/s^2)'},... ['Control Angles and Accel'],'lin',{1,2,[1:mSim]+2}); if mSim == 1 nPlot = floor(squeeze(dPlot.nEclipse.data)'); if nPlot(1) == 1 colors = [1 1 1; 0.9 0.9 0.9]; else colors = [0.9 0.9 0.9; 1 1 1]; end AddFillToPlots( t, nPlot, hF, colors ); end Plot2D(tPlot,squeeze(dPlot.accLVLH.data(:,1,:))*1e6,tL,{'x','y','z'},'Accel in LVLH frame (mm/s2)') tPlot = [1:nOrbits]; tL = 'Orbits'; Plot2D(tPlot,[dAvg.sma.data;dAvg.inc.data;dAvg.ecc.data],... mL,{'a' 'i (deg)' 'e'},... 'Average Change in Elements Each Orbit','lin',... {[1:mSim],[1:mSim]+mSim,[1:mSim]+2*mSim}); Plot2D(mT,dAvg.perigee.data,mL,{'R_P'},'Perigee Radius'); Figui;
Report
disp('-----------------------------') fprintf(1,'Mission length: %d orbits\n',nOrbits); fprintf(1,'Sail average density: %d g/m2\n',arealDensity*1000); fprintf(1,'Mass of bus moved: %d kg\n',mSC); for k = 1:length(Asail) disp('--------') fprintf(1,'Sail length: %g m\n',sqrt(Asail(k))); fprintf(1,'Change in perigee: %g km\n',dAvg.perigee.data(k,end)-dAvg.perigee.data(k,1)); fprintf(1,'%3.1f m square sail at %d g/m2, %d kg bus, %3.1f km/%d orbits\n',... sqrt(Asail(k)),arealDensity*1000,mSC,dAvg.perigee.data(k,end)-dAvg.perigee.data(k,1),nOrbits); end %-------------------------------------- % PSS internal file version information %--------------------------------------
----------------------------- Mission length: 30 orbits Sail average density: 25 g/m2 Mass of bus moved: 1730 kg -------- Sail length: 6.32456 m Change in perigee: 1.02879 km 6.3 m square sail at 25 g/m2, 1730 kg bus, 1.0 km/30 orbits -------- Sail length: 10 m Change in perigee: 2.80512 km 10.0 m square sail at 25 g/m2, 1730 kg bus, 2.8 km/30 orbits -------- Sail length: 14.1421 m Change in perigee: 5.75852 km 14.1 m square sail at 25 g/m2, 1730 kg bus, 5.8 km/30 orbits