Pointing Reference Frame
Version |
Date |
Author |
Purpose |
|---|---|---|---|
1 |
August 2019 |
Gary Turner |
Initial version |
2 |
September 2025 |
Hirad Mirhashemi/Alexandre Masset |
Refactored into new template, added mathematical formulation, and data verification procedures. |
3 |
August 2026 |
Nino Tarantino |
Converted to reStructuredText and updated coverage |
Introduction
The Pointing Reference Frame model provides an additional reference frame defined by two pre-existing frames and the following rules:
The origin of the new frame is at the origin of one of the two pre-existing frames, the Originating-Frame.
The x-axis of the new frame is aligned with the vector from the origin of the originating-frame to the origin of the other pre-existing frame, the Target-Frame.
The z-axis of the new frame is aligned with the angular momentum vector resulting from the relative linear motion of the target frame with respect to the originating frame.
The y-axis of the new frame completes the right-handed coordinate system.
A common application of this type of implementation is in creating a synodic frame, a frame that is always oriented between two bodies as they move around one another. An example of such a frame is the Earth-Moon Rotating Reference Frame.
This model is does not inherit from the jeod::RefFrame class. However, it still largely relies on this
class as the Pointing Reference Frame built is a jeod::RefFrame object. It is advised to be familiar
with this class before using this model.
Nomenclature and Concepts
In this documentation, the Pointing Reference Frame uses the terms Originating-Frame and Target-Frame, which are defined as follows:
Originating-frame: The reference frame at the origin of the Pointing Reference Frame.
Target-frame: The reference frame whose position relative to the originating-frame determines the Pointing Reference Frame's orientation.
These definitions define the Pointing Reference Frame as a reference frame that is centered at the Originating-Frame and pointing from there to the Target-Frame.
Requirements
The model shall provide a RefFrame object that defines a Pointing Reference Frame between two frames: an originating frame and a target frame.
The x-axis shall be defined along the position vector from the originating frame to the target frame.
The z-axis shall be defined along the vector resulting from the cross product of the pointing reference frame x-axis and the relative velocity between the originating frame and the target frame.
The y-axis shall complete this set to define a right-hand coordinate frame.
These vectors must be unit vectors when defined.
The model shall handle limit cases when the relative position and the relative velocity are aligned.
The model shall provide optional use of Ephemerides in the construction of the pointing reference frame, allowing a user to use external existing reference frames for the originating frame and the target frame.
The model shall guarantee that the Ephemerides tree is updated prior to the pointing reference frame.
Model Specifications
Architectural Considerations
The model consists of the primary PointingRefFrame class and the specialized extension of it,
EphemBasedPointingRefFrame. The PointingRefFrame class includes access to a reference frame
instance as a class member, instead of directly inheriting from RefFrame to allow inheritance from
SubscriptionBase for standard activation and deactivation of the model. The
EphemBasedPointingRefFrame class inherits from PointingRefFrame for scenarios where at least one
of the Originating-Frame or Target-Frame are frames managed by the jeod::EphemeridesManager. This
extended class provides a reference to the jeod::EphemeridesManager to update the ephemerides alongside
the PointingRefFrame behavior.
Model Structure
-
class PointingRefFrame : public SubscriptionBase
- #include "models/dynamics/state_descriptors/pointing_ref_frame/include/pointing_ref_frame.hh"
Defines a reference frame (the Pointing Frame) based on two other reference frames: the Originating Frrame and the Target Frame
The Pointing Frame is then defined by:
origin at the origin of the Originating Frame
x axis: Along the line from the origin of the Originating Frame to the origin of the Target Frame.
y-axis: Completes the orthogonal basis.
z-axis: Aligned with the angular momentum vector resulting from the relative linear motion of the Target Frame with respect to the Originating Frame.
Attitude-rate will always be on the local z-axis with value necessary for the x-axis to track the motion of the Target Frame. The frame is typically used to describe a vehicle state relative to a line joining two bodies such as planets. A common application would be a Synodic Frame, such as the Earth-Moon rotating frame.
Assumptions:
Both the Originating Frame and Target Frame must be registered in the simulation's frame-manager to provide a mechanism for deriving the relative state between them.
Design Considerations:
Originating Frame and Target Frame are pointers rather than references to allow for assignment of the reference frames after construction.
The jeod::RefFrame instance is a class member (has-a) rather than making this class a derivation of jeod::RefFrame (is-a). This choice is driven by a desire to avoid conflict between the two competing subscription mechanisms found in CML and JEOD. It was considered preferable to use the CML subscription pattern for the class implementation and to trigger the JEOD subscription process from the CML subscription process.
Subclassed by EphemBasedPointingRefFrame
Public Functions
-
PointingRefFrame()
Constructor
Initializes the frame with zero vectors for the position and velocity. The angular velocity is set to a unit vector along the z-axis. The transformation matrix is initialized as the identity matrix, and the attitude quaternion is set to the identity quaternion.
-
PointingRefFrame(const PointingRefFrame&) = delete
Copy constructor deleted
-
PointingRefFrame &operator=(const PointingRefFrame&) = delete
Copy assignment operator deleted
-
void set_originating_frame(jeod::RefFrame *originating_frame)
Set the Originating Frame pointer
After calling SubscriptionBase::initialize, the Originating Frame may not be changed.
- Parameters:
originating_frame -- Non-null pointer to the Originating Frame
-
void set_target_frame(jeod::RefFrame *target_frame)
Set the Target Frame pointer
After calling SubscriptionBase::initialize, the Target Frame may not be changed.
- Parameters:
target_frame -- Non-null pointer to the Target Frame
-
virtual void update()
Update the state of the Pointing Frame
Note
Since the Pointing Frame is defined with its origin at co-located with the Originating Frame's origin, only the orientation and angular rate will change.
Public Members
-
jeod::RefFrame pointing_frame
The generated reference frame
- Units:
--
-
jeod::RefFrameState target_wrt_originating_state
The state of the Target Frame with respect to the Originating Frame. Exists as a class member for logging purposes only, elements of this instance are used to define the state of the pointing-ref-frame itself.
- Units:
--
Protected Functions
-
bool setup_frames()
Add the Pointing Frame as a child of the Originating Frame and ensure that the Originating Frame and Target Frame are valid and subscribed
-
virtual void deactivate() override
Deactivate the model
Protected Attributes
-
jeod::RefFrame *originating_frame = {nullptr}
Pointer to the Originating Frame. Note this cannot be const due to subscribe/unsubscribe operations, but the PointingRefFrame class should not influence any other aspect of this RefFrame instance.
- Units:
--
-
jeod::RefFrame *target_frame = {nullptr}
Pointer to the Target Frame. Note this cannot be const due to subscribe/unsubscribe operations, but the PointingRefFrame class should not influence any other aspect of this RefFrame instance.
- Units:
--
-
class EphemBasedPointingRefFrame : public PointingRefFrame
- #include "models/dynamics/state_descriptors/pointing_ref_frame/include/ephem_based_pointing_ref_frame.hh"
Extension of the PointingRefFrame for cases where the Originating Frame or Target Frame are ephemeris-based frames.
This version should be used when the states of either the Originating Frame or the Target Frame are known only by updates coming from the Ephemeris Manager.
Subclassed by EarthMoonRotatingFrame
Public Functions
-
inline EphemBasedPointingRefFrame(jeod::EphemeridesManager &mgr)
Constructor
- Parameters:
mgr -- Reference to the JEOD Ephemeris Manager, which for most simulations will be the
jeod::DynManagerinstance
-
EphemBasedPointingRefFrame(const EphemBasedPointingRefFrame&) = delete
Copy constructor deleted
-
EphemBasedPointingRefFrame &operator=(const EphemBasedPointingRefFrame&) = delete
Copy assignment operator deleted
-
inline virtual void initialize() override
Register the Pointing Frame with the dynamics/ephem manager so that it can be used to represent the state of a vehicle
Protected Functions
-
inline virtual void activate() override
Sets up reference frames and tells the JEOD Ephemeris Manager to update the ephemerides
Protected Attributes
-
jeod::EphemeridesManager &ephem_manager
-
inline EphemBasedPointingRefFrame(jeod::EphemeridesManager &mgr)
Mathematical Formulation
Mathematical Nomenclature
In this formulation, the following notation is used:
Vectors and matrices are denoted in bold (e.g. \(\mathbf{\hat{x}}\)).
Subscripts are used to provide additional descriptions (e.g. \(\mathbf{R_{\mathit{rel}}}\) describes a relative position vector)
Superscripts are used to provide the reference frame in which the vector is expressed (e.g. \(\mathbf{R_{\mathit{rel}}^{B}}\) describes a relative position vector expressed in the B-frame).
Vectors provided in their vector form use subscripts to provide the reference frame in which they are expressed. For example: \(\begin{bmatrix}x \\y \\z \\\end{bmatrix}_{B}\)
Superscripts on derivative operators are used to provide the reference frame of observation (e.g. \(\frac{{}^{I}d}{\mathit{dt}}{(\mathbf{R})}\) denotes the inertial derivative of \(\mathbf{R}\), i.e. the time rate of change of \(\mathbf{R}\) as observed from the inertial frame).
Following this notation, the context for each expression is provided below:
\(\mathbf{R_{\mathit{rel}}}\) represents the position vector of the Target-Frame relative to the Originating-Frame, expressed in the inertial frame.
\(\mathbf{V_{\mathit{rel}}}\) represents the velocity vector of the Target-Frame relative to the Originating-Frame, expressed in the inertial frame.
\(\mathbf{\hat{x}}\) represents the first unit basis vector of the rotating frame, expressed in the inertial frame.
\(\mathbf{\hat{y}}\) represents the second unit basis vector of the rotating frame, expressed in the inertial frame.
\(\mathbf{\hat{z}}\) represents the third unit basis vector of the rotating frame, expressed in the inertial frame.
\(\mathbf{T_{\mathit{PRF}/I}}\) represents the transformation matrix from the inertial frame to the rotating frame.
\(\mathbf{\Omega_{\mathit{PRF}/I}^{\mathit{PRF}}}\) represents the angular velocity vector from the inertial frame to the rotating frame, expressed in the rotating frame.
\(\mathbf{R_{v}}\) represents the inertial position vector of the vehicle.
\(\mathbf{R_{\mathit{PRF}}}\) represents the inertial position vector of the rotating frame.
\(\mathbf{R_{v/\mathit{PRF}}}\) represents the position vector of the vehicle relative to the rotating frame.
\(\mathbf{V_{v}}\) represents the inertial velocity vector of the vehicle.
\(\mathbf{V_{\mathit{PRF}}}\) represents the inertial velocity vector of the rotating frame.
\(\mathbf{V_{v/\mathit{PRF}}}\) represents the velocity vector of the vehicle relative to the rotating frame, as seen from the rotating frame.
Pointing Reference Frame
The Pointing Reference Frame is constructed using the motion of the Target-Frame relative to the Originating-Frame to define the origin and orientation of the rotating coordinate system. The x-axis points from the Originating-Frame to the Target-Frame, the z-axis is normal to the orbital plane formed by the relative motion, and the y-axis completes the right-handed coordinate system. While it is possible to express some of these vectors in a different reference frame as long as a consistent frame is used, this model implementation specifically uses only inertial components to define the Pointing Reference Frame axes, which leads to the following expressions:
The orientation of the Pointing Reference Frame with respect to the inertial frame is then represented by the transformation matrix:
By definition, the Pointing Reference Frame is rotating uniformly about its z-axis. Its angular velocity vector relative to the inertial frame is expressed in the Pointing Reference Frame as:
Where:
Note that the calculation of \(\mathbf{\Omega_{\mathit{PRF}/I}^{\mathit{PRF}}}\) is independent of the reference frame used to express \(\mathbf{R_{\mathit{rel}}}\), \(\mathbf{V_{\mathit{rel}}}\), and \(\mathbf{\hat{y}}\). This is trivially shown by expressing the inner product with vector multiplication: \({{\mathbf{V_{\mathit{rel}}} \cdot \mathbf{\hat{y}}} = \mathbf{{V_{\mathit{rel}}}^{T}}}\mathbf{\hat{y}}\). However, they must be expressed in the same reference frame.
Singularities in PointingRefFrame Construction
Under nominal conditions, the Pointing Reference Frame is constructed as described in the Pointing Reference Frame section, using the relative position and velocity vectors of the Target-Frame with respect to the Originating-Frame to define the axes. However, certain configurations can lead to numerically undefined axes in this formulation. These configurations are handled as follows:
Zero Relative Position Vector
If the magnitude of \(\mathbf{R_{\mathit{rel}}}\) is zero (i.e. the Target- and Originating-Frames are coincident), the Pointing Reference Frame cannot be constructed meaningfully. In this case, the transformation matrix defining the orientation is not updated from its initialized state, maintaining it as the identity matrix. Additionally, the angular velocity is set to zero. This ensures the axes are well defined by fixing it to the inertial frame as there is no meaningful relative motion.
Aligned Relative Position and Velocity Vectors
If the relative position and velocity vectors are aligned or nearly aligned, the cross product used to define the z-axis becomes zero and numerically unstable, resulting in a poorly defined z-axis. To address this, two alternative solutions are formulated:
Use Last Known Y-Axis (Alternative 1): If the cross product of the relative position and velocity vectors are near zero, the z-axis is computed by using the previous y-axis vector in place of the relative velocity vector:
\begin{equation} \mathbf{\overrightarrow{z}} = \mathbf{R_{\mathit{rel}}} \times \mathbf{\hat{y}}_{prev} \end{equation}If the resulting vector has a non-zero magnitude, it is normalized and used as the new z-axis and an appropriate warning is broadcasted.
Use Previous Z-Axis (Alternative 2): If Alternative 1 fails (i.e. the previous y-axis is also aligned with the current relative position vector), the z-axis is reconstructed using the previous z-axis and the current x-axis:
\begin{equation} \mathbf{\overrightarrow{z}} = \mathbf{\hat{x}} \times (\mathbf{\hat{z}}_{prev} \times \mathbf{\hat{x}}) \end{equation}This is a vector triple product, which ensures that the resulting z-axis is orthogonal to the current x-axis (i.e. the relative position vector). This formulation cannot produce a zero vector, because the current x-axis is aligned with the previous y-axis (as established from failing Alternative 1), and the previous y- and z-axes are by nominal construction orthogonal. Therefore, the previous z-axis cannot be aligned with the current x-axis, ensuring that this cross product produces a defined z-axis.
These alternatives together are a robust fallback for defining the z-axis in all cases where the relative position and velocity vectors are aligned.
Relative Derived State
The RelativeDerivedState model belongs to JEOD and is independent of the formulation
described above. This formulation will present the relative position and velocity which is
implemented in the RelativeDerivedState, but is commonly used alongside the rotating frame model
and formulation provided earlier. For more information about the RelativeDerivedState model,
please refer to the JEOD documentation.
Once the Pointing Reference Frame is established, the position of a vehicle relative to this Pointing Reference Frame can be determined by translating its inertial position into the frame's origin and applying the transformation matrix from the inertial to the Pointing Reference Frame:
where \(\mathbf{R_{v}^{I}}\) and \(\mathbf{R_{\mathit{PRF}}^{I}}\) are the inertial position vectors for the vehicle and the origin of the Pointing Reference Frame, respectively, expressed in the inertial frame. As a result, \(\mathbf{R_{v/\mathit{PRF}}^{\mathit{PRF}}}\) is the relative position of the vehicle with respect to the origin of the pointing reference frame, expressed in the Pointing Reference Frame.
It is important to emphasize that relative velocity as seen from the Pointing Reference Frame, isn't simply:
Instead, the velocity of the vehicle as seen from the Pointing Reference Frame is computed using the transport theorem to account for the rotation of the Pointing Reference Frame with respect to the inertial. Let \(\mathbf{V_{v}} = \frac{{}^{I}d}{\mathit{dt}}{(\mathbf{R_{v}})}\) denote the inertial velocity of the vehicle, \(\mathbf{V_{\mathit{PRF}}} = \frac{{}^{I}d}{\mathit{dt}}{(\mathbf{R_{\mathit{PRF}}})}\) denote the inertial velocity of the origin of the Pointing Reference Frame, and \(\mathbf{V_{v/\mathit{PRF}}} = \frac{{}^{\mathit{PRF}}d}{\mathit{dt}}{(\mathbf{R_{v/\mathit{PRF}}})}\) denote the vehicle velocity with respect to the origin of the Pointing Reference Frame as seen from the Pointing Reference Frame. Applying transport theorem, this relative velocity of the vehicle can be expressed as:
Substituting the inertial velocities of the vehicle and the Pointing Reference Frame origin, this becomes:
Finally, expressing the terms in a common Pointing Reference Frame yields:
where \(\mathbf{V_{v}^{I}}\) and \(\mathbf{V_{\mathit{PRF}}^{I}}\) are the inertial velocity vectors for the vehicle and the origin of the rotating frame, respectively.
User's Guide
Implementation
See the Model Structure section for include paths for the PointingRefFrame
and EphemBasedPointingRefFrame classes.
Initialization
The non-ephemerides PointingRefFrame has a default constructor that
takes no arguments. The ephemerides Pointing Reference Frame constructor takes a reference to the Ephemerides Manager.
This is often provided as a reference to the jeod::DynManager, which is a derivative of the
Ephemerides Manager:
PointingRefFrame non_ephem_rotating_frame;
EphemBasedPointingRefFrame ephem_rotating_frame(dyn_manager);
For both Pointing Reference Frames, set the Originating-Frame and Target-Frame, and a name for the Pointing Reference Frame like:
non_ephem_rotating_frame.set_originating_frame(vehicleA.composite_body);
non_ephem_rotating_frame.set_target_frame(vehicleB.composite_body);
non_ephem_rotating_frame.pointing_frame.set_name("VehicleAB-rotating-frame");
ephem_rotating_frame.set_originating_frame(earth.planet.inertial);
ephem_rotating_frame.set_target_frame(sun.planet.inertial);
ephem_rotating_frame.pointing_frame.set_name("EarthSun-rotating-frame");
For the non-ephemerides Pointing Reference Frame, you will need to add the frame to the Dynamics Manager:
dyn_manager.add_ref_frame(non_ephem_rotating_frame.pointing_frame);
The ephemerides Pointing Reference Frame does not require this step, as the model handles it internally with the reference to the Ephemerides Manager.
The method to schedule for initialization of the model:
P_ENV ("initialization") non_ephem_rotating_frame.initialize();
P_DYN ("initialization") ephem_rotating_frame.initialize();
The initialization of the non-ephemerides Pointing Reference Frame can occur as early as the
reference frame initialization in P_ENV or later. However, the ephemerides pointing reference
frame should occur quite late in the initialization sequence as it should be after the Ephemeris
initialization, so P_DYN or later.
Routine Execution
The method to schedule for updates to the model:
P_ENV (DYNAMICS, "environment") non_ephem_rotating_frame.update();
P_DYN (DYNAMICS, "environment") ephem_rotating_frame.update();
Configuration
The model is inactive by default. To activate it, you could call the subscribe()
method:
non_ephem_rotating_frame.subscribe();
ephem_rotating_frame.subscribe();
Relative Derived State
One of the most common uses of this frame is for expressing the state of a vehicle. The model itself
provides only the frame, the state relative to that frame can be described using an instance of
JEOD's jeod::RelativeDerivedState model. See the JEOD documentation for information on configuring
this relative state.
Of particular relevance to this model, the configuration of a jeod::RelativeDerivedState requires
specification of the Subject-Frame and the Target-Frame. Typically, the Subject-Frame is the
vehicle frame of interest and the Target-Frame is the Pointing Reference Frame defined by this
model. To set the Target-Frame, it is necessary to know the name of the Pointing Reference Frame,
which is set in the initialization steps.
For example, to get the relative state of the vehicle to the Earth-Sun Pointing Reference Frame:
jeod::RelativeDerivedState veh_wrt_prf;
veh_wrt_prf.subject_frame_name = "test_vehicle.composite_body";
veh_wrt_prf.target_frame_name = "EarthSun-rotating-frame";
Logging
Typically, the desired output is the state of some vehicle with respect to the pointing frame, for example:
relative_derived_state_instance.rel_state.trans.position
The pointing frame itself also has a state. The position and velocity of the frame are not of interest because they are locked to the Originating-Frame, so both position and velocity are zero. However, the orientation and angular rate are occasionally useful. These are represented as follows:
Transformation matrix from the parent planet-inertial state to the pointing frame (3x3 matrix).
rotating_frame_instance.pointing_frame.state.rot.T_parent_this
Left-handed transformation quaternion describing the transformation from the parent Originating-Frame state to the pointing frame, expressed as a scalar and a 3-element vector.
rotating_frame_instance.pointing_frame.state.rot.Q_parent_this.scalar rotating_frame_instance.pointing_frame.state.rot.Q_parent_this.vector
Angular rate of the rotating frame relative to the parent Originating-Frame state, expressed in the rotating frame as a 3-element vector. By definition of the rotating frame, the x- and y-components are identically zero.
rotating_frame_instance.pointing_frame.state.rot.ang_vel_this
Verification
Code Coverage
------------------------------------------------------------------------------
GCC Code Coverage Report
Directory: .
------------------------------------------------------------------------------
File Lines Exec Cover Missing
------------------------------------------------------------------------------
models/dynamics/state_descriptors/pointing_ref_frame/include/ephem_based_pointing_ref_frame.hh
14 14 100%
models/dynamics/state_descriptors/pointing_ref_frame/src/pointing_ref_frame.cc
87 87 100%
------------------------------------------------------------------------------
TOTAL 101 101 100%
------------------------------------------------------------------------------
Exceptions
N/A
Simulation Configurations
SIM_verif
This verification simulation tests the geometry and vector operations used in defining the pointing reference frame using two arbitrary reference frames A and B corresponding to the Originating-Frame and the Target-Frame, respectively. Additionally, a subject vehicle is used to verify the relative velocity of the body to the Pointing Reference Frame, as seen from the pointing reference frame.
RUN_01_Geometric
This test verifies that the Pointing Reference Frame is properly constructed with the correct orientation and angular velocity throughout a variety of configurations, and that the relative position and velocity of the subject vehicle with respect to the Pointing Reference Frame is correct.
The default setup for these unit tests includes these states in the inertial axes (+X, +Y, +Z):
Originating-Frame is at rest at the origin: \(\mathbf{R_{O}^{I}} = \begin{bmatrix}0 & 0 & 0\end{bmatrix}\), \(\mathbf{V_{O}^{I}} = \begin{bmatrix}0 & 0 & 0\end{bmatrix}\).
Target-Frame is located at \(\mathbf{R_{T}^{I}} = \begin{bmatrix}10 & 0 & 0\end{bmatrix}\) and moving in \(\mathbf{V_{T}^{I}} = \begin{bmatrix}0 & 5 & 0\end{bmatrix}\).
vehicle is located at \(\mathbf{R_{v}^{I}} = \begin{bmatrix}10 & 0 & 0\end{bmatrix}\) and moving in \(\mathbf{V_{v}^{I}} = \begin{bmatrix}0 & 0 & 0\end{bmatrix}\).
All references to the vehicle relative position and velocity are with respect to the origin of the Pointing Reference Frame and are expressed in the Pointing Reference Frame axes. The relative velocity is also observed from the perspective of the Pointing Reference Frame.
Default Configuration
Setup: All input states are in the default configuration.
Expected Results: Pointing frame aligns with +X (Target-Frame direction), +Y (Target-Frame velocity), +Z (angular momentum direction). Vehicle lies on pointing frame x-axis and its relative velocity opposes the Target-Frame motion.
Results:
Time (s) |
\(\mathbf{R}_{v/\mathit{PRF}}^{\mathit{PRF}}\) |
\(\mathbf{V}_{v/\mathit{PRF}}^{\mathit{PRF}}\) |
\(\omega_{z}\) |
\(\mathbf{\hat{x}}^{T}\) |
\(\mathbf{\hat{y}}^{T}\) |
\(\mathbf{\hat{z}}^{T}\) |
|---|---|---|---|---|---|---|
0 |
[10,0,0] |
[0,-5,0] |
0.5 |
[1,0,0] |
[0,1,0] |
[0,0,1] |
Offset Positions in 3D
Setup: Originating-, Target-Frames, and vehicle positions are all offset by [5,5,5] to maintain same relative position and motion.
Expected Results: Same pointing frame and vehicle relative state as default configuration.
Results:
1 |
[10,0,0] |
[0,-5,0] |
0.5 |
[1,0,0] |
[0,1,0] |
[0,0,1] |
Vehicle Diagonally Located in 3D
Setup: Vehicle position is diagonally offset in the YZ-plane to be located at [10,-10,10].
Expected Results: Same pointing frame as default configuration. Vehicle relative position is the same as the vehicle inertial position, and it moves in the pointing frame x- and y-axes.
Results:
2 |
[10,-10,10] |
[-5,-5,0] |
0.5 |
[1,0,0] |
[0,1,0] |
[0,0,1] |
Vehicle Moving in +X
Setup: Vehicle now has velocity of [10,0,0] (along +X), while the Target-Frame still moves in +Y with the same velocity [0,5,0].
Expected Results: Same pointing frame and vehicle relative position as default configuration. Vehicle relative velocity now reflects the vehicle inertial motion along the pointing frame x-axis, in addition to the previous opposing Target-Frame motion in the pointing frame y-axis.
Results:
3 |
[10,0,0] |
[10,-5,0] |
0.5 |
[1,0,0] |
[0,1,0] |
[0,0,1] |
Vehicle Moving in +X, -Y, and +Z
Setup: Vehicle now has velocity of [10,-10,10], while the Target-Frame still moves in +Y with the same velocity [0,5,0].
Expected Results: Same pointing frame and vehicle relative position as default configuration. Vehicle relative velocity now reflects the vehicle inertial motion along the pointing frame x-, y-, and z-axes, in addition to the previous opposing Target-Frame motion in the pointing frame y-axis.
Results:
4 |
[10,0,0] |
[10,-15,10] |
0.5 |
[1,0,0] |
[0,1,0] |
[0,0,1] |
Target Moving in -Y
Setup: Target-Frame now moves in opposite direction (along -Y) with velocity [0,-5,0].
Expected Results: Same pointing frame x-axis and vehicle relative state as default configuration. Pointing frame y- and z-axes are in the opposite direction.
Results:
5 |
[10,0,0] |
[0,-5,0] |
0.5 |
[1,0,0] |
[0,-1,0] |
[0,0,-1] |
Target Moving in +Z
Setup: Target-Frame now moves in +Z with velocity [0,0,5] instead of +Y.
Expected Results: Same pointing frame x-axis and vehicle relative state as default configuration. With the Target-Frame moving in +Z, the pointing frame z-axis (angular momentum vector) shifts to -Y, aligning the pointing frame y-axis with +Z to maintain a right-handed frame.
Results:
6 |
[10,0,0] |
[0,-5,0] |
0.5 |
[1,0,0] |
[0,0,1] |
[0,-1,0] |
Target in +Y, Moving in +X
Setup: Target-Frame lies along +Y at position [0,10,0] and moves in +X with velocity [5,0,0].
Expected Results: Pointing frame x-axis aligns with +Y (Target-Frame direction), y-axis with +X (Target-Frame velocity), and z-axis with -Z (angular momentum direction). Vehicle relative position lies on pointing frame y-axis and it moves in the direction of the pointing frame x-axis.
Results:
7 |
[0,10,0] |
[5,0,0] |
0.5 |
[0,1,0] |
[1,0,0] |
[0,0,-1] |
Target in +Y, Moving in +Z
Setup: Target-Frame lies along +Y at position [0,10,0] and moves in +Z with velocity [0,0,5].
Expected Results: Pointing frame x-axis aligns with +Y (Target-Frame direction), y-axis with +Z (Target-Frame velocity), and z-axis with +X (angular momentum direction). Vehicle relative position lies on pointing frame z-axis with zero velocity.
Results:
8 |
[0,0,10] |
[0,0,0] |
0.5 |
[0,1,0] |
[0,0,1] |
[1,0,0] |
Target in +Z, Moving in +X
Setup: Target-Frame lies along +Z at position [0,0,10] and moves in +X with velocity [5,0,0].
Expected Results: Pointing frame x-axis aligns with +Z (Target-Frame direction), y-axis with +X (Target-Frame velocity), and z-axis with +Y (angular momentum direction). Vehicle lies on pointing frame y-axis and it moves in the direction of the pointing frame x-axis.
Results:
9 |
[0,10,0] |
[5,0,0] |
0.5 |
[0,0,1] |
[1,0,0] |
[0,1,0] |
Target in +Z, Moving in +Y
Setup: Target-Frame lies along +Z at position [0,0,10] and moves in +Y with velocity [0,5,0].
Expected Results: Pointing frame x-axis aligns with +Z (Target-Frame direction), y-axis with +Y (Target-Frame velocity), and z-axis with -X (angular momentum direction). Vehicle lies on pointing frame opposite z-axis with zero velocity.
Results:
10 |
[0,0,-10] |
[0,0,0] |
0.5 |
[0,0,1] |
[0,1,0] |
[-1,0,0] |
Target Moving Diagonally in XY
Setup: Target-Frame and vehicle located at position [10,10,0], and the Target-Frame moves diagonally with velocity [-5,5,0].
Expected Results: Pointing frame x-axis aligns with the diagonal Target-Frame position vector in XY-plane, y-axis with diagonal Target-Frame velocity in XY-plane, and z-axis remains aligned with +Z (angular momentum direction). Vehicle lies on pointing frame x-axis and it moves in the direction opposite of the pointing-frame y-axis.
Results:
11 |
[14.14,0,0] |
[0,-7.07,0] |
0.5 |
[0.707,0.707,0] |
[-0.707,0.707,0] |
[0,0,1] |
Target and Vehicle in 3D
Setup: Target-Frame and vehicle located at position [5,5,5], and the Target-Frame moves in +Z with velocity [0,0,5].
Expected Results: Pointing frame x-axis points diagonally in 3D (Target-Frame direction). The Target-Frame velocity in +Z produces an angular momentum vector in the XY-plane, pointing the pointing frame z-axis diagonal in-plane. The y-axis completes the right-handed frame and will be diagonal in 3D. Vehicle lies on the pointing frame x-axis and it moves in the direction opposite of the pointing frame y-axis. The angular velocity about the pointing frame z-axis should be lower than the other cases, because the Target-Frame velocity is less orthogonal to the position vector.
Results:
12 |
[8.66,0,0] |
[0,-4.082,0] |
0.471 |
[0.577,0.577,0.577] |
[-0.408,-0.408,0.816] |
[0.707,-0.707,0] |
Origin Moving in -Y
Setup: Originating-Frame now moves in -Y with velocity [0,-5,0], the opposite of the previous Target-Frame motion.
Expected Results: Same pointing frame axes and vehicle relative state as default configuration. The angular velocity around the pointing frame z-axis will double compared to the default configuration results.
Results:
13 |
[10,0,0] |
[0,-5,0] |
1.0 |
[1,0,0] |
[0,1,0] |
[0,0,1] |
ERROR_bad_frames
This test verifies the errors that result from incorrect configurations and warnings from cases where the Pointing Reference Frame axes aren't well defined and need to be alternatively handled using the methodology described in the Singularities section.
Configuration Frames are NULL
If the Originating-Frame or the Target-Frame are set to a NULL value during intialization, the model will broadcast a respective error.
***************************************************************
Set originating frame to NULL
***************************************************************
Non-critical Error detected at
Trick Sim-time: 0
File: /nobackup2/ataranti/cml/models/dynamics/state_descriptors/pointing_ref_frame/src/pointing_ref_frame.cc
Line: 50
Message: Configuration error
Attempt to assign the originating-frame of PointingRefFrame PointingFrame to be NULL.
This is not a valid setting.
Attempt failed.
***************************************************************
Set target frame to NULL
***************************************************************
Non-critical Error detected at
Trick Sim-time: 0
File: /nobackup2/ataranti/cml/models/dynamics/state_descriptors/pointing_ref_frame/src/pointing_ref_frame.cc
Line: 72
Message: Configuration error
Attempt to assign the target-frame of PointingRefFrame PointingFrame to be NULL.
This is not a valid setting.
Attempt failed.
Changing Configuration after Model Activation
If the Pointing Reference Frame model is already activated through its subscribe()
method, any attempt to change the Originating-Frame or Target-Frame will result in the model broadcasting
a respective error.
***************************************************************
t=0.0 Reset originating frame specification
***************************************************************
Non-critical Error detected at
Trick Sim-time: 0
File: /nobackup2/ataranti/cml/models/dynamics/state_descriptors/pointing_ref_frame/src/pointing_ref_frame.cc
Line: 43
Message: Reconfiguration error
Once activated, the PointingRefFrame PointingFrame cannot change its originating frame.
Originating-frame remains at its current setting.
***************************************************************
t=0.0 Reset target frame specification
***************************************************************
Non-critical Error detected at
Trick Sim-time: 0
File: /nobackup2/ataranti/cml/models/dynamics/state_descriptors/pointing_ref_frame/src/pointing_ref_frame.cc
Line: 65
Message: Reconfiguration error
Once activated, the PointingRefFrame PointingFrame cannot change its target frame.
Originating-frame remains at its current setting.
Relative Position Vector is Zero (Proximity Warning)
When the Pointing Reference Frame encounters a situation where the Originating-Frame and Target-Frame are very close to each other, the relative position vector between the frames will result in a zero vector, producing an undefined x-axis. The Pointing Reference Frame will result to retaining its orientation, and making the angular velocity zero.
Setup: At t=0, a nominal configuration is defined, but at t=1 both the Originating-Frame and Target-Frame are positioned at [0,0,0].
Expected Results: At t=1, the orientation from t=0 is retained and the frame has an angular velocity of zero.
Results:
Time (s) |
\(\mathbf{R}_{v/\mathit{PRF}}^{\mathit{PRF}}\) |
\(\mathbf{V}_{v/\mathit{PRF}}^{\mathit{PRF}}\) |
\(\omega_{z}\) |
\(\mathbf{\hat{x}}^{T}\) |
\(\mathbf{\hat{y}}^{T}\) |
\(\mathbf{\hat{z}}^{T}\) |
|---|---|---|---|---|---|---|
0 |
[3,2,-1] |
[8,2,-4] |
1 |
[0,0,1] |
[0,1,0] |
[-1,0,0] |
1 |
[3,2,-1] |
[6,5,-4] |
0 |
[0,0,1] |
[0,1,0] |
[-1,0,0] |
Relative Position and Velocity Vectors are Aligned (Alternative 1)
When the Pointing Reference Frame encounters a situation where the relative position and velocity vectors between the Originating-Frame and Target-Frame are very close to being aligned, the cross product of these vectors will result in a zero vector, producing an undefined z-axis. In the case where the relative position vector is not aligned with the previous y-axis, the cross product of these vectors produces the new z-axis. Ultimately, this results in the y-axis being retained from the previous iteration.
Setup: At t=2, a nominal configuration is defined, but at t=3 the Originating-Frame and Target-Frame are positioned at [0,0,0] and [0,0,-1], respectively, and are moving at velocities [0,0,0] and [0,0,1], respectively.
Expected Results: At t=3, the relative position and velocity vectors are aligned, causing the z-axis to be computed using the relative position vector from t=3 and y-axis from t=2, thus preserving the previous y-axis orientation from t=2.
Results:
2 |
[0,0,-1] |
[6,5,-4] |
1 |
[0,0,1] |
[0,1,0] |
[-1,0,0] |
3 |
[0,0,1] |
[-6,5,4] |
0 |
[0,0,-1] |
[0,1,0] |
[1,0,0] |
Relative Position and Velocity Vectors are Aligned (Alternative 2)
Similar to the previous test, when the relative position and velocity vectors are very close to being aligned, the cross product of these vectors will produce an undefined z-axis. In the off-chance where the relative position vector is also aligned with the previous y-axis, the formulation from alternative 1 produces another undefined z-axis. In this case, the z-axis is defined as the result of a triple cross product of the x-axis and the previous z-axis. Ultimately, this results in the z-axis being retained from the previous iteration.
Setup: At t=3, the Pointing Reference Frame axes is fully defined using alternative 1, but at t=4 the Originating-Frame and Target-Frame are positioned at [0,0,0] and [0,1,0], respectively, and are moving at velocities [0,0,0] and [0,1,0], respectively. The relative position and velocity vectors at t=4 are different from those at t=3.
Expected Results: At t=4, the relative position is aligned with the relative velocity vector and the previous y-axis, causing the z-axis to be computed as the result of a triple cross product of the x-axis from t=4 and z-axis from t=3, thus preserving the previous z-axis orientation from t=3.
Results:
3 |
[0,0,1] |
[-6,5,4] |
0 |
[0,0,-1] |
[0,1,0] |
[1,0,0] |
4 |
[0,0,1] |
[5,6,4] |
0 |
[0,1,0] |
[0,0,1] |
[1,0,0] |
FAIL_unassigned_frames
This test verifies that when the model is initialized without specifying the Target-Frame and/or
Originating-Frame, an error is broadcast, the model is stopped and returns the boolean false.
Non-critical Error detected at
Trick Sim-time: 0
File: /nobackup2/ataranti/cml/models/dynamics/state_descriptors/pointing_ref_frame/src/pointing_ref_frame.cc
Line: 209
Message: Incomplete specification
The target-frame and/or originating-frame of the
Pointing_Reference-Frame have not been assigned.
The Pointing-Reference-Frame PointingFrame cannot be activated.
Non-critical Error detected at
Trick Sim-time: 0
File: /nobackup2/ataranti/cml/models/utilities/subscriptions/src/subscriptions.cc
Line: 133
Message: Failure During Initialization.
The SubscriptionBase initialization for 'unnamed-instance' failed when the model
attempted to activate during initialization:
- activation sequence executed due to having pending subscriptions.
Model has been neither initialized nor activated
but pending subscriptions have been retained per setting of
configuration flag initialize_on_failed_activation.
Rerun <model>.initialize() to apply pending subscriptions and activate the model.
SIM_Ephem
This verification simulation tests the functionality of the EphemBasedPointingRefFrame class and
is limited to the very small differences between this class and its base class, PointingRefFrame.
It illustrates the potential pitfalls of using a PointingRefFrame instance rather than an
EphemBasedPointingRefFrame instance when either the Target-Frame and/or Originating-Frame are
managed by the Ephemerides Manager. See FAIL_noephem_only and FAIL_noephem_with_subscriptions
for easy mistakes to avoid.
All the runs in this simulation define the Pointing Reference Frames to track the Earth and Sun relative positions and motion, with an individual subject vehicle fixed on the Earth-Sun vector to enable verification of the relative state of the vehicle with respect to the pointing reference frame.
Since the PointingRefFrame was already geometrically verified in SIM_verif, the purpose of
logging data in this simulation is to determine which frame, EphemBasedPointingRefFrame or
PointingRefFrame is actively driving the relative state updates, and whether the inertial
positions of the Earth and Sun are being updated via the EphemeridesManager.
RUN_01_ephem_only
This test demonstrates the recommended implementation for a Pointing Reference Frame that depends on frames managed by the Ephemerides Manager.
Setup: Run only the EphemBasedPointingRefFrame and its associated relative state.
Expected Results: Only the EphemBasedPointingRefFrame instance and its relative vehicle state are
updated, not the PointingRefFrame instance. The inertial positions of the Earth and Sun are also
updated through the EphemBasedPointingRefFrame connection to the Ephemerides Manager.
Results: Results match expected.
RUN_02_both
This test demontrates that since EphemBasedPointingRefFrame can add its Ephemeris-based frames to
the Ephemeris tree through the Ephemerides Manager, PointingRefFrame can indirectly track those
same frames despite not having a connection to the Ephemerides Manager. The effect of this hidden
dependency becomes evident in the FAIL_noephem_only test, where removing the
EphemBasedPointingRefFrame causes the base PointingRefFrame to lose access to the
Ephemeris-based frames.
Setup: Runs both the EphemBasedPointingRefFrame, the base PointingRefFrame, and their associated
relative states.
Expected Results: Both the EphemBasedPointingRefFrame and the PointingRefFrame instances are
updated with their associated relative vehicle states. The inertial positions of the Earth and Sun
are also updated through the EphemBasedPointingRefFrame connection to the Ephemerides Manager.
Results: Results match expected.
RUN_03_ephem_only_resubscribe
This test is similar to RUN_01_ephem_only, in that only the EphemBasedPointingRefFrame and its
associated relative-state are computed. However, this test highlights the expected behavior when the
model is initially deactivated and later reactivated successfully, in constrast with
FAIL_noephem_with_subscriptions, where reactivation fails. It serves to verify that the
EphemBasedPointingRefFrame can correctly resume updating relative states and ephemeris-driven
positions after being re-subscribed mid-simulation.
Setup: Run only the EphemBasedPointingRefFrame and its associated relative state. Model is
initially deactivated and later reactivated during the simulation at t=300000.
Expected Results: The EphemBasedPointingRefFrame instance and its relative vehicle state are
initialized at t=0 and not updated anymore until after t=300000. Similarly, the Sun inertial
reference frame state won't be updated until that point as it is deactivated through
EphemBasedPointingRefFrame's Target-Frame. However, the Earth inertial reference frame state
continues updating as it is used as the integration frame for the subject vehicle.
Results: Results match expected.
FAIL_noephem_only
This test runs only the base PointingRefFrame and its associated relative state while still using
Ephemeris-based frames like the Earth inertial and Sun inertial as the Originating-Frame and
Target-Frame. The PointingRefFrame doesn't have access to the Ephemerides Manager unlike
EphemBasedPointingRefFrame, which causes the test to fail as the Ephemeris reference frame tree
was not built.
*********************************************************
Terminal error. Ephem tree has not been built.
Sun.inertial and Earth.inertial are not the same tree
*********************************************************
FAIL_noephem_with_subscriptions
This test is similar to FAIL_noephem_only in that only the base PointingRefFrame and its
associated relative state are computed while still using Ephemeris-based frames. However, this test
specifically highlights the behavior that happens when a separate model, one dependent on either the
Originating-Frame or Target-Frame, activates and deactivates those same Ephemeris-based frames
internally without rebuilding the Ephemeris reference frame tree. These actions could interfere with
the assumption that the frames will be simply activated and apart of the Ephemeris tree at
initialization.
In this test, the input file acts as a "lurking model" that also depends on the Sun inertial frame.
At the start of the simulation, this lurking model adds the Sun inertial frame to the Ephemeris tree
and activates the frame. Although this setup is intended for the lurking model's own functionality,
it incidentally enables the PointingRefFrame to initialize successfully, since the required frame
is present in the Ephemeris tree at that time. After initialization, the lurking model deactivates
the Sun inertial frame, removing it from the Ephemeris tree. To avoid failure at this point, the
PointingRefFrame is also deactivated. Later in the simulation (at t=300000), the lurking model
reactivates the Sun inertial frame, and the PointingRefFrame is re-enabled to test its
functionality using that frame. However, the simulation fails at this point, because the Ephemeris
tree is not automatically rebuilt upon reactivation of the Sun inertial frame or PointingRefFrame,
unlike the EphemBasedPointingRefFrame. As a result, the Earth inertial and Sun inertial frame
remain disconnected in the Ephemeris tree, failing at the computation of the relative state between
the two frames. In conclusion, when using Ephemeris-based frames without the
EphemBasedPointingRefFrame, the Ephemeris tree must be rebuilt everytime the model is
re-subscribed to ensure the Originating-Frame and Target-Frame are dynamically connected (though
the recommended approach is to use EphemBasedPointingRefFrame, which handles this automatically).
*********************************************************************
Terminal error. Sun.inertial is not in tree.
Even though sun.inertial is newly active, the Ephemeris tree has not
been rebuilt, so the frame does not exist in the tree.
*********************************************************************