1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.estimation.leastsquares;
18
19 import java.io.File;
20 import java.io.IOException;
21 import java.net.URISyntaxException;
22 import java.text.ParseException;
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.NoSuchElementException;
26
27 import org.hipparchus.exception.LocalizedCoreFormats;
28 import org.hipparchus.geometry.euclidean.threed.Vector3D;
29 import org.hipparchus.util.FastMath;
30 import org.junit.Assert;
31 import org.junit.Test;
32 import org.orekit.KeyValueFileParser;
33 import org.orekit.Utils;
34 import org.orekit.attitudes.AttitudeProvider;
35 import org.orekit.bodies.CelestialBody;
36 import org.orekit.bodies.OneAxisEllipsoid;
37 import org.orekit.errors.OrekitException;
38 import org.orekit.estimation.common.AbstractOrbitDetermination;
39 import org.orekit.estimation.common.ParameterKey;
40 import org.orekit.estimation.common.ResultBatchLeastSquares;
41 import org.orekit.forces.drag.DragSensitive;
42 import org.orekit.forces.gravity.potential.GravityFieldFactory;
43 import org.orekit.forces.gravity.potential.ICGEMFormatReader;
44 import org.orekit.forces.gravity.potential.UnnormalizedSphericalHarmonicsProvider;
45 import org.orekit.forces.radiation.RadiationSensitive;
46 import org.orekit.models.earth.atmosphere.Atmosphere;
47 import org.orekit.orbits.EquinoctialOrbit;
48 import org.orekit.orbits.Orbit;
49 import org.orekit.orbits.OrbitType;
50 import org.orekit.propagation.PropagationType;
51 import org.orekit.propagation.conversion.DSSTPropagatorBuilder;
52 import org.orekit.propagation.conversion.ODEIntegratorBuilder;
53 import org.orekit.propagation.semianalytical.dsst.forces.DSSTAtmosphericDrag;
54 import org.orekit.propagation.semianalytical.dsst.forces.DSSTForceModel;
55 import org.orekit.propagation.semianalytical.dsst.forces.DSSTSolarRadiationPressure;
56 import org.orekit.propagation.semianalytical.dsst.forces.DSSTTesseral;
57 import org.orekit.propagation.semianalytical.dsst.forces.DSSTThirdBody;
58 import org.orekit.propagation.semianalytical.dsst.forces.DSSTZonal;
59 import org.orekit.utils.Constants;
60 import org.orekit.utils.IERSConventions;
61 import org.orekit.utils.ParameterDriver;
62
63 public class DSSTOrbitDeterminationTest extends AbstractOrbitDetermination<DSSTPropagatorBuilder> {
64
65
66 private UnnormalizedSphericalHarmonicsProvider gravityField;
67
68
69 private PropagationType propagationType;
70
71
72 private PropagationType stateType;
73
74
75 @Override
76 protected void createGravityField(final KeyValueFileParser<ParameterKey> parser)
77 throws NoSuchElementException {
78
79 final int degree = parser.getInt(ParameterKey.CENTRAL_BODY_DEGREE);
80 final int order = FastMath.min(degree, parser.getInt(ParameterKey.CENTRAL_BODY_ORDER));
81 gravityField = GravityFieldFactory.getUnnormalizedProvider(degree, order);
82 }
83
84
85 @Override
86 protected double getMu() {
87 return gravityField.getMu();
88 }
89
90
91 @Override
92 protected DSSTPropagatorBuilder createPropagatorBuilder(final Orbit referenceOrbit,
93 final ODEIntegratorBuilder builder,
94 final double positionScale) {
95 final EquinoctialOrbit equiOrbit = (EquinoctialOrbit) OrbitType.EQUINOCTIAL.convertType(referenceOrbit);
96 return new DSSTPropagatorBuilder(equiOrbit, builder, positionScale, propagationType, stateType);
97 }
98
99
100 @Override
101 protected void setMass(final DSSTPropagatorBuilder propagatorBuilder,
102 final double mass) {
103 propagatorBuilder.setMass(mass);
104 }
105
106
107 @Override
108 protected List<ParameterDriver> setGravity(final DSSTPropagatorBuilder propagatorBuilder,
109 final OneAxisEllipsoid body) {
110
111
112 final DSSTForceModel tesseral = new DSSTTesseral(body.getBodyFrame(),
113 Constants.WGS84_EARTH_ANGULAR_VELOCITY, gravityField,
114 gravityField.getMaxDegree(), gravityField.getMaxOrder(), 4, 12,
115 gravityField.getMaxDegree(), gravityField.getMaxOrder(), 4);
116 propagatorBuilder.addForceModel(tesseral);
117
118
119 final DSSTForceModel zonal = new DSSTZonal(gravityField, gravityField.getMaxDegree(), 4,
120 2 * gravityField.getMaxDegree() + 1);
121 propagatorBuilder.addForceModel(zonal);
122
123
124 final List<ParameterDriver> drivers = new ArrayList<>();
125 drivers.addAll(tesseral.getParametersDrivers());
126 drivers.addAll(zonal.getParametersDrivers());
127 return drivers;
128
129 }
130
131
132 @Override
133 protected List<ParameterDriver> setOceanTides(final DSSTPropagatorBuilder propagatorBuilder,
134 final IERSConventions conventions,
135 final OneAxisEllipsoid body,
136 final int degree, final int order) {
137 throw new OrekitException(LocalizedCoreFormats.SIMPLE_MESSAGE,
138 "Ocean tides not implemented in DSST");
139 }
140
141
142 @Override
143 protected List<ParameterDriver> setSolidTides(final DSSTPropagatorBuilder propagatorBuilder,
144 final IERSConventions conventions,
145 final OneAxisEllipsoid body,
146 final CelestialBody[] solidTidesBodies) {
147 throw new OrekitException(LocalizedCoreFormats.SIMPLE_MESSAGE,
148 "Solid tides not implemented in DSST");
149 }
150
151
152 @Override
153 protected List<ParameterDriver> setThirdBody(final DSSTPropagatorBuilder propagatorBuilder,
154 final CelestialBody thirdBody) {
155 final DSSTForceModel thirdBodyModel = new DSSTThirdBody(thirdBody, gravityField.getMu());
156 propagatorBuilder.addForceModel(thirdBodyModel);
157 return thirdBodyModel.getParametersDrivers();
158 }
159
160
161 @Override
162 protected List<ParameterDriver> setDrag(final DSSTPropagatorBuilder propagatorBuilder,
163 final Atmosphere atmosphere, final DragSensitive spacecraft) {
164 final DSSTForceModel dragModel = new DSSTAtmosphericDrag(atmosphere, spacecraft, gravityField.getMu());
165 propagatorBuilder.addForceModel(dragModel);
166 return dragModel.getParametersDrivers();
167 }
168
169
170 @Override
171 protected List<ParameterDriver> setSolarRadiationPressure(final DSSTPropagatorBuilder propagatorBuilder, final CelestialBody sun,
172 final double equatorialRadius, final RadiationSensitive spacecraft) {
173 final DSSTForceModel srpModel = new DSSTSolarRadiationPressure(sun, equatorialRadius,
174 spacecraft, gravityField.getMu());
175 propagatorBuilder.addForceModel(srpModel);
176 return srpModel.getParametersDrivers();
177 }
178
179
180 @Override
181 protected List<ParameterDriver> setAlbedoInfrared(final DSSTPropagatorBuilder propagatorBuilder,
182 final CelestialBody sun, final double equatorialRadius,
183 final double angularResolution,
184 final RadiationSensitive spacecraft) {
185 throw new OrekitException(LocalizedCoreFormats.SIMPLE_MESSAGE,
186 "Albedo and infrared not implemented in DSST");
187 }
188
189
190 @Override
191 protected List<ParameterDriver> setRelativity(final DSSTPropagatorBuilder propagatorBuilder) {
192 throw new OrekitException(LocalizedCoreFormats.SIMPLE_MESSAGE,
193 "Albedo and infrared not implemented in DSST");
194 }
195
196
197 @Override
198 protected List<ParameterDriver> setPolynomialAcceleration(final DSSTPropagatorBuilder propagatorBuilder,
199 final String name, final Vector3D direction, final int degree) {
200 throw new OrekitException(LocalizedCoreFormats.SIMPLE_MESSAGE,
201 "Polynomial acceleration not implemented in DSST");
202 }
203
204
205 @Override
206 protected void setAttitudeProvider(final DSSTPropagatorBuilder propagatorBuilder,
207 final AttitudeProvider attitudeProvider) {
208 propagatorBuilder.setAttitudeProvider(attitudeProvider);
209 }
210
211
212
213
214
215
216
217
218 @Test
219 public void testLageos2()
220 throws URISyntaxException, IllegalArgumentException, IOException,
221 OrekitException, ParseException {
222
223
224 final String inputPath = DSSTOrbitDeterminationTest.class.getClassLoader().getResource("orbit-determination/Lageos2/dsst_od_test_Lageos2.in").toURI().getPath();
225 final File input = new File(inputPath);
226
227
228 Utils.setDataRoot("orbit-determination/february-2016:potential/icgem-format");
229 GravityFieldFactory.addPotentialCoefficientsReader(new ICGEMFormatReader("eigen-6s-truncated", true));
230
231
232 propagationType = PropagationType.OSCULATING;
233 stateType = PropagationType.OSCULATING;
234
235
236 ResultBatchLeastSquares odLageos2 = runBLS(input, false);
237
238
239
240 final double distanceAccuracy = 76.40;
241 final double velocityAccuracy = 1.58e-1;
242
243
244 final int numberOfIte = 7;
245 final int numberOfEval = 7;
246
247 Assert.assertEquals(numberOfIte, odLageos2.getNumberOfIteration());
248 Assert.assertEquals(numberOfEval, odLageos2.getNumberOfEvaluation());
249
250
251 final Vector3D estimatedPos = odLageos2.getEstimatedPV().getPosition();
252 final Vector3D estimatedVel = odLageos2.getEstimatedPV().getVelocity();
253
254
255 final Vector3D refPos = new Vector3D(-2551060.861, 9748629.197, -6528045.767);
256 final Vector3D refVel = new Vector3D(-4595.833, 1029.893, 3382.441);
257 Assert.assertEquals(0.0, Vector3D.distance(refPos, estimatedPos), distanceAccuracy);
258 Assert.assertEquals(0.0, Vector3D.distance(refVel, estimatedVel), velocityAccuracy);
259
260
261 final long nbRange = 95;
262 final double[] RefStatRange = { -29.030, 59.098, 0.0, 14.968 };
263 Assert.assertEquals(nbRange, odLageos2.getRangeStat().getN());
264 Assert.assertEquals(RefStatRange[0], odLageos2.getRangeStat().getMin(), 1.0e-3);
265 Assert.assertEquals(RefStatRange[1], odLageos2.getRangeStat().getMax(), 1.0e-3);
266 Assert.assertEquals(RefStatRange[2], odLageos2.getRangeStat().getMean(), 1.0e-3);
267 Assert.assertEquals(RefStatRange[3], odLageos2.getRangeStat().getStandardDeviation(), 1.0e-3);
268
269
270 }
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291 @Test
292 public void testGNSS()
293 throws URISyntaxException, IllegalArgumentException, IOException,
294 OrekitException, ParseException {
295
296
297 final String inputPath = DSSTOrbitDeterminationTest.class.getClassLoader().getResource("orbit-determination/GNSS/dsst_od_test_GPS07.in").toURI().getPath();
298 final File input = new File(inputPath);
299
300
301 Utils.setDataRoot("orbit-determination/february-2016:potential/icgem-format");
302 GravityFieldFactory.addPotentialCoefficientsReader(new ICGEMFormatReader("eigen-6s-truncated", true));
303
304
305 propagationType = PropagationType.OSCULATING;
306 stateType = PropagationType.OSCULATING;
307
308
309 ResultBatchLeastSquares odGNSS = runBLS(input, false);
310
311
312
313 final double distanceAccuracy = 6.95;
314 final double velocityAccuracy = 2.46e-3;
315
316
317 final int numberOfIte = 3;
318 final int numberOfEval = 4;
319
320 Assert.assertEquals(numberOfIte, odGNSS.getNumberOfIteration());
321 Assert.assertEquals(numberOfEval, odGNSS.getNumberOfEvaluation());
322
323
324 final Vector3D estimatedPos = odGNSS.getEstimatedPV().getPosition();
325 final Vector3D estimatedVel = odGNSS.getEstimatedPV().getVelocity();
326 final Vector3D refPos = new Vector3D(-2747606.680868164, 22572091.30648564, 13522761.402325712);
327 final Vector3D refVel = new Vector3D(-2729.5151218788005, 1142.6629459030657, -2523.9055974487947);
328 Assert.assertEquals(0.0, Vector3D.distance(refPos, estimatedPos), distanceAccuracy);
329 Assert.assertEquals(0.0, Vector3D.distance(refVel, estimatedVel), velocityAccuracy);
330
331
332 final long nbRange = 4009;
333 final double[] RefStatRange = { -3.497, 2.594, 0.0, 0.837 };
334 Assert.assertEquals(nbRange, odGNSS.getRangeStat().getN());
335 Assert.assertEquals(RefStatRange[0], odGNSS.getRangeStat().getMin(), 1.0e-3);
336 Assert.assertEquals(RefStatRange[1], odGNSS.getRangeStat().getMax(), 1.0e-3);
337 Assert.assertEquals(RefStatRange[2], odGNSS.getRangeStat().getMean(), 1.0e-3);
338 Assert.assertEquals(RefStatRange[3], odGNSS.getRangeStat().getStandardDeviation(), 1.0e-3);
339
340 }
341
342 }