Skip to content

PanelSrp

Defined in: panel_srp.rs:63

pub struct PanelSrp

Attitude-dependent solar radiation pressure model using flat surface panels.

Implements Model to produce both translational acceleration and SRP torque from per-panel radiation forces. For the SpacecraftShape::Sphere variant, the cr and area are read from the shape itself.

Per-panel force, from the panel’s PanelOptics:

F = -P·A·cosθ · [ (α + ρ_d)·ŝ + 2·(ρ_s·cosθ + ρ_d/3)·n̂ ]

with cosθ = n̂·ŝ, absorbed fraction α, specular ρ_s, diffuse ρ_d, and α + ρ_s + ρ_d = 1. Absorption and diffuse incidence push along the Sun line; specular reflection and diffuse re-emission push along the panel normal. Face-on this collapses to Cr = 1 + ρ_s + 2ρ_d/3, recovering the textbook 1 for a black panel, 2 for a mirror and 5/3 for a Lambertian one.

The torque is Σ r_cp × F_panel, so a panel whose centre of pressure sits off the centre of mass produces an attitude disturbance.

PanelOptics: super::PanelOptics

fn panels(panels: [Vec<super::SurfacePanel>](https://doc.rust-lang.org/std/vec/struct.Vec.html)) -> Self

Create a panel-based (attitude-dependent) SRP model from surface panels, with the geocentric Sun and no shadow — see Self::new.

Panics unless every panel normal is unit length and every outline is consistent with its panel — positive finite extents whose product is a finite non-zero area matching area, and a unit in-plane axis perpendicular to the normal. Both are re-checked here because SurfacePanel’s fields are public, so a struct literal can bypass the constructors that establish them.


fn for_earth(shape: SpacecraftShape) -> Self

Create an SRP model for Earth orbit with cylindrical Earth shadow.

For the SpacecraftShape::Sphere variant, cr and area come from the shape. For SpacecraftShape::Panels, each panel carries its own area and PanelOptics.

PanelOptics: super::PanelOptics

Panics unless every panel normal is unit length and every outline is consistent with its panel — positive finite extents whose product is a finite non-zero area matching area, and a unit in-plane axis perpendicular to the normal. Both are re-checked here because SurfacePanel’s fields are public, so a struct literal can bypass the constructors that establish them.


fn for_body(body: arika::body::KnownBody, shape: SpacecraftShape) -> [Result<Self, arika::sun::SunPositionError>](https://doc.rust-lang.org/std/result/enum.Result.html)

Create a panel SRP model for orbit about body.

Takes both body-dependent quantities from that body: the Sun’s position relative to it, and its own radius for the shadow. The panel force points along the satellite-to-Sun line and its torque follows the panel’s angle to that line, so a geocentric Sun direction about another body turns both — from Mars in 2026 that direction is up to 176° off.

Orbiting the Sun itself works: the Sun sits at the origin, so the satellite-to-Sun vector is -r_sat, and there is nothing to cast a shadow.

Fails only for a central body with no Sun ephemeris (Uranus, Neptune).

Panics unless every panel normal is unit length and every outline is consistent with its panel — positive finite extents whose product is a finite non-zero area matching area, and a unit in-plane axis perpendicular to the normal. Both are re-checked here because SurfacePanel’s fields are public, so a struct literal can bypass the constructors that establish them.


fn new(shape: SpacecraftShape) -> Self

Create an SRP model with the geocentric Sun and no central-body eclipse.

The Sun direction is Earth’s, so about another body the force points where the Sun is not — from Mars in 2026 up to 176° off. For a shadow-free model about body, take Self::for_body``(body, shape)?.``without_shadow() instead.

without_shadow(): Self::without_shadow

Panels still shade each other. That is a property of the shape rather than of an orbit, so it is not something either constructor turns off: an outlined panel gets the share of the force its lit part earns, at the centre of that part, here as well. The shadows are united, so a panel two others cover between them contributes nothing.

Panics unless every panel normal is unit length and every outline is consistent with its panel — positive finite extents whose product is a finite non-zero area matching area, and a unit in-plane axis perpendicular to the normal. Both are re-checked here because SurfacePanel’s fields are public, so a struct literal can bypass the constructors that establish them.


fn without_shadow(self) -> Self

Drop the shadow, keeping the Sun direction this model was built with (builder pattern).


fn with_shadow_body(self, radius: f64) -> Self

Set or override the shadow body radius (builder pattern).


fn with_shadow_model(self, model: ShadowModel) -> Self

Set the shadow model (builder pattern).