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 java.util.HashMap;
20 import java.util.Map;
21 import java.util.SortedSet;
22 import java.util.TreeSet;
23
24 import org.hipparchus.Field;
25 import org.hipparchus.RealFieldElement;
26 import org.orekit.attitudes.Attitude;
27 import org.orekit.attitudes.FieldAttitude;
28 import org.orekit.frames.Frame;
29 import org.orekit.time.AbsoluteDate;
30 import org.orekit.time.ChronologicalComparator;
31 import org.orekit.time.FieldAbsoluteDate;
32 import org.orekit.time.TimeStamped;
33 import org.orekit.utils.ExtendedPVCoordinatesProvider;
34 import org.orekit.utils.FieldPVCoordinatesProvider;
35 import org.orekit.utils.PVCoordinatesProvider;
36 import org.orekit.utils.TimeStampedAngularCoordinates;
37 import org.orekit.utils.TimeStampedFieldAngularCoordinates;
38
39
40
41
42
43
44
45 public abstract class AbstractGNSSAttitudeProvider implements GNSSAttitudeProvider {
46
47
48 private static final long serialVersionUID = 20171114L;
49
50
51 private final AbsoluteDate validityStart;
52
53
54 private final AbsoluteDate validityEnd;
55
56
57 private final ExtendedPVCoordinatesProvider sun;
58
59
60 private final Frame inertialFrame;
61
62
63 private final SortedSet<TimeStamped> turns;
64
65
66 private final transient Map<Field<? extends RealFieldElement<?>>, SortedSet<TimeStamped>> fieldTurns;
67
68
69
70
71
72
73
74 protected AbstractGNSSAttitudeProvider(final AbsoluteDate validityStart,
75 final AbsoluteDate validityEnd,
76 final ExtendedPVCoordinatesProvider sun,
77 final Frame inertialFrame) {
78 this.validityStart = validityStart;
79 this.validityEnd = validityEnd;
80 this.sun = sun;
81 this.inertialFrame = inertialFrame;
82 this.turns = new TreeSet<>(new ChronologicalComparator());
83 this.fieldTurns = new HashMap<>();
84 }
85
86
87 @Override
88 public AbsoluteDate validityStart() {
89 return validityStart;
90 }
91
92
93 @Override
94 public AbsoluteDate validityEnd() {
95 return validityEnd;
96 }
97
98
99 @Override
100 public Attitude getAttitude(final PVCoordinatesProvider pvProv,
101 final AbsoluteDate date,
102 final Frame frame) {
103
104
105 final TurnSpan turnSpan = getTurnSpan(date);
106 final GNSSAttitudeContextAttitudeContext">GNSSAttitudeContext context = new GNSSAttitudeContext(date, sun, pvProv, inertialFrame, turnSpan);
107 final TimeStampedAngularCoordinates corrected = correctedYaw(context);
108 if (turnSpan == null && context.getTurnSpan() != null) {
109
110 turns.add(context.getTurnSpan());
111 }
112
113 return new Attitude(inertialFrame, corrected).withReferenceFrame(frame);
114
115 }
116
117
118 @Override
119 public <T extends RealFieldElement<T>> FieldAttitude<T> getAttitude(final FieldPVCoordinatesProvider<T> pvProv,
120 final FieldAbsoluteDate<T> date,
121 final Frame frame) {
122
123
124 final FieldTurnSpan<T> turnSpan = getTurnSpan(date);
125 final GNSSFieldAttitudeContext<T> context = new GNSSFieldAttitudeContext<>(date, sun, pvProv, inertialFrame, turnSpan);
126 final TimeStampedFieldAngularCoordinates<T> corrected = correctedYaw(context);
127 if (turnSpan == null && context.getTurnSpan() != null) {
128
129 fieldTurns.get(date.getField()).add(context.getTurnSpan());
130 }
131
132 return new FieldAttitude<>(inertialFrame, corrected).withReferenceFrame(frame);
133
134 }
135
136
137
138
139
140 private TurnSpan getTurnSpan(final AbsoluteDate date) {
141
142
143
144 final SortedSet<TimeStamped> after = turns.tailSet(date);
145 if (!after.isEmpty()) {
146 final TurnSpan="../../../../org/orekit/gnss/attitude/TurnSpan.html#TurnSpan">TurnSpan ts = (TurnSpan) after.first();
147 if (ts.inTurnTimeRange(date)) {
148 return ts;
149 }
150 }
151
152
153 return null;
154
155 }
156
157
158
159
160
161
162 private <T extends RealFieldElement<T>> FieldTurnSpan<T> getTurnSpan(final FieldAbsoluteDate<T> date) {
163
164 SortedSet<TimeStamped> sortedSet = fieldTurns.get(date.getField());
165 if (sortedSet == null) {
166
167 sortedSet = new TreeSet<>(new ChronologicalComparator());
168 fieldTurns.put(date.getField(), sortedSet);
169 }
170
171
172
173 final AbsoluteDate dateDouble = date.toAbsoluteDate();
174 final SortedSet<TimeStamped> after = sortedSet.tailSet(dateDouble);
175 if (!after.isEmpty()) {
176 @SuppressWarnings("unchecked")
177 final FieldTurnSpan<T> ts = (FieldTurnSpan<T>) after.first();
178 if (ts.inTurnTimeRange(dateDouble)) {
179 return ts;
180 }
181 }
182
183
184 return null;
185
186 }
187
188
189
190
191
192
193 protected abstract TimeStampedAngularCoordinates correctedYaw(GNSSAttitudeContext context);
194
195
196
197
198
199
200 protected abstract <T extends RealFieldElement<T>> TimeStampedFieldAngularCoordinates<T>
201 correctedYaw(GNSSFieldAttitudeContext<T> context);
202
203 }