Module: eclipse

Executive Summary

The eclipse module is responsible for determining whether or not a spacecraft is experiencing a solar eclipse and how much of it is occluded. The module works on a list of spacecraft state messages, as well as a list of planets.

Message Connection Descriptions

The following table lists all the module input and output messages. The module msg variable name is set by the user from python. The msg type contains a link to the message structure definition, while the description provides information on what this message is used for.

Module I/O Messages

Msg Variable Name

Msg Type

Description

sunInMsgName

spicePlanetStateSimMsg

(Optional) sun state input message name. If not set, then this is set to sun_planet_data. If this message does not exist, then the sun location is set to (0,0,0).

vec:planetInMsgNames

spicePlanetStateSimMsg

The planet state input msg names are not set directly, but rather using the addPlanetName() method.

vec:positionInMsgNames

scPlusStatesSimMsg

The spacecraft state input msg names are not set directly, but rather using the addPositionMsgName() method.

vec:eclipseOutMsgNames

eclipseSimMsg

The eclipse output message names are set automatically using eclipse_data_ + positionInMsgNames.

Detailed Module Description

The eclipse module is responsible for determining whether or not a spacecraft is within the shadow of a solar eclipse and if so, how much. The module finds the states of the sun, spacecraft and planets of interest, allowing each body’s position to be related and the construction of the conical shadow model. This provides the means for computing what percent of the spacecraft is illuminated where a shadow factor of 0.0 represents a total eclipse and 1.0 represents no eclipse.

To determine the states of the bodies in question, messages are passed into the code. For the spacecraft, Cartesian vectors provide the position and velocity of its center of mass. For the sun and planets their ephemeris messages are read in. The planets desired to be used in the module are specified through the python method addPlanetName(), where corresponding strings (e.g. venus, earth, mars barycenter, etc.) are input. If given multiple planets, the code iterates through the planet list and determines which is the closest to the spacecraft. The figure below illustrates how the states are represented and will be identified in the mathematical model. Calculations in this model are taken from Montenbruck and Gill’s text Satellite Orbits Models, Methods and Applications.

../../../../_images/conical_shadow.svg

Figure 1: Illustration of the Planet’s Umbra and Penumbra Regions

Determining States

The initial step in the eclipse module is to obtain the celestial bodies’ state data and transform them into usable terms. The relationships shown below remove the dependency on relating position to the inertial frame \(N\) and instead utilize the planet \(P\), spacecraft body \(B\), and helio \(H\) frames.

(1)\[\mathbf{s}_{P/H} = \mathbf{r}_{N/H} - \mathbf{r}_{N/P}\]
(2)\[\mathbf{r}_{B/H} = \mathbf{r}_{N/H} - \mathbf{r}_{N/B}\]
(3)\[\mathbf{s}_{P/B} = \mathbf{r}_{N/B} - \mathbf{r}_{N/P}\]

The previous three equations provide coordinates for the sun with respect to both the occulting planet and occulted spacecraft as well as the spacecraft’s position with respect to the planet, respectively. The parameters on the right side of these equations come from the input state data where \(\mathbf{r}_{N/H}\), \(\mathbf{r}_{N/P}\), and \(\mathbf{r}_{N/B}\) are the sun, planet, and spacecraft positions in the inertial frame.

This module supports the use of multiple occulting bodies, so it is important to analyze only the planet with the highest potential to cause an eclipse. Thus, the closest planet is determined by comparing the magnitude of each planet’s distance to the spacecraft, \(|\mathbf{s}_{P/B}|\). Note that if the spacecraft is closer to the sun than the planet, i.e. \(|\mathbf{r}_{B/H}| < |\mathbf{s}_{P/H}|\), an eclipse is not possible and the shadow fraction is immediately set to 1.0.

Eclipse Conditions

When analyzing the conical shadow model, there are critical distances and conical dimensions that must be considered. These parameters are determined by first knowing the planet’s equatorial radius \(r_P\), which is used to solve for the angles of the shadow cones. Angles \(f_1\) and \(f_2\) are computed as shown below, where the subscript 1 relates to the cone of the penumbra and 2 relates to the umbra.

(4)\[f_1 = \frac{\arcsin(r_H + r_P)}{| \mathbf{s}_{P/H}|}\]
(5)\[f_2 = \frac{\arcsin(r_H - r_P)}{| \mathbf{s}_{P/H}|}\]

Here \(r_H\) indicates the equatorial radius of the sun, which is 695000 km. Both the sun and planet radii must be input in terms of meters.

As shown by Figure 1: Illustration of the Planet’s Umbra and Penumbra Regions, the fundamental plane is perpendicular to the shadow axis and coincident with the spacecraft body. The distance between the plane-axis intersection and the center of the planet is given by \(s_0\) as shown by Eq. (6).

