1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.estimation.sequential;
18
19 import java.util.ArrayList;
20 import java.util.Comparator;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24
25 import org.hipparchus.exception.MathRuntimeException;
26 import org.hipparchus.filtering.kalman.ProcessEstimate;
27 import org.hipparchus.filtering.kalman.extended.ExtendedKalmanFilter;
28 import org.hipparchus.filtering.kalman.extended.NonLinearEvolution;
29 import org.hipparchus.filtering.kalman.extended.NonLinearProcess;
30 import org.hipparchus.linear.Array2DRowRealMatrix;
31 import org.hipparchus.linear.ArrayRealVector;
32 import org.hipparchus.linear.MatrixUtils;
33 import org.hipparchus.linear.QRDecomposition;
34 import org.hipparchus.linear.RealMatrix;
35 import org.hipparchus.linear.RealVector;
36 import org.hipparchus.util.FastMath;
37 import org.orekit.errors.OrekitException;
38 import org.orekit.estimation.measurements.EstimatedMeasurement;
39 import org.orekit.estimation.measurements.ObservedMeasurement;
40 import org.orekit.orbits.Orbit;
41 import org.orekit.orbits.OrbitParamsType;
42 import org.orekit.orbits.OrbitalStateFactory;
43 import org.orekit.propagation.PropagationType;
44 import org.orekit.propagation.SpacecraftState;
45 import org.orekit.propagation.conversion.DSSTPropagatorBuilder;
46 import org.orekit.propagation.semianalytical.dsst.DSSTHarvester;
47 import org.orekit.propagation.semianalytical.dsst.DSSTPropagator;
48 import org.orekit.propagation.semianalytical.dsst.forces.DSSTForceModel;
49 import org.orekit.propagation.semianalytical.dsst.forces.ShortPeriodTerms;
50 import org.orekit.propagation.semianalytical.dsst.utilities.AuxiliaryElements;
51 import org.orekit.time.AbsoluteDate;
52 import org.orekit.time.ChronologicalComparator;
53 import org.orekit.utils.drivers.ParameterDriver;
54 import org.orekit.utils.drivers.ParameterDriversList;
55 import org.orekit.utils.drivers.ParameterDriversList.DelegatingDriver;
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 public class SemiAnalyticalKalmanModel implements KalmanEstimation, NonLinearProcess<MeasurementDecorator>, SemiAnalyticalProcess {
72
73
74 private final DSSTPropagatorBuilder builder;
75
76
77 private final ParameterDriversList estimatedOrbitalParameters;
78
79
80 private final ParameterDriversList estimatedPropagationParameters;
81
82
83 private final ParameterDriversList estimatedMeasurementsParameters;
84
85
86 private final Map<String, Integer> propagationParameterColumns;
87
88
89 private final Map<String, Integer> measurementParameterColumns;
90
91
92 private final double[] scale;
93
94
95 private final CovarianceMatrixProvider covarianceMatrixProvider;
96
97
98 private final CovarianceMatrixProvider measurementProcessNoiseMatrix;
99
100
101 private DSSTHarvester harvester;
102
103
104 private DSSTPropagator dsstPropagator;
105
106
107 private KalmanObserver observer;
108
109
110 private int currentMeasurementNumber;
111
112
113 private AbsoluteDate currentDate;
114
115
116 private RealVector predictedFilterCorrection;
117
118
119 private RealVector correctedFilterCorrection;
120
121
122 private EstimatedMeasurement<?> predictedMeasurement;
123
124
125 private EstimatedMeasurement<?> correctedMeasurement;
126
127
128 private SpacecraftState nominalMeanSpacecraftState;
129
130
131 private SpacecraftState previousNominalMeanSpacecraftState;
132
133
134 private ProcessEstimate correctedEstimate;
135
136
137 private RealMatrix phiS;
138
139
140 private RealMatrix psiS;
141
142
143
144
145
146
147
148 protected SemiAnalyticalKalmanModel(final DSSTPropagatorBuilder propagatorBuilder,
149 final CovarianceMatrixProvider covarianceMatrixProvider,
150 final ParameterDriversList estimatedMeasurementParameters,
151 final CovarianceMatrixProvider measurementProcessNoiseMatrix) {
152
153 final OrbitalStateFactory<?> factory = propagatorBuilder.getOrbitalStateFactory();
154 this.builder = propagatorBuilder;
155 this.estimatedMeasurementsParameters = estimatedMeasurementParameters;
156 this.measurementParameterColumns = new HashMap<>(estimatedMeasurementsParameters.getDrivers().size());
157 this.observer = null;
158 this.currentMeasurementNumber = 0;
159 this.currentDate = factory.getDate();
160 this.covarianceMatrixProvider = covarianceMatrixProvider;
161 this.measurementProcessNoiseMatrix = measurementProcessNoiseMatrix;
162
163
164 int columns = 0;
165
166
167 estimatedOrbitalParameters = new ParameterDriversList();
168 for (final ParameterDriver driver : factory.getOrbitalParametersDrivers().getDrivers()) {
169
170
171 if (driver.getReferenceDate() == null) {
172 driver.setReferenceDate(currentDate);
173 }
174
175
176 if (driver.isSelected()) {
177 estimatedOrbitalParameters.add(driver);
178 columns++;
179 }
180
181 }
182
183
184 estimatedPropagationParameters = new ParameterDriversList();
185 final List<String> estimatedPropagationParametersNames = new ArrayList<>();
186 for (final ParameterDriver driver : builder.getPropagationParametersDrivers().getDrivers()) {
187
188
189 if (driver.getReferenceDate() == null) {
190 driver.setReferenceDate(currentDate);
191 }
192
193
194 if (driver.isSelected()) {
195 estimatedPropagationParameters.add(driver);
196
197 if (!estimatedPropagationParametersNames.contains(driver.getName())) {
198 estimatedPropagationParametersNames.add(driver.getName());
199 }
200 }
201
202 }
203 estimatedPropagationParametersNames.sort(Comparator.naturalOrder());
204
205
206 propagationParameterColumns = new HashMap<>(estimatedPropagationParametersNames.size());
207 for (final String driverName : estimatedPropagationParametersNames) {
208 propagationParameterColumns.put(driverName, columns);
209 ++columns;
210 }
211
212
213 for (final ParameterDriver parameter : estimatedMeasurementsParameters.getDrivers()) {
214 if (parameter.getReferenceDate() == null) {
215 parameter.setReferenceDate(currentDate);
216 }
217 measurementParameterColumns.put(parameter.getName(), columns);
218 ++columns;
219 }
220
221
222 this.scale = new double[columns];
223 int index = 0;
224 for (final ParameterDriver driver : estimatedOrbitalParameters.getDrivers()) {
225 scale[index++] = driver.getScale();
226 }
227 for (final ParameterDriver driver : estimatedPropagationParameters.getDrivers()) {
228 scale[index++] = driver.getScale();
229 }
230 for (final ParameterDriver driver : estimatedMeasurementsParameters.getDrivers()) {
231 scale[index++] = driver.getScale();
232 }
233
234
235 updateReferenceTrajectory(getEstimatedPropagator());
236 this.nominalMeanSpacecraftState = dsstPropagator.getInitialState();
237 this.previousNominalMeanSpacecraftState = nominalMeanSpacecraftState;
238
239
240 harvester.initializeFieldShortPeriodTerms(nominalMeanSpacecraftState);
241
242
243 this.predictedFilterCorrection = MatrixUtils.createRealVector(columns);
244 this.correctedFilterCorrection = predictedFilterCorrection;
245
246
247 this.psiS = null;
248 if (estimatedPropagationParameters.getNbParams() != 0) {
249 this.psiS = MatrixUtils.createRealMatrix(estimatedOrbitalParameters.getDrivers().size(),
250 estimatedPropagationParameters.getDrivers().size());
251 }
252
253
254 this.phiS = MatrixUtils.createRealIdentityMatrix(estimatedOrbitalParameters.getDrivers().size());
255
256
257 final int nbMeas = estimatedMeasurementsParameters.getDrivers().size();
258
259
260 final int nbDyn = estimatedOrbitalParameters.getDrivers().size() + estimatedPropagationParameters.getDrivers().size();
261
262
263 final RealMatrix noiseK = MatrixUtils.createRealMatrix(nbDyn + nbMeas, nbDyn + nbMeas);
264 final RealMatrix noiseP = covarianceMatrixProvider.getInitialCovarianceMatrix(nominalMeanSpacecraftState);
265 noiseK.setSubMatrix(noiseP.getData(), 0, 0);
266 if (measurementProcessNoiseMatrix != null) {
267 final RealMatrix noiseM = measurementProcessNoiseMatrix.getInitialCovarianceMatrix(nominalMeanSpacecraftState);
268 noiseK.setSubMatrix(noiseM.getData(), nbDyn, nbDyn);
269 }
270
271
272 KalmanEstimatorUtil.checkDimension(noiseK.getRowDimension(),
273 builder.getOrbitalStateFactory().getOrbitalParametersDrivers(),
274 builder.getPropagationParametersDrivers(),
275 estimatedMeasurementsParameters);
276
277 final RealMatrix correctedCovariance = KalmanEstimatorUtil.normalizeCovarianceMatrix(noiseK, scale);
278
279
280 this.correctedEstimate = new ProcessEstimate(0.0, correctedFilterCorrection, correctedCovariance);
281
282 }
283
284
285 @Override
286 public KalmanObserver getObserver() {
287 return observer;
288 }
289
290
291
292
293 public void setObserver(final KalmanObserver observer) {
294 this.observer = observer;
295 }
296
297
298
299
300 public ProcessEstimate getEstimate() {
301 return correctedEstimate;
302 }
303
304
305
306
307 protected double[] getScale() {
308 return scale;
309 }
310
311
312
313
314
315
316
317
318
319 public DSSTPropagator processMeasurements(final List<ObservedMeasurement<?>> observedMeasurements,
320 final ExtendedKalmanFilter<MeasurementDecorator> filter) {
321 try {
322
323
324 observedMeasurements.sort(new ChronologicalComparator());
325 final AbsoluteDate tStart = observedMeasurements.getFirst().getDate();
326 final AbsoluteDate tEnd = observedMeasurements.getLast().getDate();
327 final double overshootTimeRange = FastMath.nextAfter(tEnd.durationFrom(tStart),
328 Double.POSITIVE_INFINITY);
329
330
331 final SemiAnalyticalMeasurementHandler stepHandler =
332 new SemiAnalyticalMeasurementHandler(this, filter, observedMeasurements,
333 builder.getOrbitalStateFactory().getDate());
334 dsstPropagator.getMultiplexer().add(stepHandler);
335 dsstPropagator.propagate(tStart, tStart.shiftedBy(overshootTimeRange));
336
337
338 return getEstimatedPropagator();
339
340 } catch (MathRuntimeException mrte) {
341 throw new OrekitException(mrte);
342 }
343 }
344
345
346
347
348 public DSSTPropagator getEstimatedPropagator() {
349
350 return (DSSTPropagator) builder.buildPropagator();
351 }
352
353
354 @Override
355 public NonLinearEvolution getEvolution(final double previousTime, final RealVector previousState,
356 final MeasurementDecorator measurement) {
357
358
359 final ObservedMeasurement<?> observedMeasurement = measurement.getObservedMeasurement();
360 for (final ParameterDriver driver : observedMeasurement.getParametersDrivers()) {
361 if (driver.getReferenceDate() == null) {
362 driver.setReferenceDate(builder.getOrbitalStateFactory().getDate());
363 }
364 }
365
366
367 ++currentMeasurementNumber;
368
369
370 currentDate = measurement.getObservedMeasurement().getDate();
371
372
373 final RealMatrix stm = getErrorStateTransitionMatrix();
374
375
376 predictedFilterCorrection = predictFilterCorrection(stm);
377
378
379 analyticalDerivativeComputations(nominalMeanSpacecraftState);
380
381
382 final double[] osculating = computeOsculatingElements(predictedFilterCorrection);
383 final Orbit osculatingOrbit = OrbitParamsType.EQUINOCTIAL.mapArrayToOrbit(osculating, null,
384 builder.
385 getOrbitalStateFactory().
386 getPositionAngleType(),
387 currentDate, nominalMeanSpacecraftState.getOrbit().getMu(),
388 nominalMeanSpacecraftState.getFrame());
389
390
391 predictedMeasurement = observedMeasurement.estimate(currentMeasurementNumber,
392 currentMeasurementNumber,
393 new SpacecraftState[] {
394 new SpacecraftState(osculatingOrbit,
395 nominalMeanSpacecraftState.getAttitude(),
396 nominalMeanSpacecraftState.getMass(),
397 nominalMeanSpacecraftState.getAdditionalDataValues(),
398 nominalMeanSpacecraftState.getAdditionalStatesDerivatives())
399 });
400
401
402 final RealMatrix measurementMatrix = getMeasurementMatrix();
403
404
405 final int nbMeas = estimatedMeasurementsParameters.getDrivers().size();
406
407
408 final int nbDyn = estimatedOrbitalParameters.getDrivers().size() + estimatedPropagationParameters.getDrivers().size();
409
410
411 final RealMatrix noiseK = MatrixUtils.createRealMatrix(nbDyn + nbMeas, nbDyn + nbMeas);
412 final RealMatrix noiseP = covarianceMatrixProvider.getProcessNoiseMatrix(previousNominalMeanSpacecraftState, nominalMeanSpacecraftState);
413 noiseK.setSubMatrix(noiseP.getData(), 0, 0);
414 if (measurementProcessNoiseMatrix != null) {
415 final RealMatrix noiseM = measurementProcessNoiseMatrix.getProcessNoiseMatrix(previousNominalMeanSpacecraftState, nominalMeanSpacecraftState);
416 noiseK.setSubMatrix(noiseM.getData(), nbDyn, nbDyn);
417 }
418
419
420 KalmanEstimatorUtil.checkDimension(noiseK.getRowDimension(),
421 builder.getOrbitalStateFactory().getOrbitalParametersDrivers(),
422 builder.getPropagationParametersDrivers(),
423 estimatedMeasurementsParameters);
424
425 final RealMatrix normalizedProcessNoise = KalmanEstimatorUtil.normalizeCovarianceMatrix(noiseK, scale);
426
427
428 return new NonLinearEvolution(measurement.getTime(), predictedFilterCorrection, stm,
429 normalizedProcessNoise, measurementMatrix);
430 }
431
432
433 @Override
434 public RealVector getInnovation(final MeasurementDecorator measurement, final NonLinearEvolution evolution,
435 final RealMatrix innovationCovarianceMatrix) {
436
437
438 KalmanEstimatorUtil.applyDynamicOutlierFilter(predictedMeasurement, innovationCovarianceMatrix);
439
440 return KalmanEstimatorUtil.computeInnovationVector(predictedMeasurement, predictedMeasurement.getObservedMeasurement().getTheoreticalStandardDeviation());
441 }
442
443
444 @Override
445 public void finalizeEstimation(final ObservedMeasurement<?> observedMeasurement,
446 final ProcessEstimate estimate) {
447
448 correctedEstimate = estimate;
449
450 correctedFilterCorrection = estimate.getState();
451
452 previousNominalMeanSpacecraftState = nominalMeanSpacecraftState;
453
454 final double[] osculating = computeOsculatingElements(correctedFilterCorrection);
455 final Orbit osculatingOrbit = OrbitParamsType.EQUINOCTIAL.mapArrayToOrbit(osculating, null,
456 builder.
457 getOrbitalStateFactory().
458 getPositionAngleType(),
459 currentDate, nominalMeanSpacecraftState.getOrbit().getMu(),
460 nominalMeanSpacecraftState.getFrame());
461
462
463 correctedMeasurement = observedMeasurement.estimate(currentMeasurementNumber,
464 currentMeasurementNumber,
465 new SpacecraftState[] {
466 new SpacecraftState(osculatingOrbit,
467 nominalMeanSpacecraftState.getAttitude(),
468 nominalMeanSpacecraftState.getMass(),
469 nominalMeanSpacecraftState.getAdditionalDataValues(),
470 nominalMeanSpacecraftState.getAdditionalStatesDerivatives())
471 });
472
473 if (observer != null) {
474 observer.evaluationPerformed(this);
475 }
476 }
477
478
479 @Override
480 public void finalizeOperationsObservationGrid() {
481
482 updateParameters();
483 }
484
485
486 @Override
487 public ParameterDriversList getEstimatedOrbitalParameters() {
488 return estimatedOrbitalParameters;
489 }
490
491
492 @Override
493 public ParameterDriversList getEstimatedPropagationParameters() {
494 return estimatedPropagationParameters;
495 }
496
497
498 @Override
499 public ParameterDriversList getEstimatedMeasurementsParameters() {
500 return estimatedMeasurementsParameters;
501 }
502
503
504 @Override
505 public SpacecraftState[] getPredictedSpacecraftStates() {
506 return new SpacecraftState[] {nominalMeanSpacecraftState};
507 }
508
509
510 @Override
511 public SpacecraftState[] getCorrectedSpacecraftStates() {
512 return new SpacecraftState[] {getEstimatedPropagator().getInitialState()};
513 }
514
515
516 @Override
517 public RealVector getPhysicalEstimatedState() {
518
519
520
521 final RealVector physicalEstimatedState = new ArrayRealVector(scale.length);
522 int i = 0;
523 for (final DelegatingDriver driver : getEstimatedOrbitalParameters().getDrivers()) {
524 physicalEstimatedState.setEntry(i++, driver.getValue());
525 }
526 for (final DelegatingDriver driver : getEstimatedPropagationParameters().getDrivers()) {
527 physicalEstimatedState.setEntry(i++, driver.getValue());
528 }
529 for (final DelegatingDriver driver : getEstimatedMeasurementsParameters().getDrivers()) {
530 physicalEstimatedState.setEntry(i++, driver.getValue());
531 }
532
533 return physicalEstimatedState;
534 }
535
536
537 @Override
538 public RealMatrix getPhysicalEstimatedCovarianceMatrix() {
539
540
541
542
543
544 return KalmanEstimatorUtil.unnormalizeCovarianceMatrix(correctedEstimate.getCovariance(), scale);
545 }
546
547
548 @Override
549 public RealMatrix getPhysicalStateTransitionMatrix() {
550
551
552
553
554 return correctedEstimate.getStateTransitionMatrix() == null ?
555 null : KalmanEstimatorUtil.unnormalizeStateTransitionMatrix(correctedEstimate.getStateTransitionMatrix(), scale);
556 }
557
558
559 @Override
560 public RealMatrix getPhysicalMeasurementJacobian() {
561
562
563
564
565
566
567 return correctedEstimate.getMeasurementJacobian() == null ?
568 null : KalmanEstimatorUtil.unnormalizeMeasurementJacobian(correctedEstimate.getMeasurementJacobian(),
569 scale,
570 correctedMeasurement.getObservedMeasurement().getTheoreticalStandardDeviation());
571 }
572
573
574 @Override
575 public RealMatrix getPhysicalInnovationCovarianceMatrix() {
576
577
578
579
580 return correctedEstimate.getInnovationCovariance() == null ?
581 null : KalmanEstimatorUtil.unnormalizeInnovationCovarianceMatrix(correctedEstimate.getInnovationCovariance(),
582 predictedMeasurement.getObservedMeasurement().getTheoreticalStandardDeviation());
583 }
584
585
586 @Override
587 public RealMatrix getPhysicalKalmanGain() {
588
589
590
591
592
593
594 return correctedEstimate.getKalmanGain() == null ?
595 null : KalmanEstimatorUtil.unnormalizeKalmanGainMatrix(correctedEstimate.getKalmanGain(),
596 scale,
597 correctedMeasurement.getObservedMeasurement().getTheoreticalStandardDeviation());
598 }
599
600
601 @Override
602 public int getCurrentMeasurementNumber() {
603 return currentMeasurementNumber;
604 }
605
606
607 @Override
608 public AbsoluteDate getCurrentDate() {
609 return currentDate;
610 }
611
612
613 @Override
614 public EstimatedMeasurement<?> getPredictedMeasurement() {
615 return predictedMeasurement;
616 }
617
618
619 @Override
620 public EstimatedMeasurement<?> getCorrectedMeasurement() {
621 return correctedMeasurement;
622 }
623
624
625 @Override
626 public void updateNominalSpacecraftState(final SpacecraftState nominal) {
627 this.nominalMeanSpacecraftState = nominal;
628
629 builder.resetOrbit(nominal.getOrbit(), PropagationType.MEAN);
630
631
632
633
634 builder.setMass(nominal.getMass());
635 }
636
637
638
639
640 public void updateReferenceTrajectory(final DSSTPropagator propagator) {
641
642 dsstPropagator = propagator;
643
644
645 final String equationName = SemiAnalyticalKalmanEstimator.class.getName() + "-derivatives-";
646
647
648 final SpacecraftState meanState = dsstPropagator.initialIsOsculating() ?
649 DSSTPropagator.computeMeanState(dsstPropagator.getInitialState(), dsstPropagator.getAttitudeProvider(), dsstPropagator.getAllForceModels()) :
650 dsstPropagator.getInitialState();
651
652
653 dsstPropagator.setInitialState(meanState, PropagationType.MEAN);
654 harvester = dsstPropagator.setupMatricesComputation(equationName, null, null);
655
656 }
657
658
659 @Override
660 public void updateShortPeriods(final SpacecraftState state) {
661
662 for (final DSSTForceModel model : builder.getAllForceModels()) {
663 model.updateShortPeriodTerms(model.getParameters(), state);
664 }
665 harvester.updateFieldShortPeriodTerms(state);
666 }
667
668
669 @Override
670 public void initializeShortPeriodicTerms(final SpacecraftState meanState) {
671 final List<ShortPeriodTerms> shortPeriodTerms = new ArrayList<>();
672
673 final PropagationType type = PropagationType.OSCULATING;
674 for (final DSSTForceModel force : builder.getAllForceModels()) {
675 shortPeriodTerms.addAll(force.initializeShortPeriodTerms(new AuxiliaryElements(meanState.getOrbit(), 1),
676 type, force.getParameters()));
677 }
678 dsstPropagator.setShortPeriodTerms(shortPeriodTerms);
679
680 harvester.initializeFieldShortPeriodTerms(meanState, type);
681 }
682
683
684
685
686
687
688
689 private RealMatrix getErrorStateTransitionMatrix() {
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709 final RealMatrix stm = MatrixUtils.createRealIdentityMatrix(correctedEstimate.getState().getDimension());
710
711
712 final int nbOrb = estimatedOrbitalParameters.getDrivers().size();
713 final RealMatrix dYdY0 = harvester.getB2(nominalMeanSpacecraftState);
714
715
716 final RealMatrix phi = dYdY0.multiply(phiS);
717
718
719 final List<DelegatingDriver> drivers =
720 builder.getOrbitalStateFactory().getOrbitalParametersDrivers().getDrivers();
721 for (int i = 0; i < nbOrb; ++i) {
722 if (drivers.get(i).isSelected()) {
723 int jOrb = 0;
724 for (int j = 0; j < nbOrb; ++j) {
725 if (drivers.get(j).isSelected()) {
726 stm.setEntry(i, jOrb++, phi.getEntry(i, j));
727 }
728 }
729 }
730 }
731
732
733 phiS = new QRDecomposition(dYdY0).getSolver().getInverse();
734
735
736 if (psiS != null) {
737
738 final int nbProp = estimatedPropagationParameters.getDrivers().size();
739 final RealMatrix dYdPp = harvester.getB3(nominalMeanSpacecraftState);
740
741
742 final RealMatrix psi = dYdPp.subtract(phi.multiply(psiS));
743
744
745 for (int i = 0; i < nbOrb; ++i) {
746 for (int j = 0; j < nbProp; ++j) {
747 stm.setEntry(i, j + nbOrb, psi.getEntry(i, j));
748 }
749 }
750
751
752 psiS = dYdPp;
753
754 }
755
756
757
758 for (int i = 0; i < scale.length; i++) {
759 for (int j = 0; j < scale.length; j++ ) {
760 stm.setEntry(i, j, stm.getEntry(i, j) * scale[j] / scale[i]);
761 }
762 }
763
764
765 return stm;
766
767 }
768
769
770
771
772
773
774 private RealMatrix getMeasurementMatrix() {
775
776
777 final SpacecraftState evaluationState = predictedMeasurement.getStates()[0];
778 final ObservedMeasurement<?> observedMeasurement = predictedMeasurement.getObservedMeasurement();
779 final double[] sigma = predictedMeasurement.getObservedMeasurement().getTheoreticalStandardDeviation();
780
781
782
783
784 final RealMatrix measurementMatrix = MatrixUtils.
785 createRealMatrix(observedMeasurement.getDimension(),
786 correctedEstimate.getState().getDimension());
787
788
789 final Orbit predictedOrbit = evaluationState.getOrbit();
790
791
792
793
794
795 final int nbOrb = getNumberSelectedOrbitalDrivers();
796 final int nbProp = getNumberSelectedPropagationDrivers();
797 final double[][] aCY = new double[nbOrb][nbOrb];
798 predictedOrbit.getJacobianWrtParameters(builder.getOrbitalStateFactory().getPositionAngleType(),
799 aCY);
800 final RealMatrix dCdY = new Array2DRowRealMatrix(aCY, false);
801
802
803 final RealMatrix dMdC = new Array2DRowRealMatrix(predictedMeasurement.getStateDerivatives(0), false);
804
805
806 RealMatrix dMdY = dMdC.multiply(dCdY);
807
808
809 final RealMatrix IpB1B4 = MatrixUtils.createRealMatrix(nbOrb, nbOrb + nbProp);
810
811
812 final RealMatrix B1 = harvester.getB1();
813
814
815 final RealMatrix I = MatrixUtils.createRealIdentityMatrix(nbOrb);
816 final RealMatrix IpB1 = I.add(B1);
817 IpB1B4.setSubMatrix(IpB1.getData(), 0, 0);
818
819
820 if (psiS != null) {
821 final RealMatrix B4 = harvester.getB4();
822 IpB1B4.setSubMatrix(B4.getData(), 0, nbOrb);
823 }
824
825
826 dMdY = dMdY.multiply(IpB1B4);
827
828 final List<DelegatingDriver> drivers = builder.
829 getOrbitalStateFactory().
830 getOrbitalParametersDrivers().
831 getDrivers();
832 for (int i = 0; i < dMdY.getRowDimension(); i++) {
833 for (int j = 0; j < nbOrb; j++) {
834 final double driverScale = drivers.get(j).getScale();
835 measurementMatrix.setEntry(i, j, dMdY.getEntry(i, j) / sigma[i] * driverScale);
836 }
837
838 for (int j = 0; j < nbProp; j++) {
839 final double driverScale = estimatedPropagationParameters.getDrivers().get(j).getScale();
840 measurementMatrix.setEntry(i, j + nbOrb, dMdY.getEntry(i, j + nbOrb) / sigma[i] * driverScale);
841 }
842 }
843
844
845
846
847
848
849 for (final ParameterDriver driver : observedMeasurement.getParametersDrivers()) {
850 if (driver.isSelected()) {
851
852 final double[] aMPm = predictedMeasurement.getParameterDerivatives(driver);
853
854
855 if (measurementParameterColumns.get(driver.getName()) != null) {
856
857 final int driverColumn = measurementParameterColumns.get(driver.getName());
858
859
860 for (int i = 0; i < aMPm.length; ++i) {
861 measurementMatrix.setEntry(i, driverColumn, aMPm[i] / sigma[i] * driver.getScale());
862 }
863 }
864 }
865 }
866
867 return measurementMatrix;
868 }
869
870
871
872
873
874 private RealVector predictFilterCorrection(final RealMatrix stm) {
875
876 return stm.operate(correctedFilterCorrection);
877 }
878
879
880
881
882
883 private double[] computeOsculatingElements(final RealVector filterCorrection) {
884
885
886 final int nbOrb = getNumberSelectedOrbitalDrivers();
887
888
889 final RealMatrix B1 = harvester.getB1();
890
891
892 final double[] shortPeriodTerms = dsstPropagator.getShortPeriodTermsValue(nominalMeanSpacecraftState);
893
894
895 final RealVector physicalFilterCorrection = MatrixUtils.createRealVector(nbOrb);
896 for (int index = 0; index < nbOrb; index++) {
897 physicalFilterCorrection.addToEntry(index, filterCorrection.getEntry(index) * scale[index]);
898 }
899
900
901 final RealVector B1Correction = B1.operate(physicalFilterCorrection);
902
903
904 final double[] nominalMeanElements = new double[nbOrb];
905 OrbitParamsType.EQUINOCTIAL.mapOrbitToArray(nominalMeanSpacecraftState.getOrbit(),
906 builder.getOrbitalStateFactory().getPositionAngleType(),
907 nominalMeanElements, null);
908
909
910 final double[] osculatingElements = new double[nbOrb];
911 for (int i = 0; i < nbOrb; i++) {
912 osculatingElements[i] = nominalMeanElements[i] +
913 physicalFilterCorrection.getEntry(i) +
914 shortPeriodTerms[i] +
915 B1Correction.getEntry(i);
916 }
917
918
919 return osculatingElements;
920
921 }
922
923
924
925
926
927 private void analyticalDerivativeComputations(final SpacecraftState state) {
928 harvester.setReferenceState(state);
929 }
930
931
932
933
934 private int getNumberSelectedOrbitalDrivers() {
935 return estimatedOrbitalParameters.getNbParams();
936 }
937
938
939
940
941 private int getNumberSelectedPropagationDrivers() {
942 return estimatedPropagationParameters.getNbParams();
943 }
944
945
946
947
948 private void updateParameters() {
949 final RealVector correctedState = correctedEstimate.getState();
950 int i = 0;
951
952 for (final DelegatingDriver driver : getEstimatedOrbitalParameters().getDrivers()) {
953
954 driver.setNormalizedValue(driver.getNormalizedValue() + correctedState.getEntry(i++));
955 }
956
957
958 for (final DelegatingDriver driver : getEstimatedPropagationParameters().getDrivers()) {
959
960 driver.setNormalizedValue(driver.getNormalizedValue() + correctedState.getEntry(i++));
961 }
962
963
964 for (final DelegatingDriver driver : getEstimatedMeasurementsParameters().getDrivers()) {
965
966 driver.setNormalizedValue(driver.getNormalizedValue() + correctedState.getEntry(i++));
967 }
968 }
969
970 }