1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.utils;
18
19 import org.hipparchus.analysis.differentiation.Gradient;
20 import org.hipparchus.analysis.differentiation.GradientField;
21 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
22 import org.hipparchus.linear.RealMatrix;
23 import org.orekit.attitudes.Attitude;
24 import org.orekit.attitudes.AttitudeProvider;
25 import org.orekit.attitudes.FieldAttitude;
26 import org.orekit.frames.Frame;
27 import org.orekit.orbits.FieldOrbit;
28 import org.orekit.orbits.Orbit;
29 import org.orekit.orbits.PositionAngleBased;
30 import org.orekit.orbits.PositionAngleType;
31 import org.orekit.propagation.FieldSpacecraftState;
32 import org.orekit.propagation.SpacecraftState;
33 import org.orekit.time.FieldAbsoluteDate;
34
35
36
37
38
39
40
41
42 public class DerivativeStateUtils {
43
44
45 private DerivativeStateUtils() {
46
47 }
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 public static FieldSpacecraftState<Gradient> buildSpacecraftStateTransitionGradient(final SpacecraftState state,
63 final RealMatrix partialDerivatives,
64 final AttitudeProvider attitudeProvider) {
65 final int freeParameters = partialDerivatives.getColumnDimension();
66 final GradientField field = GradientField.getField(freeParameters);
67 final int j = partialDerivatives.getRowDimension();
68 final double mass = state.getMass();
69 final Gradient fieldMass = (j >= 7) ? new Gradient(mass, partialDerivatives.getRow(6)) : Gradient.constant(freeParameters, mass);
70 if (state.isOrbitDefined()) {
71 final double[] stateValues = new double[6];
72 final double[] stateDerivatives = stateValues.clone();
73 final Orbit orbit = state.getOrbit();
74 final PositionAngleType positionAngleType = extractPositionAngleType(orbit);
75 orbit.getType().mapOrbitToArray(orbit, positionAngleType, stateValues, stateDerivatives);
76 final Gradient[] stateVariables = new Gradient[stateValues.length];
77 for (int i = 0; i < stateVariables.length; i++) {
78 stateVariables[i] = (i < freeParameters) ? new Gradient(stateValues[i], partialDerivatives.getRow(i)) :
79 Gradient.constant(freeParameters, stateValues[i]);
80 }
81 final FieldOrbit<Gradient> fieldOrbit = buildFieldOrbit(field, orbit, stateVariables, stateDerivatives);
82 return buildFieldStateFromFieldOrbit(fieldOrbit, fieldMass, state.getAttitude(), attitudeProvider);
83 } else {
84
85 final AbsolutePVCoordinates coordinates = state.getAbsPVA();
86 final double[] constants = buildPVArray(coordinates.getPVCoordinates());
87 final Gradient[] stateVariables = new Gradient[constants.length];
88 for (int i = 0; i < stateVariables.length; i++) {
89 stateVariables[i] = (i < freeParameters) ? new Gradient(constants[i], partialDerivatives.getRow(i)) :
90 Gradient.constant(freeParameters, constants[i]);
91 }
92 final FieldVector3D<Gradient> position = new FieldVector3D<>(stateVariables[0], stateVariables[1],
93 stateVariables[2]);
94 final FieldVector3D<Gradient> velocity = new FieldVector3D<>(stateVariables[3], stateVariables[4],
95 stateVariables[5]);
96 final FieldAbsolutePVCoordinates<Gradient> fieldPV = buildFieldAbsolutePV(position, velocity, coordinates);
97 return buildFieldStateFromFieldPV(fieldPV, fieldMass, state.getAttitude(), attitudeProvider);
98 }
99 }
100
101
102
103
104
105
106
107
108
109
110
111
112 public static FieldSpacecraftState<Gradient> buildSpacecraftStateGradient(final GradientField field,
113 final SpacecraftState state,
114 final AttitudeProvider attitudeProvider) {
115 final int freeParameters = field.getZero().getFreeParameters();
116 final double mass = state.getMass();
117 final Gradient fieldMass = (freeParameters >= 7) ? Gradient.variable(freeParameters, 6, mass) :
118 Gradient.constant(freeParameters, mass);
119 final Attitude oldAttitude = state.getAttitude();
120 if (state.isOrbitDefined()) {
121 final FieldOrbit<Gradient> fieldOrbit = buildOrbitGradient(field, state.getOrbit());
122 return buildFieldStateFromFieldOrbit(fieldOrbit, fieldMass, oldAttitude, attitudeProvider);
123 } else {
124
125 final FieldAbsolutePVCoordinates<Gradient> fieldPV = buildAbsolutePVGradient(field, state.getAbsPVA());
126 return buildFieldStateFromFieldPV(fieldPV, fieldMass, oldAttitude, attitudeProvider);
127 }
128 }
129
130
131
132
133
134
135
136
137
138 private static FieldSpacecraftState<Gradient> buildFieldStateFromFieldOrbit(final FieldOrbit<Gradient> fieldOrbit,
139 final Gradient fieldMass, final Attitude attitude,
140 final AttitudeProvider attitudeProvider) {
141 final FieldAttitude<Gradient> fieldAttitude = (attitudeProvider == null) ?
142 new FieldAttitude<>(fieldMass.getField(), attitude) :
143 attitudeProvider.getAttitude(fieldOrbit, fieldOrbit.getDate(), fieldOrbit.getFrame());
144 return new FieldSpacecraftState<>(fieldOrbit, fieldAttitude).withMass(fieldMass);
145 }
146
147
148
149
150
151
152
153
154
155 private static FieldSpacecraftState<Gradient> buildFieldStateFromFieldPV(final FieldAbsolutePVCoordinates<Gradient> fieldPV,
156 final Gradient fieldMass, final Attitude attitude,
157 final AttitudeProvider attitudeProvider) {
158 final FieldAttitude<Gradient> fieldAttitude = (attitudeProvider == null) ?
159 new FieldAttitude<>(fieldMass.getField(), attitude) :
160 attitudeProvider.getAttitude(fieldPV, fieldPV.getDate(), fieldPV.getFrame());
161 return new FieldSpacecraftState<>(fieldPV, fieldAttitude).withMass(fieldMass);
162 }
163
164
165
166
167
168
169
170
171
172
173 public static FieldOrbit<Gradient> buildOrbitGradient(final GradientField field, final Orbit orbit) {
174 final int freeParameters = field.getZero().getFreeParameters();
175 final double[] stateValues = new double[6];
176 final double[] stateDerivatives = stateValues.clone();
177 final PositionAngleType positionAngleType = extractPositionAngleType(orbit);
178 orbit.getType().mapOrbitToArray(orbit, positionAngleType, stateValues, stateDerivatives);
179 final Gradient[] stateVariables = new Gradient[stateValues.length];
180 for (int i = 0; i < stateVariables.length; i++) {
181 stateVariables[i] = (i < freeParameters) ? Gradient.variable(freeParameters, i, stateValues[i]) :
182 Gradient.constant(freeParameters, stateValues[i]);
183 }
184 return buildFieldOrbit(field, orbit, stateVariables, stateDerivatives);
185 }
186
187
188
189
190
191
192
193
194
195 private static FieldOrbit<Gradient> buildFieldOrbit(final GradientField field, final Orbit orbit,
196 final Gradient[] stateVariables, final double[] stateDerivatives) {
197 final FieldAbsoluteDate<Gradient> date = new FieldAbsoluteDate<>(field, orbit.getDate());
198 final int freeParameters = field.getZero().getFreeParameters();
199 final Gradient mu = Gradient.constant(freeParameters, orbit.getMu());
200 final Gradient[] fieldStateDerivatives = new Gradient[stateVariables.length];
201 for (int i = 0; i < stateVariables.length; i++) {
202 fieldStateDerivatives[i] = Gradient.constant(freeParameters, stateDerivatives[i]);
203 }
204 final PositionAngleType positionAngleType = extractPositionAngleType(orbit);
205 final Frame frame = orbit.getFrame();
206 return orbit.getType().mapArrayToOrbit(stateVariables, fieldStateDerivatives, positionAngleType, date, mu, frame);
207 }
208
209
210
211
212
213
214 private static PositionAngleType extractPositionAngleType(final Orbit orbit) {
215 if (orbit instanceof PositionAngleBased<?>) {
216 final PositionAngleBased<?> positionAngleBased = (PositionAngleBased<?>) orbit;
217 return positionAngleBased.getCachedPositionAngleType();
218 }
219 return null;
220 }
221
222
223
224
225
226
227
228
229
230
231 public static FieldAbsolutePVCoordinates<Gradient> buildAbsolutePVGradient(final GradientField field,
232 final AbsolutePVCoordinates coordinates) {
233 final int freeParameters = field.getZero().getFreeParameters();
234 final double[] constants = buildPVArray(coordinates.getPVCoordinates());
235 final Gradient[] stateVariables = new Gradient[constants.length];
236 for (int i = 0; i < stateVariables.length; i++) {
237 stateVariables[i] = (i < freeParameters) ? Gradient.variable(freeParameters, i, constants[i]) :
238 Gradient.constant(freeParameters, constants[i]);
239 }
240 final FieldVector3D<Gradient> position = new FieldVector3D<>(stateVariables[0], stateVariables[1],
241 stateVariables[2]);
242 final FieldVector3D<Gradient> velocity = new FieldVector3D<>(stateVariables[3], stateVariables[4],
243 stateVariables[5]);
244 return buildFieldAbsolutePV(position, velocity, coordinates);
245 }
246
247
248
249
250
251
252 private static double[] buildPVArray(final PVCoordinates pvCoordinates) {
253 final double[] constants = new double[6];
254 System.arraycopy(pvCoordinates.getPosition().toArray(), 0, constants, 0, 3);
255 System.arraycopy(pvCoordinates.getVelocity().toArray(), 0, constants, 3, 3);
256 return constants;
257 }
258
259
260
261
262
263
264
265
266 private static FieldAbsolutePVCoordinates<Gradient> buildFieldAbsolutePV(final FieldVector3D<Gradient> fieldPosition,
267 final FieldVector3D<Gradient> fieldVelocity,
268 final AbsolutePVCoordinates coordinates) {
269 final GradientField field = fieldPosition.getX().getField();
270 final FieldVector3D<Gradient> acceleration = new FieldVector3D<>(field, coordinates.getAcceleration());
271 final FieldAbsoluteDate<Gradient> date = new FieldAbsoluteDate<>(field, coordinates.getDate());
272 return new FieldAbsolutePVCoordinates<>(coordinates.getFrame(), date, fieldPosition, fieldVelocity, acceleration);
273 }
274 }