Physics
Attitude, control, magnetics
Rigid-body attitude dynamics with MRPs, PD attitude laws, and magnetic actuation through the local geomagnetic field. The RL policy chooses the attitude target; the controller and magnetorquers track it.
Kinematics and dynamics
\[
\dot{\boldsymbol\sigma}=\tfrac14\bigl[(1-\sigma^2)\mathbf I_3+2[\boldsymbol\sigma\times]+2\boldsymbol\sigma\boldsymbol\sigma^T\bigr]\boldsymbol\omega,\qquad
\dot{\boldsymbol\omega}=\mathbf I^{-1}\bigl(\boldsymbol\tau-\boldsymbol\omega\times\mathbf I\boldsymbol\omega\bigr)
\]
- MRP with the shadow-set switch at |σ| > 1 after every RK4 step. DCM: \(C=I+[8S^2-4(1-\sigma^2)S]/(1+\sigma^2)^2\) (Schaub & Junkins).
- Total torque = aero + SRP + Earth radiation + gravity gradient + control. Torques are held over each 2 s substep.
- Inertia: default diag(0.0125, 0.0125, 0.025) kg m².
set_inertiaaccepts a full tensor; v10r6 and the SolarCat vehicles compute it fromvehicle*.yaml. mode:point(closed loop),detumble(B-dot),prescribed(the attitude is set to the target each substep with ω = 0; used for decay studies).
Command path
- The policy outputs a quaternion. The env normalises it (identity if invalid).
slerp_cliplimits the change from the held command tomax_slew_rad(40–45°) per step.cmd_frame:inertialholds q_BN.flow,flowBandflowShold the command in the flow frame and re-evaluate the target every substep with orbit-rate feed-forward ω = C_BN h/r².- Optional
set_nav(r, v): flow-frame targets come from an onboard two-body RK4 nav state instead of truth (SC_v3 no-GNSS studies).
Attitude laws
\[
\text{MRP: }\ \boldsymbol\tau=-K_p\,\boldsymbol\sigma_{BR}-K_d(\boldsymbol\omega-\boldsymbol\omega_r)+\boldsymbol\omega\times\mathbf I\boldsymbol\omega,\qquad
\text{Quaternion: }\ \boldsymbol\tau=-K_p\,\mathbf q_{e,v}-K_d(\boldsymbol\omega-\boldsymbol\omega_r)+\boldsymbol\omega\times\mathbf I\boldsymbol\omega
\]
- Per-axis torque clip (
max_torque). A body-rate limiter rescales the command if the predicted |ω| exceedsmax_body_rate(0.125°/s default). - Gains:
config/plant/gains_mrp.yaml(v8+), otherwise kp = 4e-4 and kd = 8e-3.attitude.lawor--controllerselects the law. attitude.ideal_torque: trueapplies the PD torque as a pure body couple. That was the v2.1 plant the v8–v14 campaigns were tuned on (.physics_ideal.yaml). The defaultfalseroutes it through the magnetorquers.
Magnetic actuation
\[
\boldsymbol\tau=\mathbf m\times\mathbf B,\qquad \text{3 coils: }\ \mathbf m=\mathrm{clip}\Bigl(\frac{\mathbf B\times\boldsymbol\tau_\mathrm{cmd}}{|\mathbf B|^2},\ \mathbf m_\mathrm{max}\Bigr)
\]
- Nothing can be produced along B, so
tau_shortfall_frac= 1 − |τ|/|τ_cmd| reports the missing torque. - Torque rods (v10r6, SolarCat six-rod): torque-space least squares \(d=A^T(AA^T)^+\tau\) with \(a_k=u_k\times B\), then one uniform scale so that \(|d_k|\le d_{\max,k}\). Rods can be gated on or off by the policy.
mtq_duty(0, 1]: the coil on-fraction per substep. The rest is the magnetometer window.- B-dot detumble: \(\mathbf m=-k\,\dot{\mathbf B}\) (finite difference), used in brownout recovery.
- Power (
power.py): I²R-quadratic in the applied dipole (v8+), 249 mW peak for the 3-coil card.
Geomagnetic field
magnetics.model: wmm: spherical harmonics to degree 12 with secular variation, Schmidt semi-normalised (mag/field.cpp).dipole: tilted dipole from the IGRF-13/WMM2020 g₁⁰, g₁¹, h₁¹ coefficients. Thefastpreset uses it.- The env refuses a silent dipole fallback when a WMM file was requested but failed to load.
WMM epoch
The default
data/WMM.COF is WMM-2020 (valid 2020–2025), but the simulation epoch is 2026-01-15. The model is being extrapolated past its validity window. data/WMM2025.COF is already in the repo; set ARLAMX_WMM=data/WMM2025.COF to use it.Onboard pieces (flight-representative side)
propagator.py/propagator_f32.cpp: FP32 two-body + J2 + exponential drag + held along-track SRP. Used for the observation forecast blocks and the Duo arbiter.nav.py: no-GNSS navigation (FP32 J2 + drag from the launch state, eclipse-timing fixes from the solar panels).estimators.py: environmental-torque Kalman filter (τ, τ̇ states) from the rigid-body torque measurement.sensors.py: gyro, accelerometer, magnetometer and GNSS noise/bias from datasheet YAMLs (sensors_solarcat.yaml,sensors_gaussian.yaml).int8.py,quantize.py,inference_budget.py: integer-only actor for STM32U575-class hardware.
References
- Schaub, H. & Junkins, J. L. (2018). Analytical Mechanics of Space Systems, 4th ed., ch. 3.
- Wie, B., Weiss, H. & Arapostathis, A. (1989). Quaternion feedback regulator. JGCD 12(3).
- Stickler, A. C. & Alfriend, K. T. (1976). Elementary magnetic attitude control system. J. Spacecraft 13(5).
- Chulliat, A. et al. (2020, 2025). The US/UK World Magnetic Model.
- Markley, F. L. & Crassidis, J. L. (2014). Fundamentals of Spacecraft Attitude Determination and Control, ch. 3.