1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.gnss.attitude;
18
19 import org.hipparchus.Field;
20 import org.hipparchus.RealFieldElement;
21 import org.hipparchus.util.FastMath;
22 import org.orekit.frames.Frame;
23 import org.orekit.time.AbsoluteDate;
24 import org.orekit.utils.ExtendedPVCoordinatesProvider;
25 import org.orekit.utils.TimeStampedAngularCoordinates;
26 import org.orekit.utils.TimeStampedFieldAngularCoordinates;
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 public class GPSBlockIIR extends AbstractGNSSAttitudeProvider {
45
46
47 private static final long serialVersionUID = 20171114L;
48
49
50 private static final double YAW_RATE = FastMath.toRadians(0.2);
51
52
53 private final double END_MARGIN = 1800.0;
54
55
56
57
58
59
60
61 public GPSBlockIIR(final AbsoluteDate validityStart, final AbsoluteDate validityEnd,
62 final ExtendedPVCoordinatesProvider sun, final Frame inertialFrame) {
63 super(validityStart, validityEnd, sun, inertialFrame);
64 }
65
66
67 @Override
68 protected TimeStampedAngularCoordinates correctedYaw(final GNSSAttitudeContext context) {
69
70
71 final double aNoon = FastMath.atan(context.getMuRate() / YAW_RATE);
72 final double cNoon = FastMath.cos(aNoon);
73 final double cNight = -cNoon;
74
75 if (context.setUpTurnRegion(cNight, cNoon)) {
76
77 final double absBeta = FastMath.abs(context.getBeta());
78 context.setHalfSpan(absBeta * FastMath.sqrt(aNoon / absBeta - 1.0));
79 if (context.inTurnTimeRange(context.getDate(), END_MARGIN)) {
80
81
82 final double beta = context.getSecuredBeta();
83 final double phiStart = context.getYawStart(beta);
84 final double dtStart = context.timeSinceTurnStart(context.getDate());
85 final double phiDot;
86 final double linearPhi;
87
88 if (context.inSunSide()) {
89
90 phiDot = -FastMath.copySign(YAW_RATE, beta);
91 linearPhi = phiStart + phiDot * dtStart;
92 } else {
93
94 phiDot = FastMath.copySign(YAW_RATE, beta);
95 linearPhi = phiStart + phiDot * dtStart;
96 final double phiEnd = context.getYawEnd(beta);
97 if (phiEnd / linearPhi < 0 || phiEnd / linearPhi > 1) {
98 return context.getNominalYaw();
99 }
100 }
101
102 return context.turnCorrectedAttitude(linearPhi, phiDot);
103
104 }
105
106 }
107
108
109 return context.getNominalYaw();
110
111 }
112
113
114 @Override
115 protected <T extends RealFieldElement<T>> TimeStampedFieldAngularCoordinates<T> correctedYaw(final GNSSFieldAttitudeContext<T> context) {
116
117 final Field<T> field = context.getDate().getField();
118
119
120 final T aNoon = FastMath.atan(context.getMuRate().divide(YAW_RATE));
121 final double cNoon = FastMath.cos(aNoon.getReal());
122 final double cNight = -cNoon;
123
124 if (context.setUpTurnRegion(cNight, cNoon)) {
125
126 final T absBeta = FastMath.abs(context.getBeta());
127 context.setHalfSpan(absBeta.multiply(FastMath.sqrt(aNoon.divide(absBeta).subtract(1.0))));
128 if (context.inTurnTimeRange(context.getDate(), END_MARGIN)) {
129
130
131 final T beta = context.getSecuredBeta();
132 final T phiStart = context.getYawStart(beta);
133 final T dtStart = context.timeSinceTurnStart(context.getDate());
134 final T phiDot;
135 final T linearPhi;
136
137 if (context.inSunSide()) {
138
139 phiDot = field.getZero().add(-FastMath.copySign(YAW_RATE, beta.getReal()));
140 linearPhi = phiStart.add(phiDot.multiply(dtStart));
141 } else {
142
143 phiDot = field.getZero().add(FastMath.copySign(YAW_RATE, beta.getReal()));
144 linearPhi = phiStart.add(phiDot.multiply(dtStart));
145 final T phiEnd = context.getYawEnd(beta);
146 if (phiEnd.getReal() / linearPhi.getReal() < 0 || phiEnd.getReal() / linearPhi.getReal() > 1) {
147 return context.getNominalYaw();
148 }
149 }
150
151 return context.turnCorrectedAttitude(linearPhi, phiDot);
152
153 }
154
155 }
156
157
158 return context.getNominalYaw();
159
160 }
161
162 }