ThermalRadiation#

class ThermalRadiation(origin: CelestialBody, spacecraft: Spacecraft, base_frame: Frame, thermal_model, t0: float = None, tf: float = None)#

Bases: DynamicModel

Recoil acceleration from the thermal radiation the spacecraft emits.

Each surface \(i\) of area \(A_i\), emissivity \(\varepsilon_i\) and outward normal \(\hat{\mathbf{n}}_i\) radiates as a Lambertian emitter at temperature \(T_i\). The recoil of that emission is

\[\mathbf{a}_i = -\frac{2}{3}\, \frac{\sigma A_i \varepsilon_i}{m\,c}\,T_i^4\,\hat{\mathbf{n}}_i\]

where \(\sigma\) is the Stefan-Boltzmann constant, \(m\) the spacecraft mass and \(c\) the speed of light. The factor 2/3 is the momentum a Lambertian surface carries away along its normal. The total acceleration is

\[\mathbf{a}_\text{therm} = \eta_\text{therm} \sum_i \mathbf{a}_i\]

with \(\eta_\text{therm}\) an estimable scale factor (default 1), read from the state under ("eta_thermal", spice_id).

Temperatures. A surface temperature is read from a table of temperature against off-Sun angle \(\theta\), given at a few Sun-spacecraft distances \(d\):

\[T_i = T_{\text{table}(i)}\!\left(\theta_i,\, d\right),\qquad \cos\theta_i = \hat{\boldsymbol{\rho}}_i\cdot\hat{\mathbf{u}}_\odot\]

where \(\hat{\mathbf{u}}_\odot\) is the spacecraft-to-Sun unit vector and \(\hat{\boldsymbol{\rho}}_i\) the table’s reference direction: the table’s angle_reference when it has one (for example the spacecraft axis the thermal analysis measured the off-Sun angle from), otherwise the surface’s own normal. Each distance row is a cubic spline in \(\theta\), with zero slope imposed at 0 and 180 degrees when the table reaches them, since a temperature is symmetric about those angles. Rows are joined by linear interpolation in \(d\). Outside the tabulated angles and distances the temperature is held at the nearest edge.

A surface can carry a second, shadow_temperature table, used when \(\hat{\mathbf{n}}_i\cdot\hat{\mathbf{u}}_\odot \le 0\). This is how a high-gain antenna built from many plates picks an illuminated or a shadowed temperature for each plate.

Attitude. Normals and angle references are fixed in the spacecraft frame and reach the inertial frame through the spacecraft-fixed to inertial rotation \(C\) of DynamicalUtils, for the "CK", "inertialFixedAttitude" and "nadirPointingSun" values of Spacecraft.attitudeMode. In the last one the spacecraft \(-X\) axis points at the Sun and the Y axis follows the heliocentric velocity, so \(C\) depends on the state, the partials carry the rotation terms and the model reports depends_on_velocity.

Thermal model. thermal_model is a dict, or the path of a JSON file holding one, with two entries:

"temperature_tables"

{name: table}, each table holding

  • "angles": ArrayWUnits of off-Sun angles, strictly increasing within [0, 180] degrees, at least two;

  • "distances": ArrayWUnits of Sun distances, strictly increasing, at least one;

  • "temperatures": array of shape (n_distances, n_angles) (a single distance may be given as a 1-D array);

  • "temperature_units": "K" or "degC";

  • "angle_reference" (optional): spacecraft-fixed direction the off-Sun angle is measured from.

"surfaces"

list of dicts, each holding

  • "name": label;

  • "area": ArrayWUnits area;

  • "emissivity": value in [0, 1];

  • "normal": outward normal in the spacecraft frame;

  • "temperature": name of its temperature table;

  • "shadow_temperature" (optional): name of the table used when the surface faces away from the Sun.

Quantities with units may also be given in their serialized form ({"values", "units"}, see awu_to_dict()), which is what model_to_dict() writes.

Parameters:
originCelestialBody

Propagation origin. Used for the Sun-relative geometry.

spacecraftSpacecraft

The emitting spacecraft. Its mass and attitude are read at evaluation time.

base_frameFrame

Inertial frame of the propagated state.

thermal_modeldict or str or pathlib.Path

Surfaces and temperature tables, as described above.

t0, tffloat, optional

Propagation span in TDB seconds past J2000. When both are given and the frame is J2000, the Sun position is read from a Chebyshev ephemeris cache instead of SPICE.

Attributes:
depends_on_velocity

Whether the acceleration depends on the spacecraft velocity.

frame

The inertial frame of the propagated state.

origin

The propagation origin.

origin_name

The name of the propagation origin.

param_name

State key of the estimable scale factor.

spacecraft

The emitting spacecraft.

surface_names

Surface names, in the order of surface_temperatures().

thermal_model

The validated thermal model (surfaces and temperature tables).

Methods

compute_acceleration(position, ...)

Thermal re-radiation acceleration.

model_from_dict(thermal_model)

Validate a thermal model and return it with live quantities.

model_to_dict(thermal_model)

Serialize a thermal model to plain JSON types.

surface_temperatures(position, ...)

Temperature of every surface, in the order of surface_names.

to_dict()

Serialize this model's thermal model; see model_to_dict().

Raises:
InvalidThermalModelError

If thermal_model is not a dict or a JSON file of one, or lacks its two entries.

