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 org.hipparchus.geometry.euclidean.threed.Vector3D;
20 import org.hipparchus.util.FastMath;
21 import org.junit.jupiter.api.Assertions;
22 import org.junit.jupiter.api.Test;
23 import org.orekit.KeyValueFileParser;
24 import org.orekit.Utils;
25 import org.orekit.attitudes.AttitudeProvider;
26 import org.orekit.bodies.CelestialBody;
27 import org.orekit.bodies.OneAxisEllipsoid;
28 import org.orekit.errors.OrekitException;
29 import org.orekit.estimation.common.AbstractOrbitDetermination;
30 import org.orekit.estimation.common.ParameterKey;
31 import org.orekit.estimation.common.ResultSequentialBatchLeastSquares;
32 import org.orekit.forces.ForceModel;
33 import org.orekit.forces.drag.DragForce;
34 import org.orekit.forces.drag.DragSensitive;
35 import org.orekit.forces.empirical.AccelerationModel;
36 import org.orekit.forces.empirical.ParametricAcceleration;
37 import org.orekit.forces.empirical.PolynomialAccelerationModel;
38 import org.orekit.forces.gravity.HolmesFeatherstoneAttractionModel;
39 import org.orekit.forces.gravity.OceanTides;
40 import org.orekit.forces.gravity.Relativity;
41 import org.orekit.forces.gravity.SolidTides;
42 import org.orekit.forces.gravity.ThirdBodyAttraction;
43 import org.orekit.forces.gravity.potential.GravityFieldFactory;
44 import org.orekit.forces.gravity.potential.ICGEMFormatReader;
45 import org.orekit.forces.gravity.potential.NormalizedSphericalHarmonicsProvider;
46 import org.orekit.forces.radiation.KnockeRediffusedForceModel;
47 import org.orekit.forces.radiation.RadiationSensitive;
48 import org.orekit.forces.radiation.SolarRadiationPressure;
49 import org.orekit.models.earth.atmosphere.Atmosphere;
50 import org.orekit.orbits.Orbit;
51 import org.orekit.orbits.PositionAngleType;
52 import org.orekit.propagation.conversion.NumericalPropagatorBuilder;
53 import org.orekit.propagation.conversion.ODEIntegratorBuilder;
54 import org.orekit.time.TimeScalesFactory;
55 import org.orekit.utils.IERSConventions;
56 import org.orekit.utils.ParameterDriver;
57
58 import java.io.File;
59 import java.io.IOException;
60 import java.net.URISyntaxException;
61 import java.text.ParseException;
62 import java.util.List;
63 import java.util.NoSuchElementException;
64
65 public class NumericalSequentialOrbitDeterminationTest extends AbstractOrbitDetermination<NumericalPropagatorBuilder> {
66
67
68 private NormalizedSphericalHarmonicsProvider gravityField;
69
70
71 @Override
72 protected void createGravityField(final KeyValueFileParser<ParameterKey> parser)
73 throws NoSuchElementException {
74
75 final int degree = parser.getInt(ParameterKey.CENTRAL_BODY_DEGREE);
76 final int order = FastMath.min(degree, parser.getInt(ParameterKey.CENTRAL_BODY_ORDER));
77 gravityField = GravityFieldFactory.getNormalizedProvider(degree, order);
78
79 }
80
81
82 @Override
83 protected double getMu() {
84 return gravityField.getMu();
85 }
86
87
88 @Override
89 protected NumericalPropagatorBuilder createPropagatorBuilder(final Orbit referenceOrbit,
90 final ODEIntegratorBuilder builder,
91 final double positionScale) {
92 return new NumericalPropagatorBuilder(referenceOrbit, builder, PositionAngleType.MEAN,
93 positionScale);
94 }
95
96
97 @Override
98 protected void setMass(final NumericalPropagatorBuilder propagatorBuilder,
99 final double mass) {
100 propagatorBuilder.setMass(mass);
101 }
102
103
104 @Override
105 protected List<ParameterDriver> setGravity(final NumericalPropagatorBuilder propagatorBuilder,
106 final OneAxisEllipsoid body) {
107 final ForceModel gravityModel = new HolmesFeatherstoneAttractionModel(body.getBodyFrame(), gravityField);
108 propagatorBuilder.addForceModel(gravityModel);
109 return gravityModel.getParametersDrivers();
110 }
111
112
113 @Override
114 protected List<ParameterDriver> setOceanTides(final NumericalPropagatorBuilder propagatorBuilder,
115 final IERSConventions conventions,
116 final OneAxisEllipsoid body,
117 final int degree, final int order) {
118 final ForceModel tidesModel = new OceanTides(body.getBodyFrame(),
119 gravityField.getAe(), gravityField.getMu(),
120 degree, order, conventions,
121 TimeScalesFactory.getUT1(conventions, true));
122 propagatorBuilder.addForceModel(tidesModel);
123 return tidesModel.getParametersDrivers();
124 }
125
126
127 @Override
128 protected List<ParameterDriver> setSolidTides(final NumericalPropagatorBuilder propagatorBuilder,
129 final IERSConventions conventions,
130 final OneAxisEllipsoid body,
131 final CelestialBody[] solidTidesBodies) {
132 final ForceModel tidesModel = new SolidTides(body.getBodyFrame(),
133 gravityField.getAe(), gravityField.getMu(),
134 gravityField.getTideSystem(), conventions,
135 TimeScalesFactory.getUT1(conventions, true),
136 solidTidesBodies);
137 propagatorBuilder.addForceModel(tidesModel);
138 return tidesModel.getParametersDrivers();
139 }
140
141
142 @Override
143 protected List<ParameterDriver> setThirdBody(final NumericalPropagatorBuilder propagatorBuilder,
144 final CelestialBody thirdBody) {
145 final ForceModel thirdBodyModel = new ThirdBodyAttraction(thirdBody);
146 propagatorBuilder.addForceModel(thirdBodyModel);
147 return thirdBodyModel.getParametersDrivers();
148 }
149
150
151 @Override
152 protected List<ParameterDriver> setDrag(final NumericalPropagatorBuilder propagatorBuilder,
153 final Atmosphere atmosphere, final DragSensitive spacecraft) {
154 final ForceModel dragModel = new DragForce(atmosphere, spacecraft);
155 propagatorBuilder.addForceModel(dragModel);
156 return dragModel.getParametersDrivers();
157 }
158
159
160 @Override
161 protected List<ParameterDriver> setSolarRadiationPressure(final NumericalPropagatorBuilder propagatorBuilder, final CelestialBody sun,
162 final OneAxisEllipsoid body, final RadiationSensitive spacecraft) {
163 final ForceModel srpModel = new SolarRadiationPressure(sun, body, spacecraft);
164 propagatorBuilder.addForceModel(srpModel);
165 return srpModel.getParametersDrivers();
166 }
167
168
169 @Override
170 protected List<ParameterDriver> setAlbedoInfrared(final NumericalPropagatorBuilder propagatorBuilder,
171 final CelestialBody sun, final double equatorialRadius,
172 final double angularResolution,
173 final RadiationSensitive spacecraft) {
174 final ForceModel albedoIR = new KnockeRediffusedForceModel(sun, spacecraft, equatorialRadius, angularResolution);
175 propagatorBuilder.addForceModel(albedoIR);
176 return albedoIR.getParametersDrivers();
177 }
178
179
180 @Override
181 protected List<ParameterDriver> setRelativity(final NumericalPropagatorBuilder propagatorBuilder) {
182 final ForceModel relativityModel = new Relativity(gravityField.getMu());
183 propagatorBuilder.addForceModel(relativityModel);
184 return relativityModel.getParametersDrivers();
185 }
186
187
188 @Override
189 protected List<ParameterDriver> setPolynomialAcceleration(final NumericalPropagatorBuilder propagatorBuilder,
190 final String name, final Vector3D direction, final int degree) {
191 final AccelerationModel accModel = new PolynomialAccelerationModel(name, null, degree);
192 final ForceModel polynomialModel = new ParametricAcceleration(direction, true, accModel);
193 propagatorBuilder.addForceModel(polynomialModel);
194 return polynomialModel.getParametersDrivers();
195 }
196
197
198 @Override
199 protected void setAttitudeProvider(final NumericalPropagatorBuilder propagatorBuilder,
200 final AttitudeProvider attitudeProvider) {
201 propagatorBuilder.setAttitudeProvider(attitudeProvider);
202 }
203
204 @Test
205
206 public void testLageos2()
207 throws URISyntaxException, IllegalArgumentException, IOException,
208 OrekitException, ParseException {
209
210
211 final String inputPathModel = NumericalSequentialOrbitDeterminationTest.class.getClassLoader().getResource("orbit-determination/Lageos2/sequential_od_test_Lageos.in").toURI().getPath();
212 final File inputModel = new File(inputPathModel);
213
214
215 Utils.setDataRoot("orbit-determination/february-2016:potential/icgem-format");
216 GravityFieldFactory.addPotentialCoefficientsReader(new ICGEMFormatReader("eigen-6s-truncated", true));
217
218
219
220 final boolean print = false;
221 ResultSequentialBatchLeastSquares odLageos2 = runSequentialBLS(inputModel, print);
222
223
224
225 final double distanceAccuracyBLS = 0.13;
226 final double distanceAccuracySBLS = 0.06;
227
228
229 final int numberOfIte = 4;
230 final int numberOfEval = 4;
231
232 Assertions.assertEquals(numberOfIte, odLageos2.getNumberOfIteration());
233 Assertions.assertEquals(numberOfEval, odLageos2.getNumberOfEvaluation());
234
235
236 final int numberOfIteS = 5;
237 final int numberOfEvalS = 5;
238
239 Assertions.assertEquals(numberOfIteS, odLageos2.getNumberOfIterationSequential());
240 Assertions.assertEquals(numberOfEvalS, odLageos2.getNumberOfEvaluationSequential());
241
242
243 final Vector3D estimatedPos = odLageos2.getEstimatedPV().getPosition();
244 final Vector3D estimatedPosSequential = odLageos2.getEstimatedPVSequential().getPosition();
245
246
247
248 final Vector3D refPos = new Vector3D(-8470598.591629019, -656367.1112940479, 8683152.425956512);
249
250 Assertions.assertEquals(0.0, Vector3D.distance(refPos, estimatedPos), distanceAccuracyBLS);
251 Assertions.assertEquals(0.0, Vector3D.distance(refPos, estimatedPosSequential), distanceAccuracySBLS);
252
253 }
254 }