# Lunar Mission Analysis with the Orbit Propagator Block

This example shows how to compute and visualize access intervals between the Apollo Command and Service module and a rover on the lunar surface. The module's orbit is modeled using Reference Trajectory #2 from the NASA report Variations of the Lunar Orbital Parameters of the Apollo CSM-Module [2]. This is a lunar orbit studied by NASA for the Apollo program. The example uses:

• Aerospace Toolbox™

• Aerospace Blockset™

• Mapping Toolbox™

### Define Mission Parameters and Module Initial Conditions

Specify the start date and duration for the mission. This example uses MATLAB® structures to organize mission data. These structures make accessing data later in the example more intuitive. They also help declutter the global base workspace.

```mission.StartDate = datetime(1969, 9, 20, 5, 10, 12.176); mission.Duration = hours(2);```

Specify Keplerian orbital elements for the Command and Service module (CSM) at the `mission.StartDate` based on Reference Trajectory #2 [2]. The criteria for the reference trajectories featured in Reference 2 are:

• The plane of the trajectory must contain a landing site vector on the Earth side of the Moon, which has a longitude of between 315 and 45 degrees and a latitude of between +5 and -5 degrees in selenographic coordinates. [2]

• The plane of the orbit must be oriented so that the lunar landing side doesn't move out of the orbital plane more than 0.5 degrees during the period of 3 to 39 hours after lunar insertion. [2]

```csm.SemiMajorAxis = 1894578.3; % [m] csm.Eccentricity = 0.0004197061; csm.Inclination = 155.804726; % [deg] csm.RAAN = 182.414087; % [deg] csm.ArgOfPeriapsis = 262.877900; % [deg] csm.TrueAnomaly = 0.000824; % [deg]```

Note that the inclination angle is relative to the ICRF X-Y plane. The ICRF X-Y axis is normal to Earth's north pole. The axial tilt of Earth relative to the ecliptic is ~23.44 degrees, while the axial tilt of the Moon is ~5.145 degrees. Therefore, the axial tilt of the Moon relative to the ICRF X-Y plane varies between approximately $23.44±5.145$ degrees. This explains why the orbital inclination of ~155.8 degrees above satisfies the requirement to maintain a latitude of $±5$ degrees in selenographic coordindates.

Specify the latitude and longitude of a rover on the lunar surface to use in the line-of-sight access analysis.

```rover.Latitude =0; % [deg] rover.Longitude =23.5; % [deg]```

### Open and Configure the Model

Open the included Simulink® model. This model contains an Orbit Propagator block connected to output ports. The` Orbit Propagator` block supports vectorization. This allows you to model multiple satellites in a single block by specifying arrays of initial conditions in the Block Parameters window or using `set_param`.

```mission.mdl = "LunarOrbitPropagatorBlockExampleModel"; open_system(mission.mdl);```

Use a `SimulationInput` object to configure the model for our mission. `SimulationInput` objects provide the ability to configure multiple missions and run simulations with those settings without modifying the model.

`mission.sim.in = Simulink.SimulationInput(mission.mdl);`

Define the path to the Orbit Propagator block in the model.

`csm.blk = mission.mdl + "/Orbit Propagator";`

Load Moon properties into the base workspace.

```moon.F = 0.0012; % Moon ellipticity (flattening) (Ref 1) moon.R_eq = 1737400; % [m] Lunar radius in meters (Ref 1) moon.ReferenceEllipsoid = referenceEllipsoid("moon","meter"); % Moon reference ellipsoid moon.Data = matfile("lunarGeographicalData.mat"); % Load moon geographical data```

Set CSM initial conditions. To assign the Keplerian orbital element set defined in the previous section, use `setBlockParameter`.

```mission.sim.in = mission.sim.in.setBlockParameter(... csm.blk, "startDate", string(juliandate(mission.StartDate)),... csm.blk, "stateFormatNum", "Orbital elements",... csm.blk, "orbitType", "Keplerian",... csm.blk, "semiMajorAxis", string(csm.SemiMajorAxis),... csm.blk, "eccentricity", string(csm.Eccentricity),... csm.blk, "inclination", string(csm.Inclination),... csm.blk, "raan", string(csm.RAAN),... csm.blk, "argPeriapsis", string(csm.ArgOfPeriapsis),... csm.blk, "trueAnomaly", string(csm.TrueAnomaly));```

