1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.forces.radiation;
18
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.List;
22
23 import org.hipparchus.CalculusFieldElement;
24 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
25 import org.hipparchus.geometry.euclidean.threed.Vector3D;
26 import org.hipparchus.util.FastMath;
27 import org.hipparchus.util.FieldSinCos;
28 import org.hipparchus.util.SinCos;
29 import org.orekit.annotation.DefaultDataContext;
30 import org.orekit.bodies.OneAxisEllipsoid;
31 import org.orekit.data.DataContext;
32 import org.orekit.frames.Frames;
33 import org.orekit.propagation.FieldSpacecraftState;
34 import org.orekit.propagation.SpacecraftState;
35 import org.orekit.utils.ExtendedPositionProvider;
36 import org.orekit.utils.ParameterDriver;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 public class ECOM2 extends AbstractRadiationForceModel {
78
79
80 public static final String ECOM_COEFFICIENT = "ECOM coefficient";
81
82
83 private static final double MIN_VALUE = Double.NEGATIVE_INFINITY;
84
85
86 private static final double MAX_VALUE = Double.POSITIVE_INFINITY;
87
88
89 private final int nD;
90
91
92 private final int nB;
93
94
95
96
97
98
99
100 private final List<ParameterDriver> coefficients;
101
102
103 private final ExtendedPositionProvider sun;
104
105
106
107
108
109
110
111
112
113 @DefaultDataContext
114 public ECOM2(final int nD, final int nB, final double value,
115 final ExtendedPositionProvider sun, final double equatorialRadius) {
116 this(nD, nB, value, sun, equatorialRadius, DataContext.getDefault().getFrames());
117 }
118
119
120
121
122
123
124
125
126
127
128
129 public ECOM2(final int nD, final int nB, final double value,
130 final ExtendedPositionProvider sun, final double equatorialRadius,
131 final Frames frames) {
132 super(sun, new OneAxisEllipsoid(equatorialRadius, 0.0, frames.getGCRF()), getDefaultEclipseDetectionSettings());
133 this.nB = nB;
134 this.nD = nD;
135 this.coefficients = new ArrayList<>(2 * (nD + nB) + 3);
136
137
138 final double scale = FastMath.scalb(1.0, -22);
139
140 coefficients.add(new ParameterDriver(ECOM_COEFFICIENT + " B0", value, scale, MIN_VALUE, MAX_VALUE));
141 for (int i = 1; i < nB + 1; i++) {
142 coefficients.add(new ParameterDriver(ECOM_COEFFICIENT + " Bcos" + (i - 1), value, scale, MIN_VALUE, MAX_VALUE));
143 }
144 for (int i = nB + 1; i < 2 * nB + 1; i++) {
145 coefficients.add(new ParameterDriver(ECOM_COEFFICIENT + " Bsin" + (i - (nB + 1)), value, scale, MIN_VALUE, MAX_VALUE));
146 }
147
148 coefficients.add(2 * nB + 1, new ParameterDriver(ECOM_COEFFICIENT + " D0", value, scale, MIN_VALUE, MAX_VALUE));
149 for (int i = 2 * nB + 2; i < 2 * nB + 2 + nD; i++) {
150 coefficients.add(new ParameterDriver(ECOM_COEFFICIENT + " Dcos" + (i - (2 * nB + 2)), value, scale, MIN_VALUE, MAX_VALUE));
151 }
152 for (int i = 2 * nB + 2 + nD; i < 2 * (nB + nD) + 2; i++) {
153 coefficients.add(new ParameterDriver(ECOM_COEFFICIENT + " Dsin" + (i - (2 * nB + nD + 2)), value, scale, MIN_VALUE, MAX_VALUE));
154 }
155
156 coefficients.add(new ParameterDriver(ECOM_COEFFICIENT + " Y0", value, scale, MIN_VALUE, MAX_VALUE));
157
158
159 coefficients.forEach(parameter -> parameter.setSelected(true));
160 this.sun = sun;
161 }
162
163
164 @Override
165 public Vector3D acceleration(final SpacecraftState s, final double[] parameters) {
166
167
168 final Vector3D satPos = s.getPosition();
169 final Vector3D sunPos = sun.getPosition(s.getDate(), s.getFrame());
170
171
172 final Vector3D Z = s.getPVCoordinates().getMomentum();
173 final Vector3D Y = Z.crossProduct(sunPos).normalize();
174 final Vector3D X = Y.crossProduct(Z).normalize();
175
176
177 final Vector3D eD = sunPos.subtract(satPos).normalize();
178 final Vector3D eY = eD.crossProduct(satPos).normalize();
179 final Vector3D eB = eD.crossProduct(eY);
180
181
182 final double delta_u = FastMath.atan2(satPos.dotProduct(Y), satPos.dotProduct(X));
183
184
185 double b_u = parameters[0];
186 for (int i = 1; i < nB + 1; i++) {
187 final SinCos sc = FastMath.sinCos((2 * i - 1) * delta_u);
188 b_u += parameters[i] * sc.cos() + parameters[i + nB] * sc.sin();
189 }
190
191 double d_u = parameters[2 * nB + 1];
192 for (int i = 1; i < nD + 1; i++) {
193 final SinCos sc = FastMath.sinCos(2 * i * delta_u);
194 d_u += parameters[2 * nB + 1 + i] * sc.cos() + parameters[2 * nB + 1 + i + nD] * sc.sin();
195 }
196
197 return new Vector3D(d_u, eD, parameters[2 * (nD + nB) + 2], eY, b_u, eB);
198 }
199
200
201 @Override
202 public <T extends CalculusFieldElement<T>> FieldVector3D<T> acceleration(final FieldSpacecraftState<T> s, final T[] parameters) {
203
204
205 final FieldVector3D<T> satPos = s.getPosition();
206 final FieldVector3D<T> sunPos = sun.getPosition(s.getDate(), s.getFrame());
207
208
209 final FieldVector3D<T> Z = s.getPVCoordinates().getMomentum();
210 final FieldVector3D<T> Y = Z.crossProduct(sunPos).normalize();
211 final FieldVector3D<T> X = Y.crossProduct(Z).normalize();
212
213
214 final FieldVector3D<T> eD = sunPos.subtract(satPos).normalize();
215 final FieldVector3D<T> eY = eD.crossProduct(satPos).normalize();
216 final FieldVector3D<T> eB = eD.crossProduct(eY);
217
218
219 final T delta_u = FastMath.atan2(satPos.dotProduct(Y), satPos.dotProduct(X));
220
221
222 T b_u = parameters[0];
223 for (int i = 1; i < nB + 1; i++) {
224 final FieldSinCos<T> sc = FastMath.sinCos(delta_u.multiply(2 * i - 1));
225 b_u = b_u.add(sc.cos().multiply(parameters[i])).add(sc.sin().multiply(parameters[i + nB]));
226 }
227
228 T d_u = parameters[2 * nB + 1];
229
230 for (int i = 1; i < nD + 1; i++) {
231 final FieldSinCos<T> sc = FastMath.sinCos(delta_u.multiply(2 * i));
232 d_u = d_u.add(sc.cos().multiply(parameters[2 * nB + 1 + i])).add(sc.sin().multiply(parameters[2 * nB + 1 + i + nD]));
233 }
234
235 return new FieldVector3D<>(d_u, eD, parameters[2 * (nD + nB) + 2], eY, b_u, eB);
236 }
237
238
239 @Override
240 public List<ParameterDriver> getParametersDrivers() {
241 return Collections.unmodifiableList(coefficients);
242 }
243
244 }
245