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
//! Bevy `Component` and `Message` newtypes for non-body reference-frame
//! attachment and detached-subtree free-flight propagation.
use *;
use DVec3;
// intra-doc-link resolution
use ;
/// Component: this body is attached to a non-body **reference frame**
/// (not to another body in the mass tree).
///
/// Port of JEOD's `DynBody::frame_attach` member, populated by
/// [`DynBody::attach_to_frame`](https://github.com/nasa/jeod/blob/jeod_v5.4.0/models/dynamics/dyn_body/src/dyn_body_attach.cc#L271).
/// While present, the body's [`TranslationalStateC`] +
/// [`RotationalStateC`] are derived each tick by the
/// [`crate::frame_attach_system::propagate_frame_attached_state_system`]
/// from the parent frame entity's state composed with the captured
/// offset, and the integration system skips this body (mirrors the
/// `frame_attach.isAttached()` branch in JEOD
/// `dyn_body_integration.cc:309-333`).
///
/// Distinct from [`KinematicChildC`], which gates the same skip path
/// on a parent **body** in the mass tree. A body cannot be both at
/// once — JEOD's `attach_to_frame` writes `frame_attach` on the
/// integrated tree root, not on a child body, and the runner's
/// `Simulation::attach_to_frame` (`astrodyn_runner::Simulation::attach_to_frame`)
/// gate refuses an entity that already has a mass-tree parent. The
/// Bevy adapter's [`crate::frame_attach_system::frame_attach_system`]
/// enforces the same exclusion.
///
/// Mission code MUST NOT insert this component manually — use
/// [`FrameAttachEvent`] / [`FrameDetachEvent`] so the integrator
/// history reset and frame-tree coupling stay consistent. The
/// [`crate::frame_attach_system::frame_attach_system`] inserts and
/// removes the marker.
// JEOD_INV: DB.21 — only unattached bodies integrate (frame-attach gate)
// JEOD_INV: DB.13 — composite-body propagation delegated to parent frame
/// Message: attach a body to a non-body reference frame.
///
/// Bevy adapter for JEOD's `DynBody::attach_to_frame`. The
/// `frame_attach_system` inserts a [`FrameAttachedC`] component on
/// `body`, captures the offset, and resets multi-step integrator
/// history. Subsequent ticks derive the body's state from
/// `parent_frame`'s current state plus `offset`. See
/// `Simulation::attach_to_frame` (`astrodyn_runner::Simulation::attach_to_frame`)
/// for the runner-side equivalent.
/// Message: release a body's reference-frame attachment.
///
/// Bevy adapter for JEOD `DynBody::detach()` (the
/// `frame_attach.isAttached()` branch in
/// `models/dynamics/dyn_body/src/dyn_body_detach.cc:141-143`). The
/// `frame_attach_system` removes the [`FrameAttachedC`] component;
/// integration resumes on the next step from whatever state the
/// frame-attached propagation left in [`TranslationalStateC`] /
/// [`RotationalStateC`].
/// Composite-body inertial state of a free-flying mass-tree subtree
/// that has been detached from its parent and is coasting
/// ballistically (no force, no torque) until [`AttachEvent`] re-attaches
/// it.
///
/// Inserted on the child entity by `staging_system`'s `DetachEvent`
/// branch; removed by the `AttachEvent` branch when the same entity
/// is re-attached. While present, [`step_detached_system`](crate::step_detached_system)
/// advances the contained state by the schedule's fixed `dt` each
/// tick — position drifts at `composite_velocity`, attitude rotates
/// under `composite_ang_vel_body`. Also synchronizes the entity's
/// own [`TranslationalStateC`] / [`RotationalStateC`] each tick so
/// downstream consumers (gravity, derived state, mission code)
/// continue to read the body's current inertial state from the
/// canonical components rather than having to special-case detached
/// vs integrated bodies.
///
/// Bevy mirror of `astrodyn_runner::Simulation::detached_subtrees`. Wraps
/// [`astrodyn::DetachedSubtreeState`] (which owns the JEOD scalar-first
/// left-multiply attitude convention via
/// [`astrodyn::BodyAttitude<astrodyn::SelfRef>`](astrodyn::BodyAttitude)).
;