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 GPSBlockIIF extends AbstractGNSSAttitudeProvider {
45
46
47 private static final long serialVersionUID = 20171114L;
48
49
50 private static final double NIGHT_TURN_LIMIT = FastMath.toRadians(180.0 - 13.25);
51
52
53 private static final double YAW_BIAS = FastMath.toRadians(-0.7);
54
55
56 private static final double YAW_RATE = FastMath.toRadians(0.11);
57
58
59 private final double END_MARGIN = 1800.0;
60
61
62
63
64
65
66
67 public GPSBlockIIF(final AbsoluteDate validityStart, final AbsoluteDate validityEnd,
68 final ExtendedPVCoordinatesProvider sun, final Frame inertialFrame) {
69 super(validityStart, validityEnd, sun, inertialFrame);
70 }
71
72
73 @Override
74 protected TimeStampedAngularCoordinates correctedYaw(final GNSSAttitudeContext context) {
75
76
77 final double aNoon = FastMath.atan(context.getMuRate() / YAW_RATE);
78 final double aNight = NIGHT_TURN_LIMIT;
79 final double cNoon = FastMath.cos(aNoon);
80 final double cNight = FastMath.cos(aNight);
81
82 if (context.setUpTurnRegion(cNight, cNoon)) {
83
84 final double absBeta = FastMath.abs(context.getBeta());
85 context.setHalfSpan(context.inSunSide() ?
86 absBeta * FastMath.sqrt(aNoon / absBeta - 1.0) :
87 context.inOrbitPlaneAbsoluteAngle(aNight - FastMath.PI));
88 if (context.inTurnTimeRange(context.getDate(), END_MARGIN)) {
89
90
91 final double beta = context.getSecuredBeta();
92 final double phiStart = context.getYawStart(beta);
93 final double dtStart = context.timeSinceTurnStart(context.getDate());
94 final double phiDot;
95 final double linearPhi;
96 if (context.inSunSide()) {
97
98 if (beta > YAW_BIAS && beta < 0) {
99
100
101 phiDot = FastMath.copySign(YAW_RATE, beta);
102 linearPhi = phiStart + phiDot * dtStart;
103 } else {
104
105 phiDot = -FastMath.copySign(YAW_RATE, beta);
106 linearPhi = phiStart + phiDot * dtStart;
107 }
108 } else {
109
110 phiDot = context.yawRate(beta);
111 linearPhi = phiStart + phiDot * dtStart;
112 }
113
114 return context.turnCorrectedAttitude(linearPhi, phiDot);
115
116 }
117
118 }
119
120
121 return context.getNominalYaw();
122
123 }
124
125
126 @Override
127 protected <T extends RealFieldElement<T>> TimeStampedFieldAngularCoordinates<T> correctedYaw(final GNSSFieldAttitudeContext<T> context) {
128
129 final Field<T> field = context.getDate().getField();
130
131
132 final T aNoon = FastMath.atan(context.getMuRate().divide(YAW_RATE));
133 final T aNight = field.getZero().add(NIGHT_TURN_LIMIT);
134 final double cNoon = FastMath.cos(aNoon.getReal());
135 final double cNight = FastMath.cos(aNight.getReal());
136
137 if (context.setUpTurnRegion(cNight, cNoon)) {
138
139 final T absBeta = FastMath.abs(context.getBeta());
140 context.setHalfSpan(context.inSunSide() ?
141 absBeta.multiply(FastMath.sqrt(aNoon.divide(absBeta).subtract(1.0))) :
142 context.inOrbitPlaneAbsoluteAngle(aNight.subtract(FastMath.PI)));
143 if (context.inTurnTimeRange(context.getDate(), END_MARGIN)) {
144
145
146 final T beta = context.getSecuredBeta();
147 final T phiStart = context.getYawStart(beta);
148 final T dtStart = context.timeSinceTurnStart(context.getDate());
149 final T phiDot;
150 final T linearPhi;
151 if (context.inSunSide()) {
152
153 if (beta.getReal() > YAW_BIAS && beta.getReal() < 0) {
154
155
156 phiDot = field.getZero().add(FastMath.copySign(YAW_RATE, beta.getReal()));
157 linearPhi = phiStart.add(phiDot.multiply(dtStart));
158 } else {
159
160 phiDot = field.getZero().add(-FastMath.copySign(YAW_RATE, beta.getReal()));
161 linearPhi = phiStart.add(phiDot.multiply(dtStart));
162 }
163 } else {
164
165 phiDot = context.yawRate(beta);
166 linearPhi = phiStart.add(phiDot.multiply(dtStart));
167 }
168
169 return context.turnCorrectedAttitude(linearPhi, phiDot);
170
171 }
172
173 }
174
175
176 return context.getNominalYaw();
177
178 }
179
180 }