`FrameTransformations.AXESID_ECL2000`

— Constant`AXESID_ECL2000`

NAIF Axes ID for the Mean Ecliptic Equinox of J2000 (ECL2000).

`FrameTransformations.AXESID_EME2000`

— Constant`AXESID_EME2000`

Axes ID for the Mean Dynamical Equator and Equinox of J2000.0.

In SPICE the J2000 (EME2000) and ICRF axes are considered equal, thus there exist no specific NAIF ID for the EME2000 axes. 22 has been chosen because it is the first unassigned axes ID among the built-in SPICE frames.

`FrameTransformations.AXESID_GCRF`

— Constant`AXESID_GCRF`

Axes ID for the Geocentric Celestial Reference Frame (GCRFF)

Although the ICRF and GCRF axes are identical, they are based upon a different timescale. A different ID is here assigned to provide a robust way of distinguishing between the two. 23 has been chosen because it is one of the unassigned axes ID among the built-in SPICE frames.

`FrameTransformations.AXESID_ICRF`

— Constant`AXESID_ICRF`

NAIF Axes ID for the International Celestial Reference Frame (ICRF)

`FrameTransformations.AXESID_MOONME_DE421`

— Constant`AXESID_MOONME_DE421`

NAIF axes id for the DE421 Moon Mean Earth/Mean Rotation axes (ME421).

`FrameTransformations.AXESID_MOONPA_DE421`

— Constant`AXESID_MOONPA_DE421`

NAIF axes id for the DE421 Moon Principal Axes (PA421).

`FrameTransformations.AXESID_MOONPA_DE440`

— Constant`AXESID_MOONPA_DE440`

NAIF Axes id for the DE440 Moon Principal Axes (PA440).

`FrameTransformations.DCM_ICRF_TO_EME2000`

— Constant`DCM_ICRF_TO_EME2000`

DCM for the rotation from the International Celestial Reference Frame (`ICRF`

) and the Mean Equator and Equinox of J2000.0 (`EME2000`

). This corresponds to the `J2000`

frame in the SPICE toolkit.

The frame bias is here computed using the IAU 2006 Precession model, similarly to ESA's GODOT. Some other software libraries, such as Orekit, use the frame bias of the IAU 2000 precession model. The two definitions differ of about 1 arcsecond.

Moreover, according to Hilton there are multiple possibilities to define the proper rotation between the ICRS and the EME2000. The transformation implemented here correspond to Eq. 6 using the parameters in Table 3, line 1 (RIERS).

**References**

- Hilton, James L., and Catherine Y. Hohenkerk. – Rotation matrix from the mean dynamical equator and equinox at J2000. 0 to the ICRS. – Astronomy & Astrophysics 513.2 (2004): 765-770. DOI: 10.1051/0004-6361:20031552
- SOFA docs

`FrameTransformations.DCM_MOON_PA421_TO_ME421`

— Constant`DCM_MOON_PA421_TO_ME421`

DCM for the rotation from the Moon Principal Axis 421 (PA421) to the Moon Mean Earth/Mean Rotation DE421 (ME421) axes.

**References**

- J. G. Williams et al. (2008),
*DE421 Lunar Orbit, Physical Librations, and Surface Coordinates*, DE421 Lunar Ephemeris and Orientation

`FrameTransformations.DCM_MOON_PA430_TO_ME421`

— Constant`DCM_MOON_PA430_TO_ME421`

DCM for the rotation from the Moon Principal Axis 430 (PA430) to the Moon Mean Earth/Mean Rotation DE421 (ME421) axes.

**References**

Folkner M. William et al. (2014),

*The Planetary and Lunar EphemeridesDE430 and DE431*J. G. Williams et al. (2013),

*DE430 Lunar Orbit, Physical Librations, and Surface Coordinates*, DE430 Lunar Ephemeris and Orientation

`FrameTransformations.DCM_MOON_PA430_TO_ME430`

— Constant`DCM_MOON_PA430_TO_ME430`

DCM for the rotation from the Moon Principal Axis 430 (PA430) to the Moon Mean Earth/Mean Rotation DE430 (ME430) axes.

**References**

Folkner M. William et al. (2014),

*The Planetary and Lunar EphemeridesDE430 and DE431*J. G. Williams et al. (2013),

*DE430 Lunar Orbit, Physical Librations, and Surface Coordinates*, DE430 Lunar Ephemeris and Orientation

`FrameTransformations.DCM_MOON_PA440_TO_ME421`

— Constant`DCM_MOON_PA440_TO_ME421`

DCM for the rotation from the Moon Principal Axis 440 (PA440) to the Moon Mean Earth/Mean Rotation DE421 (ME421) axes.

**References**

- Park, S. R. et al. (2021),
*The JPL Planetary and Lunar Ephemerides DE440 and DE441*, DOI: 10.3847/1538-3881/abd414

`FrameTransformations.Direction`

— Type`Direction{O, N, D}`

Define a new direction.

**Fields**

`name`

– direction name`id`

– direction ID`f`

–`DirectionFunctions`

container

`FrameTransformations.FrameAxesNode`

— Type`FrameAxesNode{O, T, N} <: AbstractJSMDGraphNode`

Define a set of axes.

**Fields**

`name`

– axes name`class`

–`Symbol`

representing the class of the axes`id`

– axes ID (equivalent of NAIFId for axes)`parentid`

