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