Module: stripLocation

Executive Summary

This module extends the Module: groundLocation concept to model a strip imaging target on a celestial body’s surface. Instead of a single fixed point, the user defines a ground strip by specifying a start and an end location (both body-fixed). The module uses spherical linear interpolation (SLERP) to sweep a moving target point \(L\) along the great-circle arc connecting these two locations at a configurable constant acquisition speed. A pre-imaging time parameter allows the strip’s effective start point to be extrapolated backwards along the great-circle arc so that the target point begins moving before the nominal start location, giving the spacecraft time to slew.

The inertial position and velocity of the current target point \(L\) are evaluated and output as a StripStateMsgPayload message.

One or more spacecraft states can be added to compute each spacecraft’s position relative to the current target point \(L\). The associated AccessMsgPayload output message contains the relative position vector in spherical coordinates (range, azimuth, elevation) and in South-East-Zenith (SEZ) Cartesian coordinates, as well as the corresponding coordinate rates. An integer flag indicates whether the spacecraft has access (i.e. is above the minimum elevation angle of the \(L\) SEZ frame, within range, and the pre-imaging time has elapsed).

Module Assumptions and Limitations

  • The body is assumed to be a sphere with a constant radius (planetRadius).

  • The strip’s central line is a great-circle arc on that sphere; local terrain is not considered.

  • The target point moves along the arc at a constant acquisition speed (acquisitionSpeed).

  • Elevation constraints are computed assuming a conical field of view around the surface normal at the current target location.

  • The pre-imaging time feature uses the same SLERP extrapolation, extending the arc backwards.

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

planetInMsg

SpicePlanetStateMsgPayload

(optional) planet state input message. Default is a zero state for the planet.

scStateInMsgs

SCStatesMsgPayload

vector of sc state input messages. These are set through addSpacecraftToModel()

currentStripStateOutMsg

StripStateMsgPayload

strip location output message providing the current target point inertial position and velocity

accessOutMsgs

AccessMsgPayload

vector of access output messages (one per spacecraft)

Detailed Module Description

The stripLocation module handles the following behavior:

  1. Reads in the planet’s states using the planetInMsg input message.

  2. Converts the start and end latitude/longitude/altitude coordinates to planet-centered, planet-fixed (PCPF) coordinates.

  3. (Optionally) Computes an updated start point by extrapolating backwards along the

    great-circle arc using the preImagingTime parameter.

  4. Propagates the current target point \(L\) along the great-circle arc using SLERP,

    at the constant acquisitionSpeed.

  5. Computes the inertial position and velocity of \(L\), accounting for planet rotation.

  6. Converts each spacecraft’s relative position to the SEZ frame and evaluates range, azimuth, elevation, and their rates.

  7. Determines spacecraft access (visibility) considering minimum elevation, maximum range, and whether the pre-imaging time has elapsed.

  8. Supports multiple spacecraft given one stripLocation instance.

Target Propagation along the Strip

Given a start point \(\mathbf{p}_s\) and end point \(\mathbf{p}_e\) on the sphere of radius \(R\), both expressed in PCPF coordinates, the central angle is:

(1)\[\theta = \arccos\!\left(\frac{\mathbf{p}_s \cdot \mathbf{p}_e}{R^2}\right)\]

The arc length of the central line is:

(2)\[\ell = \theta \, R\]

A normalised time parameter \(\tau \in [0,1]\) is computed from the elapsed imaging time \(\Delta t\) and the acquisition speed \(v_a\):

(3)\[\tau = \frac{\Delta t}{\ell / v_a}\]

The target position is obtained via spherical linear interpolation (SLERP):

(4)\[\mathbf{p}(\tau) = \frac{\sin\!\bigl((1-\tau)\,\theta\bigr)}{\sin\theta}\,\mathbf{p}_s + \frac{\sin(\tau\,\theta)}{\sin\theta}\,\mathbf{p}_e\]

and projected back onto the sphere:

(5)\[\mathbf{r}_{L/P}^P = R \, \frac{\mathbf{p}(\tau)}{\|\mathbf{p}(\tau)\|}\]

The PCPF velocity of the target is obtained by differentiating the SLERP expression and scaling to the acquisition speed.

Determining Spacecraft-to-Target States

The position of the spacecraft relative to the current target point in the SEZ frame is parameterized by the Cartesian coordinates:

(6)\[\mathbf{r}_{B/L} = x\hat{S} + y\hat{E} + z\hat{Z}\]

The Cartesian coordinates are converted to spherical coordinates centered at the target point, giving the range (\(\rho\)), azimuth (\(Az\)), and elevation (\(El\)):

(7)\[\rho = \sqrt{x^2 + y^2 + z^2}\]
(8)\[Az = \arctan\!\frac{y}{x}\]
(9)\[El = \arctan\!\frac{z}{\sqrt{x^2+y^2}}\]