– ID of the parent axes`f`

–`FrameAxesFunctions`

container

`FrameTransformations.FramePointNode`

— Type`FramePointNode{O, T, N} <: AbstractJSMDGraphNode`

Define a frame system point.

**Fields**

`name`

– point name`class`

–`Symbol`

representing the class of the point`id`

– ID of the point`parentid`

– ID of the parent point`axesid`

– ID of the axes in which the point coordinates are expressed`f`

–`FramePointFunctions`

container

`FrameTransformations.FrameSystem`

— Type`FrameSystem{O, N, S, D}`

A `FrameSystem`

instance manages a collection of user-defined `FramePointNode`

, `FrameAxesNode`

and `Direction`

objects, enabling computation of arbitrary transformations between them. It is created by specifying the maximum transformation order `O`

, the outputs datatype `N`

and an `AbstractTimeScale`

instance `S`

; the parameter `D`

is the `length`

of the output ad shall always be `3O`

.

The following transformation orders are accepted:

**1**: position**2**: position and velocity**3**: position, velocity and acceleration**4**: position, velocity, acceleration and jerk

`FrameSystem{O, N, S}()`

Create a new, empty `FrameSystem`

object of order `O`

, datatype `N`

and timescale `S`

. The parameter `S`

can be dropped, in case the default (`BarycentricDynamicalTime`

) is used.

`FrameTransformations.Rotation`

— Type`Rotation{O, N}`

A container to efficiently compute `O`

-th order rotation matrices of type `N`

between two set of axes. It stores the Direction Cosine Matrix (DCM) and its time derivatives up to the (`O`

-1)-th order. Since this type is immutable, the data must be provided upon construction and cannot be mutated later.

The rotation of state vector between two set of axes is computed with an ad-hoc overload of the product operator. For example, a 3rd order Rotation object `R`

, constructed from the DCM `A`

and its time derivatives `δA`

and `δ²A`

rotates a vector `v`

= `[p, v, a]`

as:

`̂v = [A*p, δA*p + A*v, δ²A*p + 2δA*v + A*a]`

A `Rotation`

object `R`

call always be converted to a `SMatrix`

or a `MMatrix`

by invoking the proper constructor.

**Examples**

```
julia> A = angle_to_dcm(π/3, :Z)
DCM{Float64}:
0.5 0.866025 0.0
-0.866025 0.5 0.0
0.0 0.0 1.0
julia> R = Rotation(A);
julia> SM = SMatrix(R)
3×3 SMatrix{3, 3, Float64, 9} with indices SOneTo(3)×SOneTo(3):
0.5 0.866025 0.0
-0.866025 0.5 0.0
0.0 0.0 1.0
julia> MM = MMatrix(R)
3×3 MMatrix{3, 3, Float64, 9} with indices SOneTo(3)×SOneTo(3):
0.5 0.866025 0.0
-0.866025 0.5 0.0
0.0 0.0 1.0
```

`Rotation(dcms::DCM...)`

Create a `Rotation`

object from a Direction Cosine Matrix (DCM) and any of its time derivatives. The rotation order is inferred from the number of inputs, while the rotation type is obtained by promoting the DCMs types.

**Examples**

```
julia> A = angle_to_dcm(π/3, :Z);
julia> δA = DCM(0.0I);
julia> δ²A = DCM(0.0I);
julia> R = Rotation(A, δA, δ²A);
julia> typeof(R)
Rotation{3, Float64}
julia> R2 = Rotation(A, B, C, DCM(0.0im*I));
julia> typeof(R2)
Rotation{4, ComplexF64}
```

`Rotation{O}(dcms::DCM...) where O`

Create a `Rotation`

object of order `O`

. If the number of `dcms`

is smaller than `O`

, the remaining slots are filled with null DCMs, otherwise if the number of inputs is greater than `O`

, only the first `O`

DCMs are used.

Usage of this constructor is not recommended as it may yield unexpected results to unexperienced users.

`Rotation{S1}(dcms::NTuple{S2, DCM{N}}) where {S1, S2, N}`

Create a `Rotation`

object from a tuple of Direction Cosine Matrix (DCM) and its time derivatives. If `S1`

< `S2`

, only the first `S1`

DCMs are considered, otherwise the remaining orders are filled with null DCMs.

**Examples**

```
julia> A = angle_to_dcm(π/3, :Z);
julia> B = angle_to_dcm(π/4, π/6, :XY);
julia> R3 = Rotation{3}((A,B));
julia> R3[1] == A
true
julia> R3[3]
DCM{Float64}:
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
```

```
Rotation{O}(u::UniformScaling{N}) where {O, N}
Rotation{O, N}(u::UniformScaling) where {O, N}
```

Create an `O`

-order identity `Rotation`

object of type `N`

with identity position rotation and null time derivatives.

**Examples**

```
julia> Rotation{1}(1.0I)
Rotation{1, Float64}(([1.0 0.0 0.0; 0.0 1.0 0.0; 0.0 0.0 1.0],))
julia> Rotation{1, Int64}(I)
Rotation{1, Int64}(([1 0 0; 0 1 0; 0 0 1],))
```

```
Rotation{S1}(rot::Rotation{S2, N}) where {S1, S2, N}
Rotation{S1, N}(R::Rotation{S2}) where {S1, S2, N}
```

Transform a `Rotation`

