Module: spacecraftLocation
Executive Summary
This module determines if one satellite has a line of sight vector to another satellite. An oblate planet is modeled through the equatorial and the polar radius. If the line of sight vector between two satellites is above this surface, then the output access message is set to true. The module has a primary spacecraft which determines access to N other spacecraft orbiting the same planet.
Further, the module tracks a body-fixed location L on the primary spacecraft (i.e. location where an antenna is attached), and you can specify an optional sensor/communication bore sight axis \(\hat{\bf a}\) and an center-to-edge sensor/communication cone angle \(\theta\). In this case the access message is true if the line of sight vector between spacecraft is above the surface and the relative position vector to the other spacecraft is within this cone.
Finaly, if the other spacecraft is accessable, the range to the other satellite is stored in the output message.
Module Assumptions and Limitations
This module assumes all spacecraft are orbiting the same planet. The planet shape is assumed to be an ellipoid specified through the equatorial and polar radius. To account for a planet’s atmosphere, increase these radii to account for the atmospheric height.
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.
Msg Variable Name |
Msg Type |
Description |
---|---|---|
planetInMsg |
(optional) planet state input message. Default is a zero state for the planet. |
|
primaryScStateInMsg |
primary spacecraft state message relative to which to evaluate access to other spacecraft in |
|
scStateInMsgs |
vector of other spacecraft state input messages. These are set through |
|
accessOutMsgs |
output vector of ground location access messages |
Detailed Module Description
The spacecraftLocation
module handles the following behavior:
Spacecraft body-fixed location representation: a single
spacecraftLocation
instance represents one body-fixed location on a spacecraftThe planet-centered planet-fixed frame is either a zero state (default), or read in through an optional planet ephemeris message
An optional sensor axis can be specified to ensure the primary spacecraft is pointing this axis
Computation of spacecraft visibility (i.e. access) considering range and relative field-of-view constraints
Support for multiple other spacecraft given one
spacecraftLocation
instance
Determining Line of Sight to another spacecraft
Let P be the planet-centered planet-fixed frame. The inertial planet origin is given by \({}^{N} {\bf r}_{P/N}\). The inertial position vector of the primary spacecraft B is \({}^{N}{\bf r}_{B/N}\), while the inertial position vector to the other satellite is \({}^{\cal N}{\bf r}_{S/N}\). The first step is to determine the spacecraft positions, expressed in the P frame.
The line of sight vector is defined through the point B and the direction \({\bf r}_{S/B}\). Let \(\kappa\) be a scaling factor, the line is then defined as:
The process of intersecting a line with an ellipsoid is simplified by using an affine project to render the ellipsoid a sphere. This affine mapping preserves a line to remain a line. The math of this is as follow. The planet is assumed to have rotational symmetry about the 3:sup`rd` axis about which it is spinning. Thus, to map the ellipsoid into a sphere the planet relative 3:sup`rd` coordinates must scaled by the ratio of the equatorial radius to the polar radius. The following math assumes this affine mapping has been performed in the above planet-relative position coordinates.
To determine the minimum distance of the line \(\bf l\) to the planet origin, consider the cost function \(J\):
Setting the first variation of \(J\) with respect to \(\kappa\) to zero and solving for optimal \(\kappa^\ast\) yields
Note that if \(\kappa<0\) or \(\kappa>1\), then the point of closed approach is outside of the line-of-sight interval between the two spacecraft and the planet cannot be blocking access of one spacecraft from another.
Thus, the point of closed approach is determined through:
If \(|{\bf r}^\ast| > r_{\text{eq}}\) then the other spacecraft is visible relative to the primary spacecraft.
Determining Sensor Cone Inclusion
If the line of sight property is established, then the module can also take into consideration a sensor or communication boresight axis \(\hat {\bf a}\) which is fixed relative to the primary spacecraft body frame. The angle \(\phi\) between the relative position vector and this body fixed unit direction vector is found through:
The module sets the sensor cone half-angle \(\theta\). If \(\phi > \theta\) then the sensor or communication axis does not have access to the other spacecraft.
If this \(\hat{\bf a}\) is considered, then the access output message sets the message elevation angle as
User Guide
A new instance of spacecraftLocation
, alongside necessary user-supplied parameters, can be created by calling:
location = spacecraftLocation.SpacecraftLocation()
location.ModelTag = "scLocation"
location.rEquator = orbitalMotion.REQ_EARTH * 1000.
location.rPolar = orbitalMotion.RP_EARTH * 1000. # optional, include to account for oblateness
location.maximumRange = 100e3 # optinal, sets maximum range for visibility in meters
scSim.AddModelToTask(simTaskName, location)
The variable maximumRange
is optional and set to -1 by default. If it is set to a positive value, then the hasAccess
variable is only set to 1 if the relative spacecraft distance is less than this maximum range.
A optional planet emphemeris is connected via the``planetInMsg`` input message:
location.planetInMsg.subscribeTo(planetMsg)
It this message is not connected, then zero planet position and attitude orientation are set.
To set a primary spacecraft body fixed sensor or communication axis \(\hat{\bf a}\) and half-cone angle \(\theta\), use:
module.aHat_B = [xxx, xxx, xxx]
module.theta = xxx * macros.D2R
Spacecraft can be added to the model by calling:
location.addSpacecraftToModel(sc1.scStateOutMsg)
location.addSpacecraftToModel(sc2.scStateOutMsg)
The access output messages can be logged through:
dataRec0 = location.accessOutMsgs[0].recorder()
dataRec1 = location.accessOutMsgs[1].recorder()
-
class SpacecraftLocation : public SysModel
- #include <spacecraftLocation.h>
ground location class
Public Functions
-
SpacecraftLocation()
Creates an instance of the SpacecraftLocation class.
- Returns:
void
-
~SpacecraftLocation()
Empty destructor method.
- Returns:
void
-
void UpdateState(uint64_t CurrentSimNanos)
update module
- Parameters:
CurrentSimNanos –
-
void Reset(uint64_t CurrentSimNanos)
Resets the internal position to the specified initial position.
-
bool ReadMessages()
Read module messages
-
void WriteMessages(uint64_t CurrentClock)
write module messages
-
void addSpacecraftToModel(Message<SCStatesMsgPayload> *tmpScMsg)
Adds a scState message name to the vector of names to be subscribed to. Also creates a corresponding access message output name.
Public Members
-
double rEquator
[m] equatorial planet radius
-
double rPolar
[m] polar planet radius
-
double maximumRange
[m] Maximum slant range to compute access for; defaults to -1, which represents no maximum range.
-
Eigen::Vector3d aHat_B
[] (optional) unit direction vector vector of the senor/communication boresight axis
-
double theta
[r] (optional) sensor/communication half-cone angle, must be set if shat_B is specified
-
ReadFunctor<SCStatesMsgPayload> primaryScStateInMsg
primary spacecraft input message
-
ReadFunctor<SpicePlanetStateMsgPayload> planetInMsg
planet state input message
-
std::vector<Message<AccessMsgPayload>*> accessOutMsgs
vector of ground location access messages
-
std::vector<ReadFunctor<SCStatesMsgPayload>> scStateInMsgs
vector of other sc state input messages
-
Eigen::Vector3d r_LB_B
[m] position of the location relative to the spacecraft frame origin B, in B frame components
-
BSKLogger bskLogger
— BSK Logging
Private Functions
-
void computeAccess()
compute the spacecraft to spacecraft access messages
Private Members
-
std::vector<AccessMsgPayload> accessMsgBuffer
buffer of access output data
-
std::vector<SCStatesMsgPayload> scStatesBuffer
buffer of other spacecraft states
-
SCStatesMsgPayload primaryScStatesBuffer
buffer of primary spacecraft states
-
SpicePlanetStateMsgPayload planetState
buffer of planet data
-
Eigen::Matrix3d dcm_PN
Rotation matrix from inertial frame N to planet-centered to planet-fixed frame P.
-
Eigen::Vector3d r_PN_N
[m] Planet to inertial frame origin vector.
-
Eigen::Vector3d r_BP_P
primary spacecraft relative to planet
-
Eigen::Vector3d r_BN_N
primary spacecraft relative to inertial
-
double zScale
ration of rEquator over rPolar, used for affine scaling to turn ellipsoid to sphere
-
SpacecraftLocation()