Commit 65354415 authored by Luc Maisonobe's avatar Luc Maisonobe

Moved the propagator from generator to schedulers.

parent 7b1d2047
......@@ -59,7 +59,7 @@
class Generator {
+addScheduler(Scheduler)
+SortedSet<ObservedMeasurements> generate(startDate, endDate, propagators)
+SortedSet<ObservedMeasurements> generate(startDate, endDate)
}
enum SignSemantic {
......@@ -69,6 +69,7 @@
class "EventBasedScheduler<T>" as EventBasedScheduler_T_
interface "Scheduler<T>" as Scheduler_T_ {
+Propagator getPropagator()
+SortedSet<T> generate(interpolators)
}
......@@ -101,10 +102,13 @@
package propagation #DDEBD8 {
interface Propagator
class PropagatorsParallelizer {
propagate()
}
Generator --> PropagatorsParallelizer
Scheduler_T_ *--> "1" Propagator
Propagator <-- PropagatorsParallelizer
}
package time #DDEBD8 {
......
......@@ -17,6 +17,8 @@
package org.orekit.estimation.measurements.generation;
import org.orekit.estimation.measurements.ObservedMeasurement;
import org.orekit.propagation.Propagator;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.DatesSelector;
......@@ -33,14 +35,50 @@ public abstract class AbstractScheduler<T extends ObservedMeasurement<T>> implem
/** Selector for dates. */
private final DatesSelector selector;
/** Propagator associated with this scheduler. */
private final Propagator propagator;
/** Simple constructor.
* @param builder builder for individual measurements
* @param selector selector for dates
* @param propagator propagator associated with this scheduler
*/
protected AbstractScheduler(final MeasurementBuilder<T> builder,
final DatesSelector selector) {
this.builder = builder;
this.selector = selector;
final DatesSelector selector,
final Propagator propagator) {
this.builder = builder;
this.selector = selector;
this.propagator = propagator;
}
/** {@inheritDoc}
* <p>
* This implementation initialize the measurement builder.
* </p>
*/
@Override
public void init(final AbsoluteDate start, final AbsoluteDate end) {
builder.init(start, end);
}
/** Get the measurements builder.
* @return measurements builder
*/
public MeasurementBuilder<T> getBuilder() {
return builder;
}
/** Get the dates selector.
* @return dates selector
*/
public DatesSelector getSelector() {
return selector;
}
/** {@inheritDoc} */
@Override
public Propagator getPropagator() {
return propagator;
}
}
......@@ -16,12 +16,20 @@
*/
package org.orekit.estimation.measurements.generation;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import org.orekit.estimation.measurements.ObservedMeasurement;
import org.orekit.propagation.Propagator;
import org.orekit.propagation.SpacecraftState;
import org.orekit.propagation.events.AdapterDetector;
import org.orekit.propagation.events.EventDetector;
import org.orekit.propagation.events.handlers.EventHandler.Action;
import org.orekit.propagation.sampling.OrekitStepInterpolator;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.DatesSelector;
import org.orekit.utils.TimeSpanMap;
/** {@link Scheduler} based on {@link EventDetector} for generating measurements sequences.
......@@ -51,30 +59,112 @@ import org.orekit.time.DatesSelector;
*/
public class EventBasedScheduler<T extends ObservedMeasurement<T>> extends AbstractScheduler<T> {
/** Detector for checking measurements feasibility. */
private final EventDetector detector;
/** Semantic of the detector g function sign to use. */
private final SignSemantic signSemantic;
/** Feasibility status. */
private TimeSpanMap<Boolean> feasibility;
/** Propagation direction. */
private boolean forward;
/** Simple constructor.
* <p>
* The event detector instance should <em>not</em> be already bound to the propagator.
* It will be wrapped in an {@link AdapterDetector adapter} in order to manage time
* ranges when measurements are feasible. The wrapping adapter will be automatically
* {@link Propagator#addEventDetector(EventDetector) added} to the propagator by this
* constructor.
* </p>
* @param builder builder for individual measurements
* @param selector selector for dates
* @param propagator propagator associated with this scheduler
* @param detector detector for checking measurements feasibility
* @param signSemantic semantic of the detector g function sign to use
*/
public EventBasedScheduler(final MeasurementBuilder<T> builder, final DatesSelector selector,
final Propagator propagator,
final EventDetector detector, final SignSemantic signSemantic) {
super(builder, selector);
this.detector = detector;
super(builder, selector, propagator);
this.signSemantic = signSemantic;
this.feasibility = new TimeSpanMap<Boolean>(Boolean.FALSE);
this.forward = true;
propagator.addEventDetector(new FeasibilityAdapter(detector));
}
/** {@inheritDoc} */
@Override
public SortedSet<T> generate(final OrekitStepInterpolator... interpolators) {
// TODO
return null;
public SortedSet<T> generate(final List<OrekitStepInterpolator> interpolators) {
// select dates in the current step, using arbitrarily interpolator 0
// as all interpolators cover the same range
final List<AbsoluteDate> dates = getSelector().selectDates(interpolators.get(0).getPreviousState().getDate(),
interpolators.get(0).getCurrentState().getDate());
// generate measurements when feasible
final SortedSet<T> measurements = new TreeSet<>();
for (final AbsoluteDate date : dates) {
if (feasibility.get(date)) {
// a measurement is feasible at this date
// interpolate states at measurement date
final SpacecraftState[] states = new SpacecraftState[interpolators.size()];
for (int i = 0; i < states.length; ++i) {
states[i] = interpolators.get(i).getInterpolatedState(date);
}
// generate measurement
measurements.add(getBuilder().build(states));
}
}
return measurements;
}
/** Adapter for managing feasibility status changes. */
private class FeasibilityAdapter extends AdapterDetector {
/** Serializable UID. */
private static final long serialVersionUID = 20181206L;
/** Build an adaptor wrapping an existing detector.
* @param detector detector to wrap
*/
FeasibilityAdapter(final EventDetector detector) {
super(detector);
}
/** {@inheritDoc} */
@Override
public void init(final SpacecraftState s0, final AbsoluteDate t) {
super.init(s0, t);
forward = t.compareTo(s0.getDate()) > 0;
feasibility = new TimeSpanMap<Boolean>(signSemantic.measurementIsFeasible(g(s0)));
}
/** {@inheritDoc} */
@Override
public Action eventOccurred(final SpacecraftState s, final boolean increasing) {
// find the feasibility status AFTER the current date
final boolean statusAfter = signSemantic.measurementIsFeasible(increasing ? +1 : -1);
// store either status or its opposite according to propagation direction
if (forward) {
// forward propagation
feasibility.addValidAfter(statusAfter, s.getDate());
} else {
// backward propagation
feasibility.addValidBefore(!statusAfter, s.getDate());
}
// delegate to wrapped detector
return super.eventOccurred(s, increasing);
}
}
}
......@@ -19,9 +19,14 @@ package org.orekit.estimation.measurements.generation;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import org.orekit.estimation.measurements.ObservedMeasurement;
import org.orekit.propagation.Propagator;
import org.orekit.propagation.PropagatorsParallelizer;
import org.orekit.propagation.SpacecraftState;
import org.orekit.propagation.sampling.MultiSatStepHandler;
import org.orekit.propagation.sampling.OrekitStepInterpolator;
import org.orekit.time.AbsoluteDate;
......@@ -51,13 +56,70 @@ public class Generator {
/** Generate measurements.
* @param start start of the measurements time span
* @param end end of the measurements time span
* @param propagators propagators to use
* @return generated measurements
*/
public SortedSet<ObservedMeasurement<?>> generate(final AbsoluteDate start, final AbsoluteDate end,
final Propagator... propagators) {
// TODO
return null;
public SortedSet<ObservedMeasurement<?>> generate(final AbsoluteDate start, final AbsoluteDate end) {
// initialize schedulers
for (final Scheduler<?> scheduler : schedulers) {
scheduler.init(start, end);
}
// set up parallelized propagators
final List<Propagator> propagators = new ArrayList<>(schedulers.size());
for (final Scheduler<?> scheduler : schedulers) {
propagators.add(scheduler.getPropagator());
}
final GeneratorHandler handler = new GeneratorHandler(schedulers);
final PropagatorsParallelizer parallelizer = new PropagatorsParallelizer(propagators, handler);
// generate the measurements
parallelizer.propagate(start, end);
return handler.getMeasurements();
}
/** Handler for measurements generation steps. */
private static class GeneratorHandler implements MultiSatStepHandler {
/** Sequences generators. */
private final List<Scheduler<?>> schedulers;
/** Set for holding measurements. */
private final SortedSet<ObservedMeasurement<?>> measurements;
/** Simple constructor.
* @param schedulers sequences generators
*/
GeneratorHandler(final List<Scheduler<?>> schedulers) {
this.schedulers = schedulers;
this.measurements = new TreeSet<>();
}
/** {@inheritDoc} */
@Override
public void init(final List<SpacecraftState> states0, final AbsoluteDate t) {
for (final Scheduler<?> scheduler : schedulers) {
scheduler.init(states0.get(0).getDate(), t);
}
}
/** {@inheritDoc} */
@Override
public void handleStep(final List<OrekitStepInterpolator> interpolators, final boolean isLast) {
for (final Scheduler<?> scheduler : schedulers) {
scheduler.generate(interpolators);
}
}
/** Get the generated measurements.
* @return generated measurements
*/
public SortedSet<ObservedMeasurement<?>> getMeasurements() {
return measurements;
}
}
}
......@@ -16,10 +16,13 @@
*/
package org.orekit.estimation.measurements.generation;
import java.util.List;
import java.util.SortedSet;
import org.orekit.estimation.measurements.ObservedMeasurement;
import org.orekit.propagation.Propagator;
import org.orekit.propagation.sampling.OrekitStepInterpolator;
import org.orekit.time.AbsoluteDate;
/** Interface for generating {@link ObservedMeasurements measurements} sequences.
......@@ -29,10 +32,27 @@ import org.orekit.propagation.sampling.OrekitStepInterpolator;
*/
public interface Scheduler<T extends ObservedMeasurement<T>> {
/** Initialize scheduler at the start of a measurements generation.
* <p>
* This method is called once at the start of the measurements generation. It
* may be used by the scheduler to initialize some internal data
* if needed, typically {@link MeasurementBuilder#init(AbsoluteDate, AbsoluteDate)
* initializing builders}.
* </p>
* @param start start of the measurements time span
* @param end end of the measurements time span
*/
void init(AbsoluteDate start, AbsoluteDate end);
/** Get the propagator associated with this scheduler.
* @return propagator associated with this scheduler
*/
Propagator getPropagator();
/** Generate a sequence of measurements.
* @param interpolators interpolators for spacecraft states
* @return generated measurements
*/
SortedSet<T> generate(OrekitStepInterpolator... interpolators);
SortedSet<T> generate(List<OrekitStepInterpolator> interpolators);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment