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