/** {@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 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); }
/** {@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()); }
/** * 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 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 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()); }
/** * 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)); }
/** {@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 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); }
/* (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(); } }
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); }
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 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()); }
/** {@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 { 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 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); }
@Test public void testAdditionalStateEvent() throws OrekitException { propagator.addAdditionalEquations( new AdditionalEquations() { public String getName() { return "linear"; } public double[] computeDerivatives(SpacecraftState s, double[] pDot) { pDot[0] = 1.0; return new double[7]; } }); try { propagator.addAdditionalEquations( new AdditionalEquations() { public String getName() { return "linear"; } public double[] computeDerivatives(SpacecraftState s, double[] pDot) { pDot[0] = 1.0; return new double[7]; } }); Assert.fail("an exception should have been thrown"); } catch (OrekitException oe) { Assert.assertEquals(oe.getSpecifier(), OrekitMessages.ADDITIONAL_STATE_NAME_ALREADY_IN_USE); } try { propagator.addAdditionalStateProvider( new AdditionalStateProvider() { public String getName() { return "linear"; } public double[] getAdditionalState(SpacecraftState state) { return null; } }); Assert.fail("an exception should have been thrown"); } catch (OrekitException oe) { Assert.assertEquals(oe.getSpecifier(), OrekitMessages.ADDITIONAL_STATE_NAME_ALREADY_IN_USE); } propagator.addAdditionalStateProvider( new AdditionalStateProvider() { public String getName() { return "constant"; } public double[] getAdditionalState(SpacecraftState state) { return new double[] {1.0}; } }); Assert.assertTrue(propagator.isAdditionalStateManaged("linear")); Assert.assertTrue(propagator.isAdditionalStateManaged("constant")); Assert.assertFalse(propagator.isAdditionalStateManaged("non-managed")); Assert.assertEquals(2, propagator.getManagedAdditionalStates().length); propagator.setInitialState(propagator.getInitialState().addAdditionalState("linear", 1.5)); CheckingHandler<AdditionalStateLinearDetector> checking = new CheckingHandler<AdditionalStateLinearDetector>(Action.STOP); 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(3.0, finalState.getAdditionalState("linear")[0], 1.0e-8); Assert.assertEquals(1.5, finalState.getDate().durationFrom(initDate), 1.0e-8); }
@Test public void testPropagationTypesElliptical() throws OrekitException, ParseException, IOException { NormalizedSphericalHarmonicsProvider provider = GravityFieldFactory.getNormalizedProvider(5, 5); ForceModel gravityField = new HolmesFeatherstoneAttractionModel( FramesFactory.getITRF(IERSConventions.IERS_2010, true), provider); Orbit initialOrbit = new KeplerianOrbit( 8000000.0, 0.01, 0.1, 0.7, 0, 1.2, PositionAngle.TRUE, FramesFactory.getEME2000(), AbsoluteDate.J2000_EPOCH, provider.getMu()); double dt = 900; double dP = 0.001; for (OrbitType orbitType : OrbitType.values()) { for (PositionAngle angleType : PositionAngle.values()) { // compute state Jacobian using PartialDerivatives NumericalPropagator propagator = setUpPropagator(initialOrbit, dP, orbitType, angleType, gravityField); PartialDerivativesEquations partials = new PartialDerivativesEquations("partials", propagator); final SpacecraftState initialState = partials.setInitialJacobians(new SpacecraftState(initialOrbit), 6, 0); propagator.setInitialState(initialState); final JacobiansMapper mapper = partials.getMapper(); PickUpHandler pickUp = new PickUpHandler(mapper, null); propagator.setMasterMode(pickUp); propagator.propagate(initialState.getDate().shiftedBy(dt)); double[][] dYdY0 = pickUp.getdYdY0(); // compute reference state Jacobian using finite differences double[][] dYdY0Ref = new double[6][6]; AbstractIntegratedPropagator propagator2 = setUpPropagator(initialOrbit, dP, orbitType, angleType, gravityField); double[] steps = NumericalPropagator.tolerances(1000000 * dP, initialOrbit, orbitType)[0]; for (int i = 0; i < 6; ++i) { propagator2.resetInitialState( shiftState(initialState, orbitType, angleType, -4 * steps[i], i)); SpacecraftState sM4h = propagator2.propagate(initialState.getDate().shiftedBy(dt)); propagator2.resetInitialState( shiftState(initialState, orbitType, angleType, -3 * steps[i], i)); SpacecraftState sM3h = propagator2.propagate(initialState.getDate().shiftedBy(dt)); propagator2.resetInitialState( shiftState(initialState, orbitType, angleType, -2 * steps[i], i)); SpacecraftState sM2h = propagator2.propagate(initialState.getDate().shiftedBy(dt)); propagator2.resetInitialState( shiftState(initialState, orbitType, angleType, -1 * steps[i], i)); SpacecraftState sM1h = propagator2.propagate(initialState.getDate().shiftedBy(dt)); propagator2.resetInitialState( shiftState(initialState, orbitType, angleType, 1 * steps[i], i)); SpacecraftState sP1h = propagator2.propagate(initialState.getDate().shiftedBy(dt)); propagator2.resetInitialState( shiftState(initialState, orbitType, angleType, 2 * steps[i], i)); SpacecraftState sP2h = propagator2.propagate(initialState.getDate().shiftedBy(dt)); propagator2.resetInitialState( shiftState(initialState, orbitType, angleType, 3 * steps[i], i)); SpacecraftState sP3h = propagator2.propagate(initialState.getDate().shiftedBy(dt)); propagator2.resetInitialState( shiftState(initialState, orbitType, angleType, 4 * steps[i], i)); SpacecraftState sP4h = propagator2.propagate(initialState.getDate().shiftedBy(dt)); fillJacobianColumn( dYdY0Ref, i, orbitType, angleType, steps[i], sM4h, sM3h, sM2h, sM1h, sP1h, sP2h, sP3h, sP4h); } for (int i = 0; i < 6; ++i) { for (int j = 0; j < 6; ++j) { double error = FastMath.abs((dYdY0[i][j] - dYdY0Ref[i][j]) / dYdY0Ref[i][j]); Assert.assertEquals(0, error, 6.0e-2); } } } } }
@Test public void testJacobianIssue18() throws OrekitException { // Body mu final double mu = 3.9860047e14; final double isp = 318; final double mass = 2500; final double a = 24396159; final double e = 0.72831215; final double i = FastMath.toRadians(7); final double omega = FastMath.toRadians(180); final double OMEGA = FastMath.toRadians(261); final double lv = 0; final double duration = 3653.99; final double f = 420; final double delta = FastMath.toRadians(-7.4978); final double alpha = FastMath.toRadians(351); final AttitudeProvider law = new InertialProvider(new Rotation(new Vector3D(alpha, delta), Vector3D.PLUS_I)); final AbsoluteDate initDate = new AbsoluteDate( new DateComponents(2004, 01, 01), new TimeComponents(23, 30, 00.000), TimeScalesFactory.getUTC()); final Orbit orbit = new KeplerianOrbit( a, e, i, omega, OMEGA, lv, PositionAngle.TRUE, FramesFactory.getEME2000(), initDate, mu); final SpacecraftState initialState = new SpacecraftState(orbit, law.getAttitude(orbit, orbit.getDate(), orbit.getFrame()), mass); final AbsoluteDate fireDate = new AbsoluteDate( new DateComponents(2004, 01, 02), new TimeComponents(04, 15, 34.080), TimeScalesFactory.getUTC()); final ConstantThrustManeuver maneuver = new ConstantThrustManeuver(fireDate, duration, f, isp, Vector3D.PLUS_I); double[] absTolerance = {0.001, 1.0e-9, 1.0e-9, 1.0e-6, 1.0e-6, 1.0e-6, 0.001}; 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(0.001, 1000, absTolerance, relTolerance); integrator.setInitialStepSize(60); final NumericalPropagator propagator = new NumericalPropagator(integrator); propagator.setAttitudeProvider(law); propagator.addForceModel(maneuver); propagator.setOrbitType(OrbitType.CARTESIAN); PartialDerivativesEquations PDE = new PartialDerivativesEquations("derivatives", propagator); PDE.selectParamAndStep("thrust", Double.NaN); Assert.assertEquals(3, PDE.getAvailableParameters().size()); Assert.assertEquals("central attraction coefficient", PDE.getAvailableParameters().get(0)); Assert.assertEquals("thrust", PDE.getAvailableParameters().get(1)); Assert.assertEquals("flow rate", PDE.getAvailableParameters().get(2)); propagator.setInitialState(PDE.setInitialJacobians(initialState, 7, 1)); final AbsoluteDate finalDate = fireDate.shiftedBy(3800); final SpacecraftState finalorb = propagator.propagate(finalDate); Assert.assertEquals(0, finalDate.durationFrom(finalorb.getDate()), 1.0e-11); }
/** * The G-function is the difference between the Sat-Sun-Sat-Earth angle and the sum of the * Earth's and Sun's apparent radius. * * @param s the current state information : date, kinematics, attitude * @return value of the g function * @exception OrekitException if sun or spacecraft position cannot be computed */ public double g(final SpacecraftState s) throws OrekitException { final double[] angle = getEclipseAngles(s.getPVCoordinates().getPosition(), s.getFrame(), s.getDate()); return angle[0] - angle[1] - angle[2]; }
/** {@inheritDoc} */ public double g(final SpacecraftState s) throws OrekitException { final double rawG = rawDetector.g(s); final boolean isEnabled = enabler.eventIsEnabled(s, rawDetector, rawG); if (Double.isNaN(extremeG)) { extremeG = rawG; } // search which transformer should be applied to g if (forward) { final int last = transformers.length - 1; if (extremeT.compareTo(s.getDate()) < 0) { // we are at the forward end of the history // check if enabled status has changed final Transformer previous = transformers[last]; final Transformer next = selectTransformer(previous, extremeG, isEnabled); if (next != previous) { // there is a status change somewhere between extremeT and t. // the new transformer is valid for t (this is how we have just computed // it above), but it is in fact valid on both sides of the change, so // it was already valid before t and even up to previous time. We store // the switch at extremeT for safety, to ensure the previous transformer // is not applied too close of the root System.arraycopy(updates, 1, updates, 0, last); System.arraycopy(transformers, 1, transformers, 0, last); updates[last] = extremeT; transformers[last] = next; } extremeT = s.getDate(); extremeG = rawG; // apply the transform return next.transformed(rawG); } else { // we are in the middle of the history // select the transformer for (int i = last; i > 0; --i) { if (updates[i].compareTo(s.getDate()) <= 0) { // apply the transform return transformers[i].transformed(rawG); } } return transformers[0].transformed(rawG); } } else { if (s.getDate().compareTo(extremeT) < 0) { // we are at the backward end of the history // check if a new rough root has been crossed final Transformer previous = transformers[0]; final Transformer next = selectTransformer(previous, extremeG, isEnabled); if (next != previous) { // there is a status change somewhere between extremeT and t. // the new transformer is valid for t (this is how we have just computed // it above), but it is in fact valid on both sides of the change, so // it was already valid before t and even up to previous time. We store // the switch at extremeT for safety, to ensure the previous transformer // is not applied too close of the root System.arraycopy(updates, 0, updates, 1, updates.length - 1); System.arraycopy(transformers, 0, transformers, 1, transformers.length - 1); updates[0] = extremeT; transformers[0] = next; } extremeT = s.getDate(); extremeG = rawG; // apply the transform return next.transformed(rawG); } else { // we are in the middle of the history // select the transformer for (int i = 0; i < updates.length - 1; ++i) { if (s.getDate().compareTo(updates[i]) <= 0) { // apply the transform return transformers[i].transformed(rawG); } } return transformers[updates.length - 1].transformed(rawG); } } }
/** * Reset the initial state. * * @param state new initial state * @throws PropagationException if initial state cannot be reset */ @Override public void resetInitialState(final SpacecraftState state) throws PropagationException { super.setStartDate(state.getDate()); super.resetInitialState(state); }