1+
2+ """
3+ add_axes_bcrtod!(frames, name, id, center; deriv=true)
4+
5+ Add Body-Centered Rotating (BCR), True-of-Date (TOD) axes with `name` and `id` to `frames`.
6+ The center point (i.e., the reference body) is `center`.
7+
8+ These axes are the equivalent of SPICE's `IAU_<BODY_NAME>` frames.
9+
10+ !!! warning
11+ The parent axes are automatically set to the ICRF (ID = $(AXESID_ICRF) ). If the
12+ ICRF is not defined in `frames`, an error is thrown.
13+
14+ ### See also
15+ See also [`add_axes_rotating!`](@ref), [`add_axes_bci2000!`](@ref).
16+ """
17+ function add_axes_bcrtod! (
18+ frames:: FrameSystem , name:: Symbol , id:: Int , center; deriv:: Bool = false
19+ )
20+ # create val dispatch
21+ cid = point_id (frames, center)
22+ vid = Val (cid)
23+
24+ if length ( methods (body_rotational_elements, [Number, Val{cid}]) ) != 1
25+ throw (
26+ MethodError (
27+ body_rotational_elements,
28+ " there must be a unique method defined for $cid "
29+ )
30+ )
31+ end
32+
33+ if ! (has_axes (frames, AXESID_ICRF))
34+ throw (
35+ ErrorException (
36+ " Body-Centered Inertial (BCI) at J2000 axes can only be defined" *
37+ " w.r.t. the ICRF (ID = $(AXESID_ICRF) ), which is not defined in" *
38+ " the current frames graph."
39+ )
40+ )
41+ end
42+
43+ if ! deriv
44+ add_axes_rotating! (frames, name, id, AXESID_ICRF, t-> _bcrtod (t, vid))
45+ else
46+ add_axes_rotating! (
47+ frames, name, id, AXESID_ICRF,
48+ t-> _bcrtod (t, vid), t-> _∂bcrtod (t, vid), t-> _∂²bcrtod (t, vid), t-> _∂³bcrtod (t, vid)
49+ )
50+ end
51+ end
52+
53+ """
54+ add_axes_bci2000!(frames, axes::AbstractFrameAxes, center, data)
55+
56+ Add Body-Centered Inertial (BCI) axes at J2000 with `name` and `id` to `frames`.
57+ The center point (i.e., the reference body) is `center`.
58+
59+ !!! warning
60+ The parent axes are automatically set to the ICRF (ID = $(AXESID_ICRF) ). If the
61+ ICRF is not defined in `frames`, an error is thrown.
62+
63+ ### See also
64+ See also [`add_axes_fixedoffset!`](@ref), [`add_axes_bcrtod!`](@ref).
65+ """
66+ function add_axes_bci2000! (frames:: FrameSystem , name:: Symbol , id:: Int , center)
67+
68+ # create val dispatch
69+ cid = point_id (frames, center)
70+ vid = Val (cid)
71+
72+ if length ( methods (body_rotational_elements, [Number, Val{cid}]) ) != 1
73+ throw (
74+ ErrorException (
75+ " there must be a unique method defined for $cid "
76+ )
77+ )
78+ end
79+
80+ if ! (has_axes (frames, AXESID_ICRF))
81+ throw (
82+ ErrorException (
83+ " Body-Centered Inertial (BCI) at J2000 axes can only be defined" *
84+ " w.r.t. the ICRF (ID = $(AXESID_ICRF) ), which is not defined in" *
85+ " the current frames graph."
86+ )
87+ )
88+ end
89+
90+ # evaluate rotational elements and build the DCM
91+ α2000, δ2000, _ = body_rotational_elements (0 , vid)
92+ dcm = angle_to_dcm (π/ 2 + α2000, π/ 2 - δ2000, :ZX )
93+
94+ # insert the new axes
95+ return add_axes_fixedoffset! (frames, name, id, AXESID_ICRF, dcm)
96+
97+ end
98+
99+ function _bcrtod (seconds, val)
100+ α, δ, w = body_rotational_elements (seconds / CENTURY2SEC, val)
101+ return angle_to_dcm (π/ 2 + α, π/ 2 - δ, w, :ZXZ )
102+ end
103+
104+ function _∂bcrtod (seconds, val)
105+ T = seconds / CENTURY2SEC
106+ α, δ, w = body_rotational_elements (T, val)
107+ dα, dδ, dw = ∂body_rotational_elements (T, val)
108+
109+ R = angle_to_dcm (π/ 2 + α, π/ 2 - δ, w, :ZXZ )
110+ dR = angle_to_δdcm ( (π/ 2 + α, dα), (π/ 2 - δ, - dδ), (w, dw), :ZXZ )
111+ return R, dR
112+ end
113+
114+ function _∂²bcrtod (seconds, val)
115+ T = seconds / CENTURY2SEC
116+ α, δ, w = body_rotational_elements (T, val)
117+ dα, dδ, dw = ∂body_rotational_elements (T, val)
118+ d²α, d²δ, d²w = ∂²body_rotational_elements (T, val)
119+
120+ R = angle_to_dcm ( π/ 2 + α, π/ 2 - δ, w, :ZXZ )
121+ dR = angle_to_δdcm ( (π/ 2 + α, dα), (π/ 2 - δ, - dδ), (w, dw), :ZXZ )
122+ d²R = angle_to_δ²dcm ( (π/ 2 + α, dα, d²α), (π/ 2 - δ, - dδ, - d²δ), (w, dw, d²w), :ZXZ )
123+ return R, dR, d²R
124+ end
125+
126+ function _∂³bcrtod (seconds, val)
127+ T = seconds / CENTURY2SEC
128+ α, δ, w = body_rotational_elements (T, val)
129+ dα, dδ, dw = ∂body_rotational_elements (T, val)
130+ d²α, d²δ, d²w = ∂²body_rotational_elements (T, val)
131+ d³α, d³δ, d³w = ∂³body_rotational_elements (T, val)
132+
133+ R = angle_to_dcm ( π/ 2 + α, π/ 2 - δ, w, :ZXZ )
134+ dR = angle_to_δdcm ( (π/ 2 + α, dα), (π/ 2 - δ, - dδ), (w, dw), :ZXZ )
135+ d²R = angle_to_δ²dcm ( (π/ 2 + α, dα, d²α), (π/ 2 - δ, - dδ, - d²δ), (w, dw, d²w), :ZXZ )
136+ d³R = angle_to_δ³dcm ( (π/ 2 + α, dα, d²α, d³α), (π/ 2 - δ, - dδ, - d²δ, - d³δ), (w, dw, d²w, d³w), :ZXZ )
137+ return R, dR, d²R, d³R
138+ end
0 commit comments