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