Commit 1470b4fd authored by Bryan Cazabonne's avatar Bryan Cazabonne
Browse files

Removed duplicated code in measurement creators for OD tests.

parent 165cc6df
......@@ -41,7 +41,7 @@ import org.orekit.time.UT1Scale;
import org.orekit.utils.IERSConventions;
import org.orekit.utils.PVCoordinates;
public class Context {
public class Context implements StationDataProvider {
public IERSConventions conventions;
public OneAxisEllipsoid earth;
public CelestialBody sun;
......@@ -100,4 +100,9 @@ public class Context {
ut1.getEOPHistory(), displacements);
}
@Override
public List<GroundStation> getStations() {
return stations;
}
}
......@@ -39,7 +39,7 @@ import org.orekit.time.UT1Scale;
import org.orekit.utils.IERSConventions;
import org.orekit.utils.PVCoordinates;
public class DSSTContext {
public class DSSTContext implements StationDataProvider {
public IERSConventions conventions;
public OneAxisEllipsoid earth;
......@@ -110,4 +110,9 @@ public class DSSTContext {
ut1.getEOPHistory(), displacements);
}
@Override
public List<GroundStation> getStations() {
return stations;
}
}
package org.orekit.estimation;
import java.util.List;
import org.orekit.estimation.measurements.GroundStation;
/**
* Utility class for station data providers.
*/
public interface StationDataProvider {
List<GroundStation> getStations();
}
......@@ -34,7 +34,7 @@ import org.orekit.time.TimeScale;
import org.orekit.time.UT1Scale;
import org.orekit.utils.IERSConventions;
public class TLEContext {
public class TLEContext implements StationDataProvider {
public IERSConventions conventions;
public OneAxisEllipsoid earth;
public CelestialBody sun;
......@@ -68,4 +68,9 @@ public class TLEContext {
ut1.getEOPHistory(), displacements);
}
@Override
public List<GroundStation> getStations() {
return stations;
}
}
......@@ -31,13 +31,13 @@ import org.orekit.errors.OrekitException;
import org.orekit.errors.OrekitMessages;
import org.orekit.estimation.DSSTContext;
import org.orekit.estimation.DSSTEstimationTestUtils;
import org.orekit.estimation.measurements.DSSTRangeMeasurementCreator;
import org.orekit.estimation.measurements.DSSTRangeRateMeasurementCreator;
import org.orekit.estimation.measurements.EstimationsProvider;
import org.orekit.estimation.measurements.GroundStation;
import org.orekit.estimation.measurements.ObservedMeasurement;
import org.orekit.estimation.measurements.PVMeasurementCreator;
import org.orekit.estimation.measurements.Range;
import org.orekit.estimation.measurements.RangeMeasurementCreator;
import org.orekit.estimation.measurements.RangeRateMeasurementCreator;
import org.orekit.estimation.measurements.modifiers.OnBoardAntennaRangeModifier;
import org.orekit.frames.LOFType;
import org.orekit.orbits.Orbit;
......@@ -155,7 +155,7 @@ public class DSSTBatchLSEstimatorTest {
propagatorBuilder);
final List<ObservedMeasurement<?>> measurements =
DSSTEstimationTestUtils.createMeasurements(propagator,
new DSSTRangeMeasurementCreator(context),
new RangeMeasurementCreator(context),
1.0, 3.0, 300.0);
// create orbit estimator
......@@ -250,7 +250,7 @@ public class DSSTBatchLSEstimatorTest {
propagatorBuilder);
final List<ObservedMeasurement<?>> measurements =
DSSTEstimationTestUtils.createMeasurements(propagator,
new DSSTRangeMeasurementCreator(context, antennaPhaseCenter, 0.0),
new RangeMeasurementCreator(context, antennaPhaseCenter),
1.0, 3.0, 300.0);
// create orbit estimator
......@@ -342,7 +342,7 @@ public class DSSTBatchLSEstimatorTest {
propagatorBuilder);
final List<ObservedMeasurement<?>> measurements =
DSSTEstimationTestUtils.createMeasurements(propagator,
new DSSTRangeMeasurementCreator(context),
new RangeMeasurementCreator(context),
1.0, 3.0, 300.0);
// create orbit estimator
......@@ -408,7 +408,7 @@ public class DSSTBatchLSEstimatorTest {
final double satClkDrift = 3.2e-10;
final List<ObservedMeasurement<?>> measurements1 =
DSSTEstimationTestUtils.createMeasurements(propagator,
new DSSTRangeRateMeasurementCreator(context, false, satClkDrift),
new RangeRateMeasurementCreator(context, false, satClkDrift),
1.0, 3.0, 300.0);
final List<ObservedMeasurement<?>> measurements = new ArrayList<ObservedMeasurement<?>>();
......@@ -424,11 +424,11 @@ public class DSSTBatchLSEstimatorTest {
estimator.setMaxIterations(10);
estimator.setMaxEvaluations(20);
DSSTEstimationTestUtils.checkFit(context, estimator, 3, 4,
0.0, 1.6e-2,
0.0, 3.4e-2,
0.0, 170.0, // we only have range rate...
0.0, 6.5e-2);
DSSTEstimationTestUtils.checkFit(context, estimator, 1, 2,
0.0, 5.4e-7,
0.0, 1.2e-6,
0.0, 8.3e-4,
0.0, 4.5e-7);
}
/**
......@@ -444,11 +444,11 @@ public class DSSTBatchLSEstimatorTest {
// create perfect range measurements
final Propagator propagator = DSSTEstimationTestUtils.createPropagator(context.initialOrbit,
propagatorBuilder);
propagatorBuilder);
final List<ObservedMeasurement<?>> measurementsRange =
DSSTEstimationTestUtils.createMeasurements(propagator,
new DSSTRangeMeasurementCreator(context),
new RangeMeasurementCreator(context),
1.0, 3.0, 300.0);
final double groundClockDrift = 4.8e-9;
for (final GroundStation station : context.stations) {
......@@ -457,7 +457,7 @@ public class DSSTBatchLSEstimatorTest {
final double satClkDrift = 3.2e-10;
final List<ObservedMeasurement<?>> measurementsRangeRate =
DSSTEstimationTestUtils.createMeasurements(propagator,
new DSSTRangeRateMeasurementCreator(context, false, satClkDrift),
new RangeRateMeasurementCreator(context, false, satClkDrift),
1.0, 3.0, 300.0);
// concat measurements
......@@ -476,11 +476,11 @@ public class DSSTBatchLSEstimatorTest {
estimator.setMaxEvaluations(20);
// we have low correlation between the two types of measurement. We can expect a good estimate.
DSSTEstimationTestUtils.checkFit(context, estimator, 1, 2,
0.0, 0.16,
0.0, 0.40,
0.0, 1.9e-3,
0.0, 7.3e-7);
DSSTEstimationTestUtils.checkFit(context, estimator, 1, 3,
0.0, 4.8e-7,
0.0, 1.6e-6,
0.0, 4.4e-8,
0.0, 1.9e-11);
}
@Test
......
......@@ -31,10 +31,11 @@ import org.orekit.errors.OrekitMessages;
import org.orekit.estimation.TLEContext;
import org.orekit.estimation.TLEEstimationTestUtils;
import org.orekit.estimation.measurements.EstimationsProvider;
import org.orekit.estimation.measurements.GroundStation;
import org.orekit.estimation.measurements.ObservedMeasurement;
import org.orekit.estimation.measurements.PVMeasurementCreator;
import org.orekit.estimation.measurements.TLERangeMeasurementCreator;
import org.orekit.estimation.measurements.TLERangeRateMeasurementCreator;
import org.orekit.estimation.measurements.RangeMeasurementCreator;
import org.orekit.estimation.measurements.RangeRateMeasurementCreator;
import org.orekit.frames.FramesFactory;
import org.orekit.orbits.Orbit;
import org.orekit.orbits.OrbitType;
......@@ -156,7 +157,7 @@ public class TLEBatchLSEstimatorTest {
propagatorBuilder);
final List<ObservedMeasurement<?>> measurements =
TLEEstimationTestUtils.createMeasurements(propagator,
new TLERangeMeasurementCreator(context),
new RangeMeasurementCreator(context),
1.0, 3.0, 300.0);
// create orbit estimator
......@@ -246,7 +247,7 @@ public class TLEBatchLSEstimatorTest {
propagatorBuilder);
final List<ObservedMeasurement<?>> measurements =
TLEEstimationTestUtils.createMeasurements(propagator,
new TLERangeMeasurementCreator(context),
new RangeMeasurementCreator(context),
1.0, 3.0, 300.0);
// create orbit estimator
......@@ -309,11 +310,16 @@ public class TLEBatchLSEstimatorTest {
final List<ObservedMeasurement<?>> measurementsRange =
TLEEstimationTestUtils.createMeasurements(propagator,
new TLERangeMeasurementCreator(context),
new RangeMeasurementCreator(context),
1.0, 3.0, 300.0);
final double groundClockDrift = 4.8e-9;
for (final GroundStation station : context.stations) {
station.getClockDriftDriver().setValue(groundClockDrift);
}
final double satClkDrift = 3.2e-10;
final List<ObservedMeasurement<?>> measurementsRangeRate =
TLEEstimationTestUtils.createMeasurements(propagator,
new TLERangeRateMeasurementCreator(context, false),
new RangeRateMeasurementCreator(context, false, satClkDrift),
1.0, 3.0, 300.0);
// concat measurements
......@@ -332,11 +338,11 @@ public class TLEBatchLSEstimatorTest {
estimator.setMaxEvaluations(20);
// we have low correlation between the two types of measurement. We can expect a good estimate.
TLEEstimationTestUtils.checkFit(context, estimator, 3, 6,
0.0, 0.26,
0.0, 0.52,
0.0, 4.42e-4,
0.0, 1.48e-7);
TLEEstimationTestUtils.checkFit(context, estimator, 4, 5,
0.0, 5.2e-6,
0.0, 3.3e-5,
0.0, 6.1e-6,
0.0, 2.5e-9);
}
}
/* Copyright 2002-2022 CS GROUP
* Licensed to CS GROUP (CS) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* CS licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.orekit.estimation.measurements;
import java.util.Arrays;
import org.hipparchus.analysis.UnivariateFunction;
import org.hipparchus.analysis.solvers.BracketingNthOrderBrentSolver;
import org.hipparchus.analysis.solvers.UnivariateSolver;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.util.FastMath;
import org.orekit.estimation.DSSTContext;
import org.orekit.frames.Frame;
import org.orekit.frames.Transform;
import org.orekit.propagation.SpacecraftState;
import org.orekit.time.AbsoluteDate;
import org.orekit.utils.Constants;
import org.orekit.utils.ParameterDriver;
public class DSSTRangeMeasurementCreator extends MeasurementCreator {
private final DSSTContext context;
private final Vector3D antennaPhaseCenter;
private final double clockOffset;
private final ObservableSatellite satellite;
public DSSTRangeMeasurementCreator(final DSSTContext context) {
this(context, Vector3D.ZERO, 0.0);
}
public DSSTRangeMeasurementCreator(final DSSTContext context, final Vector3D antennaPhaseCenter,
final double clockOffset) {
this.context = context;
this.antennaPhaseCenter = antennaPhaseCenter;
this.clockOffset = clockOffset;
this.satellite = new ObservableSatellite(0);
}
public void init(SpacecraftState s0, AbsoluteDate t, double step) {
for (final GroundStation station : context.stations) {
for (ParameterDriver driver : Arrays.asList(station.getClockOffsetDriver(),
station.getEastOffsetDriver(),
station.getNorthOffsetDriver(),
station.getZenithOffsetDriver(),
station.getPrimeMeridianOffsetDriver(),
station.getPrimeMeridianDriftDriver(),
station.getPolarOffsetXDriver(),
station.getPolarDriftXDriver(),
station.getPolarOffsetYDriver(),
station.getPolarDriftYDriver())) {
if (driver.getReferenceDate() == null) {
driver.setReferenceDate(s0.getDate());
}
}
}
}
public void handleStep(final SpacecraftState currentState) {
for (final GroundStation station : context.stations) {
final AbsoluteDate date = currentState.getDate();
final Frame inertial = currentState.getFrame();
final Vector3D position = currentState.toTransform().getInverse().transformPosition(antennaPhaseCenter);
if (station.getBaseFrame().getElevation(position, inertial, date) > FastMath.toRadians(30.0)) {
final UnivariateSolver solver = new BracketingNthOrderBrentSolver(1.0e-12, 5);
final double downLinkDelay = solver.solve(1000, new UnivariateFunction() {
public double value(final double x) {
final Transform t = station.getOffsetToInertial(inertial, date.shiftedBy(x));
final double d = Vector3D.distance(position, t.transformPosition(Vector3D.ZERO));
return d - x * Constants.SPEED_OF_LIGHT;
}
}, -1.0, 1.0);
final AbsoluteDate receptionDate = currentState.getDate().shiftedBy(downLinkDelay);
final Vector3D stationAtReception =
station.getOffsetToInertial(inertial, receptionDate).transformPosition(Vector3D.ZERO);
final double downLinkDistance = Vector3D.distance(position, stationAtReception);
final double upLinkDelay = solver.solve(1000, new UnivariateFunction() {
public double value(final double x) {
final Transform t = station.getOffsetToInertial(inertial, date.shiftedBy(-x));
final double d = Vector3D.distance(position, t.transformPosition(Vector3D.ZERO));
return d - x * Constants.SPEED_OF_LIGHT;
}
}, -1.0, 1.0);
final AbsoluteDate emissionDate = currentState.getDate().shiftedBy(-upLinkDelay);
final Vector3D stationAtEmission =
station.getOffsetToInertial(inertial, emissionDate).transformPosition(Vector3D.ZERO);
final double upLinkDistance = Vector3D.distance(position, stationAtEmission);
addMeasurement(new Range(station, true, receptionDate.shiftedBy(-clockOffset),
0.5 * (downLinkDistance + upLinkDistance), 1.0, 10, satellite));
}
}
}
}
/* Copyright 2002-2022 CS GROUP
* Licensed to CS GROUP (CS) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* CS licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.orekit.estimation.measurements;
import java.util.Arrays;
import org.hipparchus.analysis.UnivariateFunction;
import org.hipparchus.analysis.solvers.BracketingNthOrderBrentSolver;
import org.hipparchus.analysis.solvers.UnivariateSolver;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.util.FastMath;
import org.orekit.estimation.DSSTContext;
import org.orekit.frames.Frame;
import org.orekit.frames.Transform;
import org.orekit.propagation.SpacecraftState;
import org.orekit.time.AbsoluteDate;
import org.orekit.utils.Constants;
import org.orekit.utils.PVCoordinates;
import org.orekit.utils.ParameterDriver;
public class DSSTRangeRateMeasurementCreator extends MeasurementCreator {
private final DSSTContext context;
private final boolean twoWay;
private final ObservableSatellite satellite;
public DSSTRangeRateMeasurementCreator(final DSSTContext context, boolean twoWay,
final double satClockDrift) {
this.context = context;
this.twoWay = twoWay;
this.satellite = new ObservableSatellite(0);
this.satellite.getClockDriftDriver().setValue(satClockDrift);
}
public ObservableSatellite getSatellite() {
return satellite;
}
public void init(SpacecraftState s0, AbsoluteDate t, double step) {
for (final GroundStation station : context.stations) {
for (ParameterDriver driver : Arrays.asList(station.getClockOffsetDriver(),
station.getClockDriftDriver(),
station.getEastOffsetDriver(),
station.getNorthOffsetDriver(),
station.getZenithOffsetDriver(),
station.getPrimeMeridianOffsetDriver(),
station.getPrimeMeridianDriftDriver(),
station.getPolarOffsetXDriver(),
station.getPolarDriftXDriver(),
station.getPolarOffsetYDriver(),
station.getPolarDriftYDriver())) {
if (driver.getReferenceDate() == null) {
driver.setReferenceDate(s0.getDate());
}
}
}
if (satellite.getClockDriftDriver().getReferenceDate() == null) {
satellite.getClockDriftDriver().setReferenceDate(s0.getDate());
}
}
public void handleStep(final SpacecraftState currentState) {
for (final GroundStation station : context.stations) {
final double groundDft = station.getClockDriftDriver().getValue();
final double satDft = satellite.getClockDriftDriver().getValue();
final double deltaD = Constants.SPEED_OF_LIGHT * (groundDft - satDft);
final AbsoluteDate date = currentState.getDate();
final Frame inertial = currentState.getFrame();
final Vector3D position = currentState.getPVCoordinates().getPosition();
final Vector3D velocity = currentState.getPVCoordinates().getVelocity();
if (station.getBaseFrame().getElevation(position, inertial, date) > FastMath.toRadians(30.0)) {
final UnivariateSolver solver = new BracketingNthOrderBrentSolver(1.0e-12, 5);
final double downLinkDelay = solver.solve(1000, new UnivariateFunction() {
public double value(final double x) {
final Transform t = station.getOffsetToInertial(inertial, date.shiftedBy(x));
final double d = Vector3D.distance(position, t.transformPosition(Vector3D.ZERO));
return d - x * Constants.SPEED_OF_LIGHT;
}
}, -1.0, 1.0);
final AbsoluteDate receptionDate = currentState.getDate().shiftedBy(downLinkDelay);
final PVCoordinates stationAtReception =
station.getOffsetToInertial(inertial, receptionDate).transformPVCoordinates(PVCoordinates.ZERO);
// line of sight at reception
final Vector3D receptionLOS = (position.subtract(stationAtReception.getPosition())).normalize();
// relative velocity, spacecraft-station, at the date of reception
final Vector3D deltaVr = velocity.subtract(stationAtReception.getVelocity());
final double upLinkDelay = solver.solve(1000, new UnivariateFunction() {
public double value(final double x) {
final Transform t = station.getOffsetToInertial(inertial, date.shiftedBy(-x));
final double d = Vector3D.distance(position, t.transformPosition(Vector3D.ZERO));
return d - x * Constants.SPEED_OF_LIGHT;
}
}, -1.0, 1.0);
final AbsoluteDate emissionDate = currentState.getDate().shiftedBy(-upLinkDelay);
final PVCoordinates stationAtEmission =
station.getOffsetToInertial(inertial, emissionDate).transformPVCoordinates(PVCoordinates.ZERO);
// line of sight at emission
final Vector3D emissionLOS = (position.subtract(stationAtEmission.getPosition())).normalize();
// relative velocity, spacecraft-station, at the date of emission
final Vector3D deltaVe = velocity.subtract(stationAtEmission.getVelocity());
// range rate at the date of reception
final double rr = twoWay ?
0.5 * (deltaVr.dotProduct(receptionLOS) + deltaVe.dotProduct(emissionLOS)) :
deltaVr.dotProduct(receptionLOS) + deltaD;
addMeasurement(new RangeRate(station, date,
rr,
1.0, 10, twoWay, satellite));
}
}
}
}
......@@ -23,7 +23,7 @@ import org.hipparchus.analysis.solvers.BracketingNthOrderBrentSolver;
import org.hipparchus.analysis.solvers.UnivariateSolver;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.util.FastMath;
import org.orekit.estimation.Context;
import org.orekit.estimation.StationDataProvider;
import org.orekit.frames.Frame;
import org.orekit.frames.Transform;
import org.orekit.propagation.SpacecraftState;
......@@ -33,22 +33,22 @@ import org.orekit.utils.ParameterDriver;
public class RangeMeasurementCreator extends MeasurementCreator {
private final Context context;
private final StationDataProvider provider;
private final Vector3D antennaPhaseCenter;
private final ObservableSatellite satellite;
public RangeMeasurementCreator(final Context context) {
public RangeMeasurementCreator(final StationDataProvider context) {
this(context, Vector3D.ZERO);
}
public RangeMeasurementCreator(final Context context, final Vector3D antennaPhaseCenter) {
this.context = context;
public RangeMeasurementCreator(final StationDataProvider provider, final Vector3D antennaPhaseCenter) {
this.provider = provider;
this.antennaPhaseCenter = antennaPhaseCenter;
this.satellite = new ObservableSatellite(0);
}
public void init(SpacecraftState s0, AbsoluteDate t, double step) {
for (final GroundStation station : context.stations) {
for (final GroundStation station : provider.getStations()) {
for (ParameterDriver driver : Arrays.asList(station.getClockOffsetDriver(),
station.getEastOffsetDriver(),
station.getNorthOffsetDriver(),
......@@ -67,7 +67,7 @@ public class RangeMeasurementCreator extends MeasurementCreator {
}
public void handleStep(final SpacecraftState currentState) {
for (final GroundStation station : context.stations) {
for (final GroundStation station : provider.getStations()) {
final AbsoluteDate date = currentState.getDate();
final Frame inertial = currentState.getFrame();
final Vector3D position = currentState.toTransform().getInverse().transformPosition(antennaPhaseCenter);
......
......@@ -23,7 +23,7 @@ import org.hipparchus.analysis.solvers.BracketingNthOrderBrentSolver;
import org.hipparchus.analysis.solvers.UnivariateSolver;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.util.FastMath;
import org.orekit.estimation.Context;
import org.orekit.estimation.StationDataProvider;
import org.orekit.frames.Frame;
import org.orekit.frames.Transform;
import org.orekit.propagation.SpacecraftState;
......@@ -34,11 +34,11 @@ import org.orekit.utils.ParameterDriver;
public class RangeRateMeasurementCreator extends MeasurementCreator {
private final Context context;
private final StationDataProvider context;
private final boolean twoWay;
private final ObservableSatellite satellite;
public RangeRateMeasurementCreator(final Context context, boolean twoWay,