Simulate ONS for elements of a heliocentric mission
This only simulates the orbital motion. It is useful to compares this with ONSCisLunarSimulation.
The simulation allows for the sun and one planet. In this case the planet is Mars
See also: Constant, PlanetPosJPL, NavigationCamera, MeasGPS, MeasRangeGroundStation, MeasStarAngleAndChord, StarCameraViewer, RHSUKFHelioMission, OpticalNavigation, RHSHelioMission, RK4, Figui, Plot2D
Contents
%-------------------------------------------------------------------------- % Copyright (c) 2021 Princeton Satellite Systems, Inc. % All rights reserved. %-------------------------------------------------------------------------- % Since version 2021.1 %--------------------------------------------------------------------------
Constants
rM = Constant('equatorial radius mars'); rS = Constant('sun radius'); muSun = Constant('mu sun'); muMars = Constant('mu mars'); aU = Constant('au'); secToDay = 1/86400; secInYear = 365.26*86400; kMars = 4; % SPICE numbering 1-9 are the planets, 10 is the moon mars = 1; sun = 2; % Get the defaults dRHS = RHSHelioMission;
Script control
massFuel = 1000; % kg dRHS.mD = 1000; % kg viewersOn = true; printAll = false; % Names are 'solar orbit' 'mars orbit' simName = 'solar orbit'; % Initialize the Mars ephemeris PlanetPosJPL( 'initialize', kMars ) % Initialize the state for different scenarios % If you add a scenario you must specify a target below switch simName case 'solar orbit' x0 = aU; dRHS.ref = sun; x = [x0;0;0;0;sqrt(muSun/x0);0;massFuel]; dT = 10000; tEnd = 1000*dT; % sec jD0 = Date2JD([2024 8 3 0 0 0]); case 'mars orbit' x0 = 6000; dRHS.ref = mars; x = [x0;0;0;0;sqrt(muMars/x0);0;massFuel]; jD0 = Date2JD([2024 8 3 0 0 0]); dT = 10; tEnd = 6000; % sec otherwise error('%s is not a pre-defined simulation',simName); end % Set the Julian date for the dynamical model dRHS.jD0 = jD0; % Simulation steps n = ceil(tEnd/dT);
Setup the camera data structure
dCam = NavigationCamera; dGPS = MeasGPS; dGS = MeasRangeGroundStation; dOM = MeasStarAngleAndChord;
Add noise
dCam.camera.sigmaXY = 1; dCam.camera.noise = true; dCam.namePlanet = {'Mars', 'Sun'}; dCam.radiusPlanet = [rM rS];
Set up the displays
TimeDisplay('initialize','ONS Simulation',n); if( viewersOn ) hNav = StarCameraViewer('initialize','Navigation Camera', n ); %#ok<*UNRCH> end % The time vector t = (0:n-1)*dT;
Setup Optical Navigation
dONS = OpticalNavigation; r = x(1:3); v = x(4:6); dONS.ukf.fData = RHSUKFHelioMission; dONS.ukf.fData.jD0 = dRHS.jD0; switch simName case 'solar orbit' dONS.target = sun; dONS.ukf.fData.ref = sun; case 'mars orbit' dONS.target = mars; dONS.ukf.fData.ref = mars; otherwise error('%s does not have a specified target',simName); end % Initialize ONS dONS = OpticalNavigation( 'initialize', dONS, r, v, dT ); meas.optical = NavigationCamera( r, dCam ); % Set up the parameters in ONS dONS.t = t(1); dONS.useUKF = true; dONS.ukf.useOptical = false; dONS.ukf.useState = true; dONS.ukf.usePos = false; dONS.ukf.f = @RHSUKFHelioMission; dONS.aBody1 = rM; dONS.aBody2 = rS; % Plotting arrays xP = zeros(21,n); target = zeros(1,n); type = zeros(1,n); nStars = zeros(1,n);
Run the simulation
for k = 1:n % ONS simulation TimeDisplay('update',k); % Determine if the spacecraft has hit the ground if( dRHS.ref == mars ) h = Mag(x(1:3))-rM; else h = Mag(x(1:3))-rS; end % Get data for plotting [~,~,~,acc] = RHSHelioMission(x,t(k),dRHS); % Get the location and velocity of Mars [rMars,~,vMars] = PlanetPosJPL( 'update', jD0 + t(k)*secToDay ); if( dRHS.ref == mars ) dCam.xPlanet = [[0;0;0] -rMars]; rMars = [0;0;0]; vMars = [0;0;0]; else dCam.xPlanet = [rMars [0;0;0]]; end % Stop on landing if( h <= 0 ) break; end % The camera boresight points at the target xCam is in the ECI frame if( dRHS.ref == sun ) rCam = x(1:3); vCam = x(4:6); else rCam = dCam.xPlanet(:,1) - x(1:3); vCam = vMars - x(4:6); end % Needed to point the camera dONS = OpticalNavigation( 'get unit vector', dONS, rMars, vMars, rCam, vCam ); % Get the measurements meas.jD0 = jD0 + t(k)*secToDay; meas.state = x(1:6); meas.acc = acc; dCam.q = U2Q(dONS.uC,[0;0;1]); dOM.cam = NavigationCamera( rCam, dCam ); dOM.type = dONS.type; dOM.target = dONS.target; dOM.ref = dRHS.ref; dOM.uCamera = dONS.uCamera; dOM.aBody1 = dONS.aBody1; dOM.aBody2 = dONS.aBody2; dOM.r1 = rMars; dOM.v1 = vMars; meas.state = x(1:6); meas.acc = acc; % Spacecraft non-gravitational acceleration meas.gps = MeasGPS( x, dGPS ); meas.gs = MeasRangeGroundStation( x, dGS ); meas.optical = MeasStarAngleAndChord( [rCam;vCam], dOM ); % ONS dONS.cam = dOM.cam; dONS.ref = dRHS.ref; dONS.r1 = dOM.r1; dONS.v1 = dOM.v1; dONS.t = t(k); target(k) = dONS.target; type(k) = dONS.type; dONS = OpticalNavigation( 'update', dONS, meas, rMars, vMars, rCam, vCam ); nStars(k) = dONS.ukf.optical.nStars; % Display the cameras if( viewersOn ) StarCameraViewer('update', dOM.cam, [], hNav, dCam, k); end xP(:,k) = [x;rMars;dRHS.thrust;dRHS.ref;h;dONS.x]; % Propagate the state x = RK4(@RHSHelioMission,x,dT,t(k),dRHS); end TimeDisplay('close');
Plotting
% Shorten the vectors if it hits the ground j = 1:k; xP = xP(:,j); t = t(j); target = target(j); type = type(j); nStars = nStars(j); % Make earth and moon reference position rSun = zeros(3,k); rMars = zeros(3,k); j = find(xP(14,:) == mars ); rMars(:,j) = xP(1:3,j); rSun(:,j) = xP(8:10,j) - rMars(:,j); j = find(xP(14,:) == sun ); rSun(:,j) = xP(1:3,j); rMars(:,j) = xP(8:10,j) + rSun(:,j); % Sun/Mars plot HelioPlot( 4, t(end)/secInYear, jD0, xP(1:3,:), {'Spacecraft'} ) % Time histories [t,tL] = TimeLabl(t); yL = {'x (km)' 'y (km)' 'z (km)'}; yD = {'a_x (km/s^2)' 'a_y (km/s^2)' 'a_z (km/s^2)' 'H (km)' '|a| (km/s^2)'}; yS = {'x (km)' 'y (km)' 'z (km)' 'v_x (km/s)' 'v_y (km/s)' 'v_z (km/s)'}; Plot2D(t,xP(1:6,:),tL,yS,'State'); Plot2D(t,rSun, tL,yL,'Sun Referenced Position'); Plot2D(t,rMars,tL,yL,'Mars Referenced Position'); Plot2D(t,xP(16:21,:) - xP(1:6,:),tL,yS,'Navigation Error'); Plot2D(t,xP(16:21,:),tL,yS,'Navigation Solution'); NewFig('Targeting') subplot(3,1,1); h = plot(t,target); set(h,'linewidth',2); grid on XLabelS(tL); YLabelS('Target') set(gca,'ytick',[1 2],'yticklabel',{'Mars' 'Sun'}); subplot(3,1,2); h = plot(t,type); set(h,'linewidth',2); grid on XLabelS(tL); YLabelS('Measurement Type') set(gca,'ytick',[1 2],'yticklabel',{'Horizon' 'Center'}); subplot(3,1,3); h = plot(t,nStars); set(h,'linewidth',2); grid on XLabelS(tL); YLabelS('Stars') Figui if( printAll ) n = get(gcf,'number'); for k = 1:n PrintFig(1,4,k,sprintf('%s%d',simName,k)); end end %--------------------------------------