Set the position and velocity output ports of the block to use the Moon-fixed frame. The fixed-frame for the Moon is the Mean Earth/Pole Axis (ME) reference system.

```mission.sim.in = mission.sim.in.setBlockParameter(... csm.blk, "centralBody", "Moon",... csm.blk, "outportFrame", "Fixed-frame");```

Configure the propagator.

```mission.sim.in = mission.sim.in.setBlockParameter(... csm.blk, "propagator", "Numerical (high precision)",... csm.blk, "gravityModel", "Spherical Harmonics",... csm.blk, "moonSH", "LP-100K",... % moon spherical harmonic potential model csm.blk, "shDegree", "100",... % Spherical harmonic model degree and order csm.blk, "useMoonLib", "off");```

Apply model-level solver settings using setModelParameter. For best performance and accuracy when using a numerical propagator, use a variable-step solver.

```mission.sim.in = mission.sim.in.setModelParameter(... SolverType="Variable-step",... SolverName="VariableStepAuto",... RelTol="1e-6",... AbsTol="1e-7",... StopTime=string(seconds(mission.Duration)));```

Save model output port data as a dataset of timetable objects.

```mission.sim.in = mission.sim.in.setModelParameter(... SaveOutput="on",... OutputSaveName="yout",... SaveFormat="Dataset",... DatasetSignalFormat="timetable");```

### Run the Model and Collect CSM Ephemerides

Simulate the model using the `SimulationInput` object defined above. In this example, the Orbit Propagator block is set to output position and velocity states in the Moon-centered fixed coordinate frame.

`mission.sim.out = sim(mission.sim.in);`

Extract the position and velocity data from the model output data structure.

```csm.TimetablePos = mission.sim.out.yout{1}.Values; csm.TimetableVel = mission.sim.out.yout{2}.Values;```

Set the start date of the mission in the `timetable` object.

`csm.TimetablePos.Properties.StartTime = mission.StartDate;`

### Process Simulation Data

Compute latitude, longitude, and altitude using lunar equatorial radius and flattening. Values are displayed in degrees and meters.

