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