The spherical coordinate rates are computed by differentiating the range, azimuth, and elevation with respect to the rotating SEZ frame:

(10)\[\dot{\rho} = \frac{x\dot{x}+y\dot{y}+z\dot{z}}{\sqrt{x^2 + y^2 + z^2}}\]
(11)\[\dot{Az} = \frac{-x\dot{y}+y\dot{x}}{x^2+y^2}\]
(12)\[\dot{El} = \frac{1}{1+\frac{z^2}{x^2+y^2}} \left( \frac{\dot{z}}{\sqrt{x^2+y^2}} - \frac{z(x\dot{x}+y\dot{y})}{(x^2+y^2)^{3/2}} \right)\]

User Guide

To use this module, instantiate the class and provide it with two body-fixed locations (start and end of the strip) and the desired acquisition speed. A planet position/attitude message (i.e., an instance of SpicePlanetStateMsgPayload) can optionally be provided; to compute access, at least one SCStatesMsgPayload message must be added to the module using the addSpacecraftToModel() method. The first spacecraft is index 0, the second is 1, and so on.

A new instance of stripLocation, alongside necessary user-supplied parameters, can be created by calling:

stripTarget = stripLocation.StripLocation()
stripTarget.ModelTag = "stripTarget"
stripTarget.planetRadius = orbitalMotion.REQ_EARTH * 1000.  # defaults to Earth's radius
stripTarget.maximumRange = 100e3              # (optional) maximum slant range for access [m]
stripTarget.minimumElevation = np.radians(10.)  # minimum elevation for access [rad]; defaults to 10 deg
stripTarget.smallAngle = 1e-12                # (optional) threshold used to treat the strip as having zero length [rad]; defaults to 1e-12
stripTarget.acquisitionSpeed = 3e-6           # constant acquisition speed along the strip [m/ns]; defaults to 3 km/s
stripTarget.preImagingTime = 6e10          # (optional) pre-imaging offset time [ns]; defaults to 0
stripTarget.specifyLocationStart(np.radians(40.0), np.radians(-105.0), 0.)  # start lat, lon, alt
stripTarget.specifyLocationEnd(np.radians(42.0), np.radians(-103.0), 0.)    # end lat, lon, alt
scSim.AddModelToTask(simTaskName, stripTarget)

The planetRadius variable is optional and defaults to Earth’s radius. Strip endpoints are specified through the specifyLocationStart() and specifyLocationEnd() methods, which accept geodetic latitude, longitude (both in radians), and altitude (in meters). Alternatively, the PCPF position vectors r_LP_P_Start and r_LP_P_End can be set directly.

The maximumRange variable is optional and defaults to -1, meaning no maximum range is considered. Set it to a positive value to have the hasAccess output depend on range.

The smallAngle variable is optional and defaults to \(10^{-12}\) rad. It is used as a numerical tolerance when evaluating near-zero strip central angles. If set to a non-positive value, it is reset to this default at module reset.

The preImagingTime variable is optional and defaults to 0. When set to a positive value, the effective start point is extrapolated backwards along the great-circle arc so that the target begins moving before the nominal start location, allowing time for spacecraft maneuvers before the imaging pass begins. Access is not granted until the pre-imaging phase has elapsed.

A stripLocation can be affixed to a specific planet by setting its planetInMsg input message:

stripTarget.planetInMsg.subscribeTo(planetMsg)

Spacecraft can be added to the model by calling:

stripTarget.addSpacecraftToModel(sc1.scStateOutMsg)
stripTarget.addSpacecraftToModel(sc2.scStateOutMsg)

#   log code
dataLog0 = stripTarget.currentStripStateOutMsg.recorder()
dataLog1 = stripTarget.accessOutMsgs[0].recorder()
dataLog2 = stripTarget.accessOutMsgs[1].recorder()

class StripLocation : public SysModel
#include <stripLocation.h>

strip location class

Public Functions

StripLocation()

create an instance of the Strip Location Class

~StripLocation()

empty destructor method.

void UpdateState(uint64_t currentSimNanos)

update module

Parameters:

currentSimNanos

void Reset(uint64_t currentSimNanos)

reset the module.

bool ReadMessages()

read module messages

void WriteMessages(uint64_t currentClock)

write module messages

void addSpacecraftToModel(Message<SCStatesMsgPayload> *tmpScMsg)

add a scState message name to the vector of names to be subscribed to (also creates a corresponding access message output name)

void specifyLocationStart(double lat, double longitude, double alt)

specify the start location of the strip from planet-centered latitude, longitude, altitude position

Parameters:
  • lat

  • longitude

  • alt

void specifyLocationEnd(double lat, double longitude, double alt)

