Hi, I have been trying to implement a station keeping script using low thrust maneuvers. Two models could be used , the ConfigurableLowThrust , and constantThrust . The issue is that, with configurableLowThrustManeuver I can’t make PythonStartStopEventTrigger work using altitude detector in order to start the maneuver at a given altitude until i reach the second altitude then stop , then keep propagating till i reach again the lower threshold altitude and again.
The error is the following one :
propagator.propagate(final_date)
orekit.JavaError: <super: <class 'JavaError'>, <JavaError object>>
Java stacktrace:
java.lang.RuntimeException: AttributeError
at org.orekit.forces.maneuvers.trigger.PythonStartStopEventsTrigger.getParametersDrivers(Native Method)
at org.orekit.forces.maneuvers.Maneuver.getParametersDrivers(Maneuver.java:275)
at org.orekit.utils.ParameterDriversProvider.getParameters(ParameterDriversProvider.java:82)
at org.orekit.forces.maneuvers.Maneuver.addContribution(Maneuver.java:159)
at org.orekit.propagation.numerical.NumericalPropagator$Main.computeDerivatives(NumericalPropagator.java:979)
at org.orekit.propagation.integration.AbstractIntegratedPropagator$ConvertedMainStateEquations.computeDerivatives(AbstractIntegratedPropagator.java:794)
at org.hipparchus.ode.ExpandableODE.computeDerivatives(ExpandableODE.java:134)
at org.hipparchus.ode.AbstractIntegrator.computeDerivatives(AbstractIntegrator.java:259)
at org.hipparchus.ode.AbstractIntegrator.initIntegration(AbstractIntegrator.java:204)
at org.hipparchus.ode.nonstiff.EmbeddedRungeKuttaIntegrator.integrate(EmbeddedRungeKuttaIntegrator.java:195)
at org.orekit.propagation.integration.AbstractIntegratedPropagator.integrateDynamics(AbstractIntegratedPropagator.java:493)
at org.orekit.propagation.integration.AbstractIntegratedPropagator.propagate(AbstractIntegratedPropagator.java:440)
at org.orekit.propagation.integration.AbstractIntegratedPropagator.propagate(AbstractIntegratedPropagator.java:400)
This is the current code :
simDur = 365 * 3600 * 24*1.0
initial_date = AbsoluteDate(2020, 8, 23, 12, 0, 0.0, TimeScalesFactory.getUTC())
############################ Orbit Definition ######################################
####################################################################################
ra = 500.0 * 1000 # Apogee in meters
rp = 500.0 * 1000
i = 87.0 # Inclination (degres)
omega = 20.0 # Perigee argument in radians
raan = 10.0 # Right ascension of ascending node in radians
lv = 0.0 # True anomaly in radians
a = (rp + ra + 2 * Constants.WGS84_EARTH_EQUATORIAL_RADIUS) / 2.0
e = 1.0 - (rp + Constants.WGS84_EARTH_EQUATORIAL_RADIUS) / a
mu = Constants.EGM96_EARTH_MU
# Setting the initial orbit :
initialOrbit = KeplerianOrbit(a, e, math.radians(i), math.radians(omega), math.radians(raan), math.radians(lv),
PositionAngleType.MEAN, FramesFactory.getEME2000(), initial_date, mu)
############################ Satellite Definition ######################################
########################################################################################
satellite_mass = 6.0
area = 0.15
############################ Environment Definition ######################################
########################################################################################
gravityProvider = GravityFieldFactory.getNormalizedProvider(60, 60)
earth = OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
Constants.WGS84_EARTH_FLATTENING,
FramesFactory.getITRF(IERSConventions.IERS_2010, True))
inertialFrame = FramesFactory.getEME2000()
sun = CelestialBodyFactory.getSun()
itrf = FramesFactory.getITRF(IERSConventions.IERS_2010, True)
earth = OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS, Constants.WGS84_EARTH_FLATTENING, itrf)
dragCoef = 2.2
drag = IsotropicDrag(area, dragCoef)
strengthLevel = MarshallSolarActivityFutureEstimation.StrengthLevel.AVERAGE
supportedNames = MarshallSolarActivityFutureEstimation.DEFAULT_SUPPORTED_NAMES
inputParameters_Drag = MarshallSolarActivityFutureEstimation(supportedNames, strengthLevel)
atmosphere = NRLMSISE00(inputParameters_Drag, sun, earth)
orbitType = OrbitType.CARTESIAN
# Attitude
attitude_provider = LofOffset(inertialFrame, LOFType.NTW)
attitude = attitude_provider.getAttitude(initialOrbit, initialOrbit.getDate(), initialOrbit.getFrame())
# Initial state with attitude
initialState = SpacecraftState(initialOrbit, attitude, satellite_mass)
############################ Reentry Definition ######################################
########################################################################################################
Altitude_reentry = 200.0 * 1000.0
altitude_low=650*1000.0
altitude_high=700*1000.0
altitudeDetector = AltitudeDetector(Altitude_reentry, earth).withHandler(StopOnEvent())
############################ Integrator and propagator Definition ######################################
########################################################################################################
# integrator
minStep = 0.00001
maxStep = 1000.0
initStep = 60.0
positionTolerance = 1.0
tolerances = NumericalPropagator.tolerances(positionTolerance, initialOrbit,orbitType)
integrator = DormandPrince853Integrator(minStep, maxStep,
JArray_double.cast_(tolerances[0]), JArray_double.cast_(tolerances[1]))
integrator.setInitialStepSize(initStep)
# Propagator
propagator = NumericalPropagator(integrator)
propagator.addEventDetector(altitudeDetector)
# AddforceModel
propagator.addForceModel(DragForce(atmosphere, drag))
#propagator.addForceModel(HolmesFeatherstoneAttractionModel(earth.getBodyFrame(), gravityProvider))
############################ Handler Definition ########################################################
########################################################################################################
sma_limite=68800000
# Paramètres de la manœuvre à poussée constante
thrust = 0.01 # Poussée en Newtons
isp = 300.0 # Impulsion spécifique (s)
duration = 6000.0 # Durée de la manœuvre en secondes
direction = Vector3D(1.0, 0.0, 0.0) # Direction de la poussée (dans le référentiel LVLH)
prop_model=BasicConstantThrustPropulsionModel(thrust,isp,direction,"low thrust")
class HandlerForDate(PythonOrekitFixedStepHandler):
def init(self, so, t, step):
super().__init__()
self.smas = []
self.dates = []
self.incs = []
self.eccs = []
def handleStep(self, state):
orbit = OrbitType.KEPLERIAN.convertType(state.getOrbit())
sma = orbit.getA()
inc = orbit.getI()
date = state.getDate()
ecc = state.getE()
#print(sma)
print(date)
self.smas.append(sma / 1000 - Constants.WGS84_EARTH_EQUATORIAL_RADIUS / 1000) # Convert to km
self.dates.append(date.durationFrom(initial_date) / (3600 * 24 * 365)) # Convert to years
self.incs.append(math.degrees(inc))
self.eccs.append(ecc)
maneuver = ConstantThrustManeuver(date, duration,attitude_provider, prop_model)
print(sma,sma_limite)
def finish(self, finalState):
orbit = KeplerianOrbit(finalState.getOrbit())
time_step = 1000.0
#Handler_Date = HandlerForDate()
#Propagator.cast_(propagator).setStepHandler(time_step,Handler_Date)
direction = Vector3D(float(1), float(0), float(0))
thrust = 0.06
thruster_axis = Vector3D(float(1), float(0), float(0))
thrust_direction_provider = ConstantThrustDirectionProvider(direction)
thrust_direction_and_attitude_provider = ThrustDirectionAndAttitudeProvider.buildFromDirectionInLOF(
LOFType.QSW,
thrust_direction_provider,
thruster_axis)
trigger_start = altitudeDetector = AltitudeDetector(altitude_low, earth).withHandler(StopOnEvent())
#trigger_start.init(propagator.getInitialState(), date_end)
trigger_end = altitudeDetector = AltitudeDetector(altitude_high, earth).withHandler(StopOnEvent())
#trigger_end.init(propagator.getInitialState(), date_end)
trigg=PythonStartStopEventsTrigger(trigger_start,trigger_end)
configurable_low_thrust_maneuver = ConfigurableLowThrustManeuver(thrust_direction_and_attitude_provider,
trigg,
thrust,
isp)
propagator.addForceModel(configurable_low_thrust_maneuver)
############################ Propagate #################################################################
########################################################################################################
propagator.setOrbitType(orbitType)
propagator.setInitialState(initialState)
#final_state = propagator.propagate(initial_date, initial_date.shiftedBy(simDur))
final_date=initial_date.shiftedBy(simDur)
propagator.propagate(final_date)
Thanks in advance for you answers