(6)\[s_0 = \frac{-\mathbf{s}_{P/B} \cdot \mathbf{s}_{P/H}}{| \mathbf{s}_{P/H}|}\]

This distance and the shadow cone angles can now be used to determine the distances, \(c_1\) and \(c_2\), between the fundamental plane and the cones’ vertices \(V_1\) and \(V_2\). These are calculated as follows:

(7)\[c_1 = s_0 + \frac{r_P}{\sin(f_1)}\]
(8)\[c_2 = s_0 - \frac{r_P}{\sin(f_2)}\]

As shown in Eq. (9) and (10), these are then used to find the radii, \(l_1\) and \(l_2\), of the shadow cones in the fundamental plane.

(9)\[l_1 = c_1 \tan(f_1)\]
(10)\[l_2 = c_2 \tan(f_2)\]

Finding these parameters provides insight into the type of eclipse that the spacecraft is experiencing. To determine the type, it is useful to compare the cone radii to the distance between the spacecraft and the shadow axis, which is given by \(l\).

(11)\[l = \sqrt{|\mathbf{s}_{P/B}|^2 - s^2_0}\]

Total and annular eclipses both require the spacecraft to be relatively close to the shadow axis, where \(|l|<| l_2|\). The difference between these two types is that the planet is closer to the spacecraft for a total eclipse (\(c_2 < 0\)) than during an annular eclipse (\(c_2 > 0\)). If the spacecraft is further from the shadow axis but still within a cone radius (\(|l|<| l_1|\)), it is experiencing a partial eclipse.

Percent Shadow

With the eclipse type determined, the shadow fraction can now be found. To find the shadow fraction, the apparent radii of the sun and planet and the apparent separation of both bodies are needed. These are given, respectively, by \(a\), \(b\), and \(c\) in the equations below.

(12)\[a = \arcsin(\frac{r_H}{| \mathbf{r}_{B/H}|})\]
(13)\[b = \arcsin(\frac{r_P}{| \mathbf{s}_{P/B}|})\]
(14)\[c = \arccos(\frac{-\mathbf{s}_{P/B} \cdot \mathbf{r}_{B/H}}{| \mathbf{s}_{P/B}| | \mathbf{r}_{B/H}|})\]

Figure 2: Occultation Disk Model below illustrates the overlapping disk model that represents the occultation, where the solid orange line indicates the sun and the dotted blue line indicates the planet.

../../../../_images/diskModel.svg

Figure 2: Occultation Disk Model

Total Eclipse (\(c < b-a\))

This type assumes that the apparent radius of the planet is larger than that of the sun (\(b>a\)). A total eclipse produces a total shadow, so the shadow fraction is 0.0.

Annular Eclipse ($c < a-b$)

This type assumes the apparent radius of the sun is larger than that of the planet (\(a>b\)). Use the equation for a circular area, \(A = \pi r^2\), to find the area of the sun and planet faces, replacing \(r\) with the corresponding apparent radius. The shadow fraction is then just the ratio of the planet’s area to the sun’s area. begin{equation} label{eq:18} Shadow Fraction = frac{A_P}{A_H} end{equation}

Partial Eclipse ($c < a+ b$)

For a partial eclipse, the occulted area is given by Eq. (15).

(15)\[A = a^2 \arccos(\frac{x}{a}) + b^2 \arccos(\frac{c-x}{b}) - cy\]

Parameters \(a\), \(b\), and \(c\) are those calculated previously in Eq. (12), (13), and (14). The values \(x\) and \(y\) are given by the following equations.

(16)\[x = \frac{c^2 + a^2 - b^2}{2c}\]
(17)\[y = \sqrt{a^2 - x^2}\]

Like with the annular partial eclipse, the shadow factor for this type is the ratio between the occulted area and the sun’s apparent area. This is given by the equation below.

(18)\[\text{Shadow Fraction} = 1 - \frac{A}{\pi a^2}\]

Module Assumptions and Limitations

  • Occultation Model: Since the apparent radius of the sun is relatively small, the occultation can be modeled as overlapping disks.

  • No Eclipse: If the spacecraft is closer to the sun than the planet, an eclipse is not possible.

  • Planets: The allowed Spice planet names for use as occulting bodies are:

    • mercury, venus, earth, mars, mars barycenter, jupiter barycenter, saturn, neptune, uranus

  • Sun and Planet States: The data defining the sun and planet states is obtained through an external Spice package. Errors may be derived from this package but will be small.

  • Spacecraft States: Spacecraft states must be input as Cartesian vectors. In the test, a conversion from orbital elements is performed.

  • Apparent Radii: When determining the type of eclipse, assume that the apparent separation \(c \geq 0\).

    • Total Eclipse (\(c<b-a\)): Assume the apparent radius of the planet is greater than that of the sun (\(b>a\)).

    • Annular Eclipse (\(c<a-b\)): Assume the apparent radius of the sun is greater than that of the planet (\(a>b\)).