```csm.MEPos = [csm.TimetablePos.Data(:,1) ... csm.TimetablePos.Data(:,2) csm.TimetablePos.Data(:,3)]; lla = ecef2lla(csm.MEPos, moon.F, moon.R_eq); csm.LLA = timetable(csm.TimetablePos.Time, ... lla(:,1), lla(:,2), lla(:,3), ... VariableNames=["Lat", "Lon", "Alt"]); clear lla; disp(csm.LLA);```
``` Time Lat Lon Alt ____________________ _________ _______ __________ 20-Sep-1969 05:10:12 -2.3072 175.32 1.5639e+05 20-Sep-1969 05:10:22 -2.3039 174.83 1.5639e+05 20-Sep-1969 05:11:12 -2.2846 172.39 1.5639e+05 20-Sep-1969 05:13:36 -2.2061 165.35 1.5639e+05 20-Sep-1969 05:16:00 -2.0947 158.31 1.564e+05 20-Sep-1969 05:18:24 -1.952 151.27 1.5641e+05 20-Sep-1969 05:20:48 -1.7804 144.24 1.5641e+05 20-Sep-1969 05:23:12 -1.5824 137.21 1.5642e+05 20-Sep-1969 05:25:36 -1.3608 130.17 1.5641e+05 20-Sep-1969 05:28:00 -1.119 123.14 1.5641e+05 20-Sep-1969 05:30:24 -0.86057 116.11 1.564e+05 20-Sep-1969 05:32:48 -0.58934 109.09 1.564e+05 20-Sep-1969 05:35:12 -0.30942 102.06 1.5639e+05 20-Sep-1969 05:37:36 -0.025001 95.032 1.5639e+05 20-Sep-1969 05:40:00 0.25967 88.006 1.564e+05 20-Sep-1969 05:42:24 0.54034 80.978 1.564e+05 20-Sep-1969 05:44:48 0.81284 73.951 1.5641e+05 20-Sep-1969 05:47:12 1.0732 66.923 1.5642e+05 20-Sep-1969 05:49:36 1.3175 59.893 1.5643e+05 20-Sep-1969 05:52:00 1.5422 52.863 1.5646e+05 20-Sep-1969 05:54:24 1.7439 45.831 1.5649e+05 20-Sep-1969 05:56:48 1.9194 38.797 1.5652e+05 20-Sep-1969 05:59:12 2.0662 31.763 1.5656e+05 20-Sep-1969 06:01:36 2.1821 24.728 1.566e+05 20-Sep-1969 06:04:00 2.2652 17.691 1.5664e+05 20-Sep-1969 06:06:24 2.3145 10.655 1.5668e+05 20-Sep-1969 06:08:48 2.3291 3.6183 1.5673e+05 20-Sep-1969 06:11:12 2.309 -3.418 1.5676e+05 20-Sep-1969 06:13:36 2.2544 -10.454 1.5679e+05 20-Sep-1969 06:16:00 2.1663 -17.489 1.5682e+05 20-Sep-1969 06:18:24 2.046 -24.522 1.5683e+05 20-Sep-1969 06:20:48 1.8953 -31.554 1.5685e+05 20-Sep-1969 06:23:12 1.7163 -38.585 1.5686e+05 20-Sep-1969 06:25:36 1.5116 -45.614 1.5686e+05 20-Sep-1969 06:28:00 1.2844 -52.642 1.5686e+05 20-Sep-1969 06:30:24 1.0381 -59.668 1.5686e+05 20-Sep-1969 06:32:48 0.77625 -66.693 1.5685e+05 20-Sep-1969 06:35:12 0.50273 -73.718 1.5684e+05 20-Sep-1969 06:37:36 0.22159 -80.741 1.5683e+05 20-Sep-1969 06:40:00 -0.062926 -87.765 1.5682e+05 20-Sep-1969 06:42:24 -0.34651 -94.789 1.568e+05 20-Sep-1969 06:44:48 -0.62489 -101.81 1.5677e+05 20-Sep-1969 06:47:12 -0.89393 -108.84 1.5673e+05 20-Sep-1969 06:49:36 -1.1497 -115.87 1.5669e+05 20-Sep-1969 06:52:00 -1.3884 -122.89 1.5664e+05 20-Sep-1969 06:54:24 -1.6064 -129.92 1.566e+05 20-Sep-1969 06:56:48 -1.8006 -136.96 1.5656e+05 20-Sep-1969 06:59:12 -1.9679 -143.99 1.5652e+05 20-Sep-1969 07:01:36 -2.1058 -151.03 1.5647e+05 20-Sep-1969 07:04:00 -2.212 -158.06 1.5641e+05 20-Sep-1969 07:06:24 -2.2849 -165.1 1.5635e+05 20-Sep-1969 07:08:48 -2.3235 -172.14 1.563e+05 20-Sep-1969 07:10:12 -2.3299 -176.25 1.5626e+05 ```

### Results

#### Display CSM Trajectories Over the 3-D Moon

```figure; axis off; colormap gray; view(-5,23); axesm("globe","Geoid", moon.ReferenceEllipsoid); geoshow(moon.Data.moonalb20c, moon.Data.moonalb20cR, DisplayType="texturemap"); plot3(csm.MEPos(:,1), csm.MEPos(:,2), csm.MEPos(:,3),"r");```

#### Display 2-D Projection of CSM Ground Trace and Rover Position

```figure; colormap gray; axesm(MapProjection="robinson"); geoshow(moon.Data.moonalb20c, moon.Data.moonalb20cR, DisplayType="texturemap"); plotm(csm.LLA.Lat, csm.LLA.Lon, Color="r"); plotm(rover.Latitude, rover.Longitude, "xy", LineWidth=3);```

#### Display CSM Field Of View at Time of Interest

Define a time of interest (TOI) to anayze. For this example, we select the 30th sample in the dataset.

`csm.TOI.LLA = csm.LLA(30,:);`

Calculate angular radius of orbiter line-of-sight (LOS) field of view (FOV) measured from the Moon center.

