1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.estimation.measurements.gnss;
18
19 import java.util.Collections;
20 import java.util.List;
21
22 import org.hipparchus.geometry.euclidean.threed.Rotation;
23 import org.hipparchus.geometry.euclidean.threed.Vector3D;
24 import org.hipparchus.util.FastMath;
25 import org.hipparchus.util.MathUtils;
26 import org.orekit.estimation.measurements.EstimatedMeasurementBase;
27 import org.orekit.estimation.measurements.EstimationModifier;
28 import org.orekit.estimation.measurements.ObservedMeasurement;
29 import org.orekit.utils.ParameterDriver;
30 import org.orekit.utils.TimeStampedPVCoordinates;
31
32
33
34
35
36
37
38 public abstract class AbstractWindUp<T extends ObservedMeasurement<T>> implements EstimationModifier<T> {
39
40
41 private final Dipole emitter;
42
43
44 private final Dipole receiver;
45
46
47 private double angularWindUp;
48
49
50
51
52
53 protected AbstractWindUp(final Dipole emitter, final Dipole receiver) {
54 this.emitter = emitter;
55 this.receiver = receiver;
56 angularWindUp = 0.0;
57 }
58
59
60
61
62
63
64 @Override
65 public List<ParameterDriver> getParametersDrivers() {
66 return Collections.emptyList();
67 }
68
69
70
71
72
73 protected abstract Rotation emitterToInert(EstimatedMeasurementBase<T> estimated);
74
75
76
77
78
79 protected abstract Rotation receiverToInert(EstimatedMeasurementBase<T> estimated);
80
81
82 @Override
83 public void modifyWithoutDerivatives(final EstimatedMeasurementBase<T> estimated) {
84
85
86 final TimeStampedPVCoordinates[] participants = estimated.getParticipants();
87 final Vector3D los = participants[1].getPosition().subtract(participants[0].getPosition()).normalize();
88
89
90 final Rotation receiverToInert = receiverToInert(estimated);
91 final Vector3D iReceiver = receiverToInert.applyTo(receiver.getPrimary());
92 final Vector3D jReceiver = receiverToInert.applyTo(receiver.getSecondary());
93 final Vector3D dReceiver = new Vector3D(1.0, iReceiver, -Vector3D.dotProduct(iReceiver, los), los).
94 add(Vector3D.crossProduct(los, jReceiver));
95
96
97 final Rotation emitterToInert = emitterToInert(estimated);
98 final Vector3D iEmitter = emitterToInert.applyTo(emitter.getPrimary());
99 final Vector3D jEmitter = emitterToInert.applyTo(emitter.getSecondary());
100 final Vector3D dEmitter = new Vector3D(1.0, iEmitter, -Vector3D.dotProduct(iEmitter, los), los).
101 subtract(Vector3D.crossProduct(los, jEmitter));
102
103
104 final double correction = FastMath.copySign(Vector3D.angle(dEmitter, dReceiver),
105 Vector3D.dotProduct(los, Vector3D.crossProduct(dEmitter, dReceiver)));
106
107
108
109
110 angularWindUp = MathUtils.normalizeAngle(correction, angularWindUp);
111
112
113 estimated.modifyEstimatedValue(this, estimated.getEstimatedValue()[0] + angularWindUp / MathUtils.TWO_PI);
114
115 }
116
117 }