use of org.orekit.forces.drag.atmosphere.Atmosphere in project Orekit by CS-SI.
the class DragForceTest method testIssue229.
@Test
public void testIssue229() throws OrekitException {
AbsoluteDate initialDate = new AbsoluteDate(2004, 1, 1, 0, 0, 0., TimeScalesFactory.getUTC());
Frame frame = FramesFactory.getEME2000();
double rpe = 160.e3 + Constants.WGS84_EARTH_EQUATORIAL_RADIUS;
double rap = 2000.e3 + Constants.WGS84_EARTH_EQUATORIAL_RADIUS;
double inc = FastMath.toRadians(0.);
double aop = FastMath.toRadians(0.);
double raan = FastMath.toRadians(0.);
double mean = FastMath.toRadians(180.);
double mass = 100.;
KeplerianOrbit orbit = new KeplerianOrbit(0.5 * (rpe + rap), (rap - rpe) / (rpe + rap), inc, aop, raan, mean, PositionAngle.MEAN, frame, initialDate, Constants.EIGEN5C_EARTH_MU);
IsotropicDrag shape = new IsotropicDrag(10., 2.2);
Frame itrf = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
BodyShape earthShape = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS, Constants.WGS84_EARTH_FLATTENING, itrf);
Atmosphere atmosphere = new SimpleExponentialAtmosphere(earthShape, 2.6e-10, 200000, 26000);
double[][] tolerance = NumericalPropagator.tolerances(0.1, orbit, OrbitType.CARTESIAN);
AbstractIntegrator integrator = new DormandPrince853Integrator(1.0e-3, 300, tolerance[0], tolerance[1]);
NumericalPropagator propagator = new NumericalPropagator(integrator);
propagator.setOrbitType(OrbitType.CARTESIAN);
propagator.setMu(orbit.getMu());
propagator.addForceModel(new DragForce(atmosphere, shape));
PartialDerivativesEquations partials = new PartialDerivativesEquations("partials", propagator);
propagator.setInitialState(partials.setInitialJacobians(new SpacecraftState(orbit, mass)));
SpacecraftState state = propagator.propagate(new AbsoluteDate(2004, 1, 1, 1, 30, 0., TimeScalesFactory.getUTC()));
double delta = 0.1;
Orbit shifted = new CartesianOrbit(new TimeStampedPVCoordinates(orbit.getDate(), orbit.getPVCoordinates().getPosition().add(new Vector3D(delta, 0, 0)), orbit.getPVCoordinates().getVelocity()), orbit.getFrame(), orbit.getMu());
propagator.setInitialState(partials.setInitialJacobians(new SpacecraftState(shifted, mass)));
SpacecraftState newState = propagator.propagate(new AbsoluteDate(2004, 1, 1, 1, 30, 0., TimeScalesFactory.getUTC()));
double[] dPVdX = new double[] { (newState.getPVCoordinates().getPosition().getX() - state.getPVCoordinates().getPosition().getX()) / delta, (newState.getPVCoordinates().getPosition().getY() - state.getPVCoordinates().getPosition().getY()) / delta, (newState.getPVCoordinates().getPosition().getZ() - state.getPVCoordinates().getPosition().getZ()) / delta, (newState.getPVCoordinates().getVelocity().getX() - state.getPVCoordinates().getVelocity().getX()) / delta, (newState.getPVCoordinates().getVelocity().getY() - state.getPVCoordinates().getVelocity().getY()) / delta, (newState.getPVCoordinates().getVelocity().getZ() - state.getPVCoordinates().getVelocity().getZ()) / delta };
double[][] dYdY0 = new double[6][6];
partials.getMapper().getStateJacobian(state, dYdY0);
for (int i = 0; i < 6; ++i) {
Assert.assertEquals(dPVdX[i], dYdY0[i][0], 6.2e-6 * FastMath.abs(dPVdX[i]));
}
}
use of org.orekit.forces.drag.atmosphere.Atmosphere in project Orekit by CS-SI.
the class DragForceTest method accelerationDerivatives.
@Override
protected FieldVector3D<DerivativeStructure> accelerationDerivatives(final ForceModel forceModel, final AbsoluteDate date, final Frame frame, final FieldVector3D<DerivativeStructure> position, final FieldVector3D<DerivativeStructure> velocity, final FieldRotation<DerivativeStructure> rotation, final DerivativeStructure mass) throws OrekitException {
try {
java.lang.reflect.Field atmosphereField = DragForce.class.getDeclaredField("atmosphere");
atmosphereField.setAccessible(true);
Atmosphere atmosphere = (Atmosphere) atmosphereField.get(forceModel);
java.lang.reflect.Field spacecraftField = DragForce.class.getDeclaredField("spacecraft");
spacecraftField.setAccessible(true);
DragSensitive spacecraft = (DragSensitive) spacecraftField.get(forceModel);
// retrieve derivation properties
final DSFactory factory = mass.getFactory();
// get atmosphere properties in atmosphere own frame
final Frame atmFrame = atmosphere.getFrame();
final Transform toBody = frame.getTransformTo(atmFrame, date);
final FieldVector3D<DerivativeStructure> posBodyDS = toBody.transformPosition(position);
final Vector3D posBody = posBodyDS.toVector3D();
final Vector3D vAtmBody = atmosphere.getVelocity(date, posBody, atmFrame);
// to the Atmosphere interface
if (factory.getCompiler().getOrder() > 1) {
throw new OrekitException(OrekitMessages.OUT_OF_RANGE_DERIVATION_ORDER, factory.getCompiler().getOrder());
}
final double delta = 1.0;
final double x = posBody.getX();
final double y = posBody.getY();
final double z = posBody.getZ();
final double rho0 = atmosphere.getDensity(date, posBody, atmFrame);
final double dRhodX = (atmosphere.getDensity(date, new Vector3D(x + delta, y, z), atmFrame) - rho0) / delta;
final double dRhodY = (atmosphere.getDensity(date, new Vector3D(x, y + delta, z), atmFrame) - rho0) / delta;
final double dRhodZ = (atmosphere.getDensity(date, new Vector3D(x, y, z + delta), atmFrame) - rho0) / delta;
final double[] dXdQ = posBodyDS.getX().getAllDerivatives();
final double[] dYdQ = posBodyDS.getY().getAllDerivatives();
final double[] dZdQ = posBodyDS.getZ().getAllDerivatives();
final double[] rhoAll = new double[dXdQ.length];
rhoAll[0] = rho0;
for (int i = 1; i < rhoAll.length; ++i) {
rhoAll[i] = dRhodX * dXdQ[i] + dRhodY * dYdQ[i] + dRhodZ * dZdQ[i];
}
final DerivativeStructure rho = factory.build(rhoAll);
// we consider that at first order the atmosphere velocity in atmosphere frame
// does not depend on local position; however atmosphere velocity in inertial
// frame DOES depend on position since the transform between the frames depends
// on it, due to central body rotation rate and velocity composition.
// So we use the transform to get the correct partial derivatives on vAtm
final FieldVector3D<DerivativeStructure> vAtmBodyDS = new FieldVector3D<>(factory.constant(vAtmBody.getX()), factory.constant(vAtmBody.getY()), factory.constant(vAtmBody.getZ()));
final FieldPVCoordinates<DerivativeStructure> pvAtmBody = new FieldPVCoordinates<>(posBodyDS, vAtmBodyDS);
final FieldPVCoordinates<DerivativeStructure> pvAtm = toBody.getInverse().transformPVCoordinates(pvAtmBody);
// now we can compute relative velocity, it takes into account partial derivatives with respect to position
final FieldVector3D<DerivativeStructure> relativeVelocity = pvAtm.getVelocity().subtract(velocity);
// compute acceleration with all its partial derivatives
return spacecraft.dragAcceleration(new FieldAbsoluteDate<>(factory.getDerivativeField(), date), frame, position, rotation, mass, rho, relativeVelocity, forceModel.getParameters(factory.getDerivativeField()));
} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
return null;
}
}
use of org.orekit.forces.drag.atmosphere.Atmosphere in project Orekit by CS-SI.
the class MarshallSolarActivityFutureEstimationTest method getNumericalPropagator.
/**
* Configure a numerical propagator.
*
* @param sun Sun.
* @param earth Earth.
* @param ic initial condition.
* @return a propagator.
* @throws OrekitException on error.
*/
private NumericalPropagator getNumericalPropagator(CelestialBody sun, OneAxisEllipsoid earth, SpacecraftState ic) throws OrekitException {
// some non-integer step size to induce truncation error in flux interpolation
final ODEIntegrator integrator = new ClassicalRungeKuttaIntegrator(120 + 0.1);
NumericalPropagator propagator = new NumericalPropagator(integrator);
DTM2000InputParameters flux = getFlux();
final Atmosphere atmosphere = new DTM2000(flux, sun, earth);
final IsotropicDrag satellite = new IsotropicDrag(1, 3.2);
propagator.addForceModel(new DragForce(atmosphere, satellite));
propagator.setInitialState(ic);
propagator.setOrbitType(OrbitType.CARTESIAN);
return propagator;
}
use of org.orekit.forces.drag.atmosphere.Atmosphere in project Orekit by CS-SI.
the class DSSTPropagatorTest method testPropagationWithDrag.
@Test
public void testPropagationWithDrag() throws OrekitException {
// Central Body geopotential 2x0
final UnnormalizedSphericalHarmonicsProvider provider = GravityFieldFactory.getUnnormalizedProvider(2, 0);
final Frame earthFrame = CelestialBodyFactory.getEarth().getBodyOrientedFrame();
DSSTForceModel zonal = new DSSTZonal(provider, 2, 0, 5);
DSSTForceModel tesseral = new DSSTTesseral(earthFrame, Constants.WGS84_EARTH_ANGULAR_VELOCITY, provider, 2, 0, 0, 2, 2, 0, 0);
// Drag Force Model
final OneAxisEllipsoid earth = new OneAxisEllipsoid(provider.getAe(), Constants.WGS84_EARTH_FLATTENING, earthFrame);
final Atmosphere atm = new HarrisPriester(CelestialBodyFactory.getSun(), earth, 6);
final double cd = 2.0;
final double area = 25.0;
DSSTForceModel drag = new DSSTAtmosphericDrag(atm, cd, area);
// LEO Orbit
final AbsoluteDate initDate = new AbsoluteDate(2003, 7, 1, 0, 0, 00.000, TimeScalesFactory.getUTC());
final Orbit orbit = new KeplerianOrbit(7204535.848109440, 0.0012402238462686, FastMath.toRadians(98.74341600466740), FastMath.toRadians(111.1990175076630), FastMath.toRadians(43.32990110790340), FastMath.toRadians(68.66852509725620), PositionAngle.MEAN, FramesFactory.getEME2000(), initDate, provider.getMu());
// Set propagator with state and force model
setDSSTProp(new SpacecraftState(orbit));
dsstProp.addForceModel(zonal);
dsstProp.addForceModel(tesseral);
dsstProp.addForceModel(drag);
// 5 days propagation
final SpacecraftState state = dsstProp.propagate(initDate.shiftedBy(5. * 86400.));
// Ref Standalone_DSST:
// a = 7204521.657141485 m
// h/ey = 0.0007093755541595772
// k/ex = -0.001016800430994036
// p/hy = 0.8698955648709271
// q/hx = 0.7757573478894775
// lM = 193°0939742953394
Assert.assertEquals(7204521.657141485, state.getA(), 6.e-1);
Assert.assertEquals(-0.001016800430994036, state.getEquinoctialEx(), 5.e-8);
Assert.assertEquals(0.0007093755541595772, state.getEquinoctialEy(), 2.e-8);
Assert.assertEquals(0.7757573478894775, state.getHx(), 5.e-8);
Assert.assertEquals(0.8698955648709271, state.getHy(), 5.e-8);
Assert.assertEquals(193.0939742953394, FastMath.toDegrees(MathUtils.normalizeAngle(state.getLM(), FastMath.PI)), 2.e-3);
// Assert.assertEquals(((DSSTAtmosphericDrag)drag).getCd(), cd, 1e-9);
// Assert.assertEquals(((DSSTAtmosphericDrag)drag).getArea(), area, 1e-9);
Assert.assertEquals(((DSSTAtmosphericDrag) drag).getAtmosphere(), atm);
// DSSTAtmosphericDrag.ATMOSPHERE_ALTITUDE_MAX
final double atmosphericMaxConstant = 1000000.0;
Assert.assertEquals(((DSSTAtmosphericDrag) drag).getRbar(), atmosphericMaxConstant + Constants.WGS84_EARTH_EQUATORIAL_RADIUS, 1e-9);
}
use of org.orekit.forces.drag.atmosphere.Atmosphere in project Orekit by CS-SI.
the class OrbitDetermination method createPropagatorBuilder.
/**
* Create a propagator builder from input parameters
* @param parser input file parser
* @param conventions IERS conventions to use
* @param gravityField gravity field
* @param body central body
* @param orbit first orbit estimate
* @return propagator builder
* @throws NoSuchElementException if input parameters are missing
* @throws OrekitException if body frame cannot be created
*/
private NumericalPropagatorBuilder createPropagatorBuilder(final KeyValueFileParser<ParameterKey> parser, final IERSConventions conventions, final NormalizedSphericalHarmonicsProvider gravityField, final OneAxisEllipsoid body, final Orbit orbit) throws NoSuchElementException, OrekitException {
final double minStep;
if (!parser.containsKey(ParameterKey.PROPAGATOR_MIN_STEP)) {
minStep = 0.001;
} else {
minStep = parser.getDouble(ParameterKey.PROPAGATOR_MIN_STEP);
}
final double maxStep;
if (!parser.containsKey(ParameterKey.PROPAGATOR_MAX_STEP)) {
maxStep = 300;
} else {
maxStep = parser.getDouble(ParameterKey.PROPAGATOR_MAX_STEP);
}
final double dP;
if (!parser.containsKey(ParameterKey.PROPAGATOR_POSITION_ERROR)) {
dP = 10.0;
} else {
dP = parser.getDouble(ParameterKey.PROPAGATOR_POSITION_ERROR);
}
final double positionScale;
if (!parser.containsKey(ParameterKey.ESTIMATOR_ORBITAL_PARAMETERS_POSITION_SCALE)) {
positionScale = dP;
} else {
positionScale = parser.getDouble(ParameterKey.ESTIMATOR_ORBITAL_PARAMETERS_POSITION_SCALE);
}
final NumericalPropagatorBuilder propagatorBuilder = new NumericalPropagatorBuilder(orbit, new DormandPrince853IntegratorBuilder(minStep, maxStep, dP), PositionAngle.MEAN, positionScale);
// initial mass
final double mass;
if (!parser.containsKey(ParameterKey.MASS)) {
mass = 1000.0;
} else {
mass = parser.getDouble(ParameterKey.MASS);
}
propagatorBuilder.setMass(mass);
// gravity field force model
propagatorBuilder.addForceModel(new HolmesFeatherstoneAttractionModel(body.getBodyFrame(), gravityField));
// ocean tides force model
if (parser.containsKey(ParameterKey.OCEAN_TIDES_DEGREE) && parser.containsKey(ParameterKey.OCEAN_TIDES_ORDER)) {
final int degree = parser.getInt(ParameterKey.OCEAN_TIDES_DEGREE);
final int order = parser.getInt(ParameterKey.OCEAN_TIDES_ORDER);
if (degree > 0 && order > 0) {
propagatorBuilder.addForceModel(new OceanTides(body.getBodyFrame(), gravityField.getAe(), gravityField.getMu(), degree, order, conventions, TimeScalesFactory.getUT1(conventions, true)));
}
}
// solid tides force model
List<CelestialBody> solidTidesBodies = new ArrayList<CelestialBody>();
if (parser.containsKey(ParameterKey.SOLID_TIDES_SUN) && parser.getBoolean(ParameterKey.SOLID_TIDES_SUN)) {
solidTidesBodies.add(CelestialBodyFactory.getSun());
}
if (parser.containsKey(ParameterKey.SOLID_TIDES_MOON) && parser.getBoolean(ParameterKey.SOLID_TIDES_MOON)) {
solidTidesBodies.add(CelestialBodyFactory.getMoon());
}
if (!solidTidesBodies.isEmpty()) {
propagatorBuilder.addForceModel(new SolidTides(body.getBodyFrame(), gravityField.getAe(), gravityField.getMu(), gravityField.getTideSystem(), conventions, TimeScalesFactory.getUT1(conventions, true), solidTidesBodies.toArray(new CelestialBody[solidTidesBodies.size()])));
}
// third body attraction
if (parser.containsKey(ParameterKey.THIRD_BODY_SUN) && parser.getBoolean(ParameterKey.THIRD_BODY_SUN)) {
propagatorBuilder.addForceModel(new ThirdBodyAttraction(CelestialBodyFactory.getSun()));
}
if (parser.containsKey(ParameterKey.THIRD_BODY_MOON) && parser.getBoolean(ParameterKey.THIRD_BODY_MOON)) {
propagatorBuilder.addForceModel(new ThirdBodyAttraction(CelestialBodyFactory.getMoon()));
}
// drag
if (parser.containsKey(ParameterKey.DRAG) && parser.getBoolean(ParameterKey.DRAG)) {
final double cd = parser.getDouble(ParameterKey.DRAG_CD);
final double area = parser.getDouble(ParameterKey.DRAG_AREA);
final boolean cdEstimated = parser.getBoolean(ParameterKey.DRAG_CD_ESTIMATED);
MarshallSolarActivityFutureEstimation msafe = new MarshallSolarActivityFutureEstimation("(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\p{Digit}\\p{Digit}\\p{Digit}\\p{Digit}F10\\.(?:txt|TXT)", MarshallSolarActivityFutureEstimation.StrengthLevel.AVERAGE);
DataProvidersManager manager = DataProvidersManager.getInstance();
manager.feed(msafe.getSupportedNames(), msafe);
Atmosphere atmosphere = new DTM2000(msafe, CelestialBodyFactory.getSun(), body);
propagatorBuilder.addForceModel(new DragForce(atmosphere, new IsotropicDrag(area, cd)));
if (cdEstimated) {
for (final ParameterDriver driver : propagatorBuilder.getPropagationParametersDrivers().getDrivers()) {
if (driver.getName().equals(DragSensitive.DRAG_COEFFICIENT)) {
driver.setSelected(true);
}
}
}
}
// solar radiation pressure
if (parser.containsKey(ParameterKey.SOLAR_RADIATION_PRESSURE) && parser.getBoolean(ParameterKey.SOLAR_RADIATION_PRESSURE)) {
final double cr = parser.getDouble(ParameterKey.SOLAR_RADIATION_PRESSURE_CR);
final double area = parser.getDouble(ParameterKey.SOLAR_RADIATION_PRESSURE_AREA);
final boolean cREstimated = parser.getBoolean(ParameterKey.SOLAR_RADIATION_PRESSURE_CR_ESTIMATED);
propagatorBuilder.addForceModel(new SolarRadiationPressure(CelestialBodyFactory.getSun(), body.getEquatorialRadius(), new IsotropicRadiationSingleCoefficient(area, cr)));
if (cREstimated) {
for (final ParameterDriver driver : propagatorBuilder.getPropagationParametersDrivers().getDrivers()) {
if (driver.getName().equals(RadiationSensitive.REFLECTION_COEFFICIENT)) {
driver.setSelected(true);
}
}
}
}
// post-Newtonian correction force due to general relativity
if (parser.containsKey(ParameterKey.GENERAL_RELATIVITY) && parser.getBoolean(ParameterKey.GENERAL_RELATIVITY)) {
propagatorBuilder.addForceModel(new Relativity(gravityField.getMu()));
}
// extra polynomial accelerations
if (parser.containsKey(ParameterKey.POLYNOMIAL_ACCELERATION_NAME)) {
final String[] names = parser.getStringArray(ParameterKey.POLYNOMIAL_ACCELERATION_NAME);
final Vector3D[] directions = parser.getVectorArray(ParameterKey.POLYNOMIAL_ACCELERATION_DIRECTION_X, ParameterKey.POLYNOMIAL_ACCELERATION_DIRECTION_Y, ParameterKey.POLYNOMIAL_ACCELERATION_DIRECTION_Z);
final List<String>[] coefficients = parser.getStringsListArray(ParameterKey.POLYNOMIAL_ACCELERATION_COEFFICIENTS, ',');
final boolean[] estimated = parser.getBooleanArray(ParameterKey.POLYNOMIAL_ACCELERATION_ESTIMATED);
for (int i = 0; i < names.length; ++i) {
final PolynomialParametricAcceleration ppa = new PolynomialParametricAcceleration(directions[i], true, names[i], null, coefficients[i].size() - 1);
for (int k = 0; k < coefficients[i].size(); ++k) {
final ParameterDriver driver = ppa.getParameterDriver(names[i] + "[" + k + "]");
driver.setValue(Double.parseDouble(coefficients[i].get(k)));
driver.setSelected(estimated[i]);
}
propagatorBuilder.addForceModel(ppa);
}
}
return propagatorBuilder;
}
Aggregations