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.analysis.differentiation.DerivativeStructure;
22 import org.hipparchus.analysis.differentiation.FieldDerivativeStructure;
23 import org.hipparchus.util.FastMath;
24 import org.orekit.frames.Frame;
25 import org.orekit.time.AbsoluteDate;
26 import org.orekit.utils.ExtendedPVCoordinatesProvider;
27 import org.orekit.utils.TimeStampedAngularCoordinates;
28 import org.orekit.utils.TimeStampedFieldAngularCoordinates;
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 public class Galileo extends AbstractGNSSAttitudeProvider {
44
45
46 public static final double DEFAULT_YAW_RATE = FastMath.toRadians(0.203);
47
48
49 private static final long serialVersionUID = 20171114L;
50
51
52 private static final double BETA_X = FastMath.toRadians(15.0);
53
54
55 private static final double COS_NOON = FastMath.cos(BETA_X);
56
57
58 private static final double COS_NIGHT = -COS_NOON;
59
60
61 private final double END_MARGIN = 0.0;
62
63
64 private final double yawRate;
65
66
67
68
69
70
71
72
73 public Galileo(final double yawRate,
74 final AbsoluteDateDate">AbsoluteDate validityStart, final AbsoluteDate validityEnd,
75 final ExtendedPVCoordinatesProvider sun, final Frame inertialFrame) {
76 super(validityStart, validityEnd, sun, inertialFrame);
77 this.yawRate = yawRate;
78 }
79
80
81 @Override
82 protected TimeStampedAngularCoordinates correctedYaw(final GNSSAttitudeContext context) {
83
84
85 final double beta0 = FastMath.atan(context.getMuRate() / yawRate);
86
87 if (FastMath.abs(context.beta(context.getDate())) < beta0 &&
88 context.setUpTurnRegion(COS_NIGHT, COS_NOON)) {
89
90 context.setHalfSpan(context.inSunSide() ?
91 BETA_X :
92 context.inOrbitPlaneAbsoluteAngle(BETA_X),
93 END_MARGIN);
94 if (context.inTurnTimeRange()) {
95
96
97 final DerivativeStructure beta = context.betaDS();
98 final DerivativeStructure cosBeta = beta.cos();
99 final DerivativeStructure sinBeta = beta.sin();
100 final double sinY = FastMath.copySign(FastMath.sin(beta0), context.getSecuredBeta());
101 final DerivativeStructure sd = FastMath.sin(context.getDeltaDS()).
102 multiply(FastMath.copySign(1.0, -context.getSVBcos() * context.getDeltaDS().getPartialDerivative(1)));
103 final DerivativeStructure c = sd.multiply(cosBeta);
104 final DerivativeStructure shy = sinBeta.negate().subtract(sinY).
105 add(sinBeta.subtract(sinY).multiply(c.abs().multiply(FastMath.PI / FastMath.sin(BETA_X)).cos())).
106 multiply(0.5);
107 final DerivativeStructure phi = FastMath.atan2(shy, c);
108
109 return context.turnCorrectedAttitude(phi);
110
111 }
112
113 }
114
115
116 return context.nominalYaw(context.getDate());
117
118 }
119
120
121 @Override
122 protected <T extends RealFieldElement<T>> TimeStampedFieldAngularCoordinates<T> correctedYaw(final GNSSFieldAttitudeContext<T> context) {
123
124
125 final double beta0 = FastMath.atan(context.getMuRate().getReal() / yawRate);
126
127 if (FastMath.abs(context.beta(context.getDate())).getReal() < beta0 &&
128 context.setUpTurnRegion(COS_NIGHT, COS_NOON)) {
129
130 final Field<T> field = context.getDate().getField();
131 final T betaX = field.getZero().add(BETA_X);
132 context.setHalfSpan(context.inSunSide() ?
133 betaX :
134 context.inOrbitPlaneAbsoluteAngle(betaX),
135 END_MARGIN);
136 if (context.inTurnTimeRange()) {
137
138
139 final FieldDerivativeStructure<T> beta = context.betaDS();
140 final FieldDerivativeStructure<T> cosBeta = beta.cos();
141 final FieldDerivativeStructure<T> sinBeta = beta.sin();
142 final T sinY = FastMath.sin(field.getZero().add(beta0)).copySign(context.getSecuredBeta());
143 final FieldDerivativeStructure<T> sd = FastMath.sin(context.getDeltaDS()).
144 multiply(FastMath.copySign(1.0, -context.getSVBcos().getReal() * context.getDeltaDS().getPartialDerivative(1).getReal()));
145 final FieldDerivativeStructure<T> c = sd.multiply(cosBeta);
146 final FieldDerivativeStructure<T> shy = sinBeta.negate().subtract(sinY).
147 add(sinBeta.subtract(sinY).multiply(c.abs().multiply(FastMath.PI / FastMath.sin(BETA_X)).cos())).
148 multiply(0.5);
149 final FieldDerivativeStructure<T> phi = FastMath.atan2(shy, c);
150
151 return context.turnCorrectedAttitude(phi);
152
153 }
154
155 }
156
157
158 return context.nominalYaw(context.getDate());
159
160 }
161
162 }