LRO Solar Radiation Pressure with Lookup Table
This example demonstrates how to compute solar radiation pressure (SRP) accelerations using pre-computed lookup tables with the pyRTX library.
lro_srp_with_lut.py
1### ------------------------------------------------------------------------------------------------------- ###
2
3# Example purpose:
4# Show the object-oriented interface of the pyRTX library
5#
6# Example case:
7# Compute the srp acceleration for LRO spacecraft, using the values stored in a lookup table.
8
9### ------------------------------------------------------------------------------------------------------- ###
10### IMPORTS
11
12import sys, os
13import spiceypy as sp
14import matplotlib.pyplot as plt
15import logging, timeit
16
17from pyRTX.classes.Spacecraft import Spacecraft
18from pyRTX.classes.Planet import Planet
19from pyRTX.classes.SRP import SunShadow, SolarPressure
20from pyRTX.classes.Precompute import Precompute
21from pyRTX.classes.LookUpTable import LookUpTable
22from pyRTX.core.analysis_utils import epochRange2
23import logging
24
25from numpy import floor, mod
26
27import warnings
28warnings.filterwarnings('ignore')
29
30### ------------------------------------------------------------------------------------------------------- ###
31### INPUTS
32
33# NOTE: before running this script you must generate the input file 'luts/lro_accel_lut.nc' by running the
34# example 'compute_lut.py' using type = 'accel'.
35
36ref_epc = "2010 may 10 09:25:00"
37duration = 10000 # seconds
38sc_mass = 2000 # can be a float, int or xarray [kg]
39timestep = 100
40METAKR = '../example_data/LRO/metakernel_lro.tm' # metakernel
41obj_path = '../example_data/LRO/' # folder with .obj files
42lutfile = 'luts/lro_accel_lut.nc' # lookup table file
43base_flux = 1361.5
44ref_radius = 1737.4
45
46if not os.path.exists(lutfile):
47 print(f"Before running this script you must generate the file '{lutfile}' by running the example 'compute_lut.py' setting type = 'accel'.")
48 sys.exit()
49
50### ------------------------------------------------------------------------------------------------------- ###
51### OBJECTS DEFINITION
52
53# Time initialization
54tic = timeit.default_timer()
55
56# Load the metakernel containing references to the necessary SPICE frames
57sp.furnsh(METAKR)
58
59# Define a basic epoch
60epc_et0 = sp.str2et( ref_epc )
61epc_et1 = epc_et0 + duration
62epochs = epochRange2(startEpoch = epc_et0, endEpoch = epc_et1, step = timestep)
63
64# Define the Spacecraft Object (Refer to the class documentation for further details)
65lro = Spacecraft( name = 'LRO',
66
67 base_frame = 'LRO_SC_BUS', # Name of the spacecraft body-fixed frame
68
69 mass = sc_mass,
70
71 spacecraft_model = { # Define a spacecraft model
72
73 'LRO_BUS': {
74 'file' : obj_path + 'bus_rotated.obj', # .obj file of the spacecraft component
75 'frame_type': 'Spice', # type of frame (can be 'Spice' or 'UD'
76 'frame_name': 'LRO_SC_BUS', # Name of the frame
77 'center': [0.0,0.0,0.0], # Origin of the component
78 'diffuse': 0.1, # Diffuse reflect. coefficient
79 'specular': 0.3, # Specular reflect. coefficient
80 },
81
82 'LRO_SA': {
83 'file': obj_path + 'SA_recentred.obj',
84 'frame_type': 'Spice',
85 'frame_name': 'LRO_SA',
86 'center': [-1,-1.1, -0.1],
87 'diffuse': 0,
88 'specular': 0.3,
89 },
90
91
92 'LRO_HGA': {
93 'file': obj_path + 'HGA_recentred.obj',
94 'frame_type': 'Spice',
95 'frame_name': 'LRO_HGA',
96 'center':[-0.99, -0.3, -3.1],
97 'diffuse': 0.2,
98 'specular': 0.1,
99 },
100 }
101 )
102
103
104# Define the Moon object
105moon = Planet( fromFile = None,
106 radius = ref_radius,
107 name = 'Moon',
108 bodyFrame = 'MOON_PA',
109 sunFixedFrame = 'GSE_MOON',
110 units = 'km',
111 subdivs = 5,
112 )
113
114
115# Precomputation object. This object performs all the calls to spiceypy before
116# calculating the acceleration. This is necessary when calculating the acceleration
117# with parallel cores.
118prec = Precompute(epochs = epochs,)
119prec.precomputeSolarPressure(lro, moon, correction='LT+S')
120prec.dump()
121
122# Define the shadow function object
123shadow = SunShadow( spacecraft = lro,
124 body = 'Moon',
125 bodyShape = moon,
126 limbDarkening = 'Eddington',
127 precomputation = prec,
128 )
129
130# Load the Look up table
131LUT = LookUpTable(lutfile)
132
133# Define the solar pressure object (LUT mode)
134srp = SolarPressure( lro,
135 rayTracer = None,
136 baseflux = base_flux,
137 shadowObj = shadow,
138 precomputation = prec,
139 lookup = LUT,
140 )
141
142# Managing Error messages from trimesh
143# (when concatenating textures, in this case, withouth .mtl definition, trimesh returns a warning that
144# would fill the stdout. Deactivate it for a clean output)
145log = logging.getLogger('trimesh')
146log.disabled = True
147
148# Compute the SRP acceleration at different epochs and plot it
149accel = srp.lookupCompute(epochs) * 1e3
150
151log.disabled = False
152
153# Always unload the SPICE kernels
154sp.unload(METAKR)
155
156### ... Elapsed time
157toc = timeit.default_timer()
158time_min = int(floor((toc-tic)/60))
159time_sec = int(mod((toc-tic), 60))
160print("")
161print("\t Elapsed time: %d min, %d sec" %(time_min, time_sec))
162print("")
163
164### ------------------------------------------------------------------------------------------------------- ###
165### PLOT
166
167epochs = [float( epc - epc_et0)/3600 for epc in epochs]
168
169fig, ax = plt.subplots(3, 1, figsize=(14,8), sharex = True)
170
171ax[0].plot(epochs, accel[:,0], linewidth = 2, color = "tab:blue")
172ax[0].set_ylabel('X [m/s^2]')
173ax[1].plot(epochs, accel[:,1], linewidth = 2, color = "tab:blue")
174ax[1].set_ylabel('Y [m/s^2]')
175ax[2].plot(epochs, accel[:,2], linewidth = 2, color = "tab:blue")
176ax[2].set_ylabel('Z [m/s^2]')
177ax[2].set_xlabel('Hours from t0')
178
179plt.tight_layout()
180plt.show()
181
182### ------------------------------------------------------------------------------------------------------- ###
183
184