InvalidTemperatureTableError

If a temperature table is malformed.

InvalidSurfaceError

If a surface is malformed.

UnknownTemperatureTableError

If a surface names a table that is not defined.

DynamicalUtils.InvalidAttitudeModeError

If the spacecraft attitude mode is not one of the three above.

DynamicalUtils.InvalidFixedAttitudeError

If an inertialFixedAttitude spacecraft has no 3x3 attitude.

DynamicalUtils.MissingVelocityError

If a nadirPointingSun spacecraft has no velocity in the state.

See also

scarabaeus.AntennaRadiationPressure

Antenna and LIDAR recoil.

scarabaeus.nPlateSRP

Solar radiation pressure on a plate model.

scarabaeus.DynamicalUtils

Spacecraft attitude modes.

Notes

The position partial carries the temperature change with the Sun distance and the off-Sun angle, and, for the Sun-pointed attitude, the rotation of the surface normals. The scale-factor partial is the acceleration with \(\eta_\text{therm} = 1\).

Switching a surface between its illuminated and shadowed tables is a step in the acceleration; the partials take the table in use.

References

J. L. Geeraert, J. M. Leonard, P. W. Kenneally, P. G. Antreasian, M. C. Moreau, and D. S. Lauretta, “OSIRIS-REx Navigation Small Force Models,” in AAS/AIAA Astrodynamics Specialist Conference, 2019, Advances in the Astronautical Sciences, Vol. 171, Univelt, 2020, pp. 931-946.

classmethod model_from_dict(thermal_model) → dict#

Validate a thermal model and return it with live quantities.

Accepts the live form (quantities as ArrayWUnits), the serialized form written by model_to_dict(), or the path of a JSON file holding either.

Parameters:
thermal_modeldict or str or pathlib.Path

The thermal model; see the class docstring for its layout.

Returns:
dict

{"temperature_tables": {...}, "surfaces": [...]} with angles, distances and areas as ArrayWUnits, temperatures as (n_distances, n_angles) arrays in the declared units, and normals and angle references as unit vectors.

Raises:
InvalidThermalModelError

If the model is not a dict or lacks its entries.

InvalidTemperatureTableError

If a table is malformed.

InvalidSurfaceError

If a surface is malformed.

UnknownTemperatureTableError

If a surface names an undefined table.

classmethod model_to_dict(thermal_model) → dict#

Serialize a thermal model to plain JSON types.

Parameters:
thermal_modeldict or str or pathlib.Path

The thermal model in any form model_from_dict() accepts.

Returns:
dict

The model with quantities as {"values", "units"} dicts and arrays as lists; model_from_dict() reads it back.

compute_acceleration(position: ndarray, current_state: dict, epoch: float, body: Spacecraft) → ndarray#

Thermal re-radiation acceleration.

Parameters:
positionnumpy.ndarray

(3,) spacecraft position relative to the origin, km.

current_statedict

The propagated state, holding ("eta_thermal", spice_id) when the scale factor is estimated.

epochfloat

TDB epoch (seconds past J2000).

bodySpacecraft

The emitting spacecraft.

Returns:
numpy.ndarray

(3,) acceleration in km/s^2.

surface_temperatures(position: ndarray, current_state: dict, epoch: float, body: Spacecraft) → ndarray#

Temperature of every surface, in the order of surface_names.

Parameters:
positionnumpy.ndarray

(3,) spacecraft position relative to the origin, km.

current_statedict

The propagated state.

epochfloat

TDB epoch (seconds past J2000).

bodySpacecraft

The emitting spacecraft.

Returns:
numpy.ndarray

Surface temperatures in K.

to_dict() → dict#

Serialize this model’s thermal model; see model_to_dict().

Returns:
dict

The serialized thermal model.

PARAMETER_NAME = 'eta_thermal'#

State key of the estimable scale factor.

property depends_on_velocity: bool#

Whether the acceleration depends on the spacecraft velocity.

True only for the nadirPointingSun attitude, where the spacecraft Y axis follows the heliocentric velocity.

property frame: Frame#

The inertial frame of the propagated state.

property origin: CelestialBody#

The propagation origin.

property origin_name: str#

The name of the propagation origin.

property param_name: str#

State key of the estimable scale factor.

property spacecraft: Spacecraft#

The emitting spacecraft.

property surface_names: list#

Surface names, in the order of surface_temperatures().

property thermal_model: dict#

The validated thermal model (surfaces and temperature tables).

exception InvalidSurfaceError#

Bases: Exception

A surface is malformed.

A surface needs a name, a positive area quantity, an emissivity in [0, 1], a nonzero spacecraft-fixed normal and a temperature table.

exception InvalidTemperatureTableError#

Bases: Exception

A temperature table is malformed.

Angles must be an angle quantity strictly increasing within [0, 180] degrees, distances a length quantity strictly increasing and positive, temperatures of shape (n_distances, n_angles) and above absolute zero, and the temperature units "K" or "degC".

exception InvalidThermalModelError#

Bases: Exception

The thermal model is not a dict, or lacks its entries.

thermal_model must be a dict, or the path of a JSON file holding one, with "temperature_tables" and "surfaces" entries.

exception UnknownTemperatureTableError#

Bases: Exception

A surface names a temperature table that is not defined.