1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
// JEOD_INV: TS.01 — `<SelfRef>` / `<SelfPlanet>` are runtime-resolved storage-boundary wildcards; see `docs/JEOD_invariants.md` row TS.01 and the lint at `tests/self_ref_self_planet_discipline.rs`.
//! Bevy `Component` newtypes for gravity sources, source-side inertial
//! state, source rotation / ephemeris configuration, the gravity-gradient
//! torque accumulator, tidal configuration / output, and the planet
//! shape + angular-velocity surface.
use ;
use *;
use ;
/// Per-body list of gravity controls keyed by source [`Entity`]. Each
/// control selects the model (point-mass / spherical-harmonics) and
/// which body it represents (central, third, etc.).
;
/// Gravity source attached to a planet entity (mu plus optional
/// spherical-harmonics coefficients). Queried by gravity controls
/// targeting this entity.
;
/// RootInertial-frame position of a gravity source.
///
/// For the central body (e.g., Earth in an Earth-centered sim), this is
/// typically `Position::<RootInertial>::zero()`. For third bodies (Sun, Moon),
/// this value should be provided and maintained by the application's
/// ephemeris/update logic. Used by the gravity computation to apply
/// differential (third-body) acceleration corrections.
///
/// Required on all gravity source entities. The gravity systems will panic
/// if a source entity referenced by a `GravityControlsC` is missing this
/// component.
;
/// RootInertial-frame velocity of a gravity source.
///
/// Optional component. For the central body (e.g., Earth in an Earth-centered
/// sim), this is typically `Velocity::<RootInertial>::zero()`. For third bodies
/// (Sun, Moon), attach this component alongside [`EphemerisBodyC`] and the
/// `ephemeris_update_system` will populate it each step. When absent,
/// relativistic corrections fall back to zero source velocity.
///
/// Used by the gravity and integration systems to provide source velocity to
/// the relativistic correction computation. Stored separately from
/// `TranslationalStateC` to avoid Bevy query conflicts (the body's
/// `TranslationalStateC` is already mutably queried by the integration system).
;
/// Gravity gradient torque in the body frame (N·m).
///
/// Written by the gravity torque system.
/// Read by `force_collection_system` as `Option<&GravityTorqueC>`.
;
/// Typed inertial→planet-fixed rotation for a gravity source entity.
///
/// Stores the rotation that maps inertial-frame vectors into the planet-fixed
/// frame of the source. The `FrameTransform`'s phantom `<RootInertial,
/// PlanetFixed<P>>` parameters encode the *direction*. Every call site must
/// pin `P` explicitly — there is no fallback.
///
/// When present on a gravity source entity, `gravity_computation_system` and
/// `integration_system` use this rotation instead of `DMat3::IDENTITY` to
/// rotate the spacecraft position into the body-fixed frame before evaluating
/// spherical-harmonic gravity.
;
/// Sidereal rotation rate (rad/s) used by `planet_fixed_rotation_system`
/// to populate [`PlanetAngularVelocityC`] each step. Sourced from
/// [`astrodyn::PlanetConfig::omega`] at insertion (e.g. from
/// [`PlanetBundle::from_config`](crate::PlanetBundle::from_config)).
///
/// Issue #71 item 1: without this, velocity composition through
/// planet-fixed frames silently uses zero angular velocity, producing
/// the wrong NED-relative or geodetic velocity.
;
/// Angular velocity of the planet-fixed frame relative to its inertial
/// parent, expressed in pfix coordinates. Computed each step by
/// `planet_fixed_rotation_system` as `[0, 0, omega]` matching JEOD's
/// `planet_rnp.cc`.
///
/// The `AngularVelocity<PlanetFixed<P>>` phantom indicates "in the
/// pfix frame of planet `P`". Every call site must pin `P` explicitly
/// — there is no fallback.
;
/// Tidal configuration for a gravity source entity.
///
/// When present on a gravity source entity alongside `PlanetFixedRotationC`,
/// the `tidal_update_system` computes ΔC20 each step and writes it to
/// `TidalDeltaC20C`. The application is responsible for updating
/// `tidal_bodies[].position_inertial` each step from ephemeris data.
///
/// Wraps [`astrodyn::TidalConfigTyped`] (typed sibling of
/// [`astrodyn::TidalConfig`]) so the untyped → typed conversion happens
/// **once at insertion**, not per tick in `tidal_update_system`. This
/// eliminates the per-frame `TidalConfigTyped::from_untyped` allocation
/// (Vec collect + per-body f64 → typed boxing). Convenience constructors
/// `from_untyped` / `From` impls are provided for callers building from
/// the untyped struct.
;
/// Computed tidal ΔC20 for a gravity source entity.
///
/// Written by `tidal_update_system`. Read by gravity computation and
/// integration systems. Defaults to zero (no tidal effect).
///
/// Wrapped as a [`Ratio`] (dimensionless) so the value carries unit
/// metadata at the type level — matching `compute_delta_c20_typed`'s
/// return type.
;
/// Per-source rotation model dispatch.
///
/// When present on a gravity source entity alongside `PlanetFixedRotationC`,
/// the `planet_fixed_rotation_system` dispatches to the correct rotation
/// computation based on this value. When absent, `EarthRNP` is assumed
/// for backward compatibility.
;
/// Ephemeris body mapping for automatic position updates from DE4xx.
///
/// When present on a gravity source entity, the `ephemeris_update_system`
/// queries the `EphemerisR` resource each step to update the entity's
/// `SourceInertialPositionC` (and optionally `TranslationalStateC`).
/// Marker component for the Sun entity (used by SRP system to find Sun position).
;
/// Marker component for the Moon entity (used by earth lighting system).
;
/// Marks an entity as the simulation's designated central body.
///
/// [`crate::SourceMutator::set_source_position`] and
/// [`crate::SourceMutator::set_source_state`] panic if the target entity
/// carries this marker. Mission code attaches it to the gravity-source
/// entity it treats as the pinned origin (e.g. Earth in an Earth-centered
/// scenario), opting that entity into the same protection that
/// `astrodyn_runner::Simulation::set_source_*` enforces against the
/// root-mapped source via `assert_ne!(fid, root_frame_id, …)`.
///
/// At most one entity should carry this marker per simulation; multiple
/// markers are not currently rejected, but `SourceMutator` panics on
/// every call that targets a marked entity, so a well-behaved app
/// attaches it once.
;
// ── Planet ──
/// Bevy component wrapping `PlanetShape`.
;