Commit 3ecf1fd5 authored by Bryan Cazabonne's avatar Bryan Cazabonne
Browse files

Merge branch 'issue-871' into 'develop'

Added atmospheric drag effect for Brouwer-Lyddane model.

Closes #871

See merge request !224
parents da389790 bd96611d
Pipeline #1611 passed with stages
in 35 minutes and 26 seconds
......@@ -21,6 +21,9 @@
</properties>
<body>
<release version="11.1" date="TBD" description="TBD">
<action dev="bryan" type="add" issue="871">
Added atmospheric drag effect for Brouwer-Lyddane model.
</action>
<action dev="bryan" type="add" issue="869">
Allowed Brouwer-Lyddane model to work for the critical inclination.
</action>
......
......@@ -17,6 +17,7 @@
package org.orekit.propagation.conversion;
import org.hipparchus.util.FastMath;
import org.orekit.attitudes.AttitudeProvider;
import org.orekit.attitudes.InertialProvider;
import org.orekit.forces.gravity.potential.GravityFieldFactory;
......@@ -25,15 +26,48 @@ import org.orekit.forces.gravity.potential.UnnormalizedSphericalHarmonicsProvide
import org.orekit.orbits.Orbit;
import org.orekit.orbits.OrbitType;
import org.orekit.orbits.PositionAngle;
import org.orekit.propagation.Propagator;
import org.orekit.propagation.analytical.BrouwerLyddanePropagator;
import org.orekit.propagation.analytical.tle.TLE;
import org.orekit.utils.ParameterDriver;
/** Builder for Brouwer-Lyddane propagator.
* <p>
* By default, Brouwer-Lyddane model considers only the perturbations due to zonal harmonics.
* However, for low Earth orbits, the magnitude of the perturbative acceleration due to
* atmospheric drag can be significant. Warren Phipps' 1992 thesis considered the atmospheric
* drag by time derivatives of the <i>mean</i> mean anomaly using the catch-all coefficient M2.
*
* Usually, M2 is adjusted during an orbit determination process and it represents the
* combination of all unmodeled secular along-track effects (i.e. not just the atmospheric drag).
* The behavior of M2 is closed to the {@link TLE#getBStar()} parameter for the TLE.
*
* If the value of M2 is equal to {@link BrouwerLyddanePropagator#M2 0.0}, the along-track
* secular effects are not considered in the dynamical model. Typical values for M2 are not known.
* It depends on the orbit type. However, the value of M2 must be very small (e.g. between 1.0e-14 and 1.0e-15).
* <p>
* To estimate the M2 parameter, it is necessary to call the {@link #getPropagationParametersDrivers()} method
* as follow:
* <pre>
* for (ParameterDriver driver : builder.getPropagationParametersDrivers().getDrivers()) {
* if (BrouwerLyddanePropagator.M2_NAME.equals(driver.getName())) {
* driver.setSelected(true);
* }
* }
* </pre>
* @author Melina Vanel
* @author Bryan Cazabonne
* @since 11.1
*/
public class BrouwerLyddanePropagatorBuilder extends AbstractPropagatorBuilder {
/** Parameters scaling factor.
* <p>
* We use a power of 2 to avoid numeric noise introduction
* in the multiplications/divisions sequences.
* </p>
*/
private static final double SCALE = FastMath.scalb(1.0, -20);
/** Provider for un-normalized coefficients. */
private final UnnormalizedSphericalHarmonicsProvider provider;
......@@ -54,43 +88,17 @@ public class BrouwerLyddanePropagatorBuilder extends AbstractPropagatorBuilder {
* @param positionAngle position angle type to use
* @param positionScale scaling factor used for orbital parameters normalization
* (typically set to the expected standard deviation of the position)
* @param M2 value of empirical drag coefficient.
* If equal to {@link BrouwerLyddanePropagator#M2} drag is not computed
* @see #BrouwerLyddanePropagatorBuilder(Orbit,
* UnnormalizedSphericalHarmonicsProvider, PositionAngle, double, AttitudeProvider)
*/
public BrouwerLyddanePropagatorBuilder(final Orbit templateOrbit,
final UnnormalizedSphericalHarmonicsProvider provider,
final PositionAngle positionAngle,
final double positionScale) {
this(templateOrbit, provider, positionAngle, positionScale,
InertialProvider.of(templateOrbit.getFrame()));
}
/** Build a new instance.
* <p>
* The template orbit is used as a model to {@link
* #createInitialOrbit() create initial orbit}. It defines the
* inertial frame, the central attraction coefficient, the orbit type, and is also
* used together with the {@code positionScale} to convert from the {@link
* org.orekit.utils.ParameterDriver#setNormalizedValue(double) normalized} parameters used by the
* callers of this builder to the real orbital parameters.
* </p>
* @param templateOrbit reference orbit from which real orbits will be built
* (note that the mu from this orbit will be overridden with the mu from the
* {@code provider})
* @param provider for un-normalized zonal coefficients
* @param positionAngle position angle type to use
* @param positionScale scaling factor used for orbital parameters normalization
* (typically set to the expected standard deviation of the position)
* @param attitudeProvider attitude law to use.
* UnnormalizedSphericalHarmonicsProvider, PositionAngle, double, AttitudeProvider, double)
*/
public BrouwerLyddanePropagatorBuilder(final Orbit templateOrbit,
final UnnormalizedSphericalHarmonicsProvider provider,
final PositionAngle positionAngle,
final double positionScale,
final AttitudeProvider attitudeProvider) {
super(overrideMu(templateOrbit, provider, positionAngle), positionAngle,
positionScale, true, attitudeProvider);
this.provider = provider;
final double M2) {
this(templateOrbit, provider, positionAngle, positionScale, InertialProvider.of(templateOrbit.getFrame()), M2);
}
/** Build a new instance.
......@@ -117,8 +125,10 @@ public class BrouwerLyddanePropagatorBuilder extends AbstractPropagatorBuilder {
* @param positionAngle position angle type to use
* @param positionScale scaling factor used for orbital parameters normalization
* (typically set to the expected standard deviation of the position)
* @param M2 value of empirical drag coefficient.
* If equal to {@link BrouwerLyddanePropagator#M2} drag is not computed
* @see #BrouwerLyddanePropagatorBuilder(Orbit,
* UnnormalizedSphericalHarmonicsProvider, PositionAngle, double, AttitudeProvider)
* UnnormalizedSphericalHarmonicsProvider, PositionAngle, double, AttitudeProvider, double)
*/
public BrouwerLyddanePropagatorBuilder(final Orbit templateOrbit,
final double referenceRadius,
......@@ -130,7 +140,8 @@ public class BrouwerLyddanePropagatorBuilder extends AbstractPropagatorBuilder {
final double c50,
final OrbitType orbitType,
final PositionAngle positionAngle,
final double positionScale) {
final double positionScale,
final double M2) {
this(templateOrbit,
GravityFieldFactory.getUnnormalizedProvider(referenceRadius, mu, tideSystem,
new double[][] {
......@@ -162,7 +173,42 @@ public class BrouwerLyddanePropagatorBuilder extends AbstractPropagatorBuilder {
0
}
}),
positionAngle, positionScale);
positionAngle, positionScale, M2);
}
/** Build a new instance.
* <p>
* The template orbit is used as a model to {@link
* #createInitialOrbit() create initial orbit}. It defines the
* inertial frame, the central attraction coefficient, the orbit type, and is also
* used together with the {@code positionScale} to convert from the {@link
* org.orekit.utils.ParameterDriver#setNormalizedValue(double) normalized} parameters used by the
* callers of this builder to the real orbital parameters.
* </p>
* @param templateOrbit reference orbit from which real orbits will be built
* (note that the mu from this orbit will be overridden with the mu from the
* {@code provider})
* @param provider for un-normalized zonal coefficients
* @param positionAngle position angle type to use
* @param positionScale scaling factor used for orbital parameters normalization
* (typically set to the expected standard deviation of the position)
* @param M2 value of empirical drag coefficient.
* If equal to {@link BrouwerLyddanePropagator#M2} drag is not computed
* @param attitudeProvider attitude law to use
*/
public BrouwerLyddanePropagatorBuilder(final Orbit templateOrbit,
final UnnormalizedSphericalHarmonicsProvider provider,
final PositionAngle positionAngle,
final double positionScale,
final AttitudeProvider attitudeProvider,
final double M2) {
super(overrideMu(templateOrbit, provider, positionAngle), positionAngle, positionScale, true, attitudeProvider);
this.provider = provider;
// initialize M2 driver
final ParameterDriver M2Driver = new ParameterDriver(BrouwerLyddanePropagator.M2_NAME, M2, SCALE,
Double.NEGATIVE_INFINITY,
Double.POSITIVE_INFINITY);
addSupportedParameter(M2Driver);
}
/** Override central attraction coefficient.
......@@ -184,9 +230,26 @@ public class BrouwerLyddanePropagatorBuilder extends AbstractPropagatorBuilder {
}
/** {@inheritDoc} */
public Propagator buildPropagator(final double[] normalizedParameters) {
public BrouwerLyddanePropagator buildPropagator(final double[] normalizedParameters) {
setParameters(normalizedParameters);
return new BrouwerLyddanePropagator(createInitialOrbit(), getAttitudeProvider(),
provider);
// Update M2 value and selection
double newM2 = 0.0;
boolean isSelected = false;
for (final ParameterDriver driver : getPropagationParametersDrivers().getDrivers()) {
if (BrouwerLyddanePropagator.M2_NAME.equals(driver.getName())) {
newM2 = driver.getValue();
isSelected = driver.isSelected();
}
}
// Initialize propagator
final BrouwerLyddanePropagator propagator = new BrouwerLyddanePropagator(createInitialOrbit(), getAttitudeProvider(), provider, newM2);
propagator.getParametersDrivers().get(0).setSelected(isSelected);
// Return
return propagator;
}
}
......@@ -78,6 +78,7 @@
* Kepler
* Eckstein-Heschler
* Brouwer-Lyddane with Warren Phipps' correction for the critical inclination of 63.4°
and the perturbative acceleration due to atmospheric drag
* SDP4/SGP4 with 2006 corrections
* GNSS: GPS, QZSS, Galileo, GLONASS, Beidou, IRNSS and SBAS
* numerical propagators
......
package org.orekit.propagation.analytical;
import static org.junit.Assert.assertTrue;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.ode.nonstiff.AdaptiveStepsizeIntegrator;
import org.hipparchus.ode.nonstiff.DormandPrince853Integrator;
......@@ -11,8 +13,13 @@ import org.junit.Before;
import org.junit.Test;
import org.orekit.Utils;
import org.orekit.attitudes.AttitudeProvider;
import org.orekit.bodies.CelestialBodyFactory;
import org.orekit.bodies.OneAxisEllipsoid;
import org.orekit.data.DataContext;
import org.orekit.errors.OrekitException;
import org.orekit.forces.ForceModel;
import org.orekit.forces.drag.DragForce;
import org.orekit.forces.drag.IsotropicDrag;
import org.orekit.forces.gravity.HolmesFeatherstoneAttractionModel;
import org.orekit.forces.gravity.potential.GravityFieldFactory;
import org.orekit.forces.gravity.potential.NormalizedSphericalHarmonicsProvider;
......@@ -20,6 +27,8 @@ import org.orekit.forces.gravity.potential.TideSystem;
import org.orekit.forces.gravity.potential.UnnormalizedSphericalHarmonicsProvider;
import org.orekit.frames.Frame;
import org.orekit.frames.FramesFactory;
import org.orekit.models.earth.atmosphere.DTM2000;
import org.orekit.models.earth.atmosphere.data.MarshallSolarActivityFutureEstimation;
import org.orekit.orbits.EquinoctialOrbit;
import org.orekit.orbits.KeplerianOrbit;
import org.orekit.orbits.Orbit;
......@@ -30,6 +39,9 @@ import org.orekit.propagation.Propagator;
import org.orekit.propagation.SpacecraftState;
import org.orekit.propagation.numerical.NumericalPropagator;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.TimeScale;
import org.orekit.time.TimeScalesFactory;
import org.orekit.utils.Constants;
import org.orekit.utils.IERSConventions;
import org.orekit.utils.PVCoordinates;
......@@ -54,7 +66,7 @@ public class BrouwerLyddanePropagatorTest {
// Extrapolation at the initial date
// ---------------------------------
BrouwerLyddanePropagator extrapolator =
new BrouwerLyddanePropagator(initialOrbit, GravityFieldFactory.getUnnormalizedProvider(provider));
new BrouwerLyddanePropagator(initialOrbit, GravityFieldFactory.getUnnormalizedProvider(provider), BrouwerLyddanePropagator.M2);
SpacecraftState finalOrbit = extrapolator.propagate(initDate);
// positions velocity and semi major axis match perfectly
......@@ -82,7 +94,7 @@ public class BrouwerLyddanePropagatorTest {
FramesFactory.getEME2000(), initDate, provider.getMu());
BrouwerLyddanePropagator extrapolator =
new BrouwerLyddanePropagator(initialOrbit, DEFAULT_LAW, GravityFieldFactory.getUnnormalizedProvider(provider));
new BrouwerLyddanePropagator(initialOrbit, DEFAULT_LAW, GravityFieldFactory.getUnnormalizedProvider(provider), BrouwerLyddanePropagator.M2);
SpacecraftState finalOrbit = extrapolator.propagate(initDate);
......@@ -131,7 +143,7 @@ public class BrouwerLyddanePropagatorTest {
// Extrapolators definitions
// -------------------------
BrouwerLyddanePropagator extrapolatorAna =
new BrouwerLyddanePropagator(initialOrbit, 1000.0, kepProvider);
new BrouwerLyddanePropagator(initialOrbit, 1000.0, kepProvider, BrouwerLyddanePropagator.M2);
KeplerianPropagator extrapolatorKep = new KeplerianPropagator(initialOrbit);
// Extrapolation at a final date different from initial date
......@@ -225,7 +237,7 @@ public class BrouwerLyddanePropagatorTest {
//_______________________________________________________________________________________________
BrouwerLyddanePropagator BLextrapolator =
new BrouwerLyddanePropagator(initialOrbit, GravityFieldFactory.getUnnormalizedProvider(provider));
new BrouwerLyddanePropagator(initialOrbit, GravityFieldFactory.getUnnormalizedProvider(provider), BrouwerLyddanePropagator.M2);
SpacecraftState BLFinalState = BLextrapolator.propagate(initDate.shiftedBy(timeshift));
final KeplerianOrbit BLOrbit = (KeplerianOrbit) OrbitType.KEPLERIAN.convertType(BLFinalState.getOrbit());
......@@ -241,6 +253,103 @@ public class BrouwerLyddanePropagatorTest {
MathUtils.normalizeAngle(BLOrbit.getTrueAnomaly(), FastMath.PI), 0.12);
}
@Test
public void compareToNumericalPropagationWithDrag() {
final Frame inertialFrame = FramesFactory.getEME2000();
final TimeScale utc = TimeScalesFactory.getUTC();
final AbsoluteDate initDate = new AbsoluteDate(2003, 1, 1, 00, 00, 00.000, utc);
double timeshift = 60000. ;
// Initial orbit
final double a = Constants.WGS84_EARTH_EQUATORIAL_RADIUS + 400e3; // semi major axis in meters
final double e = 0.01; // eccentricity
final double i = FastMath.toRadians(7); // inclination
final double omega = FastMath.toRadians(180); // perigee argument
final double raan = FastMath.toRadians(261); // right ascention of ascending node
final double lM = 0; // mean anomaly
final Orbit initialOrbit = new KeplerianOrbit(a, e, i, omega, raan, lM, PositionAngle.TRUE,
inertialFrame, initDate, provider.getMu());
// Initial state definition
final SpacecraftState initialState = new SpacecraftState(initialOrbit);
//_______________________________________________________________________________________________
// SET UP A REFERENCE NUMERICAL PROPAGATION
//_______________________________________________________________________________________________
// Adaptive step integrator with a minimum step of 0.001 and a maximum step of 1000
final double minStep = 0.001;
final double maxstep = 1000.0;
final double positionTolerance = 10.0;
final OrbitType propagationType = OrbitType.KEPLERIAN;
final double[][] tolerances =
NumericalPropagator.tolerances(positionTolerance, initialOrbit, propagationType);
final AdaptiveStepsizeIntegrator integrator =
new DormandPrince853Integrator(minStep, maxstep, tolerances[0], tolerances[1]);
// Numerical Propagator
final NumericalPropagator NumPropagator = new NumericalPropagator(integrator);
NumPropagator.setOrbitType(propagationType);
// Atmosphere
final OneAxisEllipsoid earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS, Constants.WGS84_EARTH_FLATTENING,
FramesFactory.getITRF(IERSConventions.IERS_2010, true));
MarshallSolarActivityFutureEstimation msafe =
new MarshallSolarActivityFutureEstimation("Jan2000F10-edited-data\\.txt",
MarshallSolarActivityFutureEstimation.StrengthLevel.AVERAGE);
DataContext.getDefault().getDataProvidersManager().feed(msafe.getSupportedNames(), msafe);
DTM2000 atmosphere = new DTM2000(msafe, CelestialBodyFactory.getSun(), earth);
// Force model
final ForceModel holmesFeatherstone =
new HolmesFeatherstoneAttractionModel(FramesFactory.getITRF(IERSConventions.IERS_2010, true), provider);
final ForceModel drag =
new DragForce(atmosphere, new IsotropicDrag(1.0, 1.0));
NumPropagator.addForceModel(holmesFeatherstone);
NumPropagator.addForceModel(drag);
// Set up initial state in the propagator
NumPropagator.setInitialState(initialState);
// Extrapolate from the initial to the final date
final SpacecraftState NumFinalState = NumPropagator.propagate(initDate.shiftedBy(timeshift));
final KeplerianOrbit NumOrbit = (KeplerianOrbit) OrbitType.KEPLERIAN.convertType(NumFinalState.getOrbit());
//_______________________________________________________________________________________________
// SET UP A BROUWER LYDDANE PROPAGATION WITHOUT DRAG
//_______________________________________________________________________________________________
BrouwerLyddanePropagator BLextrapolator =
new BrouwerLyddanePropagator(initialOrbit, GravityFieldFactory.getUnnormalizedProvider(provider), BrouwerLyddanePropagator.M2);
SpacecraftState BLFinalState = BLextrapolator.propagate(initDate.shiftedBy(timeshift));
KeplerianOrbit BLOrbit = (KeplerianOrbit) OrbitType.KEPLERIAN.convertType(BLFinalState.getOrbit());
// Verify a and e differences without the drag effect on Brouwer-Lyddane
final double deltaSmaBefore = 20.44;
final double deltaEccBefore = 1.0125e-4;
Assert.assertEquals(NumOrbit.getA(), BLOrbit.getA(), deltaSmaBefore);
Assert.assertEquals(NumOrbit.getE(), BLOrbit.getE(), deltaEccBefore);
//_______________________________________________________________________________________________
// SET UP A BROUWER LYDDANE PROPAGATION WITH DRAG
//_______________________________________________________________________________________________
double M2 = 1.0e-14;
BLextrapolator = new BrouwerLyddanePropagator(initialOrbit, GravityFieldFactory.getUnnormalizedProvider(provider), M2);
BLFinalState = BLextrapolator.propagate(initDate.shiftedBy(timeshift));
BLOrbit = (KeplerianOrbit) OrbitType.KEPLERIAN.convertType(BLFinalState.getOrbit());
// Verify a and e differences without the drag effect on Brouwer-Lyddane
final double deltaSmaAfter = 15.66;
final double deltaEccAfter = 1.0121e-4;
Assert.assertEquals(NumOrbit.getA(), BLOrbit.getA(), deltaSmaAfter);
Assert.assertEquals(NumOrbit.getE(), BLOrbit.getE(), deltaEccAfter);
assertTrue(deltaSmaAfter < deltaSmaBefore);
assertTrue(deltaEccAfter < deltaEccBefore);
}
@Test
public void compareToNumericalPropagationMeanInitialOrbit() {
......@@ -262,7 +371,7 @@ public class BrouwerLyddanePropagatorTest {
BrouwerLyddanePropagator BLextrapolator =
new BrouwerLyddanePropagator(initialOrbit, GravityFieldFactory.getUnnormalizedProvider(provider),
PropagationType.MEAN);
PropagationType.MEAN, BrouwerLyddanePropagator.M2);
SpacecraftState initialOsculatingState = BLextrapolator.propagate(initDate);
final KeplerianOrbit InitOrbit = (KeplerianOrbit) OrbitType.KEPLERIAN.convertType(initialOsculatingState.getOrbit());
......@@ -341,14 +450,14 @@ public class BrouwerLyddanePropagatorTest {
BrouwerLyddanePropagator BLextrapolator1 =
new BrouwerLyddanePropagator(initialOrbit, DEFAULT_LAW, Propagator.DEFAULT_MASS, GravityFieldFactory.getUnnormalizedProvider(provider),
PropagationType.OSCULATING);
PropagationType.OSCULATING, BrouwerLyddanePropagator.M2);
//_______________________________________________________________________________________________
// SET UP ANOTHER BROUWER LYDDANE PROPAGATOR
//_______________________________________________________________________________________________
BrouwerLyddanePropagator BLextrapolator2 =
new BrouwerLyddanePropagator( new KeplerianOrbit(a + 3000, e + 0.001, i - FastMath.toRadians(12.0), omega, raan, lM, PositionAngle.TRUE,
inertialFrame, initDate, provider.getMu()),DEFAULT_LAW, Propagator.DEFAULT_MASS, GravityFieldFactory.getUnnormalizedProvider(provider));
inertialFrame, initDate, provider.getMu()),DEFAULT_LAW, Propagator.DEFAULT_MASS, GravityFieldFactory.getUnnormalizedProvider(provider), BrouwerLyddanePropagator.M2);
// Reset BL2 with BL1 initial state
BLextrapolator2.resetInitialState(initialState);
......@@ -389,11 +498,11 @@ public class BrouwerLyddanePropagatorTest {
BrouwerLyddanePropagator BLPropagator1 = new BrouwerLyddanePropagator(initialOrbit, DEFAULT_LAW,
provider.getAe(), provider.getMu(), -1.08263e-3, 2.54e-6, 1.62e-6, 2.3e-7);
provider.getAe(), provider.getMu(), -1.08263e-3, 2.54e-6, 1.62e-6, 2.3e-7, BrouwerLyddanePropagator.M2);
BrouwerLyddanePropagator BLPropagator2 = new BrouwerLyddanePropagator(initialOrbit,
provider.getAe(), provider.getMu(), -1.08263e-3, 2.54e-6, 1.62e-6, 2.3e-7);
provider.getAe(), provider.getMu(), -1.08263e-3, 2.54e-6, 1.62e-6, 2.3e-7, BrouwerLyddanePropagator.M2);
BrouwerLyddanePropagator BLPropagator3 = new BrouwerLyddanePropagator(initialOrbit, Propagator.DEFAULT_MASS,
provider.getAe(), provider.getMu(), -1.08263e-3, 2.54e-6, 1.62e-6, 2.3e-7);
provider.getAe(), provider.getMu(), -1.08263e-3, 2.54e-6, 1.62e-6, 2.3e-7, BrouwerLyddanePropagator.M2);
SpacecraftState BLFinalState1 = BLPropagator1.propagate(initDate.shiftedBy(timeshift));
final KeplerianOrbit BLOrbit1 = (KeplerianOrbit) OrbitType.KEPLERIAN.convertType(BLFinalState1.getOrbit());
......@@ -438,7 +547,7 @@ public class BrouwerLyddanePropagatorTest {
// -----------------------
BrouwerLyddanePropagator extrapolator =
new BrouwerLyddanePropagator(initialOrbit, DEFAULT_LAW, provider.getAe(), provider.getMu(),
-1.08263e-3, 2.54e-6, 1.62e-6, 2.3e-7);
-1.08263e-3, 2.54e-6, 1.62e-6, 2.3e-7, BrouwerLyddanePropagator.M2);
// Extrapolation at the initial date
// ---------------------------------
......@@ -459,7 +568,7 @@ public class BrouwerLyddanePropagatorTest {
// -----------------------
BrouwerLyddanePropagator extrapolator =
new BrouwerLyddanePropagator(initialOrbit, provider.getAe(), provider.getMu(),
-1.08263e-3, 2.54e-6, 1.62e-6, 2.3e-7);
-1.08263e-3, 2.54e-6, 1.62e-6, 2.3e-7, BrouwerLyddanePropagator.M2);
// Extrapolation at the initial date
// ---------------------------------
......@@ -488,7 +597,7 @@ public class BrouwerLyddanePropagatorTest {
// Extrapolator definition
// -----------------------
BrouwerLyddanePropagator extrapolator =
new BrouwerLyddanePropagator(initialOrbit, GravityFieldFactory.getUnnormalizedProvider(provider));
new BrouwerLyddanePropagator(initialOrbit, GravityFieldFactory.getUnnormalizedProvider(provider), BrouwerLyddanePropagator.M2);
// Extrapolation at the initial date
// ---------------------------------
......@@ -547,7 +656,7 @@ public class BrouwerLyddanePropagatorTest {
// Extrapolator definition
// -----------------------
BrouwerLyddanePropagator extrapolator =
new BrouwerLyddanePropagator(initialOrbit, GravityFieldFactory.getUnnormalizedProvider(provider));
new BrouwerLyddanePropagator(initialOrbit, GravityFieldFactory.getUnnormalizedProvider(provider), BrouwerLyddanePropagator.M2);
// Extrapolation at the initial date
// ---------------------------------
......@@ -559,7 +668,7 @@ public class BrouwerLyddanePropagatorTest {
@Before
public void setUp() {
Utils.setDataRoot("regular-data:potential/icgem-format");
Utils.setDataRoot("regular-data:atmosphere:potential/icgem-format");
provider = GravityFieldFactory.getNormalizedProvider(5, 0);
}
......
......@@ -14,9 +14,14 @@ import org.junit.Before;
import org.junit.Test;
import org.orekit.Utils;
import org.orekit.attitudes.AttitudeProvider;
import org.orekit.bodies.CelestialBodyFactory;
import org.orekit.bodies.OneAxisEllipsoid;
import org.orekit.data.DataContext;
import org.orekit.errors.OrekitException;
import org.orekit.errors.OrekitMessages;
import org.orekit.forces.ForceModel;
import org.orekit.forces.drag.DragForce;
import org.orekit.forces.drag.IsotropicDrag;
import org.orekit.forces.gravity.HolmesFeatherstoneAttractionModel;
import org.orekit.forces.gravity.potential.GravityFieldFactory;
import org.orekit.forces.gravity.potential.NormalizedSphericalHarmonicsProvider;
......@@ -24,6 +29,8 @@ import org.orekit.forces.gravity.potential.TideSystem;
import org.orekit.forces.gravity.potential.UnnormalizedSphericalHarmonicsProvider;
import org.orekit.frames.Frame;
import org.orekit.frames.FramesFactory;
import org.orekit.models.earth.atmosphere.DTM2000;
import org.orekit.models.earth.atmosphere.data.MarshallSolarActivityFutureEstimation;
import org.orekit.orbits.FieldEquinoctialOrbit;
import org.orekit.orbits.FieldKeplerianOrbit;
import org.orekit.orbits.FieldOrbit;
......@@ -35,7 +42,11 @@ import org.orekit.propagation.PropagationType;
import org.orekit.propagation.Propagator;
import org.orekit.propagation.SpacecraftState;
import org.orekit.propagation.numerical.NumericalPropagator;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.FieldAbsoluteDate;
import org.orekit.time.TimeScale;
import org.orekit.time.TimeScalesFactory;
import org.orekit.utils.Constants;
import org.orekit.utils.FieldPVCoordinates;
import org.orekit.utils.IERSConventions;
......@@ -64,7 +75,7 @@ public class FieldBrouwerLyddanePropagatorTest {
// Extrapolation at the initial date
// ---------------------------------
FieldBrouwerLyddanePropagator<T> extrapolator =
new FieldBrouwerLyddanePropagator<T>(initialOrbit, GravityFieldFactory.getUnnormalizedProvider(provider));
new FieldBrouwerLyddanePropagator<T>(initialOrbit, GravityFieldFactory.getUnnormalizedProvider(provider), BrouwerLyddanePropagator.M2);
FieldSpacecraftState<T> finalOrbit = extrapolator.propagate(initDate);
// positions velocity and semi major axis match perfectly
......@@ -98,7 +109,7 @@ public class FieldBrouwerLyddanePropagatorTest {
FramesFactory.getEME2000(), initDate, zero.add(provider.getMu()));
FieldBrouwerLyddanePropagator<T> extrapolator =
new FieldBrouwerLyddanePropagator<T>(initialOrbit, DEFAULT_LAW, GravityFieldFactory.getUnnormalizedProvider(provider));
new FieldBrouwerLyddanePropagator<T>(initialOrbit, DEFAULT_LAW, GravityFieldFactory.getUnnormalizedProvider(provider), BrouwerLyddanePropagator.M2);
FieldSpacecraftState<T> finalOrbit = extrapolator.propagate(initDate);
......@@ -154,7 +165,7 @@ public class FieldBrouwerLyddanePropagatorTest {
// Extrapolators definitions
// -------------------------
FieldBrouwerLyddanePropagator<T> extrapolatorAna =
new FieldBrouwerLyddanePropagator<>(initialOrbit, zero.add(1000.0), kepProvider);
new FieldBrouwerLyddanePropagator<>(initialOrbit, zero.add(1000.0), kepProvider, BrouwerLyddanePropagator.M2);
FieldKeplerianPropagator<T> extrapolatorKep = new FieldKeplerianPropagator<>(initialOrbit);
// Extrapolation at a final date different from initial date
......@@ -253,7 +264,7 @@ public class FieldBrouwerLyddanePropagatorTest {
//_______________________________________________________________________________________________
FieldBrouwerLyddanePropagator<T> BLextrapolator =
new FieldBrouwerLyddanePropagator<T>(initialOrbit, GravityFieldFactory.getUnnormalizedProvider(provider));
new FieldBrouwerLyddanePropagator<T>(initialOrbit, GravityFieldFactory.getUnnormalizedProvider(provider), BrouwerLyddanePropagator.M2);
FieldSpacecraftState<T> BLFinalState = BLextrapolator.propagate(initDate.shiftedBy(timeshift));
final KeplerianOrbit BLOrbit = (KeplerianOrbit) OrbitType.KEPLERIAN.convertType(BLFinalState.getOrbit().toOrbit());
......@@ -270,6 +281,110 @@ public class FieldBrouwerLyddanePropagatorTest {
MathUtils.normalizeAngle(BLOrbit.getTrueAnomaly(), FastMath.PI), 0.12);
}
@Test
public void compareToNumericalPropagationWithDrag() {
doCompareToNumericalPropagationWithDrag(Decimal64Field.getInstance());
}
private <T extends CalculusFieldElement<T>> void doCompareToNumericalPropagationWithDrag(Field<T> field) {
T zero = field.getZero();
final Frame inertialFrame = FramesFactory.getEME2000();
final TimeScale utc = TimeScalesFactory.getUTC();
final AbsoluteDate date = new AbsoluteDate(2003, 1, 1, 00, 00, 00.000, utc);
final FieldAbsoluteDate<T> initDate = new FieldAbsoluteDate<>(date, zero);