1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.estimation.measurements.generation;
18
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.Comparator;
22 import java.util.HashMap;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.SortedSet;
27 import java.util.TreeSet;
28
29 import org.orekit.estimation.measurements.EstimatedMeasurementBase;
30 import org.orekit.estimation.measurements.ObservableSatellite;
31 import org.orekit.estimation.measurements.ObservedMeasurement;
32 import org.orekit.propagation.Propagator;
33 import org.orekit.propagation.PropagatorsParallelizer;
34 import org.orekit.propagation.SpacecraftState;
35 import org.orekit.propagation.sampling.MultiSatStepHandler;
36 import org.orekit.propagation.sampling.OrekitStepHandler;
37 import org.orekit.propagation.sampling.OrekitStepInterpolator;
38 import org.orekit.propagation.sampling.StepHandlerMultiplexer;
39 import org.orekit.time.AbsoluteDate;
40
41
42
43
44
45
46 public class Generator {
47
48
49
50
51 private final List<ObservableSatellite> observableSatellites;
52
53
54 private final List<Propagator> propagators;
55
56
57 private final List<Scheduler<? extends ObservedMeasurement<?>>> multiSatSchedulers;
58
59
60 private final Map<ObservableSatellite, List<Scheduler<? extends ObservedMeasurement<?>>>> singleSatSchedulers;
61
62
63
64
65 private final List<GeneratedMeasurementSubscriber> subscribers;
66
67
68
69 public Generator() {
70 this.observableSatellites = new ArrayList<>();
71 this.propagators = new ArrayList<>();
72 this.multiSatSchedulers = new ArrayList<>();
73 this.singleSatSchedulers = new HashMap<>();
74 this.subscribers = new ArrayList<>();
75 }
76
77
78
79
80
81 public ObservableSatellite addPropagator(final Propagator propagator) {
82 return addPropagator(propagator, null);
83 }
84
85
86
87
88
89
90
91 public ObservableSatellite addPropagator(final Propagator propagator, final String name) {
92 final ObservableSatellite os = new ObservableSatellite(propagators.size(), name);
93 observableSatellites.add(os);
94 propagators.add(propagator);
95 return os;
96 }
97
98
99
100
101
102 public Propagator getPropagator(final ObservableSatellite satellite) {
103 return propagators.get(satellite.getPropagatorIndex());
104 }
105
106
107
108
109
110 public <T extends ObservedMeasurement<T>> void addScheduler(final Scheduler<T> scheduler) {
111 final ObservableSatellite[] satellites = scheduler.getBuilder().getSatellites();
112 if (satellites.length == 1) {
113
114
115 final List<Scheduler<? extends ObservedMeasurement<?>>> list =
116 singleSatSchedulers.computeIfAbsent(satellites[0], k -> new ArrayList<>());
117 list.add(scheduler);
118 } else {
119
120
121 multiSatSchedulers.add(scheduler);
122 }
123 }
124
125
126
127
128
129
130 public void addSubscriber(final GeneratedMeasurementSubscriber subscriber) {
131 subscribers.add(subscriber);
132 }
133
134
135
136
137
138 public void generate(final AbsoluteDate start, final AbsoluteDate end) {
139
140
141 final MultipleSatGeneratorHandler globalHandler =
142 new MultipleSatGeneratorHandler(multiSatSchedulers, subscribers,
143 observableSatellites, end.isAfterOrEqualTo(start));
144
145
146 for (final Map.Entry<ObservableSatellite, List<Scheduler<? extends ObservedMeasurement<?>>>> entry : singleSatSchedulers.entrySet()) {
147 final StepHandlerMultiplexer multiplexer = propagators.get(entry.getKey().getPropagatorIndex()).getMultiplexer();
148 for (final Scheduler<?> scheduler : entry.getValue()) {
149 multiplexer.add(new SingleSatGeneratorHandler<>(scheduler, globalHandler));
150 }
151 }
152
153
154 final PropagatorsParallelizer parallelizer = new PropagatorsParallelizer(propagators, globalHandler);
155
156
157 parallelizer.propagate(start, end);
158
159
160 for (final Map.Entry<ObservableSatellite, List<Scheduler<? extends ObservedMeasurement<?>>>> entry : singleSatSchedulers.entrySet()) {
161
162 final StepHandlerMultiplexer multiplexer = propagators.get(entry.getKey().getPropagatorIndex()).getMultiplexer();
163 final List<OrekitStepHandler> toBeRemoved = new ArrayList<>();
164 for (final OrekitStepHandler handler : multiplexer.getHandlers()) {
165 if (handler instanceof SingleSatGeneratorHandler &&
166 ((SingleSatGeneratorHandler<?>) handler).globalHandler == globalHandler) {
167 toBeRemoved.add(handler);
168 }
169 }
170 for (final OrekitStepHandler handler : toBeRemoved) {
171 multiplexer.remove(handler);
172 }
173 }
174
175 }
176
177
178
179
180
181
182
183
184
185 private static class SingleSatGeneratorHandler<T extends ObservedMeasurement<T>> implements OrekitStepHandler {
186
187
188 private final Scheduler<T> scheduler;
189
190
191 private final ObservableSatellite satellite;
192
193
194 private final MultipleSatGeneratorHandler globalHandler;
195
196
197
198
199
200 SingleSatGeneratorHandler(final Scheduler<T> scheduler, final MultipleSatGeneratorHandler globalHandler) {
201 this.scheduler = scheduler;
202 this.satellite = scheduler.getBuilder().getSatellites()[0];
203 this.globalHandler = globalHandler;
204 }
205
206
207 @Override
208 public void init(final SpacecraftState state0, final AbsoluteDate t) {
209 scheduler.init(state0.getDate(), t);
210 }
211
212
213 @Override
214 public void handleStep(final OrekitStepInterpolator interpolator) {
215 globalHandler.addMeasurements(scheduler.generate(Collections.singletonMap(satellite, interpolator)));
216 }
217
218 }
219
220
221
222
223
224
225
226
227
228
229 private static class MultipleSatGeneratorHandler implements MultiSatStepHandler {
230
231
232 private final List<Scheduler<? extends ObservedMeasurement<?>>> schedulers;
233
234
235
236
237 private final List<GeneratedMeasurementSubscriber> subscribers;
238
239
240
241
242 private final List<ObservableSatellite> observableSatellites;
243
244
245
246
247 private final SortedSet<EstimatedMeasurementBase<?>> generated;
248
249
250
251
252 private final boolean forward;
253
254
255
256
257
258
259
260
261 MultipleSatGeneratorHandler(final List<Scheduler<? extends ObservedMeasurement<?>>> schedulers,
262 final List<GeneratedMeasurementSubscriber> subscribers,
263 final List<ObservableSatellite> observableSatellites, final boolean forward) {
264
265
266 final Comparator<EstimatedMeasurementBase<?>> comparator = forward ? Comparator.naturalOrder() : Comparator.reverseOrder();
267
268 this.schedulers = schedulers;
269 this.subscribers = subscribers;
270 this.observableSatellites = observableSatellites;
271 this.generated = new TreeSet<>(comparator);
272 this.forward = forward;
273
274 }
275
276
277 @Override
278 public void init(final List<SpacecraftState> states0, final AbsoluteDate t) {
279
280 final AbsoluteDate start = states0.get(0).getDate();
281
282
283 for (final Scheduler<?> scheduler : schedulers) {
284 scheduler.init(start, t);
285 }
286
287
288 for (final GeneratedMeasurementSubscriber subscriber : subscribers) {
289 subscriber.init(start, t);
290 }
291
292 }
293
294
295 @Override
296 public void handleStep(final List<OrekitStepInterpolator> interpolators) {
297
298
299 final Map<ObservableSatellite, OrekitStepInterpolator> interpolatorsMap =
300 new HashMap<>(interpolators.size());
301 for (int i = 0; i < interpolators.size(); ++i) {
302 interpolatorsMap.put(observableSatellites.get(i), interpolators.get(i));
303 }
304 final AbsoluteDate lastDate = interpolators.get(0).getCurrentState().getDate();
305
306 synchronized (generated) {
307
308
309 for (final Scheduler<? extends ObservedMeasurement<?>> scheduler : schedulers) {
310 generated.addAll(scheduler.generate(interpolatorsMap));
311 }
312
313
314 for (final Iterator<EstimatedMeasurementBase<?>> iterator = generated.iterator(); iterator.hasNext();) {
315 final EstimatedMeasurementBase<?> measurement = iterator.next();
316 if (forward == lastDate.isAfterOrEqualTo(measurement)) {
317
318 for (final GeneratedMeasurementSubscriber subscriber : subscribers) {
319 subscriber.handleGeneratedMeasurement(measurement);
320 }
321 iterator.remove();
322 } else {
323
324
325 break;
326 }
327 }
328
329 }
330
331 }
332
333
334 public void finish(final List<SpacecraftState> finalStates) {
335 synchronized (generated) {
336 for (final EstimatedMeasurementBase<?> measurement : generated) {
337 for (final GeneratedMeasurementSubscriber subscriber : subscribers) {
338 subscriber.handleGeneratedMeasurement(measurement);
339 }
340 }
341 generated.clear();
342 }
343 }
344
345
346
347
348
349 private void addMeasurements(final SortedSet<? extends EstimatedMeasurementBase<?>> measurements) {
350 synchronized (generated) {
351 generated.addAll(measurements);
352 }
353 }
354
355 }
356
357 }