User Guide

Setting The Spacecraft State Input Messages

The spacecrat state messages are read in by the eclipse module to determine where the spacecraft is relative to the sun and the planet(s). The module can handle a list of input messages, however, these are not set directly. Rather, use the method:

addPositionMsgName(std::string msgName)

The spacecraft state message is of type scPlusStatesSimMsg. Note that this method returns the corresponding spacecraft shadow factor output messages name. This is convenient if the script is to log this message.

Setting The Planet State Input Messages

The planet state input message is of type spicePlanetStateSimMsg. To add this as an input connection to eclipse, use the method:

addPlanetName(std::string planetName)

At least one planet must be specified. If there are multiple planets, then the shadow factor is only computed relative to the closest planet.

Setting the Sun State Input Message (Optional)

If the eclipse module input message name sunInMsgName is not specified, then the module assumes the sun state input message name is the default sun_planet_data. If this message is never created, then the module sets the sun position to (0, 0, 0) be default.

To specify a desired sunInMsgName, use:

eclipseObject = eclipse.Eclipse()
eclipseObject.sunInMsgName = "sun_state_message"

Eclipse Output Messages

The eclipse module will output a series of messages of type eclipseSimMsg corresponding to the number of spacecraft provided. The names of these output messages are auto-generated as follows:

eclipse_data_0
eclipse_data_1
eclipse_data_2

where eclipse_data_0 indicates the first spacecraft shadow factor messages, etc.


class Eclipse : public SysModel

Public Functions

Eclipse()
~Eclipse()
void SelfInit()

This method initializes the object. It creates the module’s output messages auto-named eclipse_data_0 etc.

Return

void

void CrossInit()

This method subscribes to the spice planet states, the spacecraft state messages and the sun state message.

Return

void

void UpdateState(uint64_t CurrentSimNanos)

This method governs the calculation and checking for eclipse conditions.

Return

void

Parameters
  • CurrentSimNanos: The current clock time for the simulation

void writeOutputMessages(uint64_t CurrentClock)

This method takes the computed shadow factors and outputs them to the messaging system.

Return

void

Parameters
  • CurrentClock: The current simulation time (used for time stamping)

std::string addPositionMsgName(std::string msgName)

This method adds spacecraft state data message names to a vector, creates a new unique output message name for the eclipse data message and returns this to the user so that they may assign the eclipse message name to other modules requiring eclipse data.

Return

std::string newEclipseMsgName The unique eclipse data msg name associated with the given input state message name.

Parameters
  • std::string: msgName The message name for the spacecraft state data for which to compute the eclipse data.

void addPlanetName(std::string planetName)

This method adds planet state data message names to a vector.

Return

void

Parameters
  • std::string: planetName The planet name

Public Members

uint64_t outputBufferCount

Number of output buffers to use. Default is 2.

std::string sunInMsgName

sun ephemeris message name

BSKLogger bskLogger

BSK Logging.

Private Functions

void readInputMessages()

This method reads the spacecraft state, spice planet states and the sun position from the messaging system.

Return

void

double computePercentShadow(double planetRadius, Eigen::Vector3d r_HB_N, Eigen::Vector3d s_BP_N)

This method computes the fraction of sunlight given an eclipse.

Return

double fractionShadow The eclipse shadow fraction.

Parameters
  • std::string: msgName

double getPlanetEquatorialRadius(std::string planetSpiceName)

This method return planet radii.

Return

double The equatorial radius in metres associated with the given planet name.

Parameters
  • std::string: planetSpiceName The planet name according to the spice NAIF Integer ID codes.

Private Members

std::vector<std::string> planetNames

Names of planets we want to track.

std::vector<std::string> planetInMsgNames

A vector of planet incoming message names ordered by the sequence in which planet names are added to the module.

std::map<int64_t, SpicePlanetStateSimMsg> planetInMsgIdAndStates

A map of incoming planet message Ids and planet state ordered by the sequence in which planet names are added to the module.

std::vector<float> planetRadii

[m] A vector of planet radii ordered by the sequence in which planet names are added to the module

int64_t sunInMsgId

sun msg input ID

SpicePlanetStateSimMsg sunInMsgState

copy of sun input msg

std::vector<std::string> positionInMsgNames

vector of msg names for each position state for which to evaluate eclipse conditions.

std::map<int64_t, SCPlusStatesSimMsg> positionInMsgIdAndState

A map of incoming spacecraft message IDs and msg states.

std::vector<int64_t> eclipseOutMsgId

output msg ID

std::vector<std::string> eclipseOutMsgNames

vector of eclispe output msg names

std::vector<double> eclipseShadowFactors

vector of shadow factor output values