Lunar Mission Demo
Simulate a mission from Earth orbit to lunar orbit. The spacecraft has 3 orthogonal reaction wheels and a single delta-v thruster. The mission plan does not perform the lunar insertion burn.
It uses the default values from RHSLunarMission for a 6U CubeSat. The dimensions are 30 x 20 x 10 cm.
Contents
%-------------------------------------------------------------------------- % Copyright (c) 2016 Princeton Satellite Systems, Inc. % All rights reserved. %-------------------------------------------------------------------------- % Since 2016.1 % 2020.1 Fixed the lunar insertion burn and the lunar orbit plotting %--------------------------------------------------------------------------
Constants
rMoon = 1738; dayToSec = 86400;
User inputs
dateEncounter = [2016 5 10 1 30 0]; % "Encounter" is passing into lunar sphere of influence dT = 2; % integration time step seconds el0 = [7000 0 0 0 0]; rLunarOrbit = 3000; % km incLunarOrbit = 1; surfaceMagnificationFactor = 10; % For lunar terrain display timeAdded = 36000; % sec added simulation time after intercept useSphericalHarmonics = 0;
Control setup
% Find transfer orbit to the moon jDEncounter = Date2JD( dateEncounter ); if( HasOptimizationToolbox ) [x0,el,~,jD0,jDP] = LunarTargeting( jDEncounter, el0, rLunarOrbit, incLunarOrbit, [], true ); else disp('LunarMission: Optimization toolbox not installed; using hard-coded values.') x0 = [-2.8408 6.3976 0 -0.0034 0.0099 0.0018]'*1e3; el = [-5.2588 0.0010 0.0001 0.0041 0.0016 0.0088]*1e3; jD0 = 2.457514449298204e+06; end tEnd = (jDP-jD0)*dayToSec + timeAdded; % Get the default data structure dC = LunarMissionControl; dC.dT = dT; dC = LunarMissionControl('initialize',jD0,dC); dRHS = RHSLunarMission; if( useSphericalHarmonics ) dRHS.sphHarmMoon = LoadSGM150( 'SGM150.geo' ); %#ok<*UNRCH> dRHS.sphHarmMoon.nN = 3; dRHS.sphHarmMoon.nM = 3; end % Set up the control data structure dC.mass = struct('mass',dRHS.mass,'inertia',dRHS.inertia,'cM',dRHS.surfData.cM); dC.rWA = dRHS.rWA; % This command list is for an lunar orbit insertion cList = { jDP-1e3/dayToSec,... 'lunar orbit insertion prepare',... struct('thrust',20,'massInitial',6, 'uE', 290*9.806,'body_vector',[1;0;0],'hLunarOrbit',200);... +2,... 'align for lunar insertion',... [];... +1e3,... 'start main engine',... struct('iD',1,'thrust',20)}; % Initial state setup qECIToBody = [1;0;0;0]; omega = [0;0;0]; % rad/s omegaRWA = [0;0;0]; % rad/s accelBias = [0;0;0]; % km/s^2 gyroBias = [0;0;0]; % rad/s massFuel = 3; % kg
Your initial point x0 is not between bounds lb and ub; FMINCON shifted x0 to strictly satisfy the bounds. First-order Norm of Iter F-count f(x) Feasibility optimality step 0 5 1.055884e+01 4.365e+04 3.794e-03 1 12 1.056376e+01 4.004e+04 4.917e-03 4.157e-01 2 18 1.057372e+01 3.388e+04 1.746e-02 5.230e-01 3 23 1.058152e+01 2.375e+04 2.752e-02 5.975e-01 4 28 1.057247e+01 1.086e+03 4.815e-02 4.485e-01 5 34 1.057308e+01 8.566e+02 4.113e-02 7.109e-02 6 39 1.057413e+01 4.417e+02 5.429e-02 3.161e-01 7 44 1.057504e+01 1.233e+02 5.532e-02 2.619e-01 8 50 1.057980e+01 9.027e+01 6.054e-02 5.583e-01 9 57 1.058453e+01 6.990e+01 6.460e-02 2.839e-01 10 62 1.058210e+01 2.599e+01 2.468e-02 1.284e-01 11 68 1.057692e+01 7.241e+00 9.757e-03 4.175e-01 12 81 1.057558e+01 1.662e+00 3.650e-03 1.657e-01 13 94 1.057461e+01 1.502e+00 2.497e-03 1.579e-01 14 107 1.057423e+01 2.608e-01 2.066e-03 7.406e-02 15 120 1.057392e+01 2.451e-01 1.753e-03 7.221e-02 16 131 1.057366e+01 2.351e-01 1.471e-03 7.035e-02 17 142 1.057345e+01 2.232e-01 1.217e-03 6.854e-02 18 153 1.057327e+01 2.096e-01 9.918e-04 6.696e-02 19 164 1.057314e+01 1.947e-01 7.936e-04 6.594e-02 20 175 1.057303e+01 1.785e-01 6.224e-04 6.599e-02 21 186 1.057295e+01 1.611e-01 4.784e-04 6.781e-02 22 197 1.057289e+01 1.423e-01 3.614e-04 7.195e-02 23 208 1.057285e+01 1.222e-01 2.711e-04 7.839e-02 24 223 1.057282e+01 3.347e-02 2.056e-04 4.077e-02 25 236 1.057281e+01 3.136e-02 1.487e-04 4.251e-02 26 247 1.057279e+01 2.940e-02 9.999e-05 4.487e-02 Optimization completed: The relative first-order optimality measure, 9.999374e-05, is less than options.OptimalityTolerance = 1.000000e-04, and the relative maximum constraint violation, 6.735951e-07, is less than options.ConstraintTolerance = 1.000000e-04. Hyperbolic Lunar Elements Radius of perilune 3000.03 km Semi major axis -5313.26 km Inclination 57.30 deg Longitude 6.40 deg Perigee 235.11 deg Eccentricity 1.56 Mean anomaly 496.50 deg Start JD 2457514.4732 day Transfer Time 4.0893 days

