@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); }
@Test public void testResetState() throws OrekitException { final List<AbsoluteDate> reset = new ArrayList<AbsoluteDate>(); DateDetector raw = new DateDetector(orbit.getDate().shiftedBy(3600.0)) .withMaxCheck(1000.0) .withHandler( new EventHandler<DateDetector>() { public SpacecraftState resetState( DateDetector detector, SpacecraftState oldState) { reset.add(oldState.getDate()); return oldState; } public Action eventOccurred( SpacecraftState s, DateDetector detector, boolean increasing) { return Action.RESET_STATE; } }); for (int i = 2; i < 10; ++i) { raw.addEventDate(orbit.getDate().shiftedBy(i * 3600.0)); } EventEnablingPredicateFilter<DateDetector> filtered = new EventEnablingPredicateFilter<DateDetector>( raw, new EnablingPredicate<DateDetector>() { public boolean eventIsEnabled( SpacecraftState state, DateDetector eventDetector, double g) { return state.getDate().durationFrom(orbit.getDate()) > 20000.0; } }); Propagator propagator = new KeplerianPropagator(orbit); EventsLogger logger = new EventsLogger(); propagator.addEventDetector(logger.monitorDetector(filtered)); propagator.propagate(orbit.getDate().shiftedBy(Constants.JULIAN_DAY)); List<LoggedEvent> events = logger.getLoggedEvents(); Assert.assertEquals(4, events.size()); Assert.assertEquals( 6 * 3600, events.get(0).getState().getDate().durationFrom(orbit.getDate()), 1.0e-6); Assert.assertEquals( 7 * 3600, events.get(1).getState().getDate().durationFrom(orbit.getDate()), 1.0e-6); Assert.assertEquals( 8 * 3600, events.get(2).getState().getDate().durationFrom(orbit.getDate()), 1.0e-6); Assert.assertEquals( 9 * 3600, events.get(3).getState().getDate().durationFrom(orbit.getDate()), 1.0e-6); Assert.assertEquals(4, reset.size()); Assert.assertEquals(6 * 3600, reset.get(0).durationFrom(orbit.getDate()), 1.0e-6); Assert.assertEquals(7 * 3600, reset.get(1).durationFrom(orbit.getDate()), 1.0e-6); Assert.assertEquals(8 * 3600, reset.get(2).durationFrom(orbit.getDate()), 1.0e-6); Assert.assertEquals(9 * 3600, reset.get(3).durationFrom(orbit.getDate()), 1.0e-6); }
@Test public void testFrance() throws OrekitException { final BodyShape earth = new OneAxisEllipsoid( Constants.WGS84_EARTH_EQUATORIAL_RADIUS, Constants.WGS84_EARTH_FLATTENING, FramesFactory.getITRF(IERSConventions.IERS_2010, true)); GeographicZoneDetector d = new GeographicZoneDetector(20.0, 1.e-3, earth, buildFrance(), FastMath.toRadians(0.5)) .withHandler(new ContinueOnEvent<GeographicZoneDetector>()); Assert.assertEquals(20.0, d.getMaxCheckInterval(), 1.0e-15); Assert.assertEquals(1.0e-3, d.getThreshold(), 1.0e-15); Assert.assertEquals(0.5, FastMath.toDegrees(d.getMargin()), 1.0e-15); Assert.assertEquals(AbstractDetector.DEFAULT_MAX_ITER, d.getMaxIterationCount()); final TimeScale utc = TimeScalesFactory.getUTC(); final Vector3D position = new Vector3D(-6142438.668, 3492467.56, -25767.257); final Vector3D velocity = new Vector3D(505.848, 942.781, 7435.922); final AbsoluteDate date = new AbsoluteDate(2003, 9, 16, utc); final Orbit orbit = new EquinoctialOrbit( new PVCoordinates(position, velocity), FramesFactory.getEME2000(), date, Constants.EIGEN5C_EARTH_MU); Propagator propagator = new EcksteinHechlerPropagator( orbit, Constants.EIGEN5C_EARTH_EQUATORIAL_RADIUS, Constants.EIGEN5C_EARTH_MU, Constants.EIGEN5C_EARTH_C20, Constants.EIGEN5C_EARTH_C30, Constants.EIGEN5C_EARTH_C40, Constants.EIGEN5C_EARTH_C50, Constants.EIGEN5C_EARTH_C60); EventsLogger logger = new EventsLogger(); propagator.addEventDetector(logger.monitorDetector(d)); propagator.propagate(date.shiftedBy(10 * Constants.JULIAN_DAY)); Assert.assertEquals(26, logger.getLoggedEvents().size()); }
@Test public void testEphemerisDatesBackward() throws OrekitException { // setup TimeScale tai = TimeScalesFactory.getTAI(); AbsoluteDate initialDate = new AbsoluteDate("2015-07-05", tai); AbsoluteDate startDate = new AbsoluteDate("2015-07-03", tai).shiftedBy(-0.1); AbsoluteDate endDate = new AbsoluteDate("2015-07-04", tai); Frame eci = FramesFactory.getGCRF(); KeplerianOrbit orbit = new KeplerianOrbit( 600e3 + Constants.WGS84_EARTH_EQUATORIAL_RADIUS, 0, 0, 0, 0, 0, PositionAngle.TRUE, eci, initialDate, mu); double[][] tol = NumericalPropagator.tolerances(1, orbit, OrbitType.CARTESIAN); Propagator prop = new NumericalPropagator(new DormandPrince853Integrator(0.1, 500, tol[0], tol[1])); prop.resetInitialState(new SpacecraftState(new CartesianOrbit(orbit))); // action prop.setEphemerisMode(); prop.propagate(endDate, startDate); BoundedPropagator ephemeris = prop.getGeneratedEphemeris(); // verify TimeStampedPVCoordinates actualPV = ephemeris.getPVCoordinates(startDate, eci); TimeStampedPVCoordinates expectedPV = orbit.getPVCoordinates(startDate, eci); MatcherAssert.assertThat( actualPV.getPosition(), OrekitMatchers.vectorCloseTo(expectedPV.getPosition(), 1.0)); MatcherAssert.assertThat( actualPV.getVelocity(), OrekitMatchers.vectorCloseTo(expectedPV.getVelocity(), 1.0)); MatcherAssert.assertThat( ephemeris.getMinDate().durationFrom(startDate), OrekitMatchers.closeTo(0, 0)); MatcherAssert.assertThat( ephemeris.getMaxDate().durationFrom(endDate), OrekitMatchers.closeTo(0, 0)); // test date AbsoluteDate date = endDate.shiftedBy(-0.11); Assert.assertEquals(ephemeris.propagate(date).getDate().durationFrom(date), 0, 0); }
@Test public void testExceedHistoryBackward() throws OrekitException, IOException { final double period = 900.0; // the raw detector should trigger one event at each 900s period final DateDetector raw = new DateDetector(orbit.getDate().shiftedBy(+0.5 * period)) .withMaxCheck(period / 3) .withHandler(new ContinueOnEvent<DateDetector>()); for (int i = 0; i < 300; ++i) { raw.addEventDate(orbit.getDate().shiftedBy(-(i + 0.5) * period)); } // in fact, we will filter out half of these events, so we get only one event every 2 periods final EventEnablingPredicateFilter<DateDetector> filtered = new EventEnablingPredicateFilter<DateDetector>( raw, new EnablingPredicate<DateDetector>() { public boolean eventIsEnabled( SpacecraftState state, DateDetector eventDetector, double g) { double nbPeriod = orbit.getDate().durationFrom(state.getDate()) / period; return ((int) FastMath.floor(nbPeriod)) % 2 == 1; } }); Propagator propagator = new KeplerianPropagator(orbit); EventsLogger logger = new EventsLogger(); propagator.addEventDetector(logger.monitorDetector(filtered)); propagator.propagate(orbit.getDate().shiftedBy(-301 * period)); List<LoggedEvent> events = logger.getLoggedEvents(); // 300 periods, 150 events as half of them are filtered out Assert.assertEquals(150, events.size()); // as we have encountered a lot of enabling status changes, we exceeded the internal history // if we try to display again the filtered g function for dates far in the future, // we will not see the zero crossings anymore, they have been lost propagator.clearEventsDetectors(); for (double dt = -5000.0; dt > -10000.0; dt -= 3.0) { double filteredG = filtered.g(propagator.propagate(orbit.getDate().shiftedBy(dt))); Assert.assertTrue(filteredG < 0.0); } // on the other hand, if we try to display again the filtered g function for future dates // that are still inside the history, we still see the zero crossings for (double dt = -195400.0; dt > -196200.0; dt -= 3.0) { double filteredG = filtered.g(propagator.propagate(orbit.getDate().shiftedBy(dt))); if (dt < -195750) { Assert.assertTrue(filteredG < 0.0); } else { Assert.assertTrue(filteredG > 0.0); } } }
private void doElevationTest( final double minElevation, final AbsoluteDate start, final AbsoluteDate end, final int expectedEvents, final boolean sameSign) throws OrekitException { final ElevationExtremumDetector raw = new ElevationExtremumDetector(0.001, 1.e-6, new TopocentricFrame(earth, gp, "test")) .withHandler(new ContinueOnEvent<ElevationExtremumDetector>()); final EventEnablingPredicateFilter<ElevationExtremumDetector> aboveGroundElevationDetector = new EventEnablingPredicateFilter<ElevationExtremumDetector>( raw, new EnablingPredicate<ElevationExtremumDetector>() { public boolean eventIsEnabled( final SpacecraftState state, final ElevationExtremumDetector eventDetector, final double g) throws OrekitException { return eventDetector.getElevation(state) > minElevation; } }) .withMaxCheck(60.0); Assert.assertEquals(0.001, raw.getMaxCheckInterval(), 1.0e-15); Assert.assertEquals(60.0, aboveGroundElevationDetector.getMaxCheckInterval(), 1.0e-15); Assert.assertEquals(1.0e-6, aboveGroundElevationDetector.getThreshold(), 1.0e-15); Assert.assertEquals( AbstractDetector.DEFAULT_MAX_ITER, aboveGroundElevationDetector.getMaxIterationCount()); Propagator propagator = new EcksteinHechlerPropagator( orbit, Constants.EIGEN5C_EARTH_EQUATORIAL_RADIUS, Constants.EIGEN5C_EARTH_MU, Constants.EIGEN5C_EARTH_C20, Constants.EIGEN5C_EARTH_C30, Constants.EIGEN5C_EARTH_C40, Constants.EIGEN5C_EARTH_C50, Constants.EIGEN5C_EARTH_C60); EventsLogger logger = new EventsLogger(); propagator.addEventDetector(logger.monitorDetector(aboveGroundElevationDetector)); propagator.propagate(start, end); for (LoggedEvent e : logger.getLoggedEvents()) { final double eMinus = raw.getElevation(e.getState().shiftedBy(-10.0)); final double e0 = raw.getElevation(e.getState()); final double ePlus = raw.getElevation(e.getState().shiftedBy(+10.0)); Assert.assertTrue(e0 > eMinus); Assert.assertTrue(e0 > ePlus); Assert.assertTrue(e0 > minElevation); } Assert.assertEquals(expectedEvents, logger.getLoggedEvents().size()); propagator.clearEventsDetectors(); double g1Raw = raw.g(propagator.propagate(orbit.getDate().shiftedBy(18540.0))); double g2Raw = raw.g(propagator.propagate(orbit.getDate().shiftedBy(18624.0))); double g1 = aboveGroundElevationDetector.g(propagator.propagate(orbit.getDate().shiftedBy(18540.0))); double g2 = aboveGroundElevationDetector.g(propagator.propagate(orbit.getDate().shiftedBy(18624.0))); Assert.assertTrue(g1Raw > 0); Assert.assertTrue(g2Raw < 0); if (sameSign) { Assert.assertTrue(g1 > 0); Assert.assertTrue(g2 < 0); } else { Assert.assertTrue(g1 < 0); Assert.assertTrue(g2 > 0); } }
protected void checkFit( final TLE tle, final double duration, final double stepSize, final double threshold, final boolean positionOnly, final boolean withBStar, final double expectedRMS) throws OrekitException { Propagator p = TLEPropagator.selectExtrapolator(tle); List<SpacecraftState> sample = new ArrayList<SpacecraftState>(); for (double dt = 0; dt < duration; dt += stepSize) { sample.add(p.propagate(tle.getDate().shiftedBy(dt))); } TLEPropagatorBuilder builder = new TLEPropagatorBuilder( tle.getSatelliteNumber(), tle.getClassification(), tle.getLaunchYear(), tle.getLaunchNumber(), tle.getLaunchPiece(), tle.getElementNumber(), tle.getRevolutionNumberAtEpoch()); FiniteDifferencePropagatorConverter fitter = new FiniteDifferencePropagatorConverter(builder, threshold, 1000); if (withBStar) { fitter.convert(sample, positionOnly, TLEPropagatorBuilder.B_STAR); } else { fitter.convert(sample, positionOnly); } TLEPropagator prop = (TLEPropagator) fitter.getAdaptedPropagator(); TLE fitted = prop.getTLE(); Assert.assertEquals(expectedRMS, fitter.getRMS(), 0.001 * expectedRMS); Assert.assertEquals(tle.getSatelliteNumber(), fitted.getSatelliteNumber()); Assert.assertEquals(tle.getClassification(), fitted.getClassification()); Assert.assertEquals(tle.getLaunchYear(), fitted.getLaunchYear()); Assert.assertEquals(tle.getLaunchNumber(), fitted.getLaunchNumber()); Assert.assertEquals(tle.getLaunchPiece(), fitted.getLaunchPiece()); Assert.assertEquals(tle.getElementNumber(), fitted.getElementNumber()); Assert.assertEquals(tle.getRevolutionNumberAtEpoch(), fitted.getRevolutionNumberAtEpoch()); final double eps = 1.0e-5; Assert.assertEquals(tle.getMeanMotion(), fitted.getMeanMotion(), eps * tle.getMeanMotion()); Assert.assertEquals(tle.getE(), fitted.getE(), eps * tle.getE()); Assert.assertEquals(tle.getI(), fitted.getI(), eps * tle.getI()); Assert.assertEquals( tle.getPerigeeArgument(), fitted.getPerigeeArgument(), eps * tle.getPerigeeArgument()); Assert.assertEquals(tle.getRaan(), fitted.getRaan(), eps * tle.getRaan()); Assert.assertEquals(tle.getMeanAnomaly(), fitted.getMeanAnomaly(), eps * tle.getMeanAnomaly()); if (withBStar) { Assert.assertEquals(tle.getBStar(), fitted.getBStar(), eps * tle.getBStar()); } }