specify the end location of the strip from planet-centered latitude, longitude, altitude position

Parameters:
  • lat

  • longitude

  • alt

Public Members

double minimumElevation

[rad] minimum elevation above the local horizon ; defaults to 10 degrees equivalent

double maximumRange

[m] (optional) maximum range ; defaults to -1, which represents no maximum range

double smallAngle

[rad] numerical tolerance when evaluating near-zero strip central angles

double planetRadius

[m] planet radius

Eigen::Vector3d r_LP_P_Start

[m] ground location of the starting point of the strip relative to PCPF

Eigen::Vector3d r_LP_P_End

[m] ground location of the ending point of the strip relative to PCPF

Eigen::Vector3d pStart

[m] normalized starting point to make sure it is on the Earth surface for the interpolation

Eigen::Vector3d pStartUpdated

[m] updated starting point after pre-imaging update

Eigen::Vector3d pEnd

[m] normalized ending point to make sure it is on the Earth surface for the interpolation

double acquisitionSpeed

[m/ns] constant acquisition speed of the camera

double preImagingTime

[ns] pre-imaging time used to artificially modify pStart

ReadFunctor<SpicePlanetStateMsgPayload> planetInMsg

planet state input message

Message<StripStateMsgPayload> currentStripStateOutMsg

current target location and velocity output message

std::vector<Message<AccessMsgPayload>*> accessOutMsgs

vector of current ground target access message

std::vector<ReadFunctor<SCStatesMsgPayload>> scStateInMsgs

vector of spacecraft state input message

uint64_t durationStripImaging

[ns] time already spent to image the strip (need to be re-initialized to 0 when imaging consecutive strips)

bool isStartPositionUpdated

flag indicating if the updated start position has already been computed

BSKLogger bskLogger

BSK Logging.

Private Functions

void updateInertialPosition()

compute inertial position and velocity of the target point on the strip

void updateTargetPositionPCPF(uint64_t currentClock)

update the target point on the central line in PCPF

void computeAccess()

compute access to the target point on the central line

void newpstart()

update the starting point of the strip to take into account the specified pre-imaging time

Eigen::Vector3d PositionCentralLine(double t, double teta, const Eigen::Vector3d &pStart, const Eigen::Vector3d &pEnd) const

return target point on the central line of the strip relative to PCPF

Eigen::Vector3d VelocityCentralLine(double t, double teta, const Eigen::Vector3d &pStart, const Eigen::Vector3d &pEnd) const

return the tangent velocity vector to the central line path of the target point relative to PCPF

Private Members

StripStateMsgPayload currentStripStateBuffer

buffer of target location and velocity output data

SpicePlanetStateMsgPayload planetState

buffer of planet data

std::vector<AccessMsgPayload> accessMsgBuffer

buffer of access output data

std::vector<SCStatesMsgPayload> scStatesBuffer

buffer of spacecraft states

Eigen::Vector3d r_North_N

inertial 3rd axis, defined as “North”

Eigen::Vector3d r_LP_P

[m] ground location of the current target point on the central line of the strip relative to PCPF

Eigen::Vector3d r_LP_N

[m] current target position vector relative to planet origin vector in inertial coordinates

Eigen::Vector3d r_LN_N

[m] current target position vector relative to inertial frame origin in inertial coordinates

Eigen::Vector3d r_PN_N

[m] planet position vector relative to inertial frame origin

Eigen::Vector3d v_LP_P

[m/s] velocity of the current target point on the central line of the strip relative to PCPF

Eigen::Vector3d v_LP_N

[m/s] velocity vector of the current target point relative to the planet in the inertial frame

Eigen::Vector3d v_LN_N

[m/s] velocity vector of the current target point relative to the inertial origin in the inertial frame

Eigen::Matrix3d dcm_LP

rotation matrix from planet-centered, planet-fixed frame P to site-local topographic (SEZ) frame L coordinates

Eigen::Matrix3d dcm_PN

rotation matrix from inertial frame N to planet-centered to planet-fixed frame P

Eigen::Matrix3d dcm_PN_dot

rotation matrix derivative from inertial frame N to planet-centered to planet-fixed frame P

Eigen::Vector3d w_PN

[rad/s] angular velocity of planet-fixed frame P relative to inertial frame N

Eigen::Vector3d rhat_LP_N

surface normal vector from the target location in inertial coordinates

double theta

[rad] angle between pStart and pEnd from the center of Earth (the Earth is assumed perfectly spherical)

double thetaUpdated

[rad] updated angle between pStartUpdated and pEnd used in target propagation

double lengthCentralLine

[m] length of the central line

double lengthCentralLineUpdated

[m] updated length of the central line taking into account the pre-imaging time

uint64_t OldSimNanos

[ns] previous currentSimNanos