```csm.TOI.FOV.Lambda0 = acosd(moon.R_eq / (moon.R_eq + csm.TOI.LLA.Alt)); % [deg] [csm.TOI.FOV.Lats, csm.TOI.FOV.Lons] = ... scircle1(csm.TOI.LLA.Lat, csm.TOI.LLA.Lon, csm.TOI.FOV.Lambda0);```

Plot TOI. The location of the CSM is indicated by a green cross, LOS field of view is indicated by dashed circle.

```figure; colormap gray; axesm(MapProjection="robinson"); geoshow(moon.Data.moonalb20c, moon.Data.moonalb20cR, DisplayType="texturemap"); plotm(csm.TOI.FOV.Lats, csm.TOI.FOV.Lons, "g--", LineWidth=1); % CSM visibility projected onto the map plotm(csm.LLA.Lat, csm.LLA.Lon, Color="r"); % CSM ground trace plotm(csm.TOI.LLA.Lat, csm.TOI.LLA.Lon, "g+", MarkerSize=8); % sub-CSM point plotm(rover.Latitude, rover.Longitude, "xy", LineWidth=3);```

#### Display CSM Line-of-Sight Visibility from Rover

Estimate access intervals by assuming the Moon is spherical.

```lambda_all = acosd(moon.R_eq ./ (moon.R_eq + csm.LLA.Alt)); % [deg] angular radius of CSM FOV measured from Moon center d = distance(csm.LLA.Lat, csm.LLA.Lon, ... rover.Latitude, rover.Longitude); % [deg] angular distance between sub-CSM point and rover rover.Access.InView = csm.LLA(lambda_all - d > 0,:); % timetable containing the in view data samples rover.Access.InView.Time.Format = "HH:mm:ss"; clear lambda_all d;```

Plot access intervals between the orbiting module and rover.

```if height(rover.Access.InView) ~= 0 % Look for breaks in the timestamps to identify pass starts rover.Access.StartIdx = [1, find(diff(rover.Access.InView.Time) > minutes(5))]; rover.Access.StartTime = rover.Access.InView.Time(rover.Access.StartIdx); rover.Access.StopIdx = [rover.Access.StartIdx(2:end)-1, height(rover.Access.InView)]; rover.Access.StopTime = rover.Access.InView.Time(rover.Access.StopIdx); rover.Access.Duration = rover.Access.StopTime - rover.Access.StartTime; % Show pass intervals in table rover.Access.IntervalTable = table(rover.Access.StartTime, rover.Access.StopTime, rover.Access.Duration, ... VariableNames=["Pass Start", "Pass End", "Duration"]); disp(rover.Access.IntervalTable); disp(' '); % Set up figure window/plot figure; colormap gray; axesm(MapProjection="robinson") geoshow(moon.Data.moonalb20c, moon.Data.moonalb20cR, DisplayType="texturemap") title(join(["Passes Between", string(csm.LLA.Time(1)), ... "and", string(csm.LLA.Time(end))])); % Plot inView, rover, and CSM orbit plotm(rover.Access.InView.Lat, rover.Access.InView.Lon, "+g"); plotm(rover.Latitude, rover.Longitude, "xy", LineWidth=3); plotm(csm.LLA.Lat, csm.LLA.Lon, Color="r"); % Plot pass inteval rover.Access.EdgeIndices = rover.Access.InView(sort([rover.Access.StartIdx rover.Access.StopIdx]), :); for j = 1 : height(rover.Access.EdgeIndices) textm(rover.Access.EdgeIndices.Lat(j) + 10, ... rover.Access.EdgeIndices.Lon(j), ... string(rover.Access.EdgeIndices.Time(j)), Color="y", Rotation=30); end else disp("The CSM is not visible from the rover during the defined mission time.") end ```
``` Pass Start Pass End Duration __________ ________ ________ 05:54:24 06:08:48 00:14:24 ```
``` ```

### References

[1] Williams, Dr. David R. “Moon Fact Sheet”, Planetary Fact Sheets, NSSDCA, NASA Goddard Space Flight Center, 13 January 2020, https://nssdc.gsfc.nasa.gov/planetary/factsheet/moonfact.html.

[2] Timer, T.P. (NASA Mission Analysis Office) "Variations of the Lunar Orbital Parameters of the Apollo CSM-Module", NASA TM X-55460. Greenbelt, Maryland: Goddard Space Flight Center, February 1966.