FourierAcceleration#
- class FourierAcceleration(origin: Body, spacecraft: Spacecraft, base_frame: Frame, degree: int = 0, frame: str = 'inertial', angle: str = 'time', period: float | None = None, t0: EpochArray | float | None = None, body_fixed_frame=None, relative_body=None, coefficients: ndarray | None = None)#
Bases:
DynamicModelModels an empirical acceleration as a truncated Fourier series.
Each axis of a chosen frame carries its own series in a phase angle \(\theta\),
\[a_j(\theta) = A_{j,0} + \sum_{k=1}^{N} \left[ A_{j,k}\cos(k\theta) + B_{j,k}\sin(k\theta) \right], \qquad j \in \{1, 2, 3\}\]and the resulting frame-local vector is rotated into the propagation frame,
\[\mathbf a_F = \mathbf T \, \mathbf a^{(f)} = \mathbf T \, \mathbf M(\theta) \, \mathbf p .\]Degree \(N = 0\) leaves only the constant terms, so the model degenerates to a constant empirical acceleration in the chosen frame — the usual “constant along-track acceleration” is
degree=0,frame="RTN".Because the acceleration is linear in the coefficients, the partial that the filter needs is the design matrix itself,
\[\frac{\partial \mathbf a_F}{\partial \mathbf p} = \mathbf T \, \mathbf M(\theta),\]which is exact rather than a difference approximation.
- Parameters:
- originBody
Propagation origin.
- spacecraftSpacecraft
Spacecraft the empirical acceleration acts on.
- base_frameFrame
Reference frame of the propagator.
- degreeint, optional
Highest harmonic \(N\) retained.
0(the default) gives a constant acceleration.- framestr, optional
"inertial","body_fixed", or"RTN". Defaults to"inertial".- anglestr, optional
"time","argument_of_latitude", or"solar_longitude". Defaults to"time". Ignored whendegree == 0, which has no phase dependence.- periodfloat, optional
Repeat period of the series in seconds, for
angle="time". Required whendegree >= 1and the phase is time-based.- t0EpochArray or float, optional
Epoch of zero phase for
angle="time", in ephemeris seconds (TDB) or as anEpochArray. In aMissionSequencethis must be the same epoch for every leg, since the legs share one coefficient state and a moving origin would give the phase a different meaning in each of them.- body_fixed_framestr or Frame, optional
Frame the coefficients are expressed in, for
frame="body_fixed".- relative_bodystr or Body, optional
Body the orbit is described about, when that is not the propagation origin — a lunar RTN frame while propagating an Earth-centred arc, say. Governs the RTN triad and the orbital phase angles together: they describe the same orbit, so anchoring them to different bodies would give a frame and a phase that disagree. Defaults to the propagation origin.
- coefficientsnp.ndarray, optional
Default coefficient vector, used when the propagated state carries no
a_fourierentry. This is what makes the model usable as a plain force model — a known constant or periodic acceleration applied without estimating anything.
- Attributes:
anglePhase angle driving the series.
body_fixed_frameBody-fixed frame the coefficients are expressed in, if any.
default_coefficientsCoefficients applied when the state carries no
a_fourierentry.degreeHighest harmonic retained;
0is a constant acceleration.depends_on_velocityWhether the acceleration is a function of velocity.
frameFrame the coefficients are expressed in.
n_coefficientsLength of the stacked
a_fourierstate,3 * (2 * degree + 1).n_termsNumber of terms per axis,
2 * degree + 1.originCelestial body serving as origin of the state vector.
origin_nameName of the origin body.
periodRepeat period of a time-based phase, in seconds.
ref_frameReference frame used by the model.
relative_bodyBody the RTN triad and the orbital phase are referred to, if any.
t0Epoch of zero phase for a time-based series, in ephemeris seconds.
Methods
Names of the stacked coefficients, in state order.
compute_acceleration(position, ...)Empirical Fourier acceleration applied to the body.
See also
scarabaeus.FirstOrderGaussMarkovStochastic empirical acceleration.
scarabaeus.PiecewiseFirstOrderGaussMarkovBatch-segmented stochastic variant.
scarabaeus.StateArrayState vector used to initialize the model.
scarabaeus.DynamicModelAbstract base class for all force model components.
Notes
The
frameargument selects the triad the coefficients are expressed in:"inertial"Coefficients are expressed directly in the propagation frame, \(\mathbf T = \mathbf I\).
"body_fixed"Coefficients are expressed in a rotating body-fixed frame and rotated out through SPICE, \(\mathbf T = \mathbf R_{bf\to rf}(t)\). Use this for an acceleration tied to the central body’s geography or illumination, such as an outgassing jet on a rotating comet.
"RTN"Coefficients are expressed in the spacecraft’s local orbital triad (radial / along-track / cross-track, also called RSW or RIC),
\[\hat{\mathbf R} = \frac{\mathbf r}{r}, \quad \hat{\mathbf N} = \frac{\mathbf r \times \mathbf v} {\|\mathbf r \times \mathbf v\|}, \quad \hat{\mathbf T} = \hat{\mathbf N} \times \hat{\mathbf R},\]with \(\mathbf T = [\hat{\mathbf R}\;\hat{\mathbf T}\; \hat{\mathbf N}]\). This triad depends on the state, so it contributes to \(\partial \mathbf a / \partial \mathbf r\) and \(\partial \mathbf a / \partial \mathbf v\).
The
angleargument selects the phase \(\theta\):"time"\(\theta = 2\pi (t - t_0) / T\), with
periodthe repeat time \(T\) in seconds. Independent of the state, so it adds nothing to the position and velocity partials. Required only whendegree >= 1."argument_of_latitude"\(\theta = u\), the angle from the ascending node to the spacecraft measured in the orbit plane. The natural variable for a per-revolution empirical acceleration. Undefined for an exactly equatorial orbit, where the node direction vanishes.
"solar_longitude"\(\theta = \lambda_s\), the longitude of the Sun in the coefficient frame. This is the phase McMahon and Scheeres expand solar radiation pressure in [3]: in a body-fixed frame it is exactly their \(\lambda_s\), whose frequency is the body’s rotation relative to the Sun; in RTN it is the Sun-relative in-plane angle the CODE/Bern GPS model writes as \(u - u_0\). Nothing is supplied by the caller — the geometry sets the frequency. Undefined when the Sun lies along the frame’s third axis.
The difference between the last two is where the phase is measured from. A constant offset is absorbed by the coefficients, so over a short arc the two are equivalent; the Sun’s direction drifts by about a degree a day, though, so on a long arc only
"solar_longitude"keeps a Sun-driven effect at a fixed phase.A series in true anomaly \(\nu\) is deliberately not offered: since \(u = \nu + \omega\), a Fourier series in \(u\) spans exactly the same function space for a fixed argument of periapsis, and \(u\) stays well defined on the near-circular orbits where empirical accelerations are most often used, whereas \(\nu\) does not.
The estimated state is one stacked
("a_fourier", spice_id)entry of length \(3(2N+1)\), ordered axis-major and, within an axis, by harmonic:[ A_1,0 A_1,1 B_1,1 ... A_1,N B_1,N | <- first frame axis A_2,0 A_2,1 B_2,1 ... A_2,N B_2,N | <- second frame axis A_3,0 A_3,1 B_3,1 ... A_3,N B_3,N ] <- third frame axis
so
degree=0is simply[a_1, a_2, a_3].coefficient_labels()returns the matching names.The state vector must contain an entry of the form
('a_fourier', 3*(2*degree+1), 'estimated', 'static', owner, value)
for the coefficients to be estimated. The coefficients are constants of the dynamics, so they are declared
'static': unlike the Gauss-Markov models, nothing about them is integrated.References
[1]Montenbruck, O., & Gill, E. (2000). Satellite Orbits, Sec. 3.7 (empirical accelerations in the radial / along-track / cross-track frame).
[2]Tapley, B. D., Schutz, B. E., & Born, G. H. (2004). Statistical Orbit Determination, Ch. 4 (estimating dynamic model parameters).
[3]McMahon, J. W., & Scheeres, D. J. (2010). New Solar Radiation Pressure Force Model for Navigation. Journal of Guidance, Control, and Dynamics, 33(5). See also McMahon (2011), PhD thesis, University of Colorado, Eq. (2.28), where the force is expanded as \(\sum_n [A_n(\delta_s)\cos n\lambda_s + B_n(\delta_s)\sin n\lambda_s]\).
Examples
A once-per-revolution along-track acceleration, estimated:
import scarabaeus as scb state = [ ("position", 3, "estimated", "dynamic", sc, [7000, 0, 0]), ("velocity", 3, "estimated", "dynamic", sc, [0, 7.5, 0]), ("a_fourier", 9, "estimated", "static", sc, [0.0] * 9), ] force_model = scb.ForceModelTranslation( primary_body=sc, fourier_acceleration=True, fourier_degree=1, fourier_frame="RTN", fourier_angle="argument_of_latitude", )
- coefficient_labels() list[str]#
Names of the stacked coefficients, in state order.
- Returns:
- list of str
3 * (2 * degree + 1)labels such as['A0_R', 'A1_R', 'B1_R', 'A0_T', ...]for the RTN frame, matching the layout of thea_fourierstate.
- compute_acceleration(position: ndarray, current_state: dict, epoch: float, body: Body) ndarray#
Empirical Fourier acceleration applied to the body.
\[\mathbf a_F = \mathbf T \, \mathbf M(\theta) \, \mathbf p\]- Parameters:
- positionnp.ndarray
Spacecraft position 3-vector, km.
- current_statedict
Dictionary containing the propagated state.
- epochfloat
Current epoch in ephemeris seconds (TDB).
- bodyBody
Body the acceleration is evaluated for.
- Returns:
- np.ndarray
Acceleration 3-vector in km/s^2. Zero when neither the state nor the model configuration supplies coefficients.
- property default_coefficients#
Coefficients applied when the state carries no
a_fourierentry.
- property depends_on_velocity: bool#
Whether the acceleration is a function of velocity.
True for the RTN frame, whose triad is built from the velocity, and for the argument-of-latitude phase, which is measured in the orbit plane. The force model reads this to decide whether a \(\partial \mathbf a / \partial \mathbf v\) block is needed at all.
- property ref_frame#
Reference frame used by the model.
- property relative_body: str | None#
Body the RTN triad and the orbital phase are referred to, if any.
- exception CoefficientSizeError#
Bases:
ValueErrorRaised when the
a_fourierstate does not match the model degree.
- exception DegenerateGeometryError#
Bases:
ValueErrorRaised when the orbit geometry leaves the phase angle undefined.
- exception InvalidAngleError#
Bases:
ValueErrorRaised when
angleis not one of the supported phase angles.
- exception InvalidDegreeError#
Bases:
ValueErrorRaised when
degreeis negative or not an integer.
- exception InvalidEpochError#
Bases:
TypeErrorRaised when
t0is neither anEpochArraynor a real number.
- exception MissingEpochError#
Bases:
ValueErrorRaised when a time-based or solar phase has no
t0or epoch.
- exception MissingPeriodError#
Bases:
ValueErrorRaised when a time-based phase is requested without a
period.