object of order `S2`

to order `S1`

and type `N`

. The behaviour of these functions depends on the values of `S1`

and `S2`

:

`S1`

<`S2`

: Only the first`S1`

components of`rot`

are considered.`S1`

>`S2`

: The missing orders are filled with null DCMs.

**Examples**

```
julia> A = angle_to_dcm(π/3, :Z);
julia> B = angle_to_dcm(π/4, π/6, :XY);
julia> R1 = Rotation(A, B);
julia> order(R1)
2
julia> R2 = Rotation{1}(R1);
julia> order(R2)
1
julia> R2[1] == A
true
julia> R3 = Rotation{3}(R1);
julia> R3[3]
DCM{Float64}:
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
```

`Rotation(m::DCM{N}, ω::AbstractVector) where N`

Create a 2nd order `Rotation`

object of type `N`

to rotate between two set of axes `a`

and `b`

from a Direction Cosine Matrix (DCM) and the angular velocity vector `ω`

of `b`

with respect to `a`

, expressed in `b`

`Base.axes`

— Method`axes(f::FrameSystem)`

Return the registered axes names/ids map.

`Base.inv`

— Method`inv(rot::Rotation)`

Compute the invese of the rotation object `rot`

. The operation is efficiently performed by taking the transpose of each rotation matrix within `rot`

.

`FrameTransformations.add_axes!`

— Method`add_axes!(frames, name::Symbol, id::Int, class::Int, funs, parentid)`

Add a new axes node to `frames`

.

**Inputs**

`frames`

– Target frame system`name`

– Axes name, must be unique within`frames`

`id`

– Axes ID, must be unique within`frames`

`class`

– Axes class.`funs`

–`FrameAxesFunctions`

object storing the functions to compute the DCM and, eventually, its time derivatives. It must match the type and order of`frames`

.`parentid`

– Axes ID of the parent axes. Not required only for the root axes.

This is a low-level function and is NOT meant to be directly used. Instead, to add a set of axes to the frame system, see `add_axes_inertial!`

, `add_axes_rotating!`

, `add_axes_fixedoffset!`

and `add_axes_root!`

.

`FrameTransformations.add_axes_alias!`

— Method`add_axes_alias!(frames, target, alias::Symbol)`

Add a name `alias`

to a `target`

axes registered in `frames`

.

`FrameTransformations.add_axes_bci2000!`

— Method`add_axes_bci2000!(frames, axes::AbstractFrameAxes, center, data)`

Add Body-Centered Inertial (BCI) axes at J2000 with `name`

and `id`

to `frames`

. The center point (i.e., the reference body) is `center`

.

The parent axes are automatically set to the ICRF (ID = 1). If the ICRF is not defined in `frames`

, an error is thrown.

**See also**

See also `add_axes_fixedoffset!`

, `add_axes_bcrtod!`

.

`FrameTransformations.add_axes_bcrtod!`

— Method`add_axes_bcrtod!(frames, name, id, center; deriv=true)`

Add Body-Centered Rotating (BCR), True-of-Date (TOD) axes with `name`

and `id`

to `frames`

. The center point (i.e., the reference body) is `center`

.

These axes are the equivalent of SPICE's `IAU_<BODY_NAME>`

frames.

The parent axes are automatically set to the ICRF (ID = 1). If the ICRF is not defined in `frames`

, an error is thrown.

**See also**

See also `add_axes_rotating!`

, `add_axes_bci2000!`

.

`FrameTransformations.add_axes_cirf!`

— Function```
add_axes_cirf!(frames::FrameSystem, name::Symbol, id::Int, parentid::Int=AXESID_ICRF,
model::IERSModel=iers2010b)
```

Add Celestial Intermediate Reference Frame (CIRF) axes to `frames`

. Use the `model`

argument to specify which IERS convention should be used for the computations.

Despite this class of axes has a rotation matrix that depends on time, its derivatives are assumed null.

The ID of the `parent`

set of axes must be 1 (ICRF) or 23 (GCRF) otherwise an error is thrown.

`FrameTransformations.add_axes_ecl2000!`

— Function```
add_axes_ecl2000!(frames, name::Symbol=:ECL2000, parentid::Int, id::Int = AXESID_ECL2000;
model::IERSModel=iers1996)
```

Add Ecliptic Equinox of J2000 (ECL2000) axes to `frames`

. Custom `id`

, `name`

and `parentid`

can be assigned by the user. The admissible parent axes are the following:

*ICRF*: for the International Celestial Reference Frame, with ID = 1*GCRF*: for the Geocentric Celestial Reference Frame, with ID = 23*EME2000*: the Mean Earth/Moon Ephemeris of J2000, with ID = 22

The obliquity of the ecliptic is computed using the IERS convention `model`

. To retrieve the same orientation of the ECLIPJ2000 axes avaialble in the SPICE Toolkit, the `iers1996`

model must be used.

`FrameTransformations.add_axes_eme2000!`

— Function```
add_axes_eme2000!(frames, name::Symbol=:EME2000, parentid::Int=AXESID_ICRF,
id::Int = AXESID_EME2000)
```

Add Mean Equator Mean Equinox of J2000 axes to `frames`

. Custom `name`

, `id`

and `parentid`

can be assigned by the user.

**See also**

See also `DCM_ICRF_TO_EME2000`

.

`FrameTransformations.add_axes_ephemeris!`

