1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.forces.drag;
18
19 import org.hipparchus.Field;
20 import org.hipparchus.analysis.differentiation.DSFactory;
21 import org.hipparchus.analysis.differentiation.DerivativeStructure;
22 import org.hipparchus.analysis.differentiation.Gradient;
23 import org.hipparchus.geometry.euclidean.threed.FieldRotation;
24 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
25 import org.hipparchus.geometry.euclidean.threed.Vector3D;
26 import org.hipparchus.ode.nonstiff.ClassicalRungeKuttaFieldIntegrator;
27 import org.hipparchus.ode.nonstiff.ClassicalRungeKuttaIntegrator;
28 import org.hipparchus.ode.nonstiff.DormandPrince853Integrator;
29 import org.hipparchus.util.FastMath;
30 import org.junit.jupiter.api.Assertions;
31 import org.junit.jupiter.api.BeforeEach;
32 import org.junit.jupiter.api.Test;
33 import org.orekit.Utils;
34 import org.orekit.attitudes.AttitudeProvider;
35 import org.orekit.attitudes.LofOffset;
36 import org.orekit.bodies.CelestialBody;
37 import org.orekit.bodies.CelestialBodyFactory;
38 import org.orekit.bodies.OneAxisEllipsoid;
39 import org.orekit.errors.OrekitException;
40 import org.orekit.errors.OrekitMessages;
41 import org.orekit.forces.AbstractLegacyForceModelTest;
42 import org.orekit.forces.BoxAndSolarArraySpacecraft;
43 import org.orekit.forces.ForceModel;
44 import org.orekit.frames.Frame;
45 import org.orekit.frames.FramesFactory;
46 import org.orekit.frames.LOFType;
47 import org.orekit.frames.Transform;
48 import org.orekit.models.earth.atmosphere.Atmosphere;
49 import org.orekit.models.earth.atmosphere.HarrisPriester;
50 import org.orekit.orbits.CartesianOrbit;
51 import org.orekit.orbits.FieldKeplerianOrbit;
52 import org.orekit.orbits.KeplerianOrbit;
53 import org.orekit.orbits.Orbit;
54 import org.orekit.orbits.OrbitType;
55 import org.orekit.orbits.PositionAngle;
56 import org.orekit.propagation.FieldSpacecraftState;
57 import org.orekit.propagation.SpacecraftState;
58 import org.orekit.propagation.numerical.FieldNumericalPropagator;
59 import org.orekit.propagation.numerical.NumericalPropagator;
60 import org.orekit.time.AbsoluteDate;
61 import org.orekit.time.DateComponents;
62 import org.orekit.time.FieldAbsoluteDate;
63 import org.orekit.time.TimeComponents;
64 import org.orekit.time.TimeScale;
65 import org.orekit.time.TimeScalesFactory;
66 import org.orekit.utils.Constants;
67 import org.orekit.utils.FieldPVCoordinates;
68 import org.orekit.utils.IERSConventions;
69 import org.orekit.utils.PVCoordinates;
70 import org.orekit.utils.ParameterDriver;
71 import org.orekit.utils.TimeSpanMap;
72
73 import java.util.List;
74
75 public class TimeSpanDragForceTest extends AbstractLegacyForceModelTest {
76
77
78 private TimeScale utc;
79
80
81
82
83 @Override
84 protected FieldVector3D<DerivativeStructure> accelerationDerivatives(final ForceModel forceModel,
85 final AbsoluteDate date, final Frame frame,
86 final FieldVector3D<DerivativeStructure> position,
87 final FieldVector3D<DerivativeStructure> velocity,
88 final FieldRotation<DerivativeStructure> rotation,
89 final DerivativeStructure mass)
90 {
91 try {
92
93 java.lang.reflect.Field atmosphereField = TimeSpanDragForce.class.getDeclaredField("atmosphere");
94 atmosphereField.setAccessible(true);
95 Atmosphere atmosphere = (Atmosphere) atmosphereField.get(forceModel);
96 java.lang.reflect.Field spacecraftField = DragForce.class.getDeclaredField("spacecraft");
97 spacecraftField.setAccessible(true);
98
99 DragSensitive spacecraft = ((TimeSpanDragForce) (forceModel)).getDragSensitive(date);
100
101
102 final DSFactory factory = mass.getFactory();
103
104
105 final Frame atmFrame = atmosphere.getFrame();
106 final Transform toBody = frame.getTransformTo(atmFrame, date);
107 final FieldVector3D<DerivativeStructure> posBodyDS = toBody.transformPosition(position);
108 final Vector3D posBody = posBodyDS.toVector3D();
109 final Vector3D vAtmBody = atmosphere.getVelocity(date, posBody, atmFrame);
110
111
112
113
114
115
116 if (factory.getCompiler().getOrder() > 1) {
117 throw new OrekitException(OrekitMessages.OUT_OF_RANGE_DERIVATION_ORDER, factory.getCompiler().getOrder());
118 }
119 final double delta = 1.0;
120 final double x = posBody.getX();
121 final double y = posBody.getY();
122 final double z = posBody.getZ();
123 final double rho0 = atmosphere.getDensity(date, posBody, atmFrame);
124 final double dRhodX = (atmosphere.getDensity(date, new Vector3D(x + delta, y, z), atmFrame) - rho0) / delta;
125 final double dRhodY = (atmosphere.getDensity(date, new Vector3D(x, y + delta, z), atmFrame) - rho0) / delta;
126 final double dRhodZ = (atmosphere.getDensity(date, new Vector3D(x, y, z + delta), atmFrame) - rho0) / delta;
127 final double[] dXdQ = posBodyDS.getX().getAllDerivatives();
128 final double[] dYdQ = posBodyDS.getY().getAllDerivatives();
129 final double[] dZdQ = posBodyDS.getZ().getAllDerivatives();
130 final double[] rhoAll = new double[dXdQ.length];
131 rhoAll[0] = rho0;
132 for (int i = 1; i < rhoAll.length; ++i) {
133 rhoAll[i] = dRhodX * dXdQ[i] + dRhodY * dYdQ[i] + dRhodZ * dZdQ[i];
134 }
135 final DerivativeStructure rho = factory.build(rhoAll);
136
137
138
139
140
141
142 final FieldVector3D<DerivativeStructure> vAtmBodyDS =
143 new FieldVector3D<>(factory.constant(vAtmBody.getX()),
144 factory.constant(vAtmBody.getY()),
145 factory.constant(vAtmBody.getZ()));
146 final FieldPVCoordinates<DerivativeStructure> pvAtmBody = new FieldPVCoordinates<>(posBodyDS, vAtmBodyDS);
147 final FieldPVCoordinates<DerivativeStructure> pvAtm = toBody.getInverse().transformPVCoordinates(pvAtmBody);
148
149
150 final FieldVector3D<DerivativeStructure> relativeVelocity = pvAtm.getVelocity().subtract(velocity);
151
152
153
154 DerivativeStructure[] allParameters = forceModel.getParameters(factory.getDerivativeField());
155 DerivativeStructure[] parameters = ((TimeSpanDragForce) (forceModel)).extractParameters(allParameters,
156 new FieldAbsoluteDate<>(factory.getDerivativeField(), date));
157
158
159 return spacecraft.dragAcceleration(new FieldAbsoluteDate<>(factory.getDerivativeField(), date),
160 frame, position, rotation, mass, rho, relativeVelocity,
161 parameters);
162 } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
163 return null;
164 }
165 }
166
167
168
169
170 @Override
171 protected FieldVector3D<Gradient> accelerationDerivativesGradient(final ForceModel forceModel,
172 final AbsoluteDate date, final Frame frame,
173 final FieldVector3D<Gradient> position,
174 final FieldVector3D<Gradient> velocity,
175 final FieldRotation<Gradient> rotation,
176 final Gradient mass)
177 {
178 try {
179
180 java.lang.reflect.Field atmosphereField = TimeSpanDragForce.class.getDeclaredField("atmosphere");
181 atmosphereField.setAccessible(true);
182 Atmosphere atmosphere = (Atmosphere) atmosphereField.get(forceModel);
183 java.lang.reflect.Field spacecraftField = DragForce.class.getDeclaredField("spacecraft");
184 spacecraftField.setAccessible(true);
185
186 DragSensitive spacecraft = ((TimeSpanDragForce) (forceModel)).getDragSensitive(date);
187
188 final int freeParameters = mass.getFreeParameters();
189
190
191 final Frame atmFrame = atmosphere.getFrame();
192 final Transform toBody = frame.getTransformTo(atmFrame, date);
193 final FieldVector3D<Gradient> posBodyG = toBody.transformPosition(position);
194 final Vector3D posBody = posBodyG.toVector3D();
195 final Vector3D vAtmBody = atmosphere.getVelocity(date, posBody, atmFrame);
196
197
198
199
200
201
202 final double delta = 1.0;
203 final double x = posBody.getX();
204 final double y = posBody.getY();
205 final double z = posBody.getZ();
206 final double rho0 = atmosphere.getDensity(date, posBody, atmFrame);
207 final double dRhodX = (atmosphere.getDensity(date, new Vector3D(x + delta, y, z), atmFrame) - rho0) / delta;
208 final double dRhodY = (atmosphere.getDensity(date, new Vector3D(x, y + delta, z), atmFrame) - rho0) / delta;
209 final double dRhodZ = (atmosphere.getDensity(date, new Vector3D(x, y, z + delta), atmFrame) - rho0) / delta;
210 final double[] dXdQ = posBodyG.getX().getGradient();
211 final double[] dYdQ = posBodyG.getY().getGradient();
212 final double[] dZdQ = posBodyG.getZ().getGradient();
213 final double[] rhoAll = new double[dXdQ.length];
214 for (int i = 0; i < rhoAll.length; ++i) {
215 rhoAll[i] = dRhodX * dXdQ[i] + dRhodY * dYdQ[i] + dRhodZ * dZdQ[i];
216 }
217 final Gradient rho = new Gradient(rho0, rhoAll);
218
219
220
221
222
223
224 final FieldVector3D<Gradient> vAtmBodyG =
225 new FieldVector3D<>(Gradient.constant(freeParameters, vAtmBody.getX()),
226 Gradient.constant(freeParameters, vAtmBody.getY()),
227 Gradient.constant(freeParameters, vAtmBody.getZ()));
228 final FieldPVCoordinates<Gradient> pvAtmBody = new FieldPVCoordinates<>(posBodyG, vAtmBodyG);
229 final FieldPVCoordinates<Gradient> pvAtm = toBody.getInverse().transformPVCoordinates(pvAtmBody);
230
231
232 final FieldVector3D<Gradient> relativeVelocity = pvAtm.getVelocity().subtract(velocity);
233
234
235
236 Gradient[] allParameters = forceModel.getParameters(mass.getField());
237 Gradient[] parameters = ((TimeSpanDragForce) (forceModel)).extractParameters(allParameters,
238 new FieldAbsoluteDate<>(mass.getField(), date));
239
240
241 return spacecraft.dragAcceleration(new FieldAbsoluteDate<>(mass.getField(), date),
242 frame, position, rotation, mass, rho, relativeVelocity,
243 parameters);
244 } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
245 return null;
246 }
247 }
248
249
250
251
252 @Test
253 public void testGetParameterDriversSphere() {
254
255
256 final Atmosphere atmosphere = new HarrisPriester(CelestialBodyFactory.getSun(),
257 new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
258 Constants.WGS84_EARTH_FLATTENING,
259 FramesFactory.getITRF(IERSConventions.IERS_2010, true)));
260
261
262 AbsoluteDate date = new AbsoluteDate("2000-01-01T00:00:00.000", TimeScalesFactory.getUTC());
263
264
265
266
267 double dragArea = 2.;
268 double dragCd0 = 0.;
269 TimeSpanDragForce forceModel = new TimeSpanDragForce(atmosphere, new IsotropicDrag(dragArea, dragCd0));
270 Assertions.assertFalse(forceModel.dependsOnPositionOnly());
271 List<ParameterDriver> drivers = forceModel.getParametersDrivers();
272 Assertions.assertEquals(1, drivers.size());
273 Assertions.assertEquals(dragCd0, drivers.get(0).getValue(), 0.);
274 Assertions.assertEquals(DragSensitive.DRAG_COEFFICIENT, drivers.get(0).getName());
275
276
277 IsotropicDrag isoDrag = (IsotropicDrag) forceModel.getDragSensitive(date);
278 drivers = isoDrag.getDragParametersDrivers();
279 Assertions.assertEquals(1, drivers.size());
280 Assertions.assertEquals(dragCd0, drivers.get(0).getValue(), 0.);
281 Assertions.assertEquals(DragSensitive.DRAG_COEFFICIENT, drivers.get(0).getName());
282
283
284
285 double dragCd1 = 1.;
286 double dragCd2 = 2.;
287 double dt = 120.;
288
289 isoDrag = new IsotropicDrag(dragArea, dragCd0);
290 IsotropicDrag isoDrag1 = new IsotropicDrag(dragArea, dragCd1);
291 IsotropicDrag isoDrag2 = new IsotropicDrag(dragArea, dragCd2);
292 forceModel = new TimeSpanDragForce(atmosphere, isoDrag);
293 forceModel.addDragSensitiveValidAfter(isoDrag1, date.shiftedBy(dt));
294 forceModel.addDragSensitiveValidBefore(isoDrag2, date.shiftedBy(-dt));
295
296
297 drivers = forceModel.getParametersDrivers();
298 Assertions.assertEquals(3, drivers.size());
299 Assertions.assertEquals(dragCd2, drivers.get(0).getValue(), 0.);
300 Assertions.assertEquals(DragSensitive.DRAG_COEFFICIENT + TimeSpanDragForce.DATE_BEFORE + date.shiftedBy(-dt).toString(utc),
301 drivers.get(0).getName());
302 Assertions.assertEquals(dragCd0, drivers.get(1).getValue(), 0.);
303 Assertions.assertEquals(DragSensitive.DRAG_COEFFICIENT, drivers.get(1).getName());
304 Assertions.assertEquals(dragCd0, drivers.get(1).getValue(), 0.);
305 Assertions.assertEquals(DragSensitive.DRAG_COEFFICIENT + TimeSpanDragForce.DATE_AFTER + date.shiftedBy(+dt).toString(utc),
306 drivers.get(2).getName());
307
308
309
310 double eps = 1.e-14;
311 Assertions.assertEquals(isoDrag, forceModel.getDragSensitive(date));
312 Assertions.assertEquals(isoDrag, forceModel.getDragSensitive(date.shiftedBy(-dt)));
313 Assertions.assertEquals(isoDrag, forceModel.getDragSensitive(date.shiftedBy(+dt - eps)));
314
315 Assertions.assertEquals(isoDrag2, forceModel.getDragSensitive(date.shiftedBy(-dt - eps)));
316 Assertions.assertEquals(isoDrag2, forceModel.getDragSensitive(date.shiftedBy(-dt - 86400.)));
317
318 Assertions.assertEquals(isoDrag1, forceModel.getDragSensitive(date.shiftedBy(+dt)));
319 Assertions.assertEquals(isoDrag1, forceModel.getDragSensitive(date.shiftedBy(+dt + 86400.)));
320
321
322
323 double dragCd3 = 3.;
324 IsotropicDrag isoDrag3 = new IsotropicDrag(dragArea, dragCd3);
325 isoDrag3.getDragParametersDrivers().get(0).setName("custom-Cd");
326 forceModel.addDragSensitiveValidAfter(isoDrag3, date.shiftedBy(2. * dt));
327 drivers = forceModel.getParametersDrivers();
328 Assertions.assertEquals(4, drivers.size());
329 Assertions.assertEquals(dragCd3, drivers.get(3).getValue(), 0.);
330 Assertions.assertEquals("custom-Cd", drivers.get(3).getName());
331
332
333
334 Assertions.assertEquals(isoDrag, forceModel.getDragSensitiveSpan(date).getData());
335 Assertions.assertEquals(isoDrag2, forceModel.getDragSensitiveSpan(date.shiftedBy(-dt - 86400.)).getData());
336 Assertions.assertEquals(isoDrag1, forceModel.getDragSensitiveSpan(date.shiftedBy(+dt + 1.)).getData());
337 Assertions.assertEquals(isoDrag3, forceModel.getDragSensitiveSpan(date.shiftedBy(2 * dt + 1.)).getData());
338
339
340 TimeSpanMap<DragSensitive> dragMap = forceModel.extractDragSensitiveRange(date, date.shiftedBy(dt + 1.));
341 Assertions.assertEquals(isoDrag, dragMap.getSpan(date).getData());
342 Assertions.assertEquals(isoDrag1, dragMap.getSpan(date.shiftedBy(dt + 86400.)).getData());
343 Assertions.assertEquals(isoDrag, dragMap.getSpan(date.shiftedBy(-dt - 86400.)).getData());
344 }
345
346
347
348
349
350
351
352 @Test
353 public void testParameterDerivativeSphere() {
354
355
356 final Vector3D pos = new Vector3D(6.46885878304673824e+06, -1.88050918456274318e+06, -1.32931592294715829e+04);
357 final Vector3D vel = new Vector3D(2.14718074509906819e+03, 7.38239351251748485e+03, -1.14097953925384523e+01);
358 final AbsoluteDate date = new AbsoluteDate(2003, 3, 5, 0, 24, 0.0, TimeScalesFactory.getTAI());
359 final SpacecraftState state =
360 new SpacecraftState(new CartesianOrbit(new PVCoordinates(pos, vel),
361 FramesFactory.getGCRF(),
362 date,
363 Constants.EIGEN5C_EARTH_MU));
364
365
366 final Atmosphere atmosphere = new HarrisPriester(CelestialBodyFactory.getSun(),
367 new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
368 Constants.WGS84_EARTH_FLATTENING,
369 FramesFactory.getITRF(IERSConventions.IERS_2010, true)));
370
371
372 final double dragArea = 2.5;
373
374
375 final double dragCd = 1.2;
376 final IsotropicDrag isotropicDrag = new IsotropicDrag(dragArea, dragCd);
377 isotropicDrag.getDragParametersDrivers().get(0).setName("Cd");
378 final TimeSpanDragForce forceModel = new TimeSpanDragForce(atmosphere, isotropicDrag, TimeScalesFactory.getUTC());
379
380
381
382 final double dragCd2 = 3.;
383 final double dt2 = 4 * 3600.;
384 final AbsoluteDate date2 = date.shiftedBy(dt2);
385 final IsotropicDrag isotropicDrag2 = new IsotropicDrag(dragArea, dragCd2);
386 isotropicDrag2.getDragParametersDrivers().get(0).setName("Cd2");
387 forceModel.addDragSensitiveValidAfter(isotropicDrag2, date2);
388
389
390 final double dragCd3 = 3.;
391 final double dt3 = -86400.;
392 final AbsoluteDate date3 = date.shiftedBy(dt3);
393 final IsotropicDrag isotropicDrag3 = new IsotropicDrag(dragArea, dragCd3);
394 isotropicDrag3.getDragParametersDrivers().get(0).setName("Cd3");
395 forceModel.addDragSensitiveValidBefore(isotropicDrag3, date3);
396
397
398 Assertions.assertFalse(forceModel.dependsOnPositionOnly());
399
400
401 checkParameterDerivative(state, forceModel, "Cd" , 1.0e-4, 2.0e-12);
402 checkParameterDerivative(state, forceModel, "Cd2", 1.0e-4, 0.);
403 checkParameterDerivative(state, forceModel, "Cd3", 1.0e-4, 0.);
404
405
406 checkParameterDerivative(state.shiftedBy(dt2 * 1.1), forceModel, "Cd", 1.0e-4, 0.);
407 checkParameterDerivative(state.shiftedBy(dt2 * 1.1), forceModel, "Cd2", 1.0e-4, 2.0e-12);
408 checkParameterDerivative(state.shiftedBy(dt2 * 1.1), forceModel, "Cd3", 1.0e-4, 0.);
409
410
411 checkParameterDerivative(state.shiftedBy(dt3 * 1.1), forceModel, "Cd", 1.0e-4, 0.);
412 checkParameterDerivative(state.shiftedBy(dt3 * 1.1), forceModel, "Cd2", 1.0e-4, 0.);
413 checkParameterDerivative(state.shiftedBy(dt3 * 1.1), forceModel, "Cd3", 1.0e-4, 2.0e-12);
414 }
415
416
417
418
419
420
421 @Test
422 public void testParameterDerivativeSphereGradient() {
423
424
425 final Vector3D pos = new Vector3D(6.46885878304673824e+06, -1.88050918456274318e+06, -1.32931592294715829e+04);
426 final Vector3D vel = new Vector3D(2.14718074509906819e+03, 7.38239351251748485e+03, -1.14097953925384523e+01);
427 final AbsoluteDate date = new AbsoluteDate(2003, 3, 5, 0, 24, 0.0, TimeScalesFactory.getTAI());
428 final SpacecraftState state =
429 new SpacecraftState(new CartesianOrbit(new PVCoordinates(pos, vel),
430 FramesFactory.getGCRF(),
431 date,
432 Constants.EIGEN5C_EARTH_MU));
433
434
435 final Atmosphere atmosphere = new HarrisPriester(CelestialBodyFactory.getSun(),
436 new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
437 Constants.WGS84_EARTH_FLATTENING,
438 FramesFactory.getITRF(IERSConventions.IERS_2010, true)));
439
440
441 final double dragArea = 2.5;
442
443
444 final double dragCd = 1.2;
445 final IsotropicDrag isotropicDrag = new IsotropicDrag(dragArea, dragCd);
446 isotropicDrag.getDragParametersDrivers().get(0).setName("Cd");
447 final TimeSpanDragForce forceModel = new TimeSpanDragForce(atmosphere, isotropicDrag, TimeScalesFactory.getUTC());
448
449
450
451 final double dragCd2 = 3.;
452 final double dt2 = 4 * 3600.;
453 final AbsoluteDate date2 = date.shiftedBy(dt2);
454 final IsotropicDrag isotropicDrag2 = new IsotropicDrag(dragArea, dragCd2);
455 isotropicDrag2.getDragParametersDrivers().get(0).setName("Cd2");
456 forceModel.addDragSensitiveValidAfter(isotropicDrag2, date2);
457
458
459 final double dragCd3 = 3.;
460 final double dt3 = -86400.;
461 final AbsoluteDate date3 = date.shiftedBy(dt3);
462 final IsotropicDrag isotropicDrag3 = new IsotropicDrag(dragArea, dragCd3);
463 isotropicDrag3.getDragParametersDrivers().get(0).setName("Cd3");
464 forceModel.addDragSensitiveValidBefore(isotropicDrag3, date3);
465
466
467 Assertions.assertFalse(forceModel.dependsOnPositionOnly());
468
469
470 checkParameterDerivativeGradient(state, forceModel, "Cd" , 1.0e-4, 2.0e-12);
471 checkParameterDerivativeGradient(state, forceModel, "Cd2", 1.0e-4, 0.);
472 checkParameterDerivativeGradient(state, forceModel, "Cd3", 1.0e-4, 0.);
473
474
475 checkParameterDerivativeGradient(state.shiftedBy(dt2 * 1.1), forceModel, "Cd", 1.0e-4, 0.);
476 checkParameterDerivativeGradient(state.shiftedBy(dt2 * 1.1), forceModel, "Cd2", 1.0e-4, 2.0e-12);
477 checkParameterDerivativeGradient(state.shiftedBy(dt2 * 1.1), forceModel, "Cd3", 1.0e-4, 0.);
478
479
480 checkParameterDerivativeGradient(state.shiftedBy(dt3 * 1.1), forceModel, "Cd", 1.0e-4, 0.);
481 checkParameterDerivativeGradient(state.shiftedBy(dt3 * 1.1), forceModel, "Cd2", 1.0e-4, 0.);
482 checkParameterDerivativeGradient(state.shiftedBy(dt3 * 1.1), forceModel, "Cd3", 1.0e-4, 2.0e-12);
483 }
484
485
486 @Test
487 public void testStateJacobianSphere()
488 {
489
490
491 AbsoluteDate date = new AbsoluteDate(new DateComponents(2003, 03, 01),
492 new TimeComponents(13, 59, 27.816),
493 TimeScalesFactory.getUTC());
494 double i = FastMath.toRadians(98.7);
495 double omega = FastMath.toRadians(93.0);
496 double OMEGA = FastMath.toRadians(15.0 * 22.5);
497 Orbit orbit = new KeplerianOrbit(7201009.7124401, 1e-3, i , omega, OMEGA,
498 0, PositionAngle.MEAN, FramesFactory.getEME2000(), date,
499 Constants.EIGEN5C_EARTH_MU);
500 OrbitType integrationType = OrbitType.CARTESIAN;
501 double[][] tolerances = NumericalPropagator.tolerances(0.01, orbit, integrationType);
502
503
504
505
506 final Atmosphere atmosphere = new HarrisPriester(CelestialBodyFactory.getSun(),
507 new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
508 Constants.WGS84_EARTH_FLATTENING,
509 FramesFactory.getITRF(IERSConventions.IERS_2010, true)));
510
511
512 double dragArea = 2.;
513 double dragCd0 = 1.;
514 double dragCd1 = 2.;
515 double dragCd2 = 3.;
516 double dt = 1. * 3600.;
517
518 IsotropicDrag isoDrag0 = new IsotropicDrag(dragArea, dragCd0);
519 IsotropicDrag isoDrag1 = new IsotropicDrag(dragArea, dragCd1);
520 IsotropicDrag isoDrag2 = new IsotropicDrag(dragArea, dragCd2);
521 TimeSpanDragForce forceModel = new TimeSpanDragForce(atmosphere, isoDrag0);
522 forceModel.addDragSensitiveValidAfter(isoDrag1, date.shiftedBy(dt));
523 forceModel.addDragSensitiveValidBefore(isoDrag2, date.shiftedBy(-dt));
524
525
526 NumericalPropagator propagator =
527 new NumericalPropagator(new DormandPrince853Integrator(1.0e-3, 120,
528 tolerances[0], tolerances[1]));
529 propagator.setOrbitType(integrationType);
530 propagator.addForceModel(forceModel);
531 SpacecraftState state0 = new SpacecraftState(orbit);
532
533
534 checkStateJacobian(propagator, state0, date.shiftedBy(0.5 * dt),
535 1e3, tolerances[0], 9.2e-10);
536
537
538 propagator = new NumericalPropagator(new DormandPrince853Integrator(1.0e-3, 120,
539 tolerances[0], tolerances[1]));
540 propagator.setOrbitType(integrationType);
541 propagator.addForceModel(forceModel);
542
543
544 checkStateJacobian(propagator, state0, date.shiftedBy(1.5 * dt),
545 1e3, tolerances[0], 6.7e-9);
546
547
548 propagator = new NumericalPropagator(new DormandPrince853Integrator(1.0e-3, 120,
549 tolerances[0], tolerances[1]));
550 propagator.setOrbitType(integrationType);
551 propagator.addForceModel(forceModel);
552
553
554 checkStateJacobian(propagator, state0, date.shiftedBy(-1.5 * dt),
555 1e3, tolerances[0], 6.0e-9);
556 }
557
558
559
560
561
562 @Test
563 public void testGetParameterDriversBoxOnlyDrag() {
564
565
566 final CelestialBody sun = CelestialBodyFactory.getSun();
567 final Atmosphere atmosphere = new HarrisPriester(sun,
568 new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
569 Constants.WGS84_EARTH_FLATTENING,
570 FramesFactory.getITRF(IERSConventions.IERS_2010, true)));
571
572
573 AbsoluteDate date = new AbsoluteDate("2000-01-01T00:00:00.000", TimeScalesFactory.getUTC());
574
575
576
577
578 double dragCd0 = 0.;
579 BoxAndSolarArraySpacecraft box0 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8,
580 sun, 20.0, Vector3D.PLUS_J,
581 dragCd0,
582 0.7, 0.2);
583 TimeSpanDragForce forceModel = new TimeSpanDragForce(atmosphere, box0);
584 Assertions.assertFalse(forceModel.dependsOnPositionOnly());
585 List<ParameterDriver> drivers = forceModel.getParametersDrivers();
586 Assertions.assertEquals(1, drivers.size());
587 Assertions.assertEquals(dragCd0, drivers.get(0).getValue(), 0.);
588 Assertions.assertEquals(DragSensitive.DRAG_COEFFICIENT, drivers.get(0).getName());
589
590
591 BoxAndSolarArraySpacecraft box = (BoxAndSolarArraySpacecraft) forceModel.getDragSensitive(date);
592 drivers = box.getDragParametersDrivers();
593 Assertions.assertEquals(1, drivers.size());
594 Assertions.assertEquals(dragCd0, drivers.get(0).getValue(), 0.);
595 Assertions.assertEquals(DragSensitive.DRAG_COEFFICIENT, drivers.get(0).getName());
596
597
598
599 double dragCd1 = 1.;
600 double dragCd2 = 2.;
601 double dt = 120.;
602
603 BoxAndSolarArraySpacecraft box1 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8,
604 sun, 20.0, Vector3D.PLUS_J,
605 dragCd1,
606 0.7, 0.2);
607 BoxAndSolarArraySpacecraft box2 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8,
608 sun, 20.0, Vector3D.PLUS_J,
609 dragCd2,
610 0.7, 0.2);
611 forceModel = new TimeSpanDragForce(atmosphere, box0);
612 forceModel.addDragSensitiveValidAfter(box1, date.shiftedBy(dt));
613 forceModel.addDragSensitiveValidBefore(box2, date.shiftedBy(-dt));
614
615
616 drivers = forceModel.getParametersDrivers();
617 Assertions.assertEquals(3, drivers.size());
618 Assertions.assertEquals(dragCd2, drivers.get(0).getValue(), 0.);
619 Assertions.assertEquals(DragSensitive.DRAG_COEFFICIENT + TimeSpanDragForce.DATE_BEFORE + date.shiftedBy(-dt).toString(utc),
620 drivers.get(0).getName());
621
622 Assertions.assertEquals(dragCd0, drivers.get(1).getValue(), 0.);
623 Assertions.assertEquals(DragSensitive.DRAG_COEFFICIENT, drivers.get(1).getName());
624
625 Assertions.assertEquals(dragCd1, drivers.get(2).getValue(), 0.);
626 Assertions.assertEquals(DragSensitive.DRAG_COEFFICIENT + TimeSpanDragForce.DATE_AFTER + date.shiftedBy(+dt).toString(utc),
627 drivers.get(2).getName());
628
629
630
631 double eps = 1.e-14;
632 Assertions.assertEquals(box0, forceModel.getDragSensitive(date));
633 Assertions.assertEquals(box0, forceModel.getDragSensitive(date.shiftedBy(-dt)));
634 Assertions.assertEquals(box0, forceModel.getDragSensitive(date.shiftedBy(+dt - eps)));
635
636 Assertions.assertEquals(box2, forceModel.getDragSensitive(date.shiftedBy(-dt - eps)));
637 Assertions.assertEquals(box2, forceModel.getDragSensitive(date.shiftedBy(-dt - 86400.)));
638
639 Assertions.assertEquals(box1, forceModel.getDragSensitive(date.shiftedBy(+dt)));
640 Assertions.assertEquals(box1, forceModel.getDragSensitive(date.shiftedBy(+dt + 86400.)));
641
642
643
644 double dragCd3 = 3.;
645 BoxAndSolarArraySpacecraft box3 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8,
646 sun, 20.0, Vector3D.PLUS_J,
647 dragCd3,
648 0.7, 0.2);
649 box3.getDragParametersDrivers().get(0).setName("custom-Cd");
650 forceModel.addDragSensitiveValidAfter(box3, date.shiftedBy(2. * dt));
651 drivers = forceModel.getParametersDrivers();
652 Assertions.assertEquals(4, drivers.size());
653 Assertions.assertEquals(dragCd3, drivers.get(3).getValue(), 0.);
654 Assertions.assertEquals("custom-Cd", drivers.get(3).getName());
655 }
656
657
658
659
660
661 @Test
662 public void testGetParameterDriversBox() {
663
664
665 final CelestialBody sun = CelestialBodyFactory.getSun();
666 final Atmosphere atmosphere = new HarrisPriester(sun,
667 new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
668 Constants.WGS84_EARTH_FLATTENING,
669 FramesFactory.getITRF(IERSConventions.IERS_2010, true)));
670
671
672 AbsoluteDate date = new AbsoluteDate("2000-01-01T00:00:00.000", TimeScalesFactory.getUTC());
673
674
675
676
677 double dragCd0 = 0.;
678 double dragCl0 = 0.;
679 BoxAndSolarArraySpacecraft box0 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8,
680 sun, 20.0, Vector3D.PLUS_J,
681 dragCd0, dragCl0,
682 0.7, 0.2);
683 TimeSpanDragForce forceModel = new TimeSpanDragForce(atmosphere, box0);
684 Assertions.assertFalse(forceModel.dependsOnPositionOnly());
685 List<ParameterDriver> drivers = forceModel.getParametersDrivers();
686 Assertions.assertEquals(2, drivers.size());
687 Assertions.assertEquals(dragCd0, drivers.get(0).getValue(), 0.);
688 Assertions.assertEquals(DragSensitive.DRAG_COEFFICIENT, drivers.get(0).getName());
689 Assertions.assertEquals(dragCl0, drivers.get(1).getValue(), 0.);
690 Assertions.assertEquals(DragSensitive.LIFT_RATIO, drivers.get(1).getName());
691
692
693 BoxAndSolarArraySpacecraft box = (BoxAndSolarArraySpacecraft) forceModel.getDragSensitive(date);
694 drivers = box.getDragParametersDrivers();
695 Assertions.assertEquals(2, drivers.size());
696 Assertions.assertEquals(dragCd0, drivers.get(0).getValue(), 0.);
697 Assertions.assertEquals(DragSensitive.DRAG_COEFFICIENT, drivers.get(0).getName());
698 Assertions.assertEquals(dragCl0, drivers.get(1).getValue(), 0.);
699 Assertions.assertEquals(DragSensitive.LIFT_RATIO, drivers.get(1).getName());
700
701
702
703 double dragCd1 = 1.;
704 double dragCl1 = 0.1;
705 double dragCd2 = 2.;
706 double dragCl2 = 0.2;
707 double dt = 120.;
708
709 BoxAndSolarArraySpacecraft box1 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8,
710 sun, 20.0, Vector3D.PLUS_J,
711 dragCd1, dragCl1,
712 0.7, 0.2);
713 BoxAndSolarArraySpacecraft box2 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8,
714 sun, 20.0, Vector3D.PLUS_J,
715 dragCd2, dragCl2,
716 0.7, 0.2);
717 forceModel = new TimeSpanDragForce(atmosphere, box0);
718 forceModel.addDragSensitiveValidAfter(box1, date.shiftedBy(dt));
719 forceModel.addDragSensitiveValidBefore(box2, date.shiftedBy(-dt));
720
721
722 drivers = forceModel.getParametersDrivers();
723 Assertions.assertEquals(6, drivers.size());
724 Assertions.assertEquals(dragCd2, drivers.get(0).getValue(), 0.);
725 Assertions.assertEquals(DragSensitive.DRAG_COEFFICIENT + TimeSpanDragForce.DATE_BEFORE + date.shiftedBy(-dt).toString(utc),
726 drivers.get(0).getName());
727 Assertions.assertEquals(dragCl2, drivers.get(1).getValue(), 0.);
728 Assertions.assertEquals(DragSensitive.LIFT_RATIO + TimeSpanDragForce.DATE_BEFORE + date.shiftedBy(-dt).toString(utc),
729 drivers.get(1).getName());
730
731 Assertions.assertEquals(dragCd0, drivers.get(2).getValue(), 0.);
732 Assertions.assertEquals(DragSensitive.DRAG_COEFFICIENT, drivers.get(2).getName());
733 Assertions.assertEquals(dragCl0, drivers.get(3).getValue(), 0.);
734 Assertions.assertEquals(DragSensitive.LIFT_RATIO, drivers.get(3).getName());
735
736 Assertions.assertEquals(dragCd1, drivers.get(4).getValue(), 0.);
737 Assertions.assertEquals(DragSensitive.DRAG_COEFFICIENT + TimeSpanDragForce.DATE_AFTER + date.shiftedBy(+dt).toString(utc),
738 drivers.get(4).getName());
739 Assertions.assertEquals(dragCl1, drivers.get(5).getValue(), 0.);
740 Assertions.assertEquals(DragSensitive.LIFT_RATIO + TimeSpanDragForce.DATE_AFTER + date.shiftedBy(+dt).toString(utc),
741 drivers.get(5).getName());
742
743
744
745 double eps = 1.e-14;
746 Assertions.assertEquals(box0, forceModel.getDragSensitive(date));
747 Assertions.assertEquals(box0, forceModel.getDragSensitive(date.shiftedBy(-dt)));
748 Assertions.assertEquals(box0, forceModel.getDragSensitive(date.shiftedBy(+dt - eps)));
749
750 Assertions.assertEquals(box2, forceModel.getDragSensitive(date.shiftedBy(-dt - eps)));
751 Assertions.assertEquals(box2, forceModel.getDragSensitive(date.shiftedBy(-dt - 86400.)));
752
753 Assertions.assertEquals(box1, forceModel.getDragSensitive(date.shiftedBy(+dt)));
754 Assertions.assertEquals(box1, forceModel.getDragSensitive(date.shiftedBy(+dt + 86400.)));
755
756
757
758
759 double dragCd3 = 3.;
760 double dragCl3 = 0.3;
761 BoxAndSolarArraySpacecraft box3 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8,
762 sun, 20.0, Vector3D.PLUS_J,
763 dragCd3, dragCl3,
764 0.7, 0.2);
765 box3.getDragParametersDrivers().get(0).setName("custom-Cd");
766 box3.getDragParametersDrivers().get(1).setName("custom-Cl");
767 forceModel.addDragSensitiveValidAfter(box3, date.shiftedBy(2. * dt));
768 drivers = forceModel.getParametersDrivers();
769 Assertions.assertEquals(8, drivers.size());
770 Assertions.assertEquals(dragCd3, drivers.get(6).getValue(), 0.);
771 Assertions.assertEquals("custom-Cd", drivers.get(6).getName());
772 Assertions.assertEquals(dragCl3, drivers.get(7).getValue(), 0.);
773 Assertions.assertEquals("custom-Cl", drivers.get(7).getName());
774 }
775
776
777
778
779
780
781 @Test
782 public void testParametersDerivativesBox() {
783
784
785 final Vector3D pos = new Vector3D(6.46885878304673824e+06, -1.88050918456274318e+06, -1.32931592294715829e+04);
786 final Vector3D vel = new Vector3D(2.14718074509906819e+03, 7.38239351251748485e+03, -1.14097953925384523e+01);
787 final AbsoluteDate date = new AbsoluteDate(2003, 3, 5, 0, 24, 0.0, TimeScalesFactory.getTAI());
788 final SpacecraftState state =
789 new SpacecraftState(new CartesianOrbit(new PVCoordinates(pos, vel),
790 FramesFactory.getGCRF(),
791 date,
792 Constants.EIGEN5C_EARTH_MU));
793
794
795 final CelestialBody sun = CelestialBodyFactory.getSun();
796 final Atmosphere atmosphere = new HarrisPriester(sun,
797 new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
798 Constants.WGS84_EARTH_FLATTENING,
799 FramesFactory.getITRF(IERSConventions.IERS_2010, true)));
800
801
802 final double dragCd = 1.;
803 final double dragCl = 0.1;
804 final BoxAndSolarArraySpacecraft box = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8,
805 sun, 20.0, Vector3D.PLUS_J,
806 dragCd, dragCl, 0.7, 0.2);
807 final TimeSpanDragForce forceModel = new TimeSpanDragForce(atmosphere, box);
808
809
810
811 final double dragCd2 = 2.;
812 final double dragCl2 = 0.2;
813 final double dt2 = 4 * 3600.;
814 final AbsoluteDate date2 = date.shiftedBy(dt2);
815 final BoxAndSolarArraySpacecraft box2 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8,
816 sun, 20.0, Vector3D.PLUS_J,
817 dragCd2, dragCl2, 0.7, 0.2);
818 box2.getDragParametersDrivers().get(0).setName("Cd2");
819 box2.getDragParametersDrivers().get(1).setName("Cl2");
820 forceModel.addDragSensitiveValidAfter(box2, date2);
821
822
823 final double dragCd3 = 3.;
824 final double dragCl3 = 0.3;
825 final double dt3 = -86400.;
826 final AbsoluteDate date3 = date.shiftedBy(dt3);
827 final BoxAndSolarArraySpacecraft box3 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8,
828 sun, 20.0, Vector3D.PLUS_J,
829 dragCd3, dragCl3, 0.7, 0.2);
830 box3.getDragParametersDrivers().get(0).setName("Cd3");
831 forceModel.addDragSensitiveValidBefore(box3, date3);
832
833
834 final String nameCl3 = DragSensitive.LIFT_RATIO + TimeSpanDragForce.DATE_BEFORE + date3.toString(utc);
835
836
837 Assertions.assertFalse(forceModel.dependsOnPositionOnly());
838
839
840 checkParameterDerivative(state, forceModel, DragSensitive.DRAG_COEFFICIENT, 1.0e-4, 2.0e-12);
841 checkParameterDerivative(state, forceModel, DragSensitive.LIFT_RATIO, 1.0e-4, 2.2e-11);
842 checkParameterDerivative(state, forceModel, "Cd2", 1.0e-4, 0.);
843 checkParameterDerivative(state, forceModel, "Cl2", 1.0e-4, 0.);
844 checkParameterDerivative(state, forceModel, "Cd3", 1.0e-4, 0.);
845 checkParameterDerivative(state, forceModel, nameCl3, 1.0e-4, 0.);
846
847
848 checkParameterDerivative(state.shiftedBy(dt2 * 1.1), forceModel, DragSensitive.DRAG_COEFFICIENT, 1.0e-4, 0.);
849 checkParameterDerivative(state.shiftedBy(dt2 * 1.1), forceModel, DragSensitive.LIFT_RATIO, 1.0e-4, 0.);
850 checkParameterDerivative(state.shiftedBy(dt2 * 1.1), forceModel, "Cd2", 1.0e-4, 2.2e-12);
851 checkParameterDerivative(state.shiftedBy(dt2 * 1.1), forceModel, "Cl2", 1.0e-4, 2.0e-11);
852 checkParameterDerivative(state.shiftedBy(dt2 * 1.1), forceModel, "Cd3", 1.0e-4, 0.);
853 checkParameterDerivative(state.shiftedBy(dt2 * 1.1), forceModel, nameCl3, 1.0e-4, 0.);
854
855
856 checkParameterDerivative(state.shiftedBy(dt3 * 1.1), forceModel, DragSensitive.DRAG_COEFFICIENT, 1.0e-4, 0.);
857 checkParameterDerivative(state.shiftedBy(dt3 * 1.1), forceModel, DragSensitive.LIFT_RATIO, 1.0e-4, 0.);
858 checkParameterDerivative(state.shiftedBy(dt3 * 1.1), forceModel, "Cd2", 1.0e-4, 0.);
859 checkParameterDerivative(state.shiftedBy(dt3 * 1.1), forceModel, "Cl2", 1.0e-4, 0.);
860 checkParameterDerivative(state.shiftedBy(dt3 * 1.1), forceModel, "Cd3", 1.0e-4, 2.0e-12);
861 checkParameterDerivative(state.shiftedBy(dt3 * 1.1), forceModel, nameCl3, 1.0e-4, 2.0e-11);
862 }
863
864
865
866
867
868
869 @Test
870 public void testParametersDerivativesBoxGradient() {
871
872
873 final Vector3D pos = new Vector3D(6.46885878304673824e+06, -1.88050918456274318e+06, -1.32931592294715829e+04);
874 final Vector3D vel = new Vector3D(2.14718074509906819e+03, 7.38239351251748485e+03, -1.14097953925384523e+01);
875 final AbsoluteDate date = new AbsoluteDate(2003, 3, 5, 0, 24, 0.0, TimeScalesFactory.getTAI());
876 final SpacecraftState state =
877 new SpacecraftState(new CartesianOrbit(new PVCoordinates(pos, vel),
878 FramesFactory.getGCRF(),
879 date,
880 Constants.EIGEN5C_EARTH_MU));
881
882
883 final CelestialBody sun = CelestialBodyFactory.getSun();
884 final Atmosphere atmosphere = new HarrisPriester(sun,
885 new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
886 Constants.WGS84_EARTH_FLATTENING,
887 FramesFactory.getITRF(IERSConventions.IERS_2010, true)));
888
889
890 final double dragCd = 1.;
891 final double dragCl = 0.1;
892 final BoxAndSolarArraySpacecraft box = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8,
893 sun, 20.0, Vector3D.PLUS_J,
894 dragCd, dragCl, 0.7, 0.2);
895 final TimeSpanDragForce forceModel = new TimeSpanDragForce(atmosphere, box);
896
897
898
899 final double dragCd2 = 2.;
900 final double dragCl2 = 0.2;
901 final double dt2 = 4 * 3600.;
902 final AbsoluteDate date2 = date.shiftedBy(dt2);
903 final BoxAndSolarArraySpacecraft box2 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8,
904 sun, 20.0, Vector3D.PLUS_J,
905 dragCd2, dragCl2, 0.7, 0.2);
906 box2.getDragParametersDrivers().get(0).setName("Cd2");
907 box2.getDragParametersDrivers().get(1).setName("Cl2");
908 forceModel.addDragSensitiveValidAfter(box2, date2);
909
910
911 final double dragCd3 = 3.;
912 final double dragCl3 = 0.3;
913 final double dt3 = -86400.;
914 final AbsoluteDate date3 = date.shiftedBy(dt3);
915 final BoxAndSolarArraySpacecraft box3 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8,
916 sun, 20.0, Vector3D.PLUS_J,
917 dragCd3, dragCl3, 0.7, 0.2);
918 box3.getDragParametersDrivers().get(0).setName("Cd3");
919 forceModel.addDragSensitiveValidBefore(box3, date3);
920
921
922 final String nameCl3 = DragSensitive.LIFT_RATIO + TimeSpanDragForce.DATE_BEFORE + date3.toString(utc);
923
924
925 Assertions.assertFalse(forceModel.dependsOnPositionOnly());
926
927
928 checkParameterDerivativeGradient(state, forceModel, DragSensitive.DRAG_COEFFICIENT, 1.0e-4, 2.0e-12);
929 checkParameterDerivativeGradient(state, forceModel, DragSensitive.LIFT_RATIO, 1.0e-4, 2.2e-11);
930 checkParameterDerivativeGradient(state, forceModel, "Cd2", 1.0e-4, 0.);
931 checkParameterDerivativeGradient(state, forceModel, "Cl2", 1.0e-4, 0.);
932 checkParameterDerivativeGradient(state, forceModel, "Cd3", 1.0e-4, 0.);
933 checkParameterDerivativeGradient(state, forceModel, nameCl3, 1.0e-4, 0.);
934
935
936 checkParameterDerivativeGradient(state.shiftedBy(dt2 * 1.1), forceModel, DragSensitive.DRAG_COEFFICIENT, 1.0e-4, 0.);
937 checkParameterDerivativeGradient(state.shiftedBy(dt2 * 1.1), forceModel, DragSensitive.LIFT_RATIO, 1.0e-4, 0.);
938 checkParameterDerivativeGradient(state.shiftedBy(dt2 * 1.1), forceModel, "Cd2", 1.0e-4, 2.2e-12);
939 checkParameterDerivativeGradient(state.shiftedBy(dt2 * 1.1), forceModel, "Cl2", 1.0e-4, 2.0e-11);
940 checkParameterDerivativeGradient(state.shiftedBy(dt2 * 1.1), forceModel, "Cd3", 1.0e-4, 0.);
941 checkParameterDerivativeGradient(state.shiftedBy(dt2 * 1.1), forceModel, nameCl3, 1.0e-4, 0.);
942
943
944 checkParameterDerivativeGradient(state.shiftedBy(dt3 * 1.1), forceModel, DragSensitive.DRAG_COEFFICIENT, 1.0e-4, 0.);
945 checkParameterDerivativeGradient(state.shiftedBy(dt3 * 1.1), forceModel, DragSensitive.LIFT_RATIO, 1.0e-4, 0.);
946 checkParameterDerivativeGradient(state.shiftedBy(dt3 * 1.1), forceModel, "Cd2", 1.0e-4, 0.);
947 checkParameterDerivativeGradient(state.shiftedBy(dt3 * 1.1), forceModel, "Cl2", 1.0e-4, 0.);
948 checkParameterDerivativeGradient(state.shiftedBy(dt3 * 1.1), forceModel, "Cd3", 1.0e-4, 2.0e-12);
949 checkParameterDerivativeGradient(state.shiftedBy(dt3 * 1.1), forceModel, nameCl3, 1.0e-4, 2.0e-11);
950 }
951
952
953
954
955 @Test
956 public void testJacobianBoxVs80Implementation()
957 {
958
959
960 AbsoluteDate date = new AbsoluteDate(new DateComponents(2003, 03, 01),
961 new TimeComponents(13, 59, 27.816),
962 TimeScalesFactory.getUTC());
963 double i = FastMath.toRadians(98.7);
964 double omega = FastMath.toRadians(93.0);
965 double OMEGA = FastMath.toRadians(15.0 * 22.5);
966 Orbit refOrbit = new KeplerianOrbit(7201009.7124401, 1e-3, i , omega, OMEGA,
967 0, PositionAngle.MEAN, FramesFactory.getEME2000(), date,
968 Constants.EIGEN5C_EARTH_MU);
969 CelestialBody sun = CelestialBodyFactory.getSun();
970
971
972 final Atmosphere atmosphere =
973 new HarrisPriester(sun,
974 new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
975 Constants.WGS84_EARTH_FLATTENING,
976 FramesFactory.getITRF(IERSConventions.IERS_2010, true)));
977
978 double dragCd0 = 1.;
979 double dragCl0 = 0.1;
980 double dragCd1 = 2.;
981 double dragCl1 = 0.2;
982 double dragCd2 = 3.;
983 double dragCl2 = 0.3;
984 double dt = 3. * 3600.;
985
986
987 BoxAndSolarArraySpacecraft box0 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8, sun, 20.0,
988 Vector3D.PLUS_J, dragCd0, dragCl0, 0.7, 0.2);
989 BoxAndSolarArraySpacecraft box1 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8, sun, 20.0,
990 Vector3D.PLUS_J, dragCd1, dragCl1, 0.7, 0.2);
991 BoxAndSolarArraySpacecraft box2 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8, sun, 20.0,
992 Vector3D.PLUS_J, dragCd2, dragCl2, 0.7, 0.2);
993 TimeSpanDragForce forceModel = new TimeSpanDragForce(atmosphere, box0);
994 forceModel.addDragSensitiveValidAfter(box1, date.shiftedBy(dt));
995 forceModel.addDragSensitiveValidBefore(box2, date.shiftedBy(-dt));
996
997
998 Orbit orbit = refOrbit.shiftedBy(0.);
999 SpacecraftState state = new SpacecraftState(orbit,
1000 Utils.defaultLaw().getAttitude(orbit, orbit.getDate(), orbit.getFrame()));
1001 checkStateJacobianVs80Implementation(state, forceModel,
1002 new LofOffset(state.getFrame(), LOFType.LVLH_CCSDS),
1003 5e-6, false);
1004
1005
1006 orbit = refOrbit.shiftedBy(1.1 * dt);
1007 state = new SpacecraftState(orbit,
1008 Utils.defaultLaw().getAttitude(orbit, orbit.getDate(), orbit.getFrame()));
1009 checkStateJacobianVs80Implementation(state, forceModel,
1010 new LofOffset(state.getFrame(), LOFType.LVLH_CCSDS),
1011 5e-6, false);
1012
1013
1014 orbit = refOrbit.shiftedBy(-1.1 * dt);
1015 state = new SpacecraftState(orbit,
1016 Utils.defaultLaw().getAttitude(orbit, orbit.getDate(), orbit.getFrame()));
1017 checkStateJacobianVs80Implementation(state, forceModel,
1018 new LofOffset(state.getFrame(), LOFType.LVLH_CCSDS),
1019 5e-6, false);
1020
1021 }
1022
1023
1024
1025
1026 @Test
1027 public void testJacobianBoxVs80ImplementationGradient()
1028 {
1029
1030
1031 AbsoluteDate date = new AbsoluteDate(new DateComponents(2003, 03, 01),
1032 new TimeComponents(13, 59, 27.816),
1033 TimeScalesFactory.getUTC());
1034 double i = FastMath.toRadians(98.7);
1035 double omega = FastMath.toRadians(93.0);
1036 double OMEGA = FastMath.toRadians(15.0 * 22.5);
1037 Orbit refOrbit = new KeplerianOrbit(7201009.7124401, 1e-3, i , omega, OMEGA,
1038 0, PositionAngle.MEAN, FramesFactory.getEME2000(), date,
1039 Constants.EIGEN5C_EARTH_MU);
1040 CelestialBody sun = CelestialBodyFactory.getSun();
1041 AttitudeProvider defaultLaw = Utils.defaultLaw();
1042
1043
1044 final Atmosphere atmosphere =
1045 new HarrisPriester(sun,
1046 new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
1047 Constants.WGS84_EARTH_FLATTENING,
1048 FramesFactory.getITRF(IERSConventions.IERS_2010, true)));
1049
1050 double dragCd0 = 1.;
1051 double dragCl0 = 0.1;
1052 double dragCd1 = 2.;
1053 double dragCl1 = 0.2;
1054 double dragCd2 = 3.;
1055 double dragCl2 = 0.3;
1056 double dt = 3. * 3600.;
1057
1058
1059 BoxAndSolarArraySpacecraft box0 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8, sun, 20.0,
1060 Vector3D.PLUS_J, dragCd0, dragCl0, 0.7, 0.2);
1061 BoxAndSolarArraySpacecraft box1 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8, sun, 20.0,
1062 Vector3D.PLUS_J, dragCd1, dragCl1, 0.7, 0.2);
1063 BoxAndSolarArraySpacecraft box2 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8, sun, 20.0,
1064 Vector3D.PLUS_J, dragCd2, dragCl2, 0.7, 0.2);
1065 TimeSpanDragForce forceModel = new TimeSpanDragForce(atmosphere, box0);
1066 forceModel.addDragSensitiveValidAfter(box1, date.shiftedBy(dt));
1067 forceModel.addDragSensitiveValidBefore(box2, date.shiftedBy(-dt));
1068
1069
1070 Orbit orbit = refOrbit.shiftedBy(0.);
1071 SpacecraftState state = new SpacecraftState(orbit,
1072 Utils.defaultLaw().getAttitude(orbit, orbit.getDate(), orbit.getFrame()));
1073 checkStateJacobianVs80ImplementationGradient(state, forceModel,
1074 new LofOffset(state.getFrame(), LOFType.LVLH_CCSDS),
1075 5e-6, false);
1076
1077
1078 orbit = refOrbit.shiftedBy(1.1 * dt);
1079 state = new SpacecraftState(orbit,
1080 defaultLaw.getAttitude(orbit, orbit.getDate(), orbit.getFrame()));
1081 checkStateJacobianVs80ImplementationGradient(state, forceModel,
1082 new LofOffset(state.getFrame(), LOFType.LVLH_CCSDS),
1083 5e-6, false);
1084
1085
1086 orbit = refOrbit.shiftedBy(-1.1 * dt);
1087 state = new SpacecraftState(orbit,
1088 defaultLaw.getAttitude(orbit, orbit.getDate(), orbit.getFrame()));
1089 checkStateJacobianVs80ImplementationGradient(state, forceModel,
1090 new LofOffset(state.getFrame(), LOFType.LVLH_CCSDS),
1091 5e-6, false);
1092
1093 }
1094
1095
1096
1097
1098 @Test
1099 public void testJacobianBoxVsFiniteDifferences()
1100 {
1101
1102
1103 AbsoluteDate date = new AbsoluteDate(new DateComponents(2003, 03, 01),
1104 new TimeComponents(13, 59, 27.816),
1105 TimeScalesFactory.getUTC());
1106 double i = FastMath.toRadians(98.7);
1107 double omega = FastMath.toRadians(93.0);
1108 double OMEGA = FastMath.toRadians(15.0 * 22.5);
1109 Orbit refOrbit = new KeplerianOrbit(7201009.7124401, 1e-3, i , omega, OMEGA,
1110 0, PositionAngle.MEAN, FramesFactory.getEME2000(), date,
1111 Constants.EIGEN5C_EARTH_MU);
1112 CelestialBody sun = CelestialBodyFactory.getSun();
1113 AttitudeProvider defaultLaw = Utils.defaultLaw();
1114
1115
1116 final Atmosphere atmosphere =
1117 new HarrisPriester(sun,
1118 new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
1119 Constants.WGS84_EARTH_FLATTENING,
1120 FramesFactory.getITRF(IERSConventions.IERS_2010, true)));
1121
1122
1123 double dragCd0 = 1.;
1124 double dragCl0 = 0.1;
1125 double dragCd1 = 2.;
1126 double dragCl1 = 0.2;
1127 double dragCd2 = 3.;
1128 double dragCl2 = 0.3;
1129 double dt = 3. * 3600.;
1130
1131
1132 BoxAndSolarArraySpacecraft box0 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8, sun, 20.0,
1133 Vector3D.PLUS_J, dragCd0, dragCl0, 0.7, 0.2);
1134 BoxAndSolarArraySpacecraft box1 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8, sun, 20.0,
1135 Vector3D.PLUS_J, dragCd1, dragCl1, 0.7, 0.2);
1136 BoxAndSolarArraySpacecraft box2 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8, sun, 20.0,
1137 Vector3D.PLUS_J, dragCd2, dragCl2, 0.7, 0.2);
1138 TimeSpanDragForce forceModel = new TimeSpanDragForce(atmosphere, box0);
1139 forceModel.addDragSensitiveValidAfter(box1, date.shiftedBy(dt));
1140 forceModel.addDragSensitiveValidBefore(box2, date.shiftedBy(-dt));
1141
1142
1143 Orbit orbit = refOrbit.shiftedBy(0.);
1144 SpacecraftState state = new SpacecraftState(orbit,
1145 defaultLaw.getAttitude(orbit, orbit.getDate(), orbit.getFrame()));
1146 checkStateJacobianVsFiniteDifferences(state, forceModel, defaultLaw, 1.0, 5.0e-6, false);
1147
1148
1149 orbit = refOrbit.shiftedBy(1.1 * dt);
1150 state = new SpacecraftState(orbit,
1151 defaultLaw.getAttitude(orbit, orbit.getDate(), orbit.getFrame()));
1152 checkStateJacobianVsFiniteDifferences(state, forceModel, defaultLaw, 1.0, 5.0e-6, false);
1153
1154
1155 orbit = refOrbit.shiftedBy(-1.1 * dt);
1156 state = new SpacecraftState(orbit,
1157 defaultLaw.getAttitude(orbit, orbit.getDate(), orbit.getFrame()));
1158 checkStateJacobianVsFiniteDifferences(state, forceModel, defaultLaw, 1.0, 6.0e-6, false);
1159 }
1160
1161
1162
1163
1164 @Test
1165 public void testJacobianBoxVsFiniteDifferencesGradient()
1166 {
1167
1168
1169 AbsoluteDate date = new AbsoluteDate(new DateComponents(2003, 03, 01),
1170 new TimeComponents(13, 59, 27.816),
1171 TimeScalesFactory.getUTC());
1172 double i = FastMath.toRadians(98.7);
1173 double omega = FastMath.toRadians(93.0);
1174 double OMEGA = FastMath.toRadians(15.0 * 22.5);
1175 Orbit refOrbit = new KeplerianOrbit(7201009.7124401, 1e-3, i , omega, OMEGA,
1176 0, PositionAngle.MEAN, FramesFactory.getEME2000(), date,
1177 Constants.EIGEN5C_EARTH_MU);
1178 CelestialBody sun = CelestialBodyFactory.getSun();
1179 AttitudeProvider defaultLaw = Utils.defaultLaw();
1180
1181
1182 final Atmosphere atmosphere =
1183 new HarrisPriester(sun,
1184 new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
1185 Constants.WGS84_EARTH_FLATTENING,
1186 FramesFactory.getITRF(IERSConventions.IERS_2010, true)));
1187
1188
1189 double dragCd0 = 1.;
1190 double dragCl0 = 0.1;
1191 double dragCd1 = 2.;
1192 double dragCl1 = 0.2;
1193 double dragCd2 = 3.;
1194 double dragCl2 = 0.3;
1195 double dt = 3. * 3600.;
1196
1197
1198 BoxAndSolarArraySpacecraft box0 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8, sun, 20.0,
1199 Vector3D.PLUS_J, dragCd0, dragCl0, 0.7, 0.2);
1200 BoxAndSolarArraySpacecraft box1 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8, sun, 20.0,
1201 Vector3D.PLUS_J, dragCd1, dragCl1, 0.7, 0.2);
1202 BoxAndSolarArraySpacecraft box2 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8, sun, 20.0,
1203 Vector3D.PLUS_J, dragCd2, dragCl2, 0.7, 0.2);
1204 TimeSpanDragForce forceModel = new TimeSpanDragForce(atmosphere, box0);
1205 forceModel.addDragSensitiveValidAfter(box1, date.shiftedBy(dt));
1206 forceModel.addDragSensitiveValidBefore(box2, date.shiftedBy(-dt));
1207
1208
1209 Orbit orbit = refOrbit.shiftedBy(0.);
1210 SpacecraftState state = new SpacecraftState(orbit,
1211 defaultLaw.getAttitude(orbit, orbit.getDate(), orbit.getFrame()));
1212 checkStateJacobianVsFiniteDifferencesGradient(state, forceModel, defaultLaw, 1.0, 5.0e-6, false);
1213
1214
1215 orbit = refOrbit.shiftedBy(1.1 * dt);
1216 state = new SpacecraftState(orbit,
1217 defaultLaw.getAttitude(orbit, orbit.getDate(), orbit.getFrame()));
1218 checkStateJacobianVsFiniteDifferencesGradient(state, forceModel, defaultLaw, 1.0, 5.0e-6, false);
1219
1220
1221 orbit = refOrbit.shiftedBy(-1.1 * dt);
1222 state = new SpacecraftState(orbit,
1223 defaultLaw.getAttitude(orbit, orbit.getDate(), orbit.getFrame()));
1224 checkStateJacobianVsFiniteDifferencesGradient(state, forceModel, defaultLaw, 1.0, 6.0e-6, false);
1225 }
1226
1227
1228 @Test
1229 public void testGlobalStateJacobianBox()
1230 {
1231
1232
1233 AbsoluteDate date = new AbsoluteDate(new DateComponents(2003, 03, 01),
1234 new TimeComponents(13, 59, 27.816),
1235 TimeScalesFactory.getUTC());
1236 double i = FastMath.toRadians(98.7);
1237 double omega = FastMath.toRadians(93.0);
1238 double OMEGA = FastMath.toRadians(15.0 * 22.5);
1239 Orbit orbit = new KeplerianOrbit(7201009.7124401, 1e-3, i , omega, OMEGA,
1240 0, PositionAngle.MEAN, FramesFactory.getEME2000(), date,
1241 Constants.EIGEN5C_EARTH_MU);
1242 OrbitType integrationType = OrbitType.CARTESIAN;
1243 double[][] tolerances = NumericalPropagator.tolerances(0.01, orbit, integrationType);
1244 CelestialBody sun = CelestialBodyFactory.getSun();
1245
1246
1247 final Atmosphere atmosphere = new HarrisPriester(sun,
1248 new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
1249 Constants.WGS84_EARTH_FLATTENING,
1250 FramesFactory.getITRF(IERSConventions.IERS_2010, true)));
1251
1252 double dragCd0 = 1.;
1253 double dragCl0 = 0.1;
1254 double dragCd1 = 2.;
1255 double dragCl1 = 0.2;
1256 double dragCd2 = 3.;
1257 double dragCl2 = 0.3;
1258 double dt = 1. * 3600.;
1259
1260
1261 BoxAndSolarArraySpacecraft box0 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8, sun, 20.0,
1262 Vector3D.PLUS_J, dragCd0, dragCl0, 0.7, 0.2);
1263 BoxAndSolarArraySpacecraft box1 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8, sun, 20.0,
1264 Vector3D.PLUS_J, dragCd1, dragCl1, 0.7, 0.2);
1265 BoxAndSolarArraySpacecraft box2 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8, sun, 20.0,
1266 Vector3D.PLUS_J, dragCd2, dragCl2, 0.7, 0.2);
1267 TimeSpanDragForce forceModel = new TimeSpanDragForce(atmosphere, box0);
1268 forceModel.addDragSensitiveValidAfter(box1, date.shiftedBy(dt));
1269 forceModel.addDragSensitiveValidBefore(box2, date.shiftedBy(-dt));
1270
1271
1272 NumericalPropagator propagator =
1273 new NumericalPropagator(new DormandPrince853Integrator(1.0e-3, 120,
1274 tolerances[0], tolerances[1]));
1275 propagator.setOrbitType(integrationType);
1276 propagator.addForceModel(forceModel);
1277 SpacecraftState state0 = new SpacecraftState(orbit);
1278
1279
1280 checkStateJacobian(propagator, state0, date.shiftedBy(0.5 * dt),
1281 1e3, tolerances[0], 1.1e-9);
1282
1283
1284 propagator = new NumericalPropagator(new DormandPrince853Integrator(1.0e-3, 120,
1285 tolerances[0], tolerances[1]));
1286 propagator.setOrbitType(integrationType);
1287 propagator.addForceModel(forceModel);
1288
1289
1290 checkStateJacobian(propagator, state0, date.shiftedBy(1.5 * dt),
1291 1e3, tolerances[0], 9.7e-9);
1292
1293
1294 propagator = new NumericalPropagator(new DormandPrince853Integrator(1.0e-3, 120,
1295 tolerances[0], tolerances[1]));
1296 propagator.setOrbitType(integrationType);
1297 propagator.addForceModel(forceModel);
1298
1299
1300 checkStateJacobian(propagator, state0, date.shiftedBy(-1.5 * dt),
1301 1e3, tolerances[0], 4.9e-9);
1302 }
1303
1304
1305
1306
1307
1308 @Test
1309 public void RealFieldTest() {
1310
1311
1312 DSFactory factory = new DSFactory(6, 4);
1313 DerivativeStructure a_0 = factory.variable(0, 7e6);
1314 DerivativeStructure e_0 = factory.variable(1, 0.01);
1315 DerivativeStructure i_0 = factory.variable(2, 1.2);
1316 DerivativeStructure R_0 = factory.variable(3, 0.7);
1317 DerivativeStructure O_0 = factory.variable(4, 0.5);
1318 DerivativeStructure n_0 = factory.variable(5, 0.1);
1319
1320 Field<DerivativeStructure> field = a_0.getField();
1321 DerivativeStructure zero = field.getZero();
1322
1323
1324 FieldAbsoluteDate<DerivativeStructure> J2000 = new FieldAbsoluteDate<>(field);
1325
1326
1327 Frame EME = FramesFactory.getEME2000();
1328
1329
1330 FieldKeplerianOrbit<DerivativeStructure> FKO = new FieldKeplerianOrbit<>(a_0, e_0, i_0, R_0, O_0, n_0,
1331 PositionAngle.MEAN,
1332 EME,
1333 J2000,
1334 zero.add(Constants.EIGEN5C_EARTH_MU));
1335
1336
1337 FieldSpacecraftState<DerivativeStructure> initialState = new FieldSpacecraftState<>(FKO);
1338 SpacecraftState iSR = initialState.toSpacecraftState();
1339
1340
1341 ClassicalRungeKuttaFieldIntegrator<DerivativeStructure> integrator =
1342 new ClassicalRungeKuttaFieldIntegrator<>(field, zero.add(6));
1343 ClassicalRungeKuttaIntegrator RIntegrator =
1344 new ClassicalRungeKuttaIntegrator(6);
1345 OrbitType type = OrbitType.EQUINOCTIAL;
1346
1347
1348 FieldNumericalPropagator<DerivativeStructure> FNP = new FieldNumericalPropagator<>(field, integrator);
1349 FNP.setOrbitType(type);
1350 FNP.setInitialState(initialState);
1351
1352 NumericalPropagator NP = new NumericalPropagator(RIntegrator);
1353 NP.setOrbitType(type);
1354 NP.setInitialState(iSR);
1355
1356
1357
1358 CelestialBody sun = CelestialBodyFactory.getSun();
1359
1360
1361 final Atmosphere atmosphere = new HarrisPriester(sun,
1362 new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
1363 Constants.WGS84_EARTH_FLATTENING,
1364 FramesFactory.getITRF(IERSConventions.IERS_2010, true)));
1365
1366 double dragCd0 = 1.;
1367 double dragCl0 = 0.1;
1368 double dragCd1 = 2.;
1369 double dragCl1 = 0.2;
1370 double dragCd2 = 3.;
1371 double dragCl2 = 0.3;
1372 double dt = 1000.;
1373
1374
1375 BoxAndSolarArraySpacecraft box0 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8, sun, 20.0,
1376 Vector3D.PLUS_J, dragCd0, dragCl0, 0.7, 0.2);
1377 BoxAndSolarArraySpacecraft box1 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8, sun, 20.0,
1378 Vector3D.PLUS_J, dragCd1, dragCl1, 0.7, 0.2);
1379 BoxAndSolarArraySpacecraft box2 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8, sun, 20.0,
1380 Vector3D.PLUS_J, dragCd2, dragCl2, 0.7, 0.2);
1381 TimeSpanDragForce forceModel = new TimeSpanDragForce(atmosphere, box0);
1382 forceModel.addDragSensitiveValidAfter(box1, J2000.toAbsoluteDate().shiftedBy(dt));
1383 forceModel.addDragSensitiveValidBefore(box2, J2000.toAbsoluteDate().shiftedBy(-dt));
1384 FNP.addForceModel(forceModel);
1385 NP.addForceModel(forceModel);
1386
1387
1388
1389
1390
1391 checkRealFieldPropagation(FKO, PositionAngle.MEAN, 0.9 * dt, NP, FNP,
1392 1.0e-30, 6.0e-09, 2.0e-10, 5.0e-11,
1393 1, false);
1394
1395
1396 FNP.resetInitialState(initialState);
1397 NP.resetInitialState(iSR);
1398 checkRealFieldPropagation(FKO, PositionAngle.MEAN, 1.1 * dt, NP, FNP,
1399 1.0e-30, 2.0e-08, 8.0e-11, 1.0e-10,
1400 1, false);
1401
1402
1403 FNP.resetInitialState(initialState);
1404 NP.resetInitialState(iSR);
1405 checkRealFieldPropagation(FKO, PositionAngle.MEAN, -1.1 * dt, NP, FNP,
1406 1.0e-15, 2.0e-08, 2.0e-09, 2.0e-09,
1407 1, false);
1408 }
1409
1410
1411
1412
1413
1414 @Test
1415 public void RealFieldGradientTest() {
1416
1417
1418 final int freeParameters = 6;
1419 Gradient a_0 = Gradient.variable(freeParameters, 0, 7e6);
1420 Gradient e_0 = Gradient.variable(freeParameters, 1, 0.01);
1421 Gradient i_0 = Gradient.variable(freeParameters, 2, 1.2);
1422 Gradient R_0 = Gradient.variable(freeParameters, 3, 0.7);
1423 Gradient O_0 = Gradient.variable(freeParameters, 4, 0.5);
1424 Gradient n_0 = Gradient.variable(freeParameters, 5, 0.1);
1425
1426 Field<Gradient> field = a_0.getField();
1427 Gradient zero = field.getZero();
1428
1429
1430 FieldAbsoluteDate<Gradient> J2000 = new FieldAbsoluteDate<>(field);
1431
1432
1433 Frame EME = FramesFactory.getEME2000();
1434
1435
1436 FieldKeplerianOrbit<Gradient> FKO = new FieldKeplerianOrbit<>(a_0, e_0, i_0, R_0, O_0, n_0,
1437 PositionAngle.MEAN,
1438 EME,
1439 J2000,
1440 zero.add(Constants.EIGEN5C_EARTH_MU));
1441
1442
1443 FieldSpacecraftState<Gradient> initialState = new FieldSpacecraftState<>(FKO);
1444 SpacecraftState iSR = initialState.toSpacecraftState();
1445
1446
1447 ClassicalRungeKuttaFieldIntegrator<Gradient> integrator =
1448 new ClassicalRungeKuttaFieldIntegrator<>(field, zero.add(6));
1449 ClassicalRungeKuttaIntegrator RIntegrator =
1450 new ClassicalRungeKuttaIntegrator(6);
1451 OrbitType type = OrbitType.EQUINOCTIAL;
1452
1453
1454 FieldNumericalPropagator<Gradient> FNP = new FieldNumericalPropagator<>(field, integrator);
1455 FNP.setOrbitType(type);
1456 FNP.setInitialState(initialState);
1457
1458 NumericalPropagator NP = new NumericalPropagator(RIntegrator);
1459 NP.setOrbitType(type);
1460 NP.setInitialState(iSR);
1461
1462
1463
1464 CelestialBody sun = CelestialBodyFactory.getSun();
1465
1466
1467 final Atmosphere atmosphere = new HarrisPriester(sun,
1468 new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
1469 Constants.WGS84_EARTH_FLATTENING,
1470 FramesFactory.getITRF(IERSConventions.IERS_2010, true)));
1471
1472 double dragCd0 = 1.;
1473 double dragCl0 = 0.1;
1474 double dragCd1 = 2.;
1475 double dragCl1 = 0.2;
1476 double dragCd2 = 3.;
1477 double dragCl2 = 0.3;
1478 double dt = 1000.;
1479
1480
1481 BoxAndSolarArraySpacecraft box0 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8, sun, 20.0,
1482 Vector3D.PLUS_J, dragCd0, dragCl0, 0.7, 0.2);
1483 BoxAndSolarArraySpacecraft box1 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8, sun, 20.0,
1484 Vector3D.PLUS_J, dragCd1, dragCl1, 0.7, 0.2);
1485 BoxAndSolarArraySpacecraft box2 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8, sun, 20.0,
1486 Vector3D.PLUS_J, dragCd2, dragCl2, 0.7, 0.2);
1487 TimeSpanDragForce forceModel = new TimeSpanDragForce(atmosphere, box0);
1488 forceModel.addDragSensitiveValidAfter(box1, J2000.toAbsoluteDate().shiftedBy(dt));
1489 forceModel.addDragSensitiveValidBefore(box2, J2000.toAbsoluteDate().shiftedBy(-dt));
1490 FNP.addForceModel(forceModel);
1491 NP.addForceModel(forceModel);
1492
1493
1494
1495
1496
1497 checkRealFieldPropagationGradient(FKO, PositionAngle.MEAN, 0.9 * dt, NP, FNP,
1498 1.0e-30, 2.5e-02, 7.7e-2, 1.9e-4,
1499 1, false);
1500
1501
1502 FNP.resetInitialState(initialState);
1503 NP.resetInitialState(iSR);
1504 checkRealFieldPropagationGradient(FKO, PositionAngle.MEAN, 1.1 * dt, NP, FNP,
1505 1.0e-30, 4.4e-02, 7.6e-5, 4.1e-4,
1506 1, false);
1507
1508
1509 FNP.resetInitialState(initialState);
1510 NP.resetInitialState(iSR);
1511 checkRealFieldPropagationGradient(FKO, PositionAngle.MEAN, -1.1 * dt, NP, FNP,
1512 1.0e-8, 2.4e-02, 2.3e-04, 3.9e-04,
1513 1, false);
1514 }
1515
1516
1517
1518
1519
1520 @Test
1521 public void RealFieldExpectErrorTest() {
1522
1523
1524 DSFactory factory = new DSFactory(6, 4);
1525 DerivativeStructure a_0 = factory.variable(0, 7e6);
1526 DerivativeStructure e_0 = factory.variable(1, 0.01);
1527 DerivativeStructure i_0 = factory.variable(2, 1.2);
1528 DerivativeStructure R_0 = factory.variable(3, 0.7);
1529 DerivativeStructure O_0 = factory.variable(4, 0.5);
1530 DerivativeStructure n_0 = factory.variable(5, 0.1);
1531
1532 Field<DerivativeStructure> field = a_0.getField();
1533 DerivativeStructure zero = field.getZero();
1534
1535
1536 FieldAbsoluteDate<DerivativeStructure> J2000 = new FieldAbsoluteDate<>(field);
1537
1538
1539 Frame EME = FramesFactory.getEME2000();
1540
1541
1542 FieldKeplerianOrbit<DerivativeStructure> FKO = new FieldKeplerianOrbit<>(a_0, e_0, i_0, R_0, O_0, n_0,
1543 PositionAngle.MEAN,
1544 EME,
1545 J2000,
1546 zero.add(Constants.EIGEN5C_EARTH_MU));
1547
1548
1549 FieldSpacecraftState<DerivativeStructure> initialState = new FieldSpacecraftState<>(FKO);
1550 SpacecraftState iSR = initialState.toSpacecraftState();
1551
1552
1553 ClassicalRungeKuttaFieldIntegrator<DerivativeStructure> integrator =
1554 new ClassicalRungeKuttaFieldIntegrator<>(field, zero.add(6));
1555 ClassicalRungeKuttaIntegrator RIntegrator =
1556 new ClassicalRungeKuttaIntegrator(6);
1557 OrbitType type = OrbitType.EQUINOCTIAL;
1558
1559
1560 FieldNumericalPropagator<DerivativeStructure> FNP = new FieldNumericalPropagator<>(field, integrator);
1561 FNP.setOrbitType(type);
1562 FNP.setInitialState(initialState);
1563
1564 NumericalPropagator NP = new NumericalPropagator(RIntegrator);
1565 NP.setOrbitType(type);
1566 NP.setInitialState(iSR);
1567
1568
1569
1570 CelestialBody sun = CelestialBodyFactory.getSun();
1571
1572
1573 final Atmosphere atmosphere = new HarrisPriester(sun,
1574 new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
1575 Constants.WGS84_EARTH_FLATTENING,
1576 FramesFactory.getITRF(IERSConventions.IERS_2010, true)));
1577
1578 double dragCd0 = 1.;
1579 double dragCl0 = 0.1;
1580 double dragCd1 = 2.;
1581 double dragCl1 = 0.2;
1582 double dragCd2 = 3.;
1583 double dragCl2 = 0.3;
1584 double dt = 1. * 1100.;
1585
1586
1587 BoxAndSolarArraySpacecraft box0 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8, sun, 20.0,
1588 Vector3D.PLUS_J, dragCd0, dragCl0, 0.7, 0.2);
1589 BoxAndSolarArraySpacecraft box1 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8, sun, 20.0,
1590 Vector3D.PLUS_J, dragCd1, dragCl1, 0.7, 0.2);
1591 BoxAndSolarArraySpacecraft box2 = new BoxAndSolarArraySpacecraft(1.5, 2.0, 1.8, sun, 20.0,
1592 Vector3D.PLUS_J, dragCd2, dragCl2, 0.7, 0.2);
1593 TimeSpanDragForce forceModel = new TimeSpanDragForce(atmosphere, box0);
1594 forceModel.addDragSensitiveValidAfter(box1, J2000.toAbsoluteDate().shiftedBy(dt));
1595 forceModel.addDragSensitiveValidBefore(box2, J2000.toAbsoluteDate().shiftedBy(-dt));
1596 FNP.addForceModel(forceModel);
1597
1598
1599 FieldAbsoluteDate<DerivativeStructure> target = J2000.shiftedBy(100.);
1600 FieldSpacecraftState<DerivativeStructure> finalState_DS = FNP.propagate(target);
1601 SpacecraftState finalState_R = NP.propagate(target.toAbsoluteDate());
1602 FieldPVCoordinates<DerivativeStructure> finPVC_DS = finalState_DS.getPVCoordinates();
1603 PVCoordinates finPVC_R = finalState_R.getPVCoordinates();
1604
1605 Assertions.assertFalse(FastMath.abs(finPVC_DS.toPVCoordinates().getPosition().getX() - finPVC_R.getPosition().getX()) < FastMath.abs(finPVC_R.getPosition().getX()) * 1e-11);
1606 Assertions.assertFalse(FastMath.abs(finPVC_DS.toPVCoordinates().getPosition().getY() - finPVC_R.getPosition().getY()) < FastMath.abs(finPVC_R.getPosition().getY()) * 1e-11);
1607 Assertions.assertFalse(FastMath.abs(finPVC_DS.toPVCoordinates().getPosition().getZ() - finPVC_R.getPosition().getZ()) < FastMath.abs(finPVC_R.getPosition().getZ()) * 1e-11);
1608 }
1609
1610 @BeforeEach
1611 public void setUp() {
1612 Utils.setDataRoot("regular-data");
1613 utc = TimeScalesFactory.getUTC();
1614 }
1615 }