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
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
//
// GENERATED FILE
//
use super::*;
use crate::SpiceContext;
use f2rust_std::*;
/// Evaluate a type 17 SPK data record
///
/// Evaluate a single SPK data record from a segment of type 17
/// (Equinoctial Elements).
///
/// # Required Reading
///
/// * [SPK](crate::required_reading::spk)
///
/// # Brief I/O
///
/// ```text
/// VARIABLE I/O DESCRIPTION
/// -------- --- --------------------------------------------------
/// ET I Target epoch.
/// RECIN I Data record.
/// STATE O State (position and velocity).
/// ```
///
/// # Detailed Input
///
/// ```text
/// ET is a target epoch, specified as ephemeris seconds past
/// J2000, at which a state vector is to be computed.
///
/// RECIN is a data record which, when evaluated at epoch ET,
/// will give the state (position and velocity) of some
/// body, relative to some center, in some inertial
/// reference frame.
///
/// The structure of RECIN is:
///
/// RECIN (1) epoch of the elements in ephemeris seconds
/// past J2000.
///
/// RECIN (2)-RECIN (10) Equinoctial Elements:
///
/// RECIN (2) is the semi-major axis (A) of the orbit.
///
/// RECIN (3) is the value of H at the specified
/// epoch. ( E*SIN(ARGP+NODE) ).
///
/// RECIN (4) is the value of K at the specified epoch
/// ( E*COS(ARGP+NODE) ).
///
/// RECIN (5) is the mean longitude (MEAN0+ARGP+NODE)
/// at the epoch of the elements.
///
/// RECIN (6) is the value of P
/// (TAN(INC/2)*SIN(NODE)) at the specified
/// epoch.
///
/// RECIN (7) is the value of Q
/// (TAN(INC/2)*COS(NODE)) at the specified
/// epoch.
///
/// RECIN (8) is the rate of the longitude of periapse
/// (dARGP/dt + dNODE/dt ) at the epoch of
/// the elements. This rate is assumed to
/// hold for all time.
///
/// RECIN (9) is the derivative of the mean longitude
/// ( dM/dt + dARGP/dt + dNODE/dt ). This
/// rate is assumed to be constant.
///
/// RECIN (10) is the rate of the longitude of the
/// ascending node ( dNODE/dt).
///
/// RECIN (11) Right Ascension of the pole of the
/// orbital reference system relative to the
/// reference frame of the associated SPK
/// segment.
///
/// RECIN (12) Declination of the pole of the
/// orbital reference system relative to
/// the reference frame of the associated
/// SPK segment.
/// ```
///
/// # Detailed Output
///
/// ```text
/// STATE is the state produced by evaluating RECIN at ET.
/// Units are km and km/sec.
/// ```
///
/// # Exceptions
///
/// ```text
/// 1) If the eccentricity is greater than 0.9, the error
/// SPICE(BADECCENTRICITY) is signaled.
///
/// 2) If the semi-major axis is non-positive, the error
/// SPICE(BADSEMIAXIS) is signaled.
/// ```
///
/// # Particulars
///
/// ```text
/// This routine performs a cursory examination of the elements
/// of a type 17 SPK data record and then passes the equinoctial
/// elements contained in that record on to the SPICE routine
/// EQNCPV for evaluation.
/// ```
///
/// # Examples
///
/// ```text
/// The SPKEnn routines are almost always used in conjunction with
/// the corresponding SPKRnn routines, which read the records from
/// SPK files.
///
/// The data returned by the SPKRnn routine is in its rawest form,
/// taken directly from the segment. As such, it will be meaningless
/// to a user unless he/she understands the structure of the data type
/// completely. Given that understanding, however, the SPKRnn
/// routines might be used to examine raw segment data before
/// evaluating it with the SPKEnn routines.
///
///
/// C
/// C Get a segment applicable to a specified body and epoch.
/// C
/// CALL SPKSFS ( BODY, ET, HANDLE, DESCR, IDENT, FOUND )
///
/// C
/// C Look at parts of the descriptor.
/// C
/// CALL DAFUS ( DESCR, 2, 6, DCD, ICD )
/// CENTER = ICD( 2 )
/// REF = ICD( 3 )
/// TYPE = ICD( 4 )
///
/// IF ( TYPE .EQ. 17 ) THEN
///
/// CALL SPKR17 ( HANDLE, DESCR, ET, RECORD )
/// .
/// . Look at the RECORD data.
/// .
/// CALL SPKE17 ( ET, RECORD, STATE )
/// .
/// . Check out the evaluated state.
/// .
/// END IF
/// ```
///
/// # Author and Institution
///
/// ```text
/// J. Diaz del Rio (ODC Space)
/// W.L. Taber (JPL)
/// ```
///
/// # Version
///
/// ```text
/// - SPICELIB Version 1.1.0, 27-AUG-2021 (JDR)
///
/// Added IMPLICIT NONE statement.
///
/// Edited the header to comply with NAIF standard.
///
/// - SPICELIB Version 1.0.0, 08-JAN-1997 (WLT)
/// ```
pub fn spke17(
ctx: &mut SpiceContext,
et: f64,
recin: &[f64],
state: &mut [f64; 6],
) -> crate::Result<()> {
SPKE17(et, recin, state, ctx.raw_context())?;
ctx.handle_errors()?;
Ok(())
}
//$Procedure SPKE17 ( Evaluate a type 17 SPK data record)
pub fn SPKE17(
ET: f64,
RECIN: &[f64],
STATE: &mut [f64],
ctx: &mut Context,
) -> f2rust_std::Result<()> {
let RECIN = DummyArray::new(RECIN, 1..);
let mut STATE = DummyArrayMut::new(STATE, 1..=6);
let mut A: f64 = 0.0;
let mut RAPOLE: f64 = 0.0;
let mut DECPOL: f64 = 0.0;
let mut H: f64 = 0.0;
let mut K: f64 = 0.0;
let mut ECC: f64 = 0.0;
let mut EPOCH: f64 = 0.0;
//
// SPICELIB Functions
//
//
// Local Variables
//
//
// Standard SPICE error handling.
//
if RETURN(ctx) {
return Ok(());
}
CHKIN(b"SPKE17", ctx)?;
//
// Fetch the various entities from the input record, first the epoch.
//
EPOCH = RECIN[1];
A = RECIN[2];
H = RECIN[3];
K = RECIN[4];
ECC = f64::sqrt(((H * H) + (K * K)));
RAPOLE = RECIN[11];
DECPOL = RECIN[12];
//
// Check all the inputs here for obvious failures. Yes, perhaps
// this is overkill. However, there is a lot more computation
// going on in this routine so that the small amount of overhead
// here should not be significant.
//
if (A <= 0 as f64) {
SETMSG(b"The semi-major axis supplied to the SPK type 17 evaluator was non-positive. This value must be positive. The value supplied was #.", ctx);
ERRDP(b"#", A, ctx);
SIGERR(b"SPICE(BADSEMIAXIS)", ctx)?;
CHKOUT(b"SPKE17", ctx)?;
return Ok(());
} else if (ECC > 0.9) {
SETMSG(b"The eccentricity supplied for a type 17 segment is greater than 0.9. It must be less than 0.9.The value supplied to the type 17 evaluator was #. ", ctx);
ERRDP(b"#", ECC, ctx);
SIGERR(b"SPICE(BADECCENTRICITY)", ctx)?;
CHKOUT(b"SPKE17", ctx)?;
return Ok(());
}
//
// That's all for here, just plug the elements into the routine
// knows how to evaluate the equinoctial elements.
//
EQNCPV(
ET,
EPOCH,
RECIN.subarray(2),
RAPOLE,
DECPOL,
STATE.as_slice_mut(),
ctx,
)?;
//
// That's all folks. Check out and return.
//
CHKOUT(b"SPKE17", ctx)?;
Ok(())
}