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