Simulate ONS for a spacecraft that flies by Mercury
This only simulates the orbital motion.
See also: RHSHelioMission, PlanetPosJPL, NavigationCamera, StarCameraViewer, RHSUKFHelioMission, MeasGPS, MeasRangeGroundStation, MeasStarAngleAndChord, OpticalNavigation, RK4, TimeLabl, Plot2D, Figui
Contents
%-------------------------------------------------------------------------- % Copyright (c) 2021 Princeton Satellite Systems, Inc. % All rights reserved. %--------------------------------------------------------------------------
Constants
rE = Constant('equatorial radius mercury'); rS = Constant('sun radius'); muSun = Constant('mu sun'); muMercury = Constant('mu mercury'); aU = Constant('au'); secToDay = 1/86400; secInYear = 365.26*86400; kEarth = 1; % SPICE numbering 1-9 are the planets, 10 is the moon mercury = 1; sun = 2; % Get the defaults dRHS = RHSHelioMission; dRHS.mu(1) = muMercury;
Script control
viewersOn = true; printAll = false; % acceleration model massFuel = 0; % kg dRHS.mD = 1000; % kg dRHS.uE = inf; plotRef = {'Sun' 'Mercury'}; % Initialize the ephemeris PlanetPosJPL( 'initialize', kEarth ) rHelio = [-5.102050761318097E+07; -3.914630171469574E+07; -1.563888544075625E+07]; vHelio = [ 2.159852087150890E+01; -3.063444535492430E+01; -1.827429443660471E+01]; jD0 = 2455755.50; % Initialize the state dRHS.ref = sun; dT = 10000; tEnd = 10*dT; % sec % This halo state does not take into account the sail's force [r0, mu, v0] = PlanetPosJPL( 'update', jD0 ); x = [rHelio;vHelio;massFuel]; dRHS.mu(1) = mu; % set the mu for the right planet % 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 = {'Mercury' 'Sun'}; dCam.radiusPlanet = [rE 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.mu(1) = muMercury; dONS.ukf.fData.jD0 = dRHS.jD0; dONS.target = mercury; dONS.ukf.fData.ref = sun; % 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 = false; dONS.ukf.usePos = false; dONS.ukf.f = @RHSUKFHelioMission; dONS.aBody1 = rE; dONS.aBody2 = rS; dONS.ref = dRHS.ref; % Plotting arrays xP = zeros(20,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); % Get data for plotting [~,~,~,acc] = RHSHelioMission(x,t(k),dRHS); % Get the location and velocity of Earth [rMercury,~,vMercury] = PlanetPosJPL( 'update', jD0 + t(k)*secToDay ); if( dRHS.ref == mercury ) dCam.xPlanet = [[0;0;0] -rMercury]; rMercury = [0;0;0]; vMercury = [0;0;0]; else dCam.xPlanet = [rMercury [0;0;0]]; end % The camera boresight points at the target xCam is in the helio frame rCam = x(1:3); vCam = x(4:6); % Needed to point the camera dONS = OpticalNavigation( 'get unit vector', dONS, rMercury, vMercury, 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 = rMercury; dOM.v1 = vMercury; % Measurements 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); dONS = OpticalNavigation( 'update', dONS, meas, rMercury, vMercury, rCam, vCam ); target(k) = dONS.target; type(k) = dONS.type; nStars(k) = dONS.ukf.optical.nStars; % Display the cameras if( viewersOn ) StarCameraViewer('update', dOM.cam, [], hNav, dCam, k); end xP(:,k) = [x;rMercury;dRHS.thrust;dRHS.ref;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 sun referenced positions rSun = zeros(3,k); rMercury = zeros(3,k); j = find(xP(14,:) == mercury ); rMercury(:,j) = xP(1:3,j); rSun(:,j) = xP(8:10,j) - rMercury(:,j); j = find(xP(14,:) == sun ); rSun(:,j) = xP(1:3,j); rMercury(:,j) = xP(8:10,j) - rSun(:,j); % Sun/Mercury plot HelioPlot( 3, t(end)/secInYear, jD0, xP(1:3,:), {'Spacecraft'} ) % Time histories [t,tL] = TimeLabl(t); yL = {'x (km)' 'y (km)' 'z (km)'}; 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,rMercury,tL,yL,'Mercury Referenced Position'); Plot2D(t,xP(15:20,:) - xP(1:6,:),tL,yS,'Navigation Error'); Plot2D(t,xP(15:20,:),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',{'Mercury' '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 %--------------------------------------