Simulate a heliocentric locally optimal trajectory.
You can simulate any one of four types. You can also change the direction, i.e. increase or decrease the element in question. This uses the control laws developed in McInnes and is designed to exactly duplicate the images in his book, Fig. 4.19, 4.20, 4.22, and 4.24, however there some inconsistencies between the sail properties listed in the text and the graphics.
Functions demonstrated:
ConeClockConvention
LocallyOptimalTraj
FSailGuidance
The ascending node and inclination plots also shown the analytical increase expected in these elements for the given sail acceleration and orbit (red).
Since version 7. ------------------------------------------------------------------------ Reference: Colin R. McInnes, "Solar Sailing: Technology, Dynamics and Mission Applications", Springer Praxis, London, 1999, pp. 136-148. ------------------------------------------------------------------------ See also IConv, Constant, InformDlg, NewFig, Plot2D, TimeLabl, UnwrapPhase, El2RV, M2Nu, Period, RV2El, RVFromKepler, ConeClockConvention, delta, LocallyOptimalTraj, FSailGuidance ------------------------------------------------------------------------
Contents
%------------------------------------------------------------------------------- % Copyright (c) 2005 Princeton Satellite Systems, Inc. % All rights reserved. %------------------------------------------------------------------------------- clear d;
USER PARAMETERS:
Possible control type examples
%------------------------------- % 1. ascending node % 2. eccentricity % 3. inclination % 4. semi-major axis % 5. Your custom elements and control (edit case below) kControlType = 1; % Direction flag: +/- 1 %---------------------- direction = 1; % Cone/Clock convention %---------------------- % 1. Cone angle kept positive % 2. Clock angle kept to [0,pi) iConv = 2; %%%%%%%%%%%%%%%%%%%%%%%%%
Set up the parameters
%---------------------- d.mu = Constant('mu sun'); a = 0.3*1e-6; % 0.3 mm/s^2 converted to km/s^2 beta = 0.05;
Initial conditions
%------------------- au = Constant('au'); switch kControlType case 1 % Demonstrate ascending node change x0 = au/4; % start at 0.25 AU el0 = [x0;80*pi/180;0;0;0;0]; % 80 deg inclination nYears = 1.8; % 1.8 years dEl = 88.2/sin(el0(2))*beta; % analytical change case 2 % Demonstrate eccentricity change x0 = 1.25*au; el0 = [x0;0;0;0;0.2;0]; nYears = 6.67; %7.07 unconstrained, 6.65 constrained if (direction < 0) nYears = 3; end case 3 % Demonstrate inclination change x0 = au/4; el0 = [x0;0;0;pi/2;0;0]; nYears = 1; if (direction < 0) el0(2) = 1.4; end dEl = 88.2*beta; case 4 % Demonstrate semi-major axis change x0 = 1.25*au; el0 = [x0;0;0;0;0.2;0]; nYears = 8.8; if (direction < 0) nYears = 2; end otherwise % Your custom elements and control selection x0 = 1.25*au; el0 = [x0;0.5;0;0;0.2;0]; nYears = 1; kControlType = 4; end [r0,v0] = El2RV( el0, [], d.mu ); x = [r0;v0];
Control details
%---------------- controlTypes = {'ascending node','eccentricity','inclination','semi-major axis','custom'}; controlType = controlTypes{kControlType}; disp(' ') disp('LocalOptimalSim.') disp(['Control type selected: ' controlType]) disp(['Direction: ' num2str(direction)])
LocalOptimalSim. Control type selected: ascending node Direction: 1
Integrate the trajectory
%------------------------- hDlg = InformDlg( 'Integrating...', 'LocalOptimalMission' ); odeOptions = odeset('AbsTol',1e-6,'RelTol',1e-5); [t,z] = ode113( @FSailGuidance, [0 nYears*365.25*86400], x, odeOptions,... a, [], [], d.mu, struct('type',controlType,'dirFlag',direction) ); nSim = length(t); close(hDlg);
Plotting array
%---------------
el = zeros(6,nSim);
angles = zeros(2,nSim);
nu = zeros(1,nSim);
tPlot = t';
xPlot = z';
Process the orbital elements
%----------------------------- r = z(:,1:3)'; v = z(:,4:6)'; for k = 1:nSim el(:,k) = RV2El( r(:,k), v(:,k), d.mu )'; [alpha, delta] = LocallyOptimalTraj( controlType, r(:,k), v(:,k), d.mu, direction ); angles(:,k) = [alpha;delta]; nu(k) = M2Nu(el(5,k),el(6,k)); end disp('Finished.')
Finished.
Plot the results
%----------------- [t, tL] = TimeLabl( tPlot ); controlType(1) = upper(controlType(1)); orbNum = tPlot/Period(x0,d.mu); [alpha,delta] = ConeClockConvention(angles(1,:),angles(2,:),iConv); switch kControlType case {4,2} orbNum = UnwrapPhase(nu)/(2*pi); % Semi-major axis and eccentricity [rI,vI] = RVFromKepler(el0,[],d.mu); NewFig([controlType ': Orbit and Cone Angle']); subplot(2,2,1); plot(orbNum,el(1,:)/au); ylabel('Semi-major axis (au)'); xlabel('Orbit Number') grid on subplot(2,2,2); plot(orbNum,el(5,:)); ylabel('Eccentricity'); xlabel('Orbit Number') grid on subplot(2,2,3); plot(orbNum,angles(1,:)*180/pi); ylabel('Pitch angle (deg)'); xlabel('Orbit Number') subplot(2,2,4); plot(xPlot(1,:)/au, xPlot(2,:)/au); hold on plot(rI(1,:)/au, rI(2,:)/au, '--'); xlabel('x (au)'); ylabel('y (au)') axis equal Plot2D(orbNum,[alpha;delta],'Orbit Number',{'\alpha' '\delta'},[controlType ': Angles']) case {1,3} % Analytical increase (deg/orbit) del = dEl*orbNum; NewFig([controlType ': Orbit and Clock Angle']); elk = [3 0 2]; lbl = {'Ascending Node (deg)' ' ' 'Inclination (deg)'}; subplot(2,2,1); plot(orbNum,el(elk(kControlType),:)*180/pi); hold on; plot(orbNum,del,'r'); ylabel(lbl{kControlType}); xlabel('Orbit Number') grid on subplot(2,2,2); [alpha2,delta2] = ConeClockConvention(angles(1,:),angles(2,:),1); plot(orbNum,delta2*180/pi); ylabel('Clock Angle (deg)'); xlabel('Orbit Number') grid on subplot(2,2,3); plot3(xPlot(1,:)/au,xPlot(2,:)/au,xPlot(3,:)/au); xlabel('X (au)'); ylabel('Y (au)'); zlabel('Z (au)'); grid on subplot(2,2,4); plot(xPlot(2,:)/au, xPlot(3,:)/au); xlabel('Y (au)'); ylabel('Z (au)'); grid on axis equal Plot2D(t,[el(1,:)/au;el(2:5,:)],tL,{'a' 'i' '\Omega' '\omega' 'e'},[controlType ': Elements']) end %-------------------------------------- % PSS internal file version information %--------------------------------------