1 package org.orekit.rugged.adjustment.util;
2
3 import java.io.File;
4 import java.lang.reflect.InvocationTargetException;
5 import java.net.URISyntaxException;
6 import java.util.ArrayList;
7 import java.util.Arrays;
8 import java.util.List;
9
10 import org.hipparchus.analysis.differentiation.DerivativeStructure;
11 import org.hipparchus.analysis.differentiation.Gradient;
12 import org.hipparchus.geometry.euclidean.threed.Vector3D;
13 import org.hipparchus.random.GaussianRandomGenerator;
14 import org.hipparchus.random.UncorrelatedRandomVectorGenerator;
15 import org.hipparchus.random.Well19937a;
16 import org.hipparchus.util.FastMath;
17 import org.junit.After;
18 import org.junit.Assert;
19 import org.orekit.bodies.BodyShape;
20 import org.orekit.bodies.GeodeticPoint;
21 import org.orekit.data.DataContext;
22 import org.orekit.data.DirectoryCrawler;
23 import org.orekit.errors.OrekitException;
24 import org.orekit.orbits.Orbit;
25 import org.orekit.rugged.TestUtils;
26 import org.orekit.rugged.adjustment.InterSensorsOptimizationProblemBuilder;
27 import org.orekit.rugged.adjustment.measurements.Observables;
28 import org.orekit.rugged.adjustment.measurements.SensorToSensorMapping;
29 import org.orekit.rugged.api.AlgorithmId;
30 import org.orekit.rugged.api.BodyRotatingFrameId;
31 import org.orekit.rugged.api.EllipsoidId;
32 import org.orekit.rugged.api.InertialFrameId;
33 import org.orekit.rugged.api.Rugged;
34 import org.orekit.rugged.api.RuggedBuilder;
35 import org.orekit.rugged.linesensor.LineSensor;
36 import org.orekit.rugged.linesensor.SensorPixel;
37 import org.orekit.rugged.utils.DerivativeGenerator;
38 import org.orekit.rugged.utils.SpacecraftToObservedBody;
39 import org.orekit.time.AbsoluteDate;
40 import org.orekit.utils.AngularDerivativesFilter;
41 import org.orekit.utils.CartesianDerivativesFilter;
42 import org.orekit.utils.Constants;
43 import org.orekit.utils.TimeStampedAngularCoordinates;
44 import org.orekit.utils.TimeStampedPVCoordinates;
45
46
47
48
49
50
51
52 public class InitInterRefiningTest {
53
54
55 private PleiadesViewingModel pleiadesViewingModelA;
56
57
58 private PleiadesViewingModel pleiadesViewingModelB;
59
60
61 private LineSensor lineSensorA;
62
63
64 private LineSensor lineSensorB;
65
66
67 private Rugged ruggedA;
68
69
70 private Rugged ruggedB;
71
72
73 private int parameterToAdjust;
74
75
76 static final String rollSuffix = "_roll";
77 static final String pitchSuffix = "_pitch";
78 static final String factorName = "factor";
79
80
81 static final double defaultRollDisruptionA = 0.004;
82 static final double defaultPitchDisruptionA = 0.0008;
83 static final double defaultFactorDisruptionA = 1.000000001;
84 static final double defaultRollDisruptionB = -0.004;
85 static final double defaultPitchDisruptionB = 0.0008;
86
87
88
89
90 public void initRefiningTest() {
91
92 initRefiningTest(defaultRollDisruptionA, defaultPitchDisruptionA, defaultFactorDisruptionA,
93 defaultRollDisruptionB, defaultPitchDisruptionB);
94 }
95
96
97
98
99
100
101
102
103 public void initRefiningTest(double rollDisruptionA, double pitchDisruptionA, double factorDisruptionA,
104 double rollDisruptionB, double pitchDisruptionB) {
105 try {
106
107 String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
108 DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
109
110
111
112 final String sensorNameA = "SensorA";
113 final double rollAngleA = -5.0;
114 final String dateA = "2016-01-01T11:59:50.0";
115 this.pleiadesViewingModelA = new PleiadesViewingModel(sensorNameA, rollAngleA, dateA);
116
117 final String sensorNameB = "SensorB";
118 final double rollAngleB = 0.0;
119 final String dateB = "2016-01-01T12:02:50.0";
120 this.pleiadesViewingModelB = new PleiadesViewingModel(sensorNameB, rollAngleB, dateB);
121
122 PleiadesOrbitModel orbitmodelA = new PleiadesOrbitModel();
123 PleiadesOrbitModel orbitmodelB = new PleiadesOrbitModel();
124
125
126
127
128
129 final AbsoluteDate minDateA = pleiadesViewingModelA.getMinDate();
130 final AbsoluteDate maxDateA = pleiadesViewingModelA.getMaxDate();
131 final AbsoluteDate refDateA = pleiadesViewingModelA.getDatationReference();
132 this.lineSensorA = pleiadesViewingModelA.getLineSensor();
133
134
135 BodyShape earthA = TestUtils.createEarth();
136 Orbit orbitA = orbitmodelA.createOrbit(Constants.EIGEN5C_EARTH_MU, refDateA);
137
138
139 final double [] rollPoly = {0.0,0.0,0.0};
140 final double[] pitchPoly = {0.025,0.0};
141 final double[] yawPoly = {0.0,0.0,0.0};
142 orbitmodelA.setLOFTransform(rollPoly, pitchPoly, yawPoly, minDateA);
143
144
145 List<TimeStampedAngularCoordinates> satelliteQListA = orbitmodelA.orbitToQ(orbitA, earthA, minDateA.shiftedBy(-0.0), maxDateA.shiftedBy(+0.0), 0.25);
146 final int nbQPoints = 2;
147
148
149 List<TimeStampedPVCoordinates> satellitePVListA = orbitmodelA.orbitToPV(orbitA, earthA, minDateA.shiftedBy(-0.0), maxDateA.shiftedBy(+0.0), 0.25);
150 final int nbPVPoints = 8;
151
152
153
154 RuggedBuilder ruggedBuilderA = new RuggedBuilder();
155
156 ruggedBuilderA.addLineSensor(lineSensorA);
157 ruggedBuilderA.setAlgorithm(AlgorithmId.IGNORE_DEM_USE_ELLIPSOID);
158 ruggedBuilderA.setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF);
159 ruggedBuilderA.setTimeSpan(minDateA,maxDateA, 0.001, 5.0);
160 ruggedBuilderA.setTrajectory(InertialFrameId.EME2000, satellitePVListA, nbPVPoints,
161 CartesianDerivativesFilter.USE_PV, satelliteQListA,
162 nbQPoints, AngularDerivativesFilter.USE_R);
163 ruggedBuilderA.setLightTimeCorrection(false);
164 ruggedBuilderA.setAberrationOfLightCorrection(false);
165
166 ruggedBuilderA.setName("RuggedA");
167
168 this.ruggedA = ruggedBuilderA.build();
169
170
171
172 final AbsoluteDate minDateB = pleiadesViewingModelB.getMinDate();
173 final AbsoluteDate maxDateB = pleiadesViewingModelB.getMaxDate();
174 final AbsoluteDate refDateB = pleiadesViewingModelB.getDatationReference();
175 this.lineSensorB = pleiadesViewingModelB.getLineSensor();
176
177
178 BodyShape earthB = TestUtils.createEarth();
179 Orbit orbitB = orbitmodelB.createOrbit(Constants.EIGEN5C_EARTH_MU, refDateB);
180
181
182 List<TimeStampedAngularCoordinates> satelliteQListB = orbitmodelB.orbitToQ(orbitB, earthB, minDateB.shiftedBy(-0.0), maxDateB.shiftedBy(+0.0), 0.25);
183
184
185 List<TimeStampedPVCoordinates> satellitePVListB = orbitmodelB.orbitToPV(orbitB, earthB, minDateB.shiftedBy(-0.0), maxDateB.shiftedBy(+0.0), 0.25);
186
187
188
189 RuggedBuilder ruggedBuilderB = new RuggedBuilder();
190
191 ruggedBuilderB.addLineSensor(lineSensorB);
192 ruggedBuilderB.setAlgorithm(AlgorithmId.IGNORE_DEM_USE_ELLIPSOID);
193 ruggedBuilderB.setEllipsoid(EllipsoidId.WGS84, BodyRotatingFrameId.ITRF);
194 ruggedBuilderB.setTimeSpan(minDateB,maxDateB, 0.001, 5.0);
195 ruggedBuilderB.setTrajectory(InertialFrameId.EME2000, satellitePVListB, nbPVPoints,
196 CartesianDerivativesFilter.USE_PV, satelliteQListB,
197 nbQPoints, AngularDerivativesFilter.USE_R);
198 ruggedBuilderB.setLightTimeCorrection(false);
199 ruggedBuilderB.setAberrationOfLightCorrection(false);
200
201 ruggedBuilderB.setName("RuggedB");
202
203 this.ruggedB = ruggedBuilderB.build();
204
205
206
207
208 RefiningParametersDriver.setSelectedRoll(ruggedA, sensorNameA);
209 RefiningParametersDriver.setSelectedPitch(ruggedA, sensorNameA);
210
211 RefiningParametersDriver.setSelectedRoll(ruggedB, sensorNameB);
212 RefiningParametersDriver.setSelectedPitch(ruggedB, sensorNameB);
213
214 this.parameterToAdjust = 4;
215
216
217
218
219
220
221 RefiningParametersDriver.applyDisruptionsRoll(ruggedA, sensorNameA, FastMath.toRadians(rollDisruptionA));
222 RefiningParametersDriver.applyDisruptionsPitch(ruggedA, sensorNameA, FastMath.toRadians(pitchDisruptionA));
223 RefiningParametersDriver.applyDisruptionsFactor(ruggedA, sensorNameA, factorDisruptionA);
224
225
226 RefiningParametersDriver.applyDisruptionsRoll(ruggedB, sensorNameB, FastMath.toRadians(rollDisruptionB));
227 RefiningParametersDriver.applyDisruptionsPitch(ruggedB, sensorNameB, FastMath.toRadians(pitchDisruptionB));
228
229
230 } catch (OrekitException oe) {
231 Assert.fail(oe.getLocalizedMessage());
232 } catch (URISyntaxException use) {
233 Assert.fail(use.getLocalizedMessage());
234 }
235 }
236
237
238
239
240
241 public List<Rugged> getRuggedList(){
242
243 List<Rugged> ruggedList = Arrays.asList(ruggedA, ruggedB);
244 return ruggedList;
245 }
246
247
248
249
250
251
252
253 public double[] computeDistancesBetweenLOS(final SensorPixel realPixelA, final SensorPixel realPixelB) {
254
255 final SpacecraftToObservedBody scToBodyA = ruggedA.getScToBody();
256
257 final AbsoluteDate realDateA = lineSensorA.getDate(realPixelA.getLineNumber());
258 final AbsoluteDate realDateB = lineSensorB.getDate(realPixelB.getLineNumber());
259
260 final double[] distanceLOSB = ruggedB.distanceBetweenLOS(
261 lineSensorA, realDateA, realPixelA.getPixelNumber(),
262 scToBodyA,
263 lineSensorB, realDateB, realPixelB.getPixelNumber());
264
265 return distanceLOSB;
266 }
267
268
269
270
271
272
273
274 public DerivativeStructure[] computeDistancesBetweenLOSDerivatives(final SensorPixel realPixelA, final SensorPixel realPixelB,
275 final double losDistance, final double earthDistance)
276 throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
277 final Gradient[] gradient = computeDistancesBetweenLOSGradient(realPixelA, realPixelB, losDistance, earthDistance);
278 final DerivativeStructure[] ds = new DerivativeStructure[gradient.length];
279 for (int i = 0; i < gradient.length; ++i) {
280 ds[i] = gradient[i].toDerivativeStructure();
281 }
282 return ds;
283 }
284
285
286
287
288
289
290
291 public Gradient[] computeDistancesBetweenLOSGradient(final SensorPixel realPixelA, final SensorPixel realPixelB,
292 final double losDistance, final double earthDistance)
293 throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
294
295 final SpacecraftToObservedBody scToBodyA = ruggedA.getScToBody();
296
297 final AbsoluteDate realDateA = lineSensorA.getDate(realPixelA.getLineNumber());
298 final AbsoluteDate realDateB = lineSensorB.getDate(realPixelB.getLineNumber());
299
300 final List<LineSensor> sensors = new ArrayList<LineSensor>();
301 sensors.addAll(ruggedA.getLineSensors());
302 sensors.addAll(ruggedB.getLineSensors());
303
304 final List<Rugged> ruggedList = new ArrayList<Rugged>();
305 ruggedList.add(ruggedA);
306 ruggedList.add(ruggedB);
307
308
309 final Observables measurements = new Observables(2);
310 SensorToSensorMapping interMapping = new SensorToSensorMapping(lineSensorA.getName(), ruggedA.getName(), lineSensorB.getName(), ruggedB.getName());
311 interMapping.addMapping(realPixelA, realPixelB, losDistance, earthDistance);
312 measurements.addInterMapping(interMapping);
313
314
315 InterSensorsOptimizationProblemBuilder optimizationPbBuilder = new InterSensorsOptimizationProblemBuilder(sensors, measurements, ruggedList);
316 java.lang.reflect.Method createGenerator = InterSensorsOptimizationProblemBuilder.class.getSuperclass().getDeclaredMethod("createGenerator", List.class);
317 createGenerator.setAccessible(true);
318
319 List<LineSensor> listLineSensor = new ArrayList<LineSensor>();
320 listLineSensor.addAll(ruggedA.getLineSensors());
321 listLineSensor.addAll(ruggedB.getLineSensors());
322
323 @SuppressWarnings("unchecked")
324 DerivativeGenerator<Gradient> generator = (DerivativeGenerator<Gradient>) createGenerator.invoke(optimizationPbBuilder, listLineSensor);
325
326 return ruggedB.distanceBetweenLOSderivatives(lineSensorA, realDateA, realPixelA.getPixelNumber(),
327 scToBodyA,
328 lineSensorB, realDateB, realPixelB.getPixelNumber(),
329 generator);
330
331 }
332
333
334
335
336
337
338
339 public Observables generateNoisyPoints(final int lineSampling, final int pixelSampling, final double earthConstraintWeight, final boolean earthConstraintPostponed) {
340
341
342 final double outlierValue = 1.e+2;
343
344
345
346
347
348
349
350 SensorToSensorMapping interMapping;
351 if (! earthConstraintPostponed) {
352 interMapping = new SensorToSensorMapping(lineSensorA.getName(), ruggedA.getName(),
353 lineSensorB.getName(), ruggedB.getName(),
354 earthConstraintWeight);
355 } else {
356 interMapping = new SensorToSensorMapping(lineSensorA.getName(), ruggedA.getName(),
357 lineSensorB.getName(), ruggedB.getName());
358
359 interMapping.setBodyConstraintWeight(earthConstraintWeight);
360 }
361
362
363 Observables observables = new Observables(2);
364
365
366
367 final double meanA[] = { 5.0, 5.0 };
368 final double stdA[] = { 0.1, 0.1 };
369 final double meanB[] = { 0.0, 0.0 };
370 final double stdB[] = { 0.1, 0.1 };
371
372
373 final GaussianRandomGenerator rngA = new GaussianRandomGenerator(new Well19937a(0xefac03d9be4d24b9l));
374 final UncorrelatedRandomVectorGenerator rvgA = new UncorrelatedRandomVectorGenerator(meanA, stdA, rngA);
375
376
377 final GaussianRandomGenerator rngB = new GaussianRandomGenerator(new Well19937a(0xdf1c03d9be0b34b9l));
378 final UncorrelatedRandomVectorGenerator rvgB = new UncorrelatedRandomVectorGenerator(meanB, stdB, rngB);
379
380
381
382 final int minLine = 0;
383 final int maxLine = pleiadesViewingModelB.getDimension() - 1;
384
385 final String sensorNameB = lineSensorB.getName();
386
387 for (double line = 0; line < pleiadesViewingModelA.getDimension(); line += lineSampling) {
388
389 final AbsoluteDate dateA = lineSensorA.getDate(line);
390
391 for (double pixelA = 0; pixelA < lineSensorA.getNbPixels(); pixelA += pixelSampling) {
392
393 final GeodeticPoint gpA = ruggedA.directLocation(dateA, lineSensorA.getPosition(),
394 lineSensorA.getLOS(dateA, pixelA));
395 final SensorPixel sensorPixelB = ruggedB.inverseLocation(sensorNameB, gpA, minLine, maxLine);
396
397
398
399 if (sensorPixelB != null) {
400
401 final AbsoluteDate dateB = lineSensorB.getDate(sensorPixelB.getLineNumber());
402 final double pixelB = sensorPixelB.getPixelNumber();
403
404
405 final SpacecraftToObservedBody scToBodyA = ruggedA.getScToBody();
406
407 final GeodeticPoint gpB = ruggedB.directLocation(dateB, lineSensorB.getPosition(),
408 lineSensorB.getLOS(dateB, pixelB));
409 final double geoDistance = computeDistanceInMeter(gpA, gpB);
410
411
412 if (geoDistance < outlierValue) {
413
414 final double[] vecRandomA = rvgA.nextVector();
415 final double[] vecRandomB = rvgB.nextVector();
416
417 final SensorPixel realPixelA = new SensorPixel(line + vecRandomA[0], pixelA + vecRandomA[1]);
418 final SensorPixel realPixelB = new SensorPixel(sensorPixelB.getLineNumber() + vecRandomB[0],
419 sensorPixelB.getPixelNumber() + vecRandomB[1]);
420
421 final AbsoluteDate realDateA = lineSensorA.getDate(realPixelA.getLineNumber());
422 final AbsoluteDate realDateB = lineSensorB.getDate(realPixelB.getLineNumber());
423
424 final double[] distanceLOSB = ruggedB.distanceBetweenLOS(lineSensorA, realDateA, realPixelA.getPixelNumber(), scToBodyA,
425 lineSensorB, realDateB, realPixelB.getPixelNumber());
426 final Double losDistance = 0.0;
427 final Double earthDistance = distanceLOSB[1];
428
429 interMapping.addMapping(realPixelA, realPixelB, losDistance, earthDistance);
430
431 }
432 }
433
434 }
435 }
436
437 observables.addInterMapping(interMapping);
438 return observables;
439 }
440
441
442
443
444
445
446
447
448 public Observables generateSimpleInterMapping(final int lineSampling, final int pixelSampling, final double earthConstraintWeight, final boolean earthConstraintPostponed) {
449
450
451 final double outlierValue = 1.e+2;
452
453
454
455
456
457
458
459 SensorToSensorMapping interMapping;
460 if (! earthConstraintPostponed) {
461 interMapping = new SensorToSensorMapping(lineSensorA.getName(), lineSensorB.getName(), earthConstraintWeight);
462 } else {
463 interMapping = new SensorToSensorMapping(lineSensorA.getName(), lineSensorB.getName());
464
465 interMapping.setBodyConstraintWeight(earthConstraintWeight);
466 }
467
468
469 Observables observables = new Observables(2);
470
471
472
473 final double meanA[] = { 5.0, 5.0 };
474 final double stdA[] = { 0.1, 0.1 };
475 final double meanB[] = { 0.0, 0.0 };
476 final double stdB[] = { 0.1, 0.1 };
477
478
479 final GaussianRandomGenerator rngA = new GaussianRandomGenerator(new Well19937a(0xefac03d9be4d24b9l));
480 final UncorrelatedRandomVectorGenerator rvgA = new UncorrelatedRandomVectorGenerator(meanA, stdA, rngA);
481
482
483 final GaussianRandomGenerator rngB = new GaussianRandomGenerator(new Well19937a(0xdf1c03d9be0b34b9l));
484 final UncorrelatedRandomVectorGenerator rvgB = new UncorrelatedRandomVectorGenerator(meanB, stdB, rngB);
485
486
487
488 final int minLine = 0;
489 final int maxLine = pleiadesViewingModelB.getDimension() - 1;
490
491 final String sensorNameB = lineSensorB.getName();
492
493 for (double line = 0; line < pleiadesViewingModelA.getDimension(); line += lineSampling) {
494
495 final AbsoluteDate dateA = lineSensorA.getDate(line);
496
497 for (double pixelA = 0; pixelA < lineSensorA.getNbPixels(); pixelA += pixelSampling) {
498
499 final GeodeticPoint gpA = ruggedA.directLocation(dateA, lineSensorA.getPosition(),
500 lineSensorA.getLOS(dateA, pixelA));
501 final SensorPixel sensorPixelB = ruggedB.inverseLocation(sensorNameB, gpA, minLine, maxLine);
502
503
504
505 if (sensorPixelB != null) {
506
507 final AbsoluteDate dateB = lineSensorB.getDate(sensorPixelB.getLineNumber());
508 final double pixelB = sensorPixelB.getPixelNumber();
509
510 final GeodeticPoint gpB = ruggedB.directLocation(dateB, lineSensorB.getPosition(),
511 lineSensorB.getLOS(dateB, pixelB));
512 final double geoDistance = computeDistanceInMeter(gpA, gpB);
513
514
515 if (geoDistance < outlierValue) {
516
517 final double[] vecRandomA = rvgA.nextVector();
518 final double[] vecRandomB = rvgB.nextVector();
519
520 final SensorPixel realPixelA = new SensorPixel(line + vecRandomA[0], pixelA + vecRandomA[1]);
521 final SensorPixel realPixelB = new SensorPixel(sensorPixelB.getLineNumber() + vecRandomB[0],
522 sensorPixelB.getPixelNumber() + vecRandomB[1]);
523
524 final Double losDistance = FastMath.abs(vecRandomA[0]);
525
526 interMapping.addMapping(realPixelA, realPixelB, losDistance);
527
528 }
529 }
530
531 }
532 }
533
534 observables.addInterMapping(interMapping);
535 return observables;
536 }
537
538
539
540
541
542
543 private static double computeDistanceInMeter(final GeodeticPoint geoPoint1, final GeodeticPoint geoPoint2) {
544
545
546 final Vector3D p1 = new Vector3D(geoPoint1.getLatitude(), geoPoint1.getLongitude());
547 final Vector3D p2 = new Vector3D(geoPoint2.getLatitude(), geoPoint2.getLongitude());
548 return Constants.WGS84_EARTH_EQUATORIAL_RADIUS * Vector3D.angle(p1, p2);
549 }
550
551
552
553
554 public int getParameterToAdjust() {
555 return parameterToAdjust;
556 }
557
558 @After
559 public void tearDown() {
560 }
561 }