Initialize the simulation model
% Initialize JPL Ephemerides to include the Sun, Earth and Moon PlanetPosJPL( 'initialize', [0 3 10] ); nSim = ceil(tEnd/dT); dRHS.jD0 = jD0; x = [x0;qECIToBody;omega;massFuel;dRHS.power.batteryCapacity;... accelBias;gyroBias;omegaRWA]; % This initializes the state and auxiliary output names RHSLunarMission( x );
Run the simulation
t = 0; xP = zeros(length(x),nSim); [~, p] = RHSLunarMission( x, t, dRHS ); pP = zeros(length(p.auxNames),nSim); % Globals for the time tracking GUI global simulationAction simulationAction = ' '; for k = 1:nSim % Plot storage [~, p] = RHSLunarMission( x, t, dRHS ); q = x(7:10); xP(:,k) = x; pP(:,k) = p.aux; % The controller jD = jD0 + t/dayToSec; dC.rMoon = pP(21:23,k); dC.vMoon = pP(24:26,k); [dC, dRHS] = LunarMissionControl( 'update', jD, dC, dRHS, x, cList ); % Propagate x = RK4(@RHSLunarMission,x,dT,t,dRHS); t = t + dT; switch simulationAction case 'pause' pause simulationAction = ' '; case 'stop' LunarMissionControl( 'terminate' ); return; case 'plot' break; end end LunarMissionControl( 'terminate' );
jD 2457519.03193 lunar orbit insertion prepare jD 2457519.03195 align for lunar insertion jD 2457519.04352 start main engine
Plot the results
if k<nSim xP = xP(:,1:k); pP = pP(:,1:k); nSim = k; end tS = (0:nSim-1)*dT; jD = jD0 + t/dayToSec; % in days [t,tL] = TimeLabl(tS); % Plot the states k = 1:3; Plot2D(t,xP(k,:),tL,p.stateNames(k),'Position'); k = 4:6; Plot2D(t,xP(k,:),tL,p.stateNames(k),'Velocity'); k = 7:10; Plot2D(t,xP(k,:),tL,p.stateNames(k),'Quaternion'); k = 11:13; Plot2D(t,xP(k,:),tL,p.stateNames(k),'Angular Velocity'); k = 14:15; Plot2D(t,xP(k,:),tL,p.stateNames(k),'Fuel and Battery'); k = 16:18; Plot2D(t,xP(k,:),tL,p.stateNames(k),'IMU Accel Bias'); k = 19:21; Plot2D(t,xP(k,:),tL,p.stateNames(k),'IMU Gyro Bias'); k = 22:24; Plot2D(t,xP(k,:),tL,p.stateNames(k),'Reaction Wheel Rates'); % Plot the auxiliary outputs k = 4:6; Plot2D(t,pP(k,:),tL,p.auxNames(k),'Thruster Force'); k = k+3; Plot2D(t,pP(k,:),tL,p.auxNames(k),'Solar Torque'); k = 10:12; Plot2D(t,pP(k,:),tL,p.auxNames(k),'Solar Force'); k = 13:14; Plot2D(t,pP(k,:),tL,p.auxNames(k),'Power'); k = 21:23; dR = xP(1:3,:) - pP(k,:); dV = Mag(xP(4:6,:) - pP(24:26,:)); h = Mag(dR) - rMoon; yL = {'x (km)', 'y (km)', 'z (km)', 'h (km)' '|v| (km/s)'}; Plot2D(t,[dR;h;dV],tL,yL,'Moon Relative Position'); % Plot the trajectory for the Earth/Moon transfer EarthMoon( xP(1:3,:), jD, [1, 1], pP(21:23,:) ); % Display from encounter time jD = jD0 + tS/dayToSec; kB = find(jD>jDEncounter); k = kB(1):nSim; dR = dR(:,k); jD = jD(1,k); uSun = SunV1(jD(1)); PlotLunarOrbit( dR, jD, uSun, pP(4:6,k), surfaceMagnificationFactor ); Figui; %--------------------------------------
ans = 126















