gistools/space/propagation/
dpper.rs1use crate::space::{OperationMode, Satellite};
2use core::f64::consts::{PI, TAU};
3use libm::{atan2, cos, fabs, sin};
4
5#[derive(Debug, Default, Clone, Copy, PartialEq)]
7pub struct DpperOptions {
8 pub init: bool,
10 pub ep: f64,
12 pub inclp: f64,
14 pub nodep: f64,
16 pub argpp: f64,
18 pub mp: f64,
20}
21
22#[derive(Debug, Default, Clone, Copy, PartialEq)]
24pub struct DpperOutput {
25 pub ep: f64,
27 pub inclp: f64,
29 pub nodep: f64,
31 pub argpp: f64,
33 pub mp: f64,
35}
36
37pub fn dpper(
60 sat: &Satellite,
61 options: DpperOptions,
62 tsince: f64, ) -> DpperOutput {
64 let Satellite {
65 e3,
66 ee2,
67 peo,
68 pgho,
69 pho,
70 pinco,
71 plo,
72 se2,
73 se3,
74 sgh2,
75 sgh3,
76 sgh4,
77 sh2,
78 sh3,
79 si2,
80 si3,
81 sl2,
82 sl3,
83 sl4,
84 xgh2,
85 xgh3,
86 xgh4,
87 xh2,
88 xh3,
89 xi2,
90 xi3,
91 xl2,
92 xl3,
93 xl4,
94 zmol,
95 zmos,
96 opsmode,
97 ..
98 } = sat;
99
100 let DpperOptions { init, mut ep, mut inclp, mut nodep, mut argpp, mut mp } = options;
101
102 let mut alfdp: f64;
106 let mut betdp: f64;
107 let cosip: f64;
108 let sinip: f64;
109 let cosop: f64;
110 let sinop: f64;
111 let dalf: f64;
112 let dbet: f64;
113 let dls: f64;
114 let mut f2: f64;
115 let mut f3: f64;
116 let mut pe: f64;
117 let mut pgh: f64;
118 let mut ph: f64;
119 let mut pinc: f64;
120 let mut pl: f64;
121 let mut sinzf: f64;
122 let mut xls: f64;
123 let xnoh: f64;
124 let mut zf: f64;
125
126 let zns = 1.19459e-5;
128 let zes = 0.01675;
129 let znl = 1.5835218e-4;
130 let zel = 0.0549;
131
132 let mut zm = zmos + zns * tsince;
134
135 if init {
137 zm = *zmos;
138 }
139 zf = zm + 2.0 * zes * sin(zm);
140 sinzf = sin(zf);
141 f2 = 0.5 * sinzf * sinzf - 0.25;
142 f3 = -0.5 * sinzf * cos(zf);
143
144 let ses = se2 * f2 + se3 * f3;
145 let sis = si2 * f2 + si3 * f3;
146 let sls = sl2 * f2 + sl3 * f3 + sl4 * sinzf;
147 let sghs = sgh2 * f2 + sgh3 * f3 + sgh4 * sinzf;
148 let shs = sh2 * f2 + sh3 * f3;
149
150 zm = zmol + znl * tsince;
151 if init {
152 zm = *zmol;
153 }
154
155 zf = zm + 2.0 * zel * sin(zm);
156 sinzf = sin(zf);
157 f2 = 0.5 * sinzf * sinzf - 0.25;
158 f3 = -0.5 * sinzf * cos(zf);
159
160 let sel = ee2 * f2 + e3 * f3;
161 let sil = xi2 * f2 + xi3 * f3;
162 let sll = xl2 * f2 + xl3 * f3 + xl4 * sinzf;
163 let sghl = xgh2 * f2 + xgh3 * f3 + xgh4 * sinzf;
164 let shll = xh2 * f2 + xh3 * f3;
165
166 pe = ses + sel;
167 pinc = sis + sil;
168 pl = sls + sll;
169 pgh = sghs + sghl;
170 ph = shs + shll;
171
172 if !init {
173 pe -= peo;
174 pinc -= pinco;
175 pl -= plo;
176 pgh -= pgho;
177 ph -= pho;
178 inclp += pinc;
179 ep += pe;
180 sinip = sin(inclp);
181 cosip = cos(inclp);
182
183 if inclp >= 0.2 {
193 ph /= sinip;
194 pgh -= cosip * ph;
195 argpp += pgh;
196 nodep += ph;
197 mp += pl;
198 } else {
199 sinop = sin(nodep);
201 cosop = cos(nodep);
202 alfdp = sinip * sinop;
203 betdp = sinip * cosop;
204 dalf = ph * cosop + pinc * cosip * sinop;
205 dbet = -ph * sinop + pinc * cosip * cosop;
206 alfdp += dalf;
207 betdp += dbet;
208 nodep %= TAU;
209
210 if nodep < 0.0 && *opsmode == OperationMode::A {
213 nodep += TAU;
214 }
215 xls = mp + argpp + cosip * nodep;
216 dls = pl + pgh - pinc * nodep * sinip;
217 xls += dls;
218 xnoh = nodep;
219 nodep = atan2(alfdp, betdp);
220
221 if nodep < 0.0 && *opsmode == OperationMode::A {
224 nodep += TAU;
225 }
226 if fabs(xnoh - nodep) > PI {
227 if nodep < xnoh {
228 nodep += TAU;
229 } else {
230 nodep -= TAU;
231 }
232 }
233 mp += pl;
234 argpp = xls - mp - cosip * nodep;
235 }
236 }
237
238 DpperOutput { ep, inclp, nodep, argpp, mp }
239}