package org.orekit.forces.maneuvers; import org.hipparchus.geometry.euclidean.threed.Vector3D; import org.hipparchus.ode.nonstiff.AdaptiveStepsizeIntegrator; import org.hipparchus.ode.nonstiff.DormandPrince853Integrator; import org.hipparchus.util.FastMath; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.orekit.Utils; import org.orekit.errors.OrekitException; import org.orekit.frames.Frame; import org.orekit.frames.FramesFactory; import org.orekit.orbits.KeplerianOrbit; import org.orekit.orbits.Orbit; import org.orekit.orbits.OrbitType; import org.orekit.orbits.PositionAngle; import org.orekit.propagation.SpacecraftState; import org.orekit.propagation.numerical.NumericalPropagator; import org.orekit.time.AbsoluteDate; import org.orekit.utils.Constants; /** * Tests the functionality of starting a propagation in between and on start and end times * of a Constant Thrust Maneuver * * @author Greg Carbott */ public class ConstantThrustManeuverInitializationTest { private NumericalPropagator propagator; private AbsoluteDate startDate; private SpacecraftState initialState; /** Propagation duration in seconds */ private double propDuration = 1200.; /** Maneuver duration in seconds */ private double duration = 60.; /** Maneuver Thrust Force in Newtons */ private double thrust = 1e3; /** Maneuver Specific Impulse in seconds */ private double isp = 100.; /** Mass of Spacecraft in kilograms */ private double mass = 2e3; /** Tolerance of deltaV (m/s) and mass (kg) difference */ private double tolerance = 1e-8; /** Direction of Maneuver */ private Vector3D direction = new Vector3D(1, 0, 1); /** Control Items */ private double deltaVControlFullForward; private double massControlFullForward; private double massControlHalfForward; private double deltaVControlFullReverse; private double deltaVControlHalfReverse; private double massControlFullReverse; private double massControlHalfReverse; /** set orekit data */ @BeforeClass public static void setUpBefore() { Utils.setDataRoot("regular-data"); } @Before public void setUp() throws OrekitException { startDate = new AbsoluteDate(); double a = Constants.EGM96_EARTH_EQUATORIAL_RADIUS + 400e3; double e = 0.001; double i = (Math.PI / 4); double pa = 0.0; double raan = 0.0; double anomaly = 0.0; PositionAngle type = PositionAngle.MEAN; Frame frame = FramesFactory.getEME2000(); double mu = Constants.EGM96_EARTH_MU; Orbit orbit = new KeplerianOrbit(a, e, i, pa, raan, anomaly, type, frame, startDate, mu); initialState = new SpacecraftState(orbit, mass); //Numerical Propagator double minStep = 0.001; double maxStep = 1000.0; double positionTolerance = 10.; OrbitType propagationType = OrbitType.KEPLERIAN; double[][] tolerances = NumericalPropagator.tolerances(positionTolerance, orbit, propagationType); AdaptiveStepsizeIntegrator integrator = new DormandPrince853Integrator(minStep, maxStep, tolerances[0], tolerances[1]); //Set up propagator propagator = new NumericalPropagator(integrator); propagator.setOrbitType(propagationType); //Control deltaVs and mass changes double flowRate = -thrust / (Constants.G0_STANDARD_GRAVITY * isp); massControlFullForward = mass + (flowRate * duration); deltaVControlFullForward = isp * Constants.G0_STANDARD_GRAVITY * FastMath.log(mass / massControlFullForward); massControlHalfForward = mass + (flowRate * duration / 2); massControlFullReverse = mass - (flowRate * duration); deltaVControlFullReverse = isp * Constants.G0_STANDARD_GRAVITY * FastMath.log(massControlFullReverse / mass); massControlHalfReverse = mass - (flowRate * duration / 2); deltaVControlHalfReverse = isp * Constants.G0_STANDARD_GRAVITY * FastMath.log(massControlHalfReverse / mass); } @Test public void testInBetween() throws OrekitException { //Create test Thrust Maneuver ConstantThrustManeuver ctm = new ConstantThrustManeuver( startDate.shiftedBy(-(duration / 2)), duration, thrust, isp, direction); //Reset and populate propagator propagator.removeForceModels(); propagator.addForceModel(ctm); propagator.setInitialState(initialState); SpacecraftState finalStateTest = propagator.propagate(startDate.shiftedBy(propDuration)); Assert.assertEquals(massControlHalfForward, finalStateTest.getMass(), tolerance); } @Test public void testOnStart() throws OrekitException { //Create test Thrust Maneuver ConstantThrustManeuver ctm = new ConstantThrustManeuver( startDate.shiftedBy(0.0), duration, thrust, isp, direction); //Reset and populate propagator propagator.removeForceModels(); propagator.addForceModel(ctm); propagator.setInitialState(initialState); SpacecraftState finalStateTest = propagator.propagate(startDate.shiftedBy(propDuration)); double deltaVTest = isp * Constants.G0_STANDARD_GRAVITY * FastMath.log(mass / finalStateTest.getMass()); Assert.assertEquals(deltaVControlFullForward, deltaVTest, tolerance); Assert.assertEquals(massControlFullForward, finalStateTest.getMass(), tolerance); } @Test public void testOnEnd() throws OrekitException { //Create test Thrust Maneuver ConstantThrustManeuver ctm = new ConstantThrustManeuver( startDate.shiftedBy(0.0 - duration), duration, thrust, isp, direction); //Reset and populate propagator propagator.removeForceModels(); propagator.addForceModel(ctm); propagator.setInitialState(initialState); SpacecraftState finalStateTest = propagator.propagate(startDate.shiftedBy(propDuration)); double deltaVTest = isp * Constants.G0_STANDARD_GRAVITY * FastMath.log(mass / finalStateTest.getMass()); Assert.assertTrue(deltaVTest == 0.0); Assert.assertTrue(finalStateTest.getMass() == mass); } @Test public void testOnEndReverse() throws OrekitException { //Create test Thrust Maneuver ConstantThrustManeuver ctm = new ConstantThrustManeuver( startDate.shiftedBy(0.0), -duration, thrust, isp, direction); //Reset and populate propagator propagator.removeForceModels(); propagator.addForceModel(ctm); propagator.setInitialState(initialState); SpacecraftState finalStateTest = propagator.propagate(startDate.shiftedBy(-propDuration)); double deltaVTest = isp * Constants.G0_STANDARD_GRAVITY * FastMath.log(finalStateTest.getMass() / mass); Assert.assertEquals(deltaVControlFullReverse, deltaVTest, tolerance); Assert.assertEquals(massControlFullReverse, finalStateTest.getMass(), tolerance); } @Test public void testOnStartReverse() throws OrekitException { //Create test Thrust Maneuver ConstantThrustManeuver ctm = new ConstantThrustManeuver( startDate.shiftedBy(0.0), duration, thrust, isp, direction); //Reset and populate propagator propagator.removeForceModels(); propagator.addForceModel(ctm); propagator.setInitialState(initialState); SpacecraftState finalStateTest = propagator.propagate(startDate.shiftedBy(-propDuration)); double deltaVTest = isp * Constants.G0_STANDARD_GRAVITY * FastMath.log(finalStateTest.getMass() / mass); Assert.assertTrue(deltaVTest == 0.0); Assert.assertTrue(finalStateTest.getMass() == mass); } @Test public void testInBetweenReverse() throws OrekitException { //Create test Thrust Maneuver ConstantThrustManeuver ctm = new ConstantThrustManeuver( startDate.shiftedBy(duration / 2), -duration, thrust, isp, direction); //Reset and populate propagator propagator.removeForceModels(); propagator.addForceModel(ctm); propagator.setInitialState(initialState); SpacecraftState finalStateTest = propagator.propagate(startDate.shiftedBy(-propDuration)); double deltaVTest = isp * Constants.G0_STANDARD_GRAVITY * FastMath.log(finalStateTest.getMass() / mass); Assert.assertEquals(deltaVControlHalfReverse, deltaVTest, tolerance); Assert.assertEquals(massControlHalfReverse, finalStateTest.getMass(), tolerance); } @Test public void testControlForward() throws OrekitException { //Create test Thrust Maneuver ConstantThrustManeuver ctm = new ConstantThrustManeuver( startDate.shiftedBy(1.0), duration, thrust, isp, direction); //Reset and populate propagator propagator.removeForceModels(); propagator.addForceModel(ctm); propagator.setInitialState(initialState); SpacecraftState finalStateTest = propagator.propagate(startDate.shiftedBy(propDuration)); double deltaVTest = isp * Constants.G0_STANDARD_GRAVITY * FastMath.log(mass / finalStateTest.getMass()); Assert.assertEquals(deltaVControlFullForward, deltaVTest, tolerance); Assert.assertEquals(massControlFullForward, finalStateTest.getMass(), tolerance); } @Test public void testControlReverse() throws OrekitException { //Create test Thrust Maneuver ConstantThrustManeuver ctm = new ConstantThrustManeuver( startDate.shiftedBy(-1.0), -duration, thrust, isp, direction); //Reset and populate propagator propagator.removeForceModels(); propagator.addForceModel(ctm); propagator.setInitialState(initialState); SpacecraftState finalStateTest = propagator.propagate(startDate.shiftedBy(-propDuration)); double deltaVTest = isp * Constants.G0_STANDARD_GRAVITY * FastMath.log(finalStateTest.getMass() / mass); Assert.assertEquals(deltaVControlFullReverse, deltaVTest, tolerance); Assert.assertEquals(massControlFullReverse, finalStateTest.getMass(), tolerance); } }