1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation;
18
19 import java.util.ArrayList;
20 import java.util.List;
21
22 import org.hipparchus.analysis.differentiation.Gradient;
23 import org.hipparchus.analysis.differentiation.GradientField;
24 import org.hipparchus.geometry.euclidean.threed.FieldRotation;
25 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
26 import org.orekit.attitudes.AttitudeProvider;
27 import org.orekit.attitudes.FieldAttitude;
28 import org.orekit.orbits.CartesianOrbit;
29 import org.orekit.orbits.OrbitType;
30 import org.orekit.orbits.FieldOrbit;
31 import org.orekit.orbits.PositionAngleBased;
32 import org.orekit.orbits.PositionAngleType;
33 import org.orekit.time.AbsoluteDate;
34 import org.orekit.time.FieldAbsoluteDate;
35 import org.orekit.utils.DerivativeStateUtils;
36 import org.orekit.utils.FieldPVCoordinates;
37 import org.orekit.utils.FieldAbsolutePVCoordinates;
38 import org.orekit.utils.ParameterDriver;
39 import org.orekit.utils.ParameterDriversProvider;
40 import org.orekit.utils.TimeStampedFieldAngularCoordinates;
41 import org.orekit.utils.TimeSpanMap.Span;
42
43
44
45
46
47
48 public abstract class AbstractGradientConverter {
49
50
51 private final int freeStateParameters;
52
53
54 private final List<FieldSpacecraftState<Gradient>> gStates;
55
56
57
58
59 protected AbstractGradientConverter(final int freeStateParameters) {
60 this.freeStateParameters = freeStateParameters;
61 this.gStates = new ArrayList<>();
62 }
63
64
65
66
67 public int getFreeStateParameters() {
68 return freeStateParameters;
69 }
70
71
72
73
74
75 public void initStates(final FieldSpacecraftState<Gradient> zeroParametersState) {
76 gStates.clear();
77 gStates.add(zeroParametersState);
78 }
79
80
81
82
83
84
85 private Gradient extend(final Gradient original, final int freeParameters) {
86 final double[] originalDerivatives = original.getGradient();
87 final double[] extendedDerivatives = new double[freeParameters];
88 System.arraycopy(originalDerivatives, 0, extendedDerivatives, 0, originalDerivatives.length);
89 return new Gradient(original.getValue(), extendedDerivatives);
90 }
91
92
93
94
95
96
97 private FieldAbsoluteDate<Gradient> extend(final FieldAbsoluteDate<Gradient> original, final int freeParameters) {
98 final AbsoluteDate date = original.toAbsoluteDate();
99 return new FieldAbsoluteDate<>(date, extend(original.durationFrom(date), freeParameters));
100 }
101
102
103
104
105
106
107 private FieldVector3D<Gradient> extend(final FieldVector3D<Gradient> original, final int freeParameters) {
108 return new FieldVector3D<>(extend(original.getX(), freeParameters),
109 extend(original.getY(), freeParameters),
110 extend(original.getZ(), freeParameters));
111 }
112
113
114
115
116
117
118 private FieldRotation<Gradient> extend(final FieldRotation<Gradient> original, final int freeParameters) {
119 return new FieldRotation<>(extend(original.getQ0(), freeParameters),
120 extend(original.getQ1(), freeParameters),
121 extend(original.getQ2(), freeParameters),
122 extend(original.getQ3(), freeParameters),
123 false);
124 }
125
126
127
128
129
130
131 private TimeStampedFieldAngularCoordinates<Gradient> extend(final TimeStampedFieldAngularCoordinates<Gradient> original,
132 final int freeParameters) {
133 return new TimeStampedFieldAngularCoordinates<>(extend(original.getDate(), freeParameters),
134 extend(original.getRotation(), freeParameters),
135 extend(original.getRotationRate(), freeParameters),
136 extend(original.getRotationAcceleration(), freeParameters));
137
138 }
139
140
141
142
143
144
145 private FieldAttitude<Gradient> extend(final FieldAttitude<Gradient> original, final int freeParameters) {
146 return new FieldAttitude<>(original.getReferenceFrame(),
147 extend(original.getOrientation(), freeParameters));
148 }
149
150
151
152
153
154
155
156 private FieldOrbit<Gradient> extend(final FieldOrbit<Gradient> orbit, final int freeParameters) {
157
158 final PositionAngleType positionAngleType = orbit instanceof PositionAngleBased<?> pab ?
159 pab.getCachedPositionAngleType() :
160 PositionAngleType.MEAN;
161
162
163 final Gradient[] originalState = new Gradient[6];
164 orbit.getType().mapOrbitToArray(orbit, positionAngleType, originalState, null);
165
166
167 final Gradient[] extendedState = new Gradient[originalState.length];
168 for (int i = 0; i < originalState.length; i++) {
169 extendedState[i] = extend(originalState[i], freeParameters);
170 }
171
172 return orbit.getType().mapArrayToOrbit(extendedState, null, positionAngleType,
173 extend(orbit.getDate(), freeParameters),
174 extend(orbit.getMu(), freeParameters),
175 orbit.getFrame());
176
177 }
178
179
180
181
182
183
184
185 private FieldPVCoordinates<Gradient> extend(final FieldPVCoordinates<Gradient> pv, final int freeParameters) {
186 return new FieldPVCoordinates<>(extend(pv.getPosition(), freeParameters),
187 extend(pv.getVelocity(), freeParameters),
188 extend(pv.getAcceleration(), freeParameters));
189 }
190
191
192
193
194
195
196
197 private FieldAbsolutePVCoordinates<Gradient> extend(final FieldAbsolutePVCoordinates<Gradient> apv,
198 final int freeParameters) {
199 return new FieldAbsolutePVCoordinates<>(apv.getFrame(),
200 extend(apv.getDate(), freeParameters),
201 extend(apv.getPVCoordinates(), freeParameters));
202 }
203
204
205
206
207
208
209
210
211 public static FieldSpacecraftState<Gradient> buildBasicGradientSpacecraftState(final SpacecraftState state,
212 final int freeStateParameters,
213 final AttitudeProvider provider) {
214
215
216 final GradientField field = GradientField.getField(freeStateParameters);
217
218 if (state.isOrbitDefined()) {
219 final CartesianOrbit cartesianOrbit = (CartesianOrbit) OrbitType.CARTESIAN.convertType(state.getOrbit());
220 final SpacecraftState cartesianState = new SpacecraftState(cartesianOrbit, state.getAttitude()).withMass(state.getMass());
221 return DerivativeStateUtils.buildSpacecraftStateGradient(field, cartesianState, provider);
222 } else {
223 return DerivativeStateUtils.buildSpacecraftStateGradient(field, state, provider);
224 }
225
226 }
227
228
229
230
231
232
233 public FieldSpacecraftState<Gradient> getState(final ParameterDriversProvider parametricModel) {
234
235
236 int nbParams = 0;
237 for (final ParameterDriver driver : parametricModel.getParametersDrivers()) {
238 if (driver.isSelected()) {
239 nbParams += driver.getNbOfValues();
240 }
241 }
242
243
244 while (gStates.size() < nbParams + 1) {
245 gStates.add(null);
246 }
247
248 if (gStates.get(nbParams) == null) {
249
250
251 final int freeParameters = freeStateParameters + nbParams;
252 final FieldSpacecraftState<Gradient> s0 = gStates.getFirst();
253
254
255 final FieldAttitude<Gradient> gAttitude = extend(s0.getAttitude(), freeParameters);
256
257
258 final FieldSpacecraftState<Gradient> spacecraftState =
259 s0.isOrbitDefined() ?
260 new FieldSpacecraftState<>(extend(s0.getOrbit(), freeParameters), gAttitude) :
261 new FieldSpacecraftState<>(extend(s0.getAbsPVA(), freeParameters), gAttitude);
262
263
264 final Gradient gMass = extend(s0.getMass(), freeParameters);
265
266 gStates.set(nbParams, spacecraftState.withMass(gMass));
267
268 }
269
270 return gStates.get(nbParams);
271
272 }
273
274
275
276
277
278
279
280
281
282
283 public Gradient[] getParameters(final FieldSpacecraftState<Gradient> state,
284 final ParameterDriversProvider parametricModel) {
285 final int freeParameters = state.getMass().getFreeParameters();
286 final List<ParameterDriver> drivers = parametricModel.getParametersDrivers();
287 int sizeDrivers = 0;
288 for ( ParameterDriver driver : drivers) {
289 sizeDrivers += driver.getNbOfValues();
290 }
291 final Gradient[] parameters = new Gradient[sizeDrivers];
292 int index = freeStateParameters;
293 int i = 0;
294 for (ParameterDriver driver : drivers) {
295
296 for (Span<Double> span = driver.getValueSpanMap().getFirstSpan(); span != null; span = span.next()) {
297 parameters[i++] = driver.isSelected() ?
298 Gradient.variable(freeParameters, index++, span.getData()) :
299 Gradient.constant(freeParameters, span.getData());
300 }
301 }
302 return parameters;
303 }
304
305
306
307
308
309
310
311
312
313
314 public Gradient[] getParametersAtStateDate(final FieldSpacecraftState<Gradient> state,
315 final ParameterDriversProvider parametricModel) {
316 final int freeParameters = state.getMass().getFreeParameters();
317 final List<ParameterDriver> drivers = parametricModel.getParametersDrivers();
318
319 final AbsoluteDate date = state.getDate().toAbsoluteDate();
320 final Gradient[] parameters = new Gradient[drivers.size()];
321 int index = freeStateParameters;
322 int i = 0;
323 for (ParameterDriver driver : drivers) {
324 for (Span<String> span = driver.getNamesSpanMap().getFirstSpan(); span != null; span = span.next()) {
325 if (span.getData().equals(driver.getNameSpan(date))) {
326 parameters[i++] = driver.isSelected() ?
327 Gradient.variable(freeParameters, index, driver.getValue(date)) :
328 Gradient.constant(freeParameters, driver.getValue(date));
329 }
330 index = driver.isSelected() ? index + 1 : index;
331 }
332 }
333 return parameters;
334 }
335
336
337 }