/** * Conversion from osculating to mean, orbit. * * <p>Compute osculating state <b>in a DSST sense</b>, corresponding to the mean SpacecraftState * in input, and according to the Force models taken into account. * * <p>Since the osculating state is obtained with the computation of short-periodic variation of * each force model, the resulting output will depend on the force models parametrized in input. * * <p>The computing is done through a fixed-point iteration process. * * @param osculating Osculating state to convert * @param forces Forces to take into account * @return mean state in a DSST sense * @throws OrekitException if computation of short periodics fails or iteration algorithm does not * converge */ public static SpacecraftState computeMeanState( final SpacecraftState osculating, final Collection<DSSTForceModel> forces) throws OrekitException { // Creation of a DSSTPropagator instance final AbstractIntegrator integrator = new ClassicalRungeKuttaIntegrator(43200.); final DSSTPropagator dsst = new DSSTPropagator(integrator, false); // Create the auxiliary object final AuxiliaryElements aux = new AuxiliaryElements(osculating.getOrbit(), I); // Set the force models for (final DSSTForceModel force : forces) { force.initialize(aux, false); dsst.addForceModel(force); } dsst.setInitialState(osculating, true); final Orbit meanOrbit = dsst.mapper.computeMeanOrbit(osculating); return new SpacecraftState( meanOrbit, osculating.getAttitude(), osculating.getMass(), osculating.getAdditionalStates()); }
/** {@inheritDoc} */ @Override public double[] computeDerivatives(final SpacecraftState state) throws OrekitException { // compute common auxiliary elements final AuxiliaryElements aux = new AuxiliaryElements(state.getOrbit(), I); // initialize all perturbing forces for (final DSSTForceModel force : mapper.getForceModels()) { force.initializeStep(aux); } Arrays.fill(yDot, 0.0); // compute the contributions of all perturbing forces for (final DSSTForceModel forceModel : mapper.getForceModels()) { final double[] daidt = forceModel.getMeanElementRate(state); for (int i = 0; i < daidt.length; i++) { yDot[i] += daidt[i]; } } // finalize derivatives by adding the Kepler contribution final EquinoctialOrbit orbit = (EquinoctialOrbit) OrbitType.EQUINOCTIAL.convertType(state.getOrbit()); orbit.addKeplerContribution(PositionAngle.MEAN, getMu(), yDot); return yDot.clone(); }
@Test public void testEventDetectionBug() throws OrekitException, IOException, ParseException { TimeScale utc = TimeScalesFactory.getUTC(); AbsoluteDate initialDate = new AbsoluteDate(2005, 1, 1, 0, 0, 0.0, utc); double duration = 100000.; AbsoluteDate endDate = new AbsoluteDate(initialDate, duration); // Initialization of the frame EME2000 Frame EME2000 = FramesFactory.getEME2000(); // Initial orbit double a = 35786000. + 6378137.0; double e = 0.70; double rApogee = a * (1 + e); double vApogee = FastMath.sqrt(mu * (1 - e) / (a * (1 + e))); Orbit geo = new CartesianOrbit( new PVCoordinates(new Vector3D(rApogee, 0., 0.), new Vector3D(0., vApogee, 0.)), EME2000, initialDate, mu); duration = geo.getKeplerianPeriod(); endDate = new AbsoluteDate(initialDate, duration); // Numerical Integration final double minStep = 0.001; final double maxStep = 1000; final double initStep = 60; final double[] absTolerance = {0.001, 1.0e-9, 1.0e-9, 1.0e-6, 1.0e-6, 1.0e-6, 0.001}; final double[] relTolerance = {1.0e-7, 1.0e-4, 1.0e-4, 1.0e-7, 1.0e-7, 1.0e-7, 1.0e-7}; AdaptiveStepsizeIntegrator integrator = new DormandPrince853Integrator(minStep, maxStep, absTolerance, relTolerance); integrator.setInitialStepSize(initStep); // Numerical propagator based on the integrator propagator = new NumericalPropagator(integrator); double mass = 1000.; SpacecraftState initialState = new SpacecraftState(geo, mass); propagator.setInitialState(initialState); propagator.setOrbitType(OrbitType.CARTESIAN); // Set the events Detectors ApsideDetector event1 = new ApsideDetector(geo); propagator.addEventDetector(event1); // Set the propagation mode propagator.setSlaveMode(); // Propagate SpacecraftState finalState = propagator.propagate(endDate); // we should stop long before endDate Assert.assertTrue(endDate.durationFrom(finalState.getDate()) > 40000.0); }
private double[] stateToArray( SpacecraftState state, OrbitType orbitType, PositionAngle angleType, boolean withMass) { double[] array = new double[withMass ? 7 : 6]; switch (orbitType) { case CARTESIAN: { CartesianOrbit cart = (CartesianOrbit) orbitType.convertType(state.getOrbit()); array[0] = cart.getPVCoordinates().getPosition().getX(); array[1] = cart.getPVCoordinates().getPosition().getY(); array[2] = cart.getPVCoordinates().getPosition().getZ(); array[3] = cart.getPVCoordinates().getVelocity().getX(); array[4] = cart.getPVCoordinates().getVelocity().getY(); array[5] = cart.getPVCoordinates().getVelocity().getZ(); } break; case CIRCULAR: { CircularOrbit circ = (CircularOrbit) orbitType.convertType(state.getOrbit()); array[0] = circ.getA(); array[1] = circ.getCircularEx(); array[2] = circ.getCircularEy(); array[3] = circ.getI(); array[4] = circ.getRightAscensionOfAscendingNode(); array[5] = circ.getAlpha(angleType); } break; case EQUINOCTIAL: { EquinoctialOrbit equ = (EquinoctialOrbit) orbitType.convertType(state.getOrbit()); array[0] = equ.getA(); array[1] = equ.getEquinoctialEx(); array[2] = equ.getEquinoctialEy(); array[3] = equ.getHx(); array[4] = equ.getHy(); array[5] = equ.getL(angleType); } break; case KEPLERIAN: { KeplerianOrbit kep = (KeplerianOrbit) orbitType.convertType(state.getOrbit()); array[0] = kep.getA(); array[1] = kep.getE(); array[2] = kep.getI(); array[3] = kep.getPerigeeArgument(); array[4] = kep.getRightAscensionOfAscendingNode(); array[5] = kep.getAnomaly(angleType); } break; } if (withMass) { array[6] = state.getMass(); } return array; }
/** {@inheritDoc} */ public SpacecraftState apply(final SpacecraftState state1) { if (state1.getDate().compareTo(referenceDate) <= 0 && !applyBefore) { // the orbit change has not occurred yet, don't change anything return state1; } return new SpacecraftState( updateOrbit(state1.getOrbit()), state1.getAttitude(), state1.getMass()); }
@Test public void testPropagationTypesHyperbolic() throws OrekitException, ParseException, IOException { SpacecraftState state = new SpacecraftState( new KeplerianOrbit( -10000000.0, 2.5, 0.3, 0, 0, 0.0, PositionAngle.TRUE, FramesFactory.getEME2000(), initDate, mu)); ForceModel gravityField = new HolmesFeatherstoneAttractionModel( FramesFactory.getITRF(IERSConventions.IERS_2010, true), GravityFieldFactory.getNormalizedProvider(5, 5)); propagator.addForceModel(gravityField); // Propagation of the initial at t + dt final PVCoordinates pv = state.getPVCoordinates(); final double dP = 0.001; final double dV = state.getMu() * dP / (pv.getPosition().getNormSq() * pv.getVelocity().getNorm()); final PVCoordinates pvcM = propagateInType(state, dP, OrbitType.CARTESIAN, PositionAngle.MEAN); final PVCoordinates pvkM = propagateInType(state, dP, OrbitType.KEPLERIAN, PositionAngle.MEAN); final PVCoordinates pvcE = propagateInType(state, dP, OrbitType.CARTESIAN, PositionAngle.ECCENTRIC); final PVCoordinates pvkE = propagateInType(state, dP, OrbitType.KEPLERIAN, PositionAngle.ECCENTRIC); final PVCoordinates pvcT = propagateInType(state, dP, OrbitType.CARTESIAN, PositionAngle.TRUE); final PVCoordinates pvkT = propagateInType(state, dP, OrbitType.KEPLERIAN, PositionAngle.TRUE); Assert.assertEquals(0, pvcM.getPosition().subtract(pvkT.getPosition()).getNorm() / dP, 0.3); Assert.assertEquals(0, pvcM.getVelocity().subtract(pvkT.getVelocity()).getNorm() / dV, 0.4); Assert.assertEquals(0, pvkM.getPosition().subtract(pvkT.getPosition()).getNorm() / dP, 0.2); Assert.assertEquals(0, pvkM.getVelocity().subtract(pvkT.getVelocity()).getNorm() / dV, 0.3); Assert.assertEquals(0, pvcE.getPosition().subtract(pvkT.getPosition()).getNorm() / dP, 0.3); Assert.assertEquals(0, pvcE.getVelocity().subtract(pvkT.getVelocity()).getNorm() / dV, 0.4); Assert.assertEquals(0, pvkE.getPosition().subtract(pvkT.getPosition()).getNorm() / dP, 0.009); Assert.assertEquals(0, pvkE.getVelocity().subtract(pvkT.getVelocity()).getNorm() / dV, 0.006); Assert.assertEquals(0, pvcT.getPosition().subtract(pvkT.getPosition()).getNorm() / dP, 0.3); Assert.assertEquals(0, pvcT.getVelocity().subtract(pvkT.getVelocity()).getNorm() / dV, 0.4); }
@Test public void testStopEvent() throws OrekitException { final AbsoluteDate stopDate = initDate.shiftedBy(1000); CheckingHandler<DateDetector> checking = new CheckingHandler<DateDetector>(Action.STOP); propagator.addEventDetector(new DateDetector(stopDate).withHandler(checking)); Assert.assertEquals(1, propagator.getEventsDetectors().size()); checking.assertEvent(false); final SpacecraftState finalState = propagator.propagate(initDate.shiftedBy(3200)); checking.assertEvent(true); Assert.assertEquals(0, finalState.getDate().durationFrom(stopDate), 1.0e-10); propagator.clearEventsDetectors(); Assert.assertEquals(0, propagator.getEventsDetectors().size()); }
@Test public void testCartesian() throws OrekitException { // Propagation of the initial at t + dt final double dt = 3200; propagator.setOrbitType(OrbitType.CARTESIAN); final PVCoordinates finalState = propagator.propagate(initDate.shiftedBy(dt)).getPVCoordinates(); final Vector3D pFin = finalState.getPosition(); final Vector3D vFin = finalState.getVelocity(); // Check results final PVCoordinates reference = initialState.shiftedBy(dt).getPVCoordinates(); final Vector3D pRef = reference.getPosition(); final Vector3D vRef = reference.getVelocity(); Assert.assertEquals(0, pRef.subtract(pFin).getNorm(), 2e-4); Assert.assertEquals(0, vRef.subtract(vFin).getNorm(), 7e-8); try { propagator.getGeneratedEphemeris(); Assert.fail("an exception should have been thrown"); } catch (IllegalStateException ise) { // expected } }
/** {@inheritDoc} */ @Override public void mapStateToArray(final SpacecraftState state, final double[] y) throws OrekitException { final Orbit meanOrbit; if (!initialIsOsculating) { // the state is considered to be already a mean state meanOrbit = state.getOrbit(); } else { // the state is considered to be an osculating state meanOrbit = computeMeanState(state, forceModels).getOrbit(); } OrbitType.EQUINOCTIAL.mapOrbitToArray(meanOrbit, PositionAngle.MEAN, y); y[6] = state.getMass(); }
/** * Method called just before integration. * * <p>The default implementation does nothing, it may be specialized in subclasses. * * @param initialState initial state * @param tEnd target date at which state should be propagated * @exception OrekitException if hook cannot be run */ @Override protected void beforeIntegration(final SpacecraftState initialState, final AbsoluteDate tEnd) throws OrekitException { // compute common auxiliary elements final AuxiliaryElements aux = new AuxiliaryElements(initialState.getOrbit(), I); // check if only mean elements must be used final boolean meanOnly = isMeanOrbit(); // initialize all perturbing forces for (final DSSTForceModel force : mapper.getForceModels()) { force.initialize(aux, meanOnly); } // if required, insert the special short periodics step handler if (!meanOnly) { final InterpolationGrid grid = new VariableStepInterpolationGrid(INTERPOLATION_POINTS_PER_STEP); final ShortPeriodicsHandler spHandler = new ShortPeriodicsHandler(grid); final Collection<StepHandler> stepHandlers = new ArrayList<StepHandler>(); stepHandlers.add(spHandler); final AbstractIntegrator integrator = getIntegrator(); final Collection<StepHandler> existing = integrator.getStepHandlers(); stepHandlers.addAll(existing); integrator.clearStepHandlers(); // add back the existing handlers after the short periodics one for (final StepHandler sp : stepHandlers) { integrator.addStepHandler(sp); } } }
/** * Simple constructor. * * <p>The {@code applyBefore} parameter is mainly used when the differential effect is associated * with a maneuver. In this case, the parameter must be set to {@code false}. * * @param original original state at reference date * @param directEffect direct effect changing the orbit * @param applyBefore if true, effect is applied both before and after reference date, if false it * is only applied after reference date * @param referenceRadius reference radius of the Earth for the potential model (m) * @param mu central attraction coefficient (m³/s²) * @param j2 un-normalized zonal coefficient (about +1.08e-3 for Earth) * @exception OrekitException if direct effect cannot be applied */ public J2DifferentialEffect( final SpacecraftState original, final AdapterPropagator.DifferentialEffect directEffect, final boolean applyBefore, final double referenceRadius, final double mu, final double j2) throws OrekitException { this( original.getOrbit(), directEffect.apply(original.shiftedBy(0.001)).getOrbit().shiftedBy(-0.001), applyBefore, referenceRadius, mu, j2); }
/** {@inheritDoc} */ @Override public double[] getMeanElementRate(final SpacecraftState spacecraftState) throws OrekitException { // Compute potential derivatives final double[] dU = computeUDerivatives(spacecraftState.getDate()); final double dUda = dU[0]; final double dUdh = dU[1]; final double dUdk = dU[2]; final double dUdl = dU[3]; final double dUdAl = dU[4]; final double dUdBe = dU[5]; final double dUdGa = dU[6]; // Compute the cross derivative operator : final double UAlphaGamma = alpha * dUdGa - gamma * dUdAl; final double UAlphaBeta = alpha * dUdBe - beta * dUdAl; final double UBetaGamma = beta * dUdGa - gamma * dUdBe; final double Uhk = h * dUdk - k * dUdh; final double pUagmIqUbgoAB = (p * UAlphaGamma - I * q * UBetaGamma) * ooAB; final double UhkmUabmdUdl = Uhk - UAlphaBeta - dUdl; final double da = ax2oA * dUdl; final double dh = BoA * dUdk + k * pUagmIqUbgoAB - h * BoABpo * dUdl; final double dk = -(BoA * dUdh + h * pUagmIqUbgoAB + k * BoABpo * dUdl); final double dp = Co2AB * (p * UhkmUabmdUdl - UBetaGamma); final double dq = Co2AB * (q * UhkmUabmdUdl - I * UAlphaGamma); final double dM = -ax2oA * dUda + BoABpo * (h * dUdh + k * dUdk) + pUagmIqUbgoAB; return new double[] {da, dk, dh, dq, dp, dM}; }
@Test public void testResetStateEvent() throws OrekitException { final AbsoluteDate resetDate = initDate.shiftedBy(1000); CheckingHandler<DateDetector> checking = new CheckingHandler<DateDetector>(Action.RESET_STATE) { public SpacecraftState resetState(DateDetector detector, SpacecraftState oldState) { return new SpacecraftState( oldState.getOrbit(), oldState.getAttitude(), oldState.getMass() - 200.0); } }; propagator.addEventDetector(new DateDetector(resetDate).withHandler(checking)); checking.assertEvent(false); final SpacecraftState finalState = propagator.propagate(initDate.shiftedBy(3200)); checking.assertEvent(true); Assert.assertEquals(initialState.getMass() - 200, finalState.getMass(), 1.0e-10); }
/** * Compute mean state from osculating state. * * <p>Compute in a DSST sense the mean state corresponding to the input osculating state. * * <p>The computing is done through a fixed-point iteration process. * * @param osculating initial osculating state * @return mean state * @throws OrekitException if the underlying computation of short periodic variation fails */ private Orbit computeMeanOrbit(final SpacecraftState osculating) throws OrekitException { // rough initialization of the mean parameters EquinoctialOrbit meanOrbit = new EquinoctialOrbit(osculating.getOrbit()); // threshold for each parameter final double epsilon = 1.0e-13; final double thresholdA = epsilon * (1 + FastMath.abs(meanOrbit.getA())); final double thresholdE = epsilon * (1 + meanOrbit.getE()); final double thresholdAngles = epsilon * FastMath.PI; int i = 0; while (i++ < 200) { final SpacecraftState meanState = new SpacecraftState(meanOrbit, osculating.getAttitude(), osculating.getMass()); // recompute the osculating parameters from the current mean parameters final EquinoctialOrbit rebuilt = (EquinoctialOrbit) computeOsculatingOrbit(meanState); // adapted parameters residuals final double deltaA = osculating.getA() - rebuilt.getA(); final double deltaEx = osculating.getEquinoctialEx() - rebuilt.getEquinoctialEx(); final double deltaEy = osculating.getEquinoctialEy() - rebuilt.getEquinoctialEy(); final double deltaHx = osculating.getHx() - rebuilt.getHx(); final double deltaHy = osculating.getHy() - rebuilt.getHy(); final double deltaLm = MathUtils.normalizeAngle(osculating.getLM() - rebuilt.getLM(), 0.0); // check convergence if ((FastMath.abs(deltaA) < thresholdA) && (FastMath.abs(deltaEx) < thresholdE) && (FastMath.abs(deltaEy) < thresholdE) && (FastMath.abs(deltaLm) < thresholdAngles)) { return meanOrbit; } // update mean parameters meanOrbit = new EquinoctialOrbit( meanOrbit.getA() + deltaA, meanOrbit.getEquinoctialEx() + deltaEx, meanOrbit.getEquinoctialEy() + deltaEy, meanOrbit.getHx() + deltaHx, meanOrbit.getHy() + deltaHy, meanOrbit.getLM() + deltaLm, PositionAngle.MEAN, meanOrbit.getFrame(), meanOrbit.getDate(), meanOrbit.getMu()); } throw new PropagationException(OrekitMessages.UNABLE_TO_COMPUTE_DSST_MEAN_PARAMETERS, i); }
/** * Launch the computation of short periodics coefficients. * * @param state input state * @throws OrekitException if the computation of a short periodic coefficient fails * @see {@link DSSTForceModel#computeShortPeriodicsCoefficients(AuxiliaryElements)} */ private void computeShortPeriodicsCoefficients(final SpacecraftState state) throws OrekitException { final AuxiliaryElements aux = new AuxiliaryElements(state.getOrbit(), I); for (final DSSTForceModel forceModel : forceModels) { forceModel.initializeStep(aux); forceModel.computeShortPeriodicsCoefficients(state); } }
/** {@inheritDoc} */ public FieldVector3D<DerivativeStructure> accelerationDerivatives( final SpacecraftState s, final String paramName) throws OrekitException { complainIfNotSupported(paramName); final AbsoluteDate date = s.getDate(); final Frame frame = s.getFrame(); final Vector3D position = s.getPVCoordinates().getPosition(); final Vector3D sunSatVector = position.subtract(sun.getPVCoordinates(date, frame).getPosition()); final double r2 = sunSatVector.getNormSq(); // compute flux final double rawP = kRef * getLightningRatio(position, frame, date) / r2; final Vector3D flux = new Vector3D(rawP / FastMath.sqrt(r2), sunSatVector); return spacecraft.radiationPressureAcceleration( date, frame, position, s.getAttitude().getRotation(), s.getMass(), flux, paramName); }
private SpacecraftState shiftState( SpacecraftState state, OrbitType orbitType, PositionAngle angleType, double delta, int column) { double[] array = stateToArray(state, orbitType, angleType, true); array[column] += delta; return arrayToState( array, orbitType, angleType, state.getFrame(), state.getDate(), state.getMu(), state.getAttitude()); }
/** check propagation succeeds when two events are within the tolerance of each other. */ @Test public void testCloseEventDates() throws PropagationException { // setup DateDetector d1 = new DateDetector(10, 1, initDate.shiftedBy(15)) .withHandler(new ContinueOnEvent<DateDetector>()); DateDetector d2 = new DateDetector(10, 1, initDate.shiftedBy(15.5)) .withHandler(new ContinueOnEvent<DateDetector>()); propagator.addEventDetector(d1); propagator.addEventDetector(d2); // action AbsoluteDate end = initDate.shiftedBy(30); SpacecraftState actual = propagator.propagate(end); // verify Assert.assertEquals(actual.getDate().durationFrom(end), 0.0, 0.0); }
/* (non-Javadoc) * @see org.orekit.propagation.sampling.OrekitFixedStepHandler#handleStep(org.orekit.propagation.SpacecraftState, boolean) */ public void handleStep(SpacecraftState currentState, boolean isLast) throws PropagationException { /** Create position vector. */ D3Vector position = new D3Vector( "", "Position", "Position", "The orbital position of the satellite at the given time.", currentState.getOrbit().getPVCoordinates().getPosition().getX(), currentState.getOrbit().getPVCoordinates().getPosition().getY(), currentState.getOrbit().getPVCoordinates().getPosition().getZ()); /** Create velocity vector. */ D3Vector velocity = new D3Vector( "", "Velocity", "Velocity", "The orbital velocity of the satellite at the given time", currentState.getOrbit().getPVCoordinates().getVelocity().getX(), currentState.getOrbit().getPVCoordinates().getVelocity().getY(), currentState.getOrbit().getPVCoordinates().getVelocity().getZ()); try { /** Create orbital state. */ OrbitalState state = new OrbitalState( predictor.name, orbitalStateName, orbitalStateDescription, currentState.getDate().toDate(TimeScalesFactory.getUTC()).getTime(), datasetidentifier, satellite, position, velocity); /** Send the orbital state on the response stream. */ predictor.addResult(state); } catch (OrekitException e) { e.printStackTrace(); } }
/** * Compute osculating state from mean state. * * <p>Compute and add the short periodic variation to the mean {@link SpacecraftState}. * * @param meanState initial mean state * @return osculating state * @throws OrekitException if the computation of the short-periodic variation fails */ private Orbit computeOsculatingOrbit(final SpacecraftState meanState) throws OrekitException { resetShortPeriodicsCoefficients(); computeShortPeriodicsCoefficients(meanState); final double[] mean = new double[6]; OrbitType.EQUINOCTIAL.mapOrbitToArray(meanState.getOrbit(), PositionAngle.MEAN, mean); final double[] y = mean.clone(); for (final DSSTForceModel forceModel : this.forceModels) { final double[] shortPeriodic = forceModel.getShortPeriodicVariations(meanState.getDate(), mean); for (int i = 0; i < shortPeriodic.length; i++) { y[i] += shortPeriodic[i]; } } return OrbitType.EQUINOCTIAL.mapArrayToOrbit( y, PositionAngle.MEAN, meanState.getDate(), meanState.getMu(), meanState.getFrame()); }
/** {@inheritDoc} */ public FieldVector3D<DerivativeStructure> accelerationDerivatives( final SpacecraftState s, final String paramName) throws OrekitException { complainIfNotSupported(paramName); // compute bodies separation vectors and squared norm final Vector3D centralToBody = body.getPVCoordinates(s.getDate(), s.getFrame()).getPosition(); final double r2Central = centralToBody.getNormSq(); final Vector3D satToBody = centralToBody.subtract(s.getPVCoordinates().getPosition()); final double r2Sat = satToBody.getNormSq(); final DerivativeStructure gmds = new DerivativeStructure(1, 1, 0, gm); // compute relative acceleration return new FieldVector3D<DerivativeStructure>( gmds.divide(r2Sat * FastMath.sqrt(r2Sat)), satToBody, gmds.divide(-r2Central * FastMath.sqrt(r2Central)), centralToBody); }
/** {@inheritDoc} */ public void addContribution(final SpacecraftState s, final TimeDerivativesEquations adder) throws OrekitException { // compute bodies separation vectors and squared norm final Vector3D centralToBody = body.getPVCoordinates(s.getDate(), s.getFrame()).getPosition(); final double r2Central = centralToBody.getNormSq(); final Vector3D satToBody = centralToBody.subtract(s.getPVCoordinates().getPosition()); final double r2Sat = satToBody.getNormSq(); // compute relative acceleration final Vector3D gamma = new Vector3D( gm / (r2Sat * FastMath.sqrt(r2Sat)), satToBody, -gm / (r2Central * FastMath.sqrt(r2Central)), centralToBody); // add contribution to the ODE second member adder.addXYZAcceleration(gamma.getX(), gamma.getY(), gamma.getZ()); }
private PVCoordinates propagateInType( SpacecraftState state, double dP, OrbitType type, PositionAngle angle) throws PropagationException { final double dt = 3200; final double minStep = 0.001; final double maxStep = 1000; double[][] tol = NumericalPropagator.tolerances(dP, state.getOrbit(), type); AdaptiveStepsizeIntegrator integrator = new DormandPrince853Integrator(minStep, maxStep, tol[0], tol[1]); NumericalPropagator newPropagator = new NumericalPropagator(integrator); newPropagator.setOrbitType(type); newPropagator.setPositionAngleType(angle); newPropagator.setInitialState(state); for (ForceModel force : propagator.getForceModels()) { newPropagator.addForceModel(force); } return newPropagator.propagate(state.getDate().shiftedBy(dt)).getPVCoordinates(); }
/** {@inheritDoc} */ public void init(final SpacecraftState s0, final AbsoluteDate t) { // delegate to raw detector rawDetector.init(s0, t); // initialize events triggering logic forward = t.compareTo(s0.getDate()) >= 0; extremeT = forward ? AbsoluteDate.PAST_INFINITY : AbsoluteDate.FUTURE_INFINITY; extremeG = Double.NaN; Arrays.fill(transformers, Transformer.UNINITIALIZED); Arrays.fill(updates, extremeT); }
@Test public void testNoExtrapolation() throws OrekitException { // Propagate of the initial at the initial date final SpacecraftState finalState = propagator.propagate(initDate); // Initial orbit definition final Vector3D initialPosition = initialState.getPVCoordinates().getPosition(); final Vector3D initialVelocity = initialState.getPVCoordinates().getVelocity(); // Final orbit definition final Vector3D finalPosition = finalState.getPVCoordinates().getPosition(); final Vector3D finalVelocity = finalState.getPVCoordinates().getVelocity(); // Check results Assert.assertEquals(initialPosition.getX(), finalPosition.getX(), 1.0e-10); Assert.assertEquals(initialPosition.getY(), finalPosition.getY(), 1.0e-10); Assert.assertEquals(initialPosition.getZ(), finalPosition.getZ(), 1.0e-10); Assert.assertEquals(initialVelocity.getX(), finalVelocity.getX(), 1.0e-10); Assert.assertEquals(initialVelocity.getY(), finalVelocity.getY(), 1.0e-10); Assert.assertEquals(initialVelocity.getZ(), finalVelocity.getZ(), 1.0e-10); }
/** * Simple constructor. * * <p>The {@code applyBefore} parameter is mainly used when the differential effect is associated * with a maneuver. In this case, the parameter must be set to {@code false}. * * @param original original state at reference date * @param directEffect direct effect changing the orbit * @param applyBefore if true, effect is applied both before and after reference date, if false it * is only applied after reference date * @param gravityField gravity field to use * @exception OrekitException if gravity field does not contain J2 coefficient */ public J2DifferentialEffect( final SpacecraftState original, final AdapterPropagator.DifferentialEffect directEffect, final boolean applyBefore, final UnnormalizedSphericalHarmonicsProvider gravityField) throws OrekitException { this( original, directEffect, applyBefore, gravityField.getAe(), gravityField.getMu(), -gravityField.onDate(original.getDate()).getUnnormalizedCnm(2, 0)); }
@Test public void testResetAdditionalStateEvent() throws OrekitException { propagator.addAdditionalEquations( new AdditionalEquations() { public String getName() { return "linear"; } public double[] computeDerivatives(SpacecraftState s, double[] pDot) { pDot[0] = 1.0; return null; } }); propagator.setInitialState(propagator.getInitialState().addAdditionalState("linear", 1.5)); CheckingHandler<AdditionalStateLinearDetector> checking = new CheckingHandler<AdditionalStateLinearDetector>(Action.RESET_STATE) { public SpacecraftState resetState( AdditionalStateLinearDetector detector, SpacecraftState oldState) throws OrekitException { return oldState.addAdditionalState( "linear", oldState.getAdditionalState("linear")[0] * 2); } }; propagator.addEventDetector( new AdditionalStateLinearDetector(10.0, 1.0e-8).withHandler(checking)); final double dt = 3200; checking.assertEvent(false); final SpacecraftState finalState = propagator.propagate(initDate.shiftedBy(dt)); checking.assertEvent(true); Assert.assertEquals(dt + 4.5, finalState.getAdditionalState("linear")[0], 1.0e-8); Assert.assertEquals(dt, finalState.getDate().durationFrom(initDate), 1.0e-8); }
/** {@inheritDoc} */ public void computeShortPeriodicsCoefficients(final SpacecraftState state) throws OrekitException { // Initialise the Hansen coefficients for (int s = -maxDegree; s <= maxDegree; s++) { // coefficients with j == 0 are always needed this.hansenObjects[s + maxDegree][0].computeInitValues(e2, chi, chi2); if (!mDailiesOnly) { // initialize other objects only if required for (int j = 1; j <= jMax; j++) { this.hansenObjects[s + maxDegree][j].computeInitValues(e2, chi, chi2); } } } // Compute coefficients tesseralSPCoefs.computeCoefficients(state.getDate()); }
/** {@inheritDoc} */ public void addContribution(final SpacecraftState s, final TimeDerivativesEquations adder) throws OrekitException { final AbsoluteDate date = s.getDate(); final Frame frame = s.getFrame(); final Vector3D position = s.getPVCoordinates().getPosition(); final Vector3D sunSatVector = position.subtract(sun.getPVCoordinates(date, frame).getPosition()); final double r2 = sunSatVector.getNormSq(); // compute flux final double rawP = kRef * getLightningRatio(position, frame, date) / r2; final Vector3D flux = new Vector3D(rawP / FastMath.sqrt(r2), sunSatVector); final Vector3D acceleration = spacecraft.radiationPressureAcceleration( date, frame, position, s.getAttitude().getRotation(), s.getMass(), flux); // provide the perturbing acceleration to the derivatives adder adder.addAcceleration(acceleration, s.getFrame()); }
@Test public void testSpin() throws OrekitException { AbsoluteDate date = new AbsoluteDate( new DateComponents(1970, 01, 01), new TimeComponents(3, 25, 45.6789), TimeScalesFactory.getUTC()); KeplerianOrbit orbit = new KeplerianOrbit( 7178000.0, 1.e-4, FastMath.toRadians(50.), FastMath.toRadians(10.), FastMath.toRadians(20.), FastMath.toRadians(30.), PositionAngle.MEAN, FramesFactory.getEME2000(), date, 3.986004415e14); final AttitudeProvider law = new LofOffsetPointing( earthSpheric, new LofOffset(orbit.getFrame(), LOFType.VVLH, RotationOrder.XYX, 0.1, 0.2, 0.3), Vector3D.PLUS_K); Propagator propagator = new KeplerianPropagator(orbit, law); double h = 0.01; SpacecraftState sMinus = propagator.propagate(date.shiftedBy(-h)); SpacecraftState s0 = propagator.propagate(date); SpacecraftState sPlus = propagator.propagate(date.shiftedBy(h)); // check spin is consistent with attitude evolution double errorAngleMinus = Rotation.distance( sMinus.shiftedBy(h).getAttitude().getRotation(), s0.getAttitude().getRotation()); double evolutionAngleMinus = Rotation.distance(sMinus.getAttitude().getRotation(), s0.getAttitude().getRotation()); Assert.assertEquals(0.0, errorAngleMinus, 1.0e-6 * evolutionAngleMinus); double errorAnglePlus = Rotation.distance( s0.getAttitude().getRotation(), sPlus.shiftedBy(-h).getAttitude().getRotation()); double evolutionAnglePlus = Rotation.distance(s0.getAttitude().getRotation(), sPlus.getAttitude().getRotation()); Assert.assertEquals(0.0, errorAnglePlus, 1.0e-6 * evolutionAnglePlus); Vector3D spin0 = s0.getAttitude().getSpin(); Vector3D reference = AngularCoordinates.estimateRate( sMinus.getAttitude().getRotation(), sPlus.getAttitude().getRotation(), 2 * h); Assert.assertTrue(spin0.getNorm() > 1.0e-3); Assert.assertEquals(0.0, spin0.subtract(reference).getNorm(), 1.0e-10); }