1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.numerical;
18
19 import java.util.ArrayList;
20 import java.util.List;
21
22 import org.hipparchus.Field;
23 import org.hipparchus.analysis.differentiation.Gradient;
24 import org.hipparchus.analysis.differentiation.GradientField;
25 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
26 import org.hipparchus.geometry.euclidean.threed.Vector3D;
27 import org.orekit.attitudes.AttitudeProvider;
28 import org.orekit.attitudes.FieldAttitude;
29 import org.orekit.forces.ForceModel;
30 import org.orekit.orbits.FieldCartesianOrbit;
31 import org.orekit.orbits.FieldOrbit;
32 import org.orekit.propagation.FieldSpacecraftState;
33 import org.orekit.propagation.SpacecraftState;
34 import org.orekit.propagation.integration.AbstractGradientConverter;
35 import org.orekit.utils.FieldAngularCoordinates;
36 import org.orekit.utils.FieldPVCoordinates;
37 import org.orekit.utils.ParameterDriver;
38 import org.orekit.utils.TimeStampedFieldAngularCoordinates;
39 import org.orekit.utils.TimeStampedFieldPVCoordinates;
40
41
42
43
44
45 class NumericalGradientConverter extends AbstractGradientConverter {
46
47
48 private final int freeStateParameters;
49
50
51 private final List<FieldSpacecraftState<Gradient>> gStates;
52
53
54
55
56
57
58 NumericalGradientConverter(final SpacecraftState state, final int freeStateParameters,
59 final AttitudeProvider provider) {
60
61 super(freeStateParameters);
62 this.freeStateParameters = freeStateParameters;
63
64
65 final Field<Gradient> field = GradientField.getField(freeStateParameters);
66
67
68 final Vector3D pos = state.getPVCoordinates().getPosition();
69 final FieldVector3D<Gradient> posG = new FieldVector3D<>(Gradient.variable(freeStateParameters, 0, pos.getX()),
70 Gradient.variable(freeStateParameters, 1, pos.getY()),
71 Gradient.variable(freeStateParameters, 2, pos.getZ()));
72
73
74 final Vector3D vel = state.getPVCoordinates().getVelocity();
75 final FieldVector3D<Gradient> velG;
76 if (freeStateParameters > 3) {
77 velG = new FieldVector3D<>(Gradient.variable(freeStateParameters, 3, vel.getX()),
78 Gradient.variable(freeStateParameters, 4, vel.getY()),
79 Gradient.variable(freeStateParameters, 5, vel.getZ()));
80 } else {
81 velG = new FieldVector3D<>(Gradient.constant(freeStateParameters, vel.getX()),
82 Gradient.constant(freeStateParameters, vel.getY()),
83 Gradient.constant(freeStateParameters, vel.getZ()));
84 }
85
86
87 final Vector3D acc = state.getPVCoordinates().getAcceleration();
88 final FieldVector3D<Gradient> accG = new FieldVector3D<>(Gradient.constant(freeStateParameters, acc.getX()),
89 Gradient.constant(freeStateParameters, acc.getY()),
90 Gradient.constant(freeStateParameters, acc.getZ()));
91
92
93 final Gradient gM = Gradient.constant(freeStateParameters, state.getMass());
94
95 final Gradient gMu = Gradient.constant(freeStateParameters, state.getMu());
96
97 final FieldOrbit<Gradient> gOrbit =
98 new FieldCartesianOrbit<>(new TimeStampedFieldPVCoordinates<>(state.getDate(), posG, velG, accG),
99 state.getFrame(), gMu);
100
101 final FieldAttitude<Gradient> gAttitude;
102 if (freeStateParameters > 3) {
103
104 gAttitude = provider.getAttitude(gOrbit, gOrbit.getDate(), gOrbit.getFrame());
105 } else {
106
107 gAttitude = new FieldAttitude<>(field, state.getAttitude());
108 }
109
110
111 gStates = new ArrayList<>();
112 gStates.add(new FieldSpacecraftState<>(gOrbit, gAttitude, gM));
113
114 }
115
116
117
118
119
120 public FieldSpacecraftState<Gradient> getState(final ForceModel forceModel) {
121
122
123 int nbParams = 0;
124 for (final ParameterDriver driver : forceModel.getParametersDrivers()) {
125 if (driver.isSelected()) {
126 ++nbParams;
127 }
128 }
129
130
131 while (gStates.size() < nbParams + 1) {
132 gStates.add(null);
133 }
134
135 if (gStates.get(nbParams) == null) {
136
137
138 final int freeParameters = freeStateParameters + nbParams;
139 final FieldSpacecraftState<Gradient> s0 = gStates.get(0);
140
141
142 final FieldPVCoordinates<Gradient> pv0 = s0.getPVCoordinates();
143 final FieldOrbit<Gradient> gOrbit =
144 new FieldCartesianOrbit<>(new TimeStampedFieldPVCoordinates<>(s0.getDate().toAbsoluteDate(),
145 extend(pv0.getPosition(), freeParameters),
146 extend(pv0.getVelocity(), freeParameters),
147 extend(pv0.getAcceleration(), freeParameters)),
148 s0.getFrame(),
149 extend(s0.getMu(), freeParameters));
150
151
152 final FieldAngularCoordinates<Gradient> ac0 = s0.getAttitude().getOrientation();
153 final FieldAttitude<Gradient> gAttitude =
154 new FieldAttitude<>(s0.getAttitude().getReferenceFrame(),
155 new TimeStampedFieldAngularCoordinates<>(gOrbit.getDate(),
156 extend(ac0.getRotation(), freeParameters),
157 extend(ac0.getRotationRate(), freeParameters),
158 extend(ac0.getRotationAcceleration(), freeParameters)));
159
160
161 final Gradient gM = extend(s0.getMass(), freeParameters);
162
163 gStates.set(nbParams, new FieldSpacecraftState<>(gOrbit, gAttitude, gM));
164
165 }
166
167 return gStates.get(nbParams);
168
169 }
170
171
172
173
174
175
176 public Gradient[] getParameters(final FieldSpacecraftState<Gradient> state,
177 final ForceModel forceModel) {
178 final int freeParameters = state.getMass().getFreeParameters();
179 final List<ParameterDriver> drivers = forceModel.getParametersDrivers();
180 final Gradient[] parameters = new Gradient[drivers.size()];
181 int index = freeStateParameters;
182 int i = 0;
183 for (ParameterDriver driver : drivers) {
184 parameters[i++] = driver.isSelected() ?
185 Gradient.variable(freeParameters, index++, driver.getValue()) :
186 Gradient.constant(freeParameters, driver.getValue());
187 }
188 return parameters;
189 }
190
191 }