LRO Albedo and Thermal IR (Simple)

This example demonstrates how to compute albedo and thermal infrared accelerations using the object-oriented interface of the pyRTX library.

In this simplified case, we use single uniform values for:

  • Planet emissivity

  • Planet albedo

  • Planet surface temperature

This provides a quick way to compute planetary radiation pressure effects without requiring detailed surface property maps.

lro_alb_ir_simple.py
  1### ------------------------------------------------------------------------------------------------------- ###
  2
  3# Example purpose:
  4# Show the object-oriented interface of the pyRTX library
  5#
  6# Example case:
  7# Show how to compute albedo and thermal-ir accelerations
  8# Here we use a single value for the emissivity, albedo and temperature for the planet.
  9
 10### ------------------------------------------------------------------------------------------------------- ###
 11### IMPORTS
 12
 13import sys, os
 14import numpy as np
 15import spiceypy as sp
 16import matplotlib.pyplot as plt
 17import timeit
 18
 19from pyRTX.classes.Spacecraft import Spacecraft
 20from pyRTX.classes.Planet import Planet
 21from pyRTX.classes.Radiation import Albedo, Emissivity
 22from pyRTX.classes.Precompute import Precompute
 23from pyRTX.classes.LookUpTable import LookUpTable
 24from pyRTX.core.analysis_utils import epochRange2
 25
 26from numpy import floor, mod
 27
 28### ------------------------------------------------------------------------------------------------------- ###
 29### INPUTS
 30
 31# NOTE: before running this script you must generate the input file 'luts/lro_accel_lut.nc' by running the 
 32# example 'compute_lut.py' using type = 'accel'.
 33
 34ref_epc		=  "2010 may 10 09:25:00"
 35duration    =  10000  									  # seconds
 36timestep    =  100
 37METAKR      = '../example_data/LRO/metakernel_lro.tm'     # metakernel
 38obj_path    = '../example_data/LRO/'				      # folder with .obj files
 39lutfile     = 'luts/lro_accel_lut.nc'					  # lookup table file
 40base_flux   =  1361.5
 41ref_radius  =  1737.4
 42n_cores     =  10
 43sc_mass		=  2000  									  # can be a float, int or xarray [kg]
 44
 45if not os.path.exists(lutfile):
 46    print(f"Before running this script you must generate the file '{lutfile}' by running the example 'compute_lut.py' setting type = 'accel'.")
 47    sys.exit()
 48    
 49### ------------------------------------------------------------------------------------------------------- ###
 50### OBJECTS DEFINITION
 51
 52# Time initialization
 53tic = timeit.default_timer()
 54
 55# Load the metakernel containing references to the necessary SPICE frames
 56sp.furnsh(METAKR)
 57
 58# Define epochs
 59epc_et0  = sp.str2et( ref_epc )
 60epc_et1  = epc_et0 + duration
 61epochs   = epochRange2(startEpoch = epc_et0, endEpoch = epc_et1, step = timestep)
 62 
 63# Define the Spacecraft Object (Refer to the class documentation for further details)
 64lro = Spacecraft( name = 'LRO',
 65                 
 66				  base_frame = 'LRO_SC_BUS', 					     # Name of the spacecraft body-fixed frame
 67      
 68                  mass = sc_mass,
 69      
 70				  spacecraft_model = {						         # Define a spacecraft model
 71                          
 72					'LRO_BUS': { 
 73							 'file' : obj_path + 'bus_rotated.obj',	 # .obj file of the spacecraft component
 74							 'frame_type': 'Spice',				     # type of frame (can be 'Spice' or 'UD'
 75							 'frame_name': 'LRO_SC_BUS',			 # Name of the frame
 76							 'center': [0.0,0.0,0.0],			     # Origin of the component
 77							 'diffuse': 0.1,				         # Diffuse reflect. coefficient
 78							 'specular': 0.3,				         # Specular reflect. coefficient
 79							 },
 80
 81					'LRO_SA': {	
 82							'file': obj_path + 'SA_recentred.obj',
 83							'frame_type': 'Spice',
 84							'frame_name': 'LRO_SA',
 85							'center': [-1,-1.1, -0.1],
 86							'diffuse': 0,
 87							'specular': 0.3,
 88							},
 89
 90
 91					'LRO_HGA': { 	
 92							'file': obj_path + 'HGA_recentred.obj',
 93							'frame_type': 'Spice',
 94							'frame_name': 'LRO_HGA',
 95							'center':[-0.99,    -0.3,  -3.1],
 96							'diffuse': 0.2,
 97							'specular': 0.1,
 98							},
 99					}
100					)
101
102# Define the Moon object
103moon = Planet(  fromFile = None,
104                radius = ref_radius,
105                name = 'Moon',
106                bodyFrame = 'MOON_PA',
107                sunFixedFrame = 'GSE_MOON',
108                units = 'km',
109                subdivs = 5,
110                )
111
112# Set the albedo and emissivity values
113# Here we use dummy values and assume that
114# albedo and emissivity are constant over the whole planet
115# and set a different dayside and nightside temperature
116# pyRTX supports also gridded values for albedo and emissivity (see examples/lro_alb_ir_grid.py)
117
118moon.albedo = 0.3
119moon.emissivity  = 0.8 
120moon.dayside_temperature = 300
121moon.nightside_temperature = 200
122
123# Load the Look up table
124LUT  = LookUpTable(lutfile)
125
126# Precomputation object
127prec = Precompute(epochs = epochs,)
128prec.precomputePlanetaryRadiation(lro, moon, LUT.moving_frames, correction='CN')
129prec.dump()
130
131# Create the albedo object
132albedo = Albedo(lro, LUT, moon, precomputation  = prec, baseflux  = base_flux,)
133
134# Create the thermal infrared object
135thermal_ir = Emissivity(lro, LUT, moon, precomputation  = prec, baseflux  = base_flux,)
136
137### ------------------------------------------------------------------------------------------------------- ###
138### COMPUTATIONS
139
140# Both the albedo and emissivity objects have a .compute() method.
141# This method returns the normalized fluxes, direction and albedo values
142# for each of the planet faces contributing to the computation
143# The general formula for computing the acceleration of an elementary face is:
144#
145# acc_i = L * albedo_value/mass * norm_flux
146#
147# where L is the normalized optical response of the spacecraft which can be computed
148# with raytracing setting a unitary radiance of the impacting rays
149# Due to the very high number of rays involved in these computations
150# it is mandatory to precompute L in the form of a lookup table.
151# Here we import the lookup table for LRO which can be computed using the example script
152# 'compute_lut.py'
153
154# Parallel computations
155alb_accel = albedo.compute(epochs, n_cores = n_cores)[0] * 1e3 
156ir_accel  = thermal_ir.compute(epochs, n_cores = n_cores)[0] * 1e3 
157
158# Always unload the SPICE kernels
159sp.unload(METAKR)
160
161### ... Elapsed time
162toc = timeit.default_timer()
163time_min = int(floor((toc-tic)/60))
164time_sec = int(mod((toc-tic), 60))
165print("")
166print("\t Elapsed time: %d min, %d sec" %(time_min, time_sec))
167print("")
168
169### ------------------------------------------------------------------------------------------------------- ###
170### PLOT
171
172epochs  = [float( epc - epc_et0 )/3600 for epc in epochs]
173
174# ALBEDO 
175fig, ax = plt.subplots(3, 1, figsize=(14,8), sharex = True)
176
177ax[0].plot(epochs, alb_accel[:,0], linewidth = 2, color = "tab:blue")
178ax[0].set_ylabel('X [m/s^2]')
179ax[1].plot(epochs, alb_accel[:,1], linewidth = 2, color = "tab:blue")
180ax[1].set_ylabel('Y [m/s^2]')
181ax[2].plot(epochs, alb_accel[:,2], linewidth = 2, color = "tab:blue")
182ax[2].set_ylabel('Z [m/s^2]')
183ax[2].set_xlabel('Hours from CA')
184fig.suptitle('Albedo in S/C body frame')
185plt.tight_layout()
186
187# IR
188fig, ax = plt.subplots(3, 1, figsize=(14,8), sharex = True)
189
190ax[0].plot(epochs, ir_accel[:,0], linewidth = 2, color = "tab:blue")
191ax[0].set_ylabel('X [m/s^2]')
192ax[1].plot(epochs, ir_accel[:,1], linewidth = 2, color = "tab:blue")
193ax[1].set_ylabel('Y [m/s^2]')
194ax[2].plot(epochs, ir_accel[:,2], linewidth = 2, color = "tab:blue")
195ax[2].set_ylabel('Z [m/s^2]')
196ax[2].set_xlabel('Hours from CA')
197fig.suptitle('IR in S/C body frame')
198plt.tight_layout()
199
200plt.show()
201
202### ------------------------------------------------------------------------------------------------------- ###