— Method```
add_axes_ephemeris!(frames::FrameSystem{O, N}, eph::AbstractEphemerisProvider,
name::Symbol, id::Int, seq::Symbol, class::Int) where {O, N}
```

Add axes coming from an `AbstractEphemerisProvider`

subtype to `frames`

. The axes are identifies by the `id`

and a have a user defined `name`

. The rotation matrix is build using the rotation sequence specified in `seq`

. The axes type is specified by `class`

.

This is an interface only, concrete subtypes of `AbstractEphemerisProvider`

requires an proper implementation.

`FrameTransformations.add_axes_fixedoffset!`

— Method`add_axes_fixedoffset!(frames, name::Symbol, id::Int, parent, dcm:DCM)`

Add axes `name`

with id `id`

to `frames`

with a fixed-offset from `parent`

. Fixed offset axes have a constant orientation with respect to their `parent`

axes, represented by `dcm`

, a Direction Cosine Matrix (DCM).

**See also**

See also `add_axes!`

.

`FrameTransformations.add_axes_frozen!`

— Method`add_axes_frozen!(frames, name, id, frozen, e)`

Create a frozen axes version of `frozen`

at epoch `e`

, with `name`

and `id`

and add it to `frames`

.

The parent axes are automatically assigned to the `frozen`

parent.

`FrameTransformations.add_axes_gcrf!`

— Method`add_axes_gcrf!(frames::FrameSystem)`

Add the Geocentric Celestial Reference Frame (GCRF) to the frames graph. The axes are automatically named `GCRF`

and assigned the 23 ID. These axes can only be defined as a set of root axes or as child of the ICRF (ID = 1).

**See also**

See also `add_axes_icrf!`

and `AXESID_GCRF`

.

`FrameTransformations.add_axes_gtod!`

— Function```
add_axes_gtod!(frames::FrameSystem, name::Symbol, id::Int, parentid::Int=AXESID_ICRF,
model::IERSModel=iers2010b)
```

Add Greenwich True-of-Date (GTOD) axes to `frames`

. Use the `model`

argument to specify which IERS convention should be used for the computations.

Despite this class of axes has a rotation matrix that depends on time, its derivatives are assumed null.

The ID of the `parent`

set of axes must be 1 (ICRF) or 23 (GCRF) otherwise an error is thrown.

`FrameTransformations.add_axes_icrf!`

— Method`add_axes_icrf!(frames::FrameSystem)`

Add the International Celestial Reference Frame (ICRF) as the root axes of the frames graph. The axes are automatically named `ICRF`

and assigned the 1 ID.

**See also**

See also `add_axes_root!`

, `add_axes_gcrf!`

and `AXESID_ICRF`

.

`FrameTransformations.add_axes_inertial!`

— Method`add_axes_inertial!(frames, name, id, parent, fun)`

Add inertial axes `name`

and id `id`

as a set of inertial axes to `frames`

. The axes relation to the `parent`

axes are given by a `fun`

.

**See also**

See also `add_axes!`

.

`FrameTransformations.add_axes_itrf!`

— Function```
add_axes_itrf!(frames::FrameSystem, name::Symbol, parentid::Int=AXESID_ICRF, id::Int=AXESID_ITRF,
model::IERSModel=iers2010b)
```

Add International Terrestrial Reference Frame (ITRF) axes to `frames`

. Use the `model`

argument to specify which IERS convention should be used for the computations.

If the ID of the parent set of `axes`

is neither the ICRF (ID = 1) nor the GCRF (ID = 23), an error is thrown.

`FrameTransformations.add_axes_me421!`

— Function`add_axes_me421!(frames, name::Symbol, parentid::Int, axesid::Int=AXESID_MOONME_DE421)`

Add DE421 Moon's Mean Earth/Mean Rotation (ME) axes to `frames`

.

The `parent`

set of axes must either the DE440 Principal Axes (PA440, ID =

- or the DE421 Principal Axes (PA421, ID =

31006), otherwise an error is thrown. Depending on that, the relative axes orientation will be automatically selected by this function.

`FrameTransformations.add_axes_mod!`

— Function```
add_axes_mod!(frames, name::Symbol, axesid::Int, parentid::Int,
model::IERSConventions.IERSModel=iers2010b)
```

Add Mean Equator and Equinox of Date (MOD) axes to `frames`

. Use the `model`

argument to specify which IERS convention should be used for the computations.

The Mean-of-Date axes are obtained by applying the frame bias and precession matrix. For this reason, if the IERS 1996 conventions are used, the rotation is actually computed starting from the EME2000 rather than the GCRF.

Despite this class of axes has a rotation matrix that depends on time, its derivatives are assumed null.

The ID of the `parent`

set of axes must be 1 (ICRF) or 23 (GCRF) otherwise an error is thrown.

`FrameTransformations.add_axes_pa421!`

— Function```
add_axes_pa421!(frames, eph::AbstractEphemerisProvider, name::Symbol,
id::Int=AXESID_MOONPA_DE421)
```

Add DE421 Moon's Principal Axes (PA) axes to `frames`

. The libration angles are extracted from the `eph`

ephemeris kernels, an error is thrown if such orientation data is not available.

The parent axes are automatically set to the ICRF (ID = 1). If such axes are not registered in the frame system, an error is thrown.

To properly read the ephemeris kernels, the ID associated to the input `axes`

must match NAIF's FRAME ID for the Moon PA DE421 axes (31006).

`FrameTransformations.add_axes_pa440!`

— Function```
add_axes_pa440!(frames, eph::AbstractEphemerisProvider, name::Symbol,
id::Int=AXESID_MOONPA_DE440)
```

Add DE440 Moon's Principal Axes (PA) axes to `frames`

. The libration angles are extracted from the `eph`

ephemeris kernels, an error is thrown if such orientation data is not available.

The parent axes are automatically set to the ICRF (ID = 1). If such axes are not registered in the frame system, an error is thrown.

To properly read the ephemeris kernels, the ID associated to the input `axes`

must match NAIF's FRAME ID for the Moon PA DE440 axes (31008).

`FrameTransformations.add_axes_pef!`

— Function```
add_axes_pef!(frames::FrameSystem, name::Symbol, id::Int, parentid::Int=AXESID_ICRF,
model::IERSModel=iers2010b)
```

Add Pseudo-Earth Fixed (PEF) axes to `frames`

. Use the `model`

argument to specify which IERS convention should be used for the computations.

The ID of the `parent`

set of axes must be 1 (ICRF) or 23 (GCRF) otherwise an error is thrown.

`FrameTransformations.add_axes_root!`

— Method`add_axes_root!(frames, name::Symbol, id::Int)`

Create root axes in `frames`

.

`FrameTransformations.add_axes_rotating!`

— Method```
add_axes_rotating!(frames, name::Symbol, id::Int, parent, fun, δfun=nothing,
δ²fun=nothing, δ³fun=nothing)
```

Add `axes`

as a set of rotating axes to `frames`

. The orientation of these axes depends only on time and is computed through the custom functions provided by the user.

The input functions must accept only time as argument and their outputs must be as follows:

`fun`

: return a Direction Cosine Matrix (DCM).`δfun`

: return the DCM and its 1st order time derivative.`δ²fun`

: return the DCM and its 1st and 2nd order time derivatives.`δ³fun`

: return the DCM and its 1st, 2nd and 3rd order time derivatives.

If `δfun`

, `δ²fun`

or `δ³fun`

are not provided, they are computed via automatic differentiation.

It is expected that the input functions and their outputs have the correct signature. This function does not perform any checks on the output types.

`FrameTransformations.add_axes_tirf!`

— Function```
add_axes_tirf!(frames::FrameSystem, name::Symbol, id::Int, parentid::Int=AXESID_ICRF,
model::IERSModel=iers2010b)
```

Add Terrestrial Intermediate Reference Frame (TIRF) axes to `frames`

. Use the `model`

argument to specify which IERS convention should be used for the computations.

The ID of the `parent`

set of axes must be 1 (ICRF) or 23 (GCRF) otherwise an error is thrown.

`FrameTransformations.add_axes_tod!`

— Function```
add_axes_tod!(frames::FrameSystem, name::Symbol, id::Int, parentid::Int=AXESID_ICRF,
model::IERSModel=iers2010b)
```

Add True Equator of Date (TOD) axes to `frames`

. Use the `model`

argument to specify which IERS convention should be used for the computations.

The True-of-Date axes are obtained by applying the frame bias, precession and nutation matrix. For this reason, if the IERS 1996 conventions are used, the rotation is actually computed starting from the EME2000 rather than the GCRF.

The ID of the `parent`

set of axes must be 1 (ICRF) or 23 (GCRF) otherwise an error is thrown.

`FrameTransformations.add_axes_topocentric!`

— Method`add_axes_topocentric!(frames, name::Symbol, id::Int, parentid::Int, λ, ϕ, mount)`

Add topocentric axes to `frames`

at a specified location and mounting.

The orientation relative to the parent axes `parentid`

is defined throuh the longitude `λ`

, the geodetic latitude `ϕ`

and the mounting type `mount`

, which may be any of the following:

`:NED`

(North, East, Down): the X-axis points North, the Y-axis is directed eastward and the Z-axis points inwards towards the nadir.`:SEZ`

(South, East, Zenith): the X-axis points South, the Y-axis is directed East, and the Z-axis points outwards towards the zenith.`:ENU`

(East, North, Up): the X-axis points East, the Y-axis is directed North and the Z-axis points outwards towards the zenith.

The parent axes must be a set of body-fixed reference axes. This is under user resposibility.

`FrameTransformations.add_axes_twovectors!`

— Method```
add_axes_twovectors!(frames, name::Symbol, id::Int, parentid::Int,
from1::Int, to1::Int, from2::Int, to2::Int, seq::Symbol;
inertial::Bool=false)
```

Add a set of axes to `frames`

based on two vectors defined by four points.

This function adds a new set of axes to `frames`

using two vectors defined by four points. The vectors are constructed from the points specified by `from1`

to `to1`

and `from2`

to `to2`

. A right-handed coordinate system is generated based on the specified sequence direction (`seq`

), which determines the order in which the vectors are used to define the basis. The `inertial`

flag specifies whether the resulting axes are inertial.

`FrameTransformations.add_direction!`

— Method`add_direction!(frames, name::Symbol, axes, fun, δfun=nothing, δ²fun=nothing, δ³fun=nothing)`

Add a new direction node to `frames`

. The orientation of these direction depends only on time and is computed through the custom functions provided by the user.

The input functions must accept only time as argument and their outputs must be as follows:

`fun`

: return a direction vector.`δfun`

: return a direction vector and its 1st order time derivative.`δ²fun`

: return a direction vector and its 1st and 2nd order time derivatives.`δ³fun`

: return a direction vector and its 1st, 2nd and 3rd order time derivatives.

If `δfun`

, `δ²fun`

or `δ³fun`

are not provided, they are computed via automatic differentiation.

It is expected that the input functions and their outputs have the correct signature. This function does not perform any checks on the output types.

`FrameTransformations.add_direction!`

— Method`add_direction!(frames, name::Symbol, axesid, funs)`

Add a new direction node to `frames`

.

**Inputs**

`frames`

– Target frame system`name`

– Direction name, must be unique within`frames`

`axesid`

– ID of the axes the direction is expressed in`funs`

–`DirectionFunctions`

object storing the functions to compute the direction and, eventually, its time derivatives. It must match the type and order of`frames`

.

`FrameTransformations.add_direction_fixed!`

— Method`add_direction_fixed!(frames, name, axes, offset::AbstractVector)`

Add a fixed direction to `frames`

.

`FrameTransformations.add_direction_normalize!`

— Method`add_direction_normalize!(frames, name::Symbol, dir)`

Add a direction as the normalized version of `dir`

.

`FrameTransformations.add_direction_orthogonal!`

— Method`add_direction_orthogonal!(frames, name::Symbol, dir1, dir2)`

Add a direction as the cross product between two existing directions (i.e. `dir1`

and `dir2`

).

`FrameTransformations.add_direction_position!`

— Method`add_direction_position!(frames, name::Symbol, origin, target, axes)`

Add a direction based on the position vector from `origin`

to `target`

in the specified `axes`

.

`FrameTransformations.add_direction_velocity!`

— Method`add_direction_velocity!(frames, name::Symbol, origin, target, axes)`

Add a direction based on the velocity vector from `origin`

to `target`

in the specified `axes`

.

`FrameTransformations.add_point!`

— Method`add_point!(frames, name, id, axesid, class, funs, parentid=nothing)`

Create and add a new point node `name`

to `frames`

based on the input parameters.

**Inputs**

`frames`

– Target frame system`name`

– Point name, must be unique within`frames`

`id`

– Point ID, must be unique within`frames`

`axesid`

– ID of the axes in which the state vector of the point is expressed.`class`

– Point class.`funs`

–`FramePointFunctions`

object storing the functions to update the state vectors of the point. It must match the type and order of`frames`

`parentid`

– NAIF ID of the parent point. Not required only for the root point.

This is a low-level function and is NOT meant to be directly used. Instead, to add a point to the frame system, see `add_point_dynamical!`

, `add_point_fixedoffset!`

and `add_point_root!`

.

`FrameTransformations.add_point_alias!`

— Method```
add_point_alias!(frames, target, alias::Symbol)
add_point_alias!(frames, target, alias::Symbol)
```

Add a name `alias`

to a `target`

point registered in `frames`

.

`FrameTransformations.add_point_dynamical!`

— Method`add_point_dynamical!(frames, name, id, parent, axes, fun, δfun=nothing, δ²fun=nothing, δ³fun=nothing)`

Add `point`

as a time point to `frames`

. The state vector for these points depends only on time and is computed through the custom functions provided by the user.

The input functions must accept only time as argument and their outputs must be as follows:

**fun**: return a 3-elements vector: position**δfun**: return a 6-elements vector: position and velocity**δ²fun**: return a 9-elements vector: position, velocity and acceleration**δ³fun**: return a 12-elements vector: position, velocity, acceleration and jerk

If `δfun`

, `δ²fun`

or `δ³fun`

are not provided, they are computed with automatic differentiation.

It is expected that the input functions and their ouputs have the correct signature. This function does not perform any checks on whether the returned vectors have the appropriate dimensions.

`FrameTransformations.add_point_ephemeris!`

— Method`add_point_ephemeris!(frames, eph::AbstractEphemerisProvider, book::Dict{Int, Symbol})`

Add all points found in the `eph`

and using id-names relationships specified in `book`

.

`FrameTransformations.add_point_ephemeris!`

— Method```
add_point_ephemeris!(frames::FrameSystem{O, N}, eph::AbstractEphemerisProvider,
name::Symbol, id::Int) where {O, N}
```

Add a point coming from an `AbstractEphemerisProvider`

subtype. The point is identifies by the `id`

and a have a user defined `name`

.

This is an interface only, concrete subtypes of `AbstractEphemerisProvider`

requires an proper implementation.

`FrameTransformations.add_point_fixedoffset!`

— Method`add_point_fixedoffset!(frames, name, id, parent, axes, offset::AbstractVector)`

Add `point`

as a fixed-offset point to `frames`

. Fixed points are those whose positions have a constant `offset`

with respect their `parent`

points in the given set of `axes`

. Thus, points eligible for this class must have null velocity and acceleration with respect to `parent`

.

`FrameTransformations.add_point_root!`

— Method`add_point_root!(frames, name, id, axes)`

Add root `name`

root point with the specified `id`

to `frames`

.

`FrameTransformations.add_point_surface!`

— Function```
add_point_surface!(frames, name::Symbol, pointid::Int, parentid::Int, axesid::Int,
λ::Number, ϕ::Number, R::Number, f::Number=0.0, h::Number=0.0)
```

Add `point`

to `frames`

as a fixed point on the surface of the `parent`

point body. The relative position is specified by the longitude `λ`

, the geodetic latitude `ϕ`

, the reference radius of the ellipsoid `R`

and its flattening `f`

. The altitude over the reference surface of the ellipsoid `h`

defaults to 0.

Axes used here must be a set of body-fixed reference axes for the body represented by `parentid`

. This is under user resposibility.

`FrameTransformations.axes_graph`

— Method`axes_graph(frames::FrameSystem)`

Return the frame system axes graph.

`FrameTransformations.axes_id`

— Method`axes_id(f::FrameSystem, id)`

Get the `id`

associate to an axes.

`FrameTransformations.direction12`

— Method`direction12(frames::FrameSystem, name::Symbol, axes, t::Number)`

Compute the direction vector `name`

of order 12 at epoch `t`

, where `t`

is expressed in seconds since `J2000`

.

Requires a frame system of order ≥ 4.

`FrameTransformations.direction12`

— Method`direction12(frames::FrameSystem, name::Symbol, axes, ep::Epoch)`

Compute the direction vector `name`

of order 12 at epoch `ep`

expressed in the `axes`

frame.

Requires a frame system of order ≥ 4.

`FrameTransformations.direction3`

— Method`direction3(frames::FrameSystem, name::Symbol, axes, t::Number)`

Compute the direction vector `name`

of order 3 at epoch `t`

, where `t`

is expressed in seconds since `J2000`

.

Requires a frame system of order ≥ 1.

`FrameTransformations.direction3`

— Method`direction3(frames::FrameSystem, name::Symbol, axes, ep::Epoch)`

Compute the direction vector `name`

of order 3 at epoch `ep`

expressed in the `axes`

frame.

Requires a frame system of order ≥ 1.

`FrameTransformations.direction6`

— Method`direction6(frames::FrameSystem, name::Symbol, axes, t::Number)`

Compute the direction vector `name`

of order 6 at epoch `t`

, where `t`

is expressed in seconds since `J2000`

.

Requires a frame system of order ≥ 2.

`FrameTransformations.direction6`

— Method`direction6(frames::FrameSystem, name::Symbol, axes, ep::Epoch)`

Compute the direction vector `name`

of order 6 at epoch `ep`

expressed in the `axes`

frame.

Requires a frame system of order ≥ 2.

`FrameTransformations.direction9`

— Method`direction9(frames::FrameSystem, name::Symbol, axes, t::Number)`

Compute the direction vector `name`

of order 9 at epoch `t`

, where `t`

is expressed in seconds since `J2000`

.

Requires a frame system of order ≥ 3.

`FrameTransformations.direction9`

— Method`direction9(frames::FrameSystem, name::Symbol, axes, ep::Epoch)`

Compute the direction vector `name`

of order 9 at epoch `ep`

expressed in the `axes`

frame.

Requires a frame system of order ≥ 3.

`FrameTransformations.directions`

— Method`directions(f::FrameSystem)`

Return the registered directions names.

`FrameTransformations.directions_map`

— Method`directions_map(f::FrameSystem)`

Return the direction dictionary.

`FrameTransformations.has_axes`

— Method`has_axes(frames::FrameSystem, ax)`

Check if `ax`

axes is within `frames`

.

`FrameTransformations.has_direction`

— Method`has_axes(frames::FrameSystem, name::Symbol)`

Check if `name`

direction is within `frames`

.

`FrameTransformations.has_point`

— Method`has_point(frames::FrameSystem, id)`

Check if `id`

point is within `frames`

.

`FrameTransformations.order`

— Method`order(frames::FrameSystem{O}) where O`

Return the frame system order `O`

.

`FrameTransformations.order`

— Method`order(R::Rotation{O}) where O`

Return the rotation order O.

`FrameTransformations.point_id`

— Method`point_id(f::FrameSystem, id)`

Get the `id`

associate to a point.

`FrameTransformations.points`

— Method`points(f::FrameSystem)`

Return the registered points names/ids map.

`FrameTransformations.points_graph`

— Method`points_graph(frames::FrameSystem)`

Return the frame system points graph.

`FrameTransformations.rotation12`

— Method`rotation12(frame::FrameSystem, from, to, ep::Epoch)`

Compute the rotation that transforms a 12-elements state vector from one specified set of axes to another at a given epoch.

Requires a frame system of order ≥ 4.

**Inputs**

`frame`

– The`FrameSystem`

container object`from`

– ID or instance of the axes to transform from`to`

– ID or instance of the axes to transform to`ep`

–`Epoch`

of the rotation. Its timescale must match that of the frame system.

**Output**

A `Rotation`

object of order 4.

`FrameTransformations.rotation12`

— Method`rotation12(frame::FrameSystem, from, to, t::Number)`

Compute the rotation that transforms a 12-elements state vector from one specified set of axes to another at a given time `t`

, expressed in seconds since `J2000`

.

`FrameTransformations.rotation3`

— Method`rotation3(frame::FrameSystem, from, to, ep::Epoch)`

Compute the rotation that transforms a 3-elements state vector from one specified set of axes to another at a given epoch.

Requires a frame system of order ≥ 1.

**Inputs**

`frame`

– The`FrameSystem`

container object`from`

– ID or instance of the axes to transform from`to`

– ID or instance of the axes to transform to`ep`

–`Epoch`

of the rotation. Its timescale must match that of the frame system.

**Output**

A `Rotation`

object of order 1.

`FrameTransformations.rotation3`

— Method`rotation3(frame::FrameSystem, from, to, t::Number)`

Compute the rotation that transforms a 3-elements state vector from one specified set of axes to another at a given time `t`

, expressed in seconds since `J2000`

.

`FrameTransformations.rotation6`

— Method`rotation6(frame::FrameSystem, from, to, ep::Epoch)`

Compute the rotation that transforms a 6-elements state vector from one specified set of axes to another at a given epoch.

Requires a frame system of order ≥ 2.

**Inputs**

`frame`

– The`FrameSystem`

container object`from`

– ID or instance of the axes to transform from`to`

– ID or instance of the axes to transform to`ep`

–`Epoch`

of the rotation. Its timescale must match that of the frame system.

**Output**

A `Rotation`

object of order 2.

`FrameTransformations.rotation6`

— Method`rotation6(frame::FrameSystem, from, to, t::Number)`

Compute the rotation that transforms a 6-elements state vector from one specified set of axes to another at a given time `t`

, expressed in seconds since `J2000`

.

`FrameTransformations.rotation9`

— Method`rotation9(frame::FrameSystem, from, to, ep::Epoch)`

Compute the rotation that transforms a 9-elements state vector from one specified set of axes to another at a given epoch.

Requires a frame system of order ≥ 3.

**Inputs**

`frame`

– The`FrameSystem`

container object`from`

– ID or instance of the axes to transform from`to`

– ID or instance of the axes to transform to`ep`

–`Epoch`

of the rotation. Its timescale must match that of the frame system.

**Output**

A `Rotation`

object of order 3.

`FrameTransformations.rotation9`

— Method`rotation9(frame::FrameSystem, from, to, t::Number)`

Compute the rotation that transforms a 9-elements state vector from one specified set of axes to another at a given time `t`

, expressed in seconds since `J2000`

.

`FrameTransformations.timescale`

— Method`timescale(frames::FrameSystem{O, N, S}) where {O, N, S}`

Return the frame system order timescale `S`

.

`FrameTransformations.vector12`

— Method`vector12(frame, from, to, axes, t::Number)`

Compute 12-elements state vector of a target point relative to an observing point, in a given set of axes, at the desired time `t`

expressed in seconds since `J2000`

.

`FrameTransformations.vector12`

— Method`vector12(frame::FrameSystem, from, to, axes, ep::Epoch)`

Compute 12-elements state vector of a target point relative to an observing point, in a given set of axes, at the desired epoch `ep`

.

Requires a frame system of order ≥ 4.

**Inputs**

`frame`

– The`FrameSystem`

container object`from`

– ID or instance of the observing point`to`

– ID or instance of the target point`axes`

– ID or instance of the output state vector axes`ep`

–`Epoch`

of the observer. Its timescale must match that of the frame system.

`FrameTransformations.vector3`

— Method`vector3(frame, from, to, axes, t::Number)`

Compute 3-elements state vector of a target point relative to an observing point, in a given set of axes, at the desired time `t`

expressed in seconds since `J2000`

.

`FrameTransformations.vector3`

— Method`vector3(frame::FrameSystem, from, to, axes, ep::Epoch)`

Compute 3-elements state vector of a target point relative to an observing point, in a given set of axes, at the desired epoch `ep`

.

Requires a frame system of order ≥ 1.

**Inputs**

`frame`

– The`FrameSystem`

container object`from`

– ID or instance of the observing point`to`

– ID or instance of the target point`axes`

– ID or instance of the output state vector axes`ep`

–`Epoch`

of the observer. Its timescale must match that of the frame system.

`FrameTransformations.vector6`

— Method`vector6(frame, from, to, axes, t::Number)`

Compute 6-elements state vector of a target point relative to an observing point, in a given set of axes, at the desired time `t`

expressed in seconds since `J2000`

.

`FrameTransformations.vector6`

— Method`vector6(frame::FrameSystem, from, to, axes, ep::Epoch)`

Compute 6-elements state vector of a target point relative to an observing point, in a given set of axes, at the desired epoch `ep`

.

Requires a frame system of order ≥ 2.

**Inputs**

`frame`

– The`FrameSystem`

container object`from`

– ID or instance of the observing point`to`

– ID or instance of the target point`axes`

– ID or instance of the output state vector axes`ep`

–`Epoch`

of the observer. Its timescale must match that of the frame system.

`FrameTransformations.vector9`

— Method`vector9(frame, from, to, axes, t::Number)`

Compute 9-elements state vector of a target point relative to an observing point, in a given set of axes, at the desired time `t`

expressed in seconds since `J2000`

.

`FrameTransformations.vector9`

— Method`vector9(frame::FrameSystem, from, to, axes, ep::Epoch)`

Compute 9-elements state vector of a target point relative to an observing point, in a given set of axes, at the desired epoch `ep`

.

Requires a frame system of order ≥ 3.

**Inputs**

`frame`

– The`FrameSystem`

container object`from`

– ID or instance of the observing point`to`

– ID or instance of the target point`axes`

– ID or instance of the output state vector axes`ep`

–`Epoch`

of the observer. Its timescale must match that of the frame system.