Module MAPLEAF.Rocket.Recovery
Expand source code
from MAPLEAF.Motion import AeroParameters, ForceMomentSystem, Vector
from MAPLEAF.Rocket import EventTypes, FixedMass
__pdoc__ = {
'RecoverySystem._deployNextStage': True
}
__all__ = [ "RecoverySystem" ]
class RecoverySystem(FixedMass):
''' Represents a recovery system with an arbitrary number of stages '''
#### Init Functions ####
def __init__(self, componentDictReader, rocket, stage):
FixedMass.__init__(self, componentDictReader, rocket, stage)
self.numStages = componentDictReader.getInt("numStages")
# Set rocket properties
rocket.recoverySystem = self
self._initRecoveryStages()
def _initRecoveryStages(self):
self.stageTriggers = [ None, ]
self.stageTriggerValues = [ None, ]
self.chuteAreas = [ 0, ]
self.chuteCds = [ 0, ]
self.delayTimes = [ 0, ]
for i in range(1,self.numStages+1):
self.stageTriggers.append(self.componentDictReader.getString("stage{}Trigger".format(i)))
try:
self.stageTriggerValues.append(self.componentDictReader.getFloat("stage{}TriggerValue".format(i)))
except KeyError:
self.stageTriggerValues.append(None)
self.chuteAreas.append(self.componentDictReader.getFloat("stage{}ChuteArea".format(i)))
self.chuteCds.append(self.componentDictReader.getFloat("stage{}Cd".format(i)))
self.delayTimes.append(self.componentDictReader.getFloat("stage{}DelayTime".format(i)))
self.currentStage = -1
self.nextStageDeployTime = None
# Initialize by deploying stage 0 (no chutes)
# Sets up trigger function for the real first chute
self._deployNextStage()
#### Operational Functions ####
def getAppliedForce(self, rocketState, time, environment, CG):
'''
Calculates force/moment applied by the recovery system using a simple drag coefficient + area model
'''
#### Calculate Aero Force ####
if self.currentStage == 0:
# No recovery system deployed yet
return ForceMomentSystem(Vector(0,0,0))
else:
# 3DoF force-only aero
airVel = AeroParameters.getAirVelRelativeToVehicle(rocketState, environment)
dragForceMagnitude = self.chuteCds[self.currentStage] * self.chuteAreas[self.currentStage] * AeroParameters.getDynamicPressure(rocketState, environment)
totalForce = airVel.normalize() * dragForceMagnitude
return ForceMomentSystem(totalForce)
def _deployNextStage(self):
'''
Deploys the next stage of the recovery system
If appropriate, will set the simulation mode to 3DoF.
If appropriate, will set up the trigger to deploy the next stage of the recovery system, by calling this function again.
If this is the final recovery system stage, records the main chute deployment time.
'''
self.currentStage += 1
if self.currentStage > 0:
print("Deployed Recovery Stage {}".format(self.currentStage))
if self.currentStage == 1:
self.rocket.isUnderChute = True
self.rocket._switchTo3DoF()
if self.currentStage == self.numStages:
self.rocket.mainChuteDeployTime = self.rocket.rigidBody.time
if self.currentStage < self.numStages:
nextTrigger = self.stageTriggers[self.currentStage + 1]
nextTriggerValue = self.stageTriggerValues[self.currentStage + 1]
nextTriggerDelay = self.delayTimes[self.currentStage + 1]
# Translate trigger conditions into language simEventDetector can understand
if nextTrigger == "Apogee":
nextTrigger = EventTypes.Apogee
if nextTrigger == "Altitude":
nextTrigger = EventTypes.DescendingThroughAltitude
if nextTrigger == "Time":
nextTrigger = EventTypes.TimeReached
# Set the trigger
self.rocket.simEventDetector.subscribeToEvent(nextTrigger, self._deployNextStage, eventTriggerValue=nextTriggerValue, triggerDelay=nextTriggerDelay)
Classes
class RecoverySystem (componentDictReader, rocket, stage)
-
Represents a recovery system with an arbitrary number of stages
Expand source code
class RecoverySystem(FixedMass): ''' Represents a recovery system with an arbitrary number of stages ''' #### Init Functions #### def __init__(self, componentDictReader, rocket, stage): FixedMass.__init__(self, componentDictReader, rocket, stage) self.numStages = componentDictReader.getInt("numStages") # Set rocket properties rocket.recoverySystem = self self._initRecoveryStages() def _initRecoveryStages(self): self.stageTriggers = [ None, ] self.stageTriggerValues = [ None, ] self.chuteAreas = [ 0, ] self.chuteCds = [ 0, ] self.delayTimes = [ 0, ] for i in range(1,self.numStages+1): self.stageTriggers.append(self.componentDictReader.getString("stage{}Trigger".format(i))) try: self.stageTriggerValues.append(self.componentDictReader.getFloat("stage{}TriggerValue".format(i))) except KeyError: self.stageTriggerValues.append(None) self.chuteAreas.append(self.componentDictReader.getFloat("stage{}ChuteArea".format(i))) self.chuteCds.append(self.componentDictReader.getFloat("stage{}Cd".format(i))) self.delayTimes.append(self.componentDictReader.getFloat("stage{}DelayTime".format(i))) self.currentStage = -1 self.nextStageDeployTime = None # Initialize by deploying stage 0 (no chutes) # Sets up trigger function for the real first chute self._deployNextStage() #### Operational Functions #### def getAppliedForce(self, rocketState, time, environment, CG): ''' Calculates force/moment applied by the recovery system using a simple drag coefficient + area model ''' #### Calculate Aero Force #### if self.currentStage == 0: # No recovery system deployed yet return ForceMomentSystem(Vector(0,0,0)) else: # 3DoF force-only aero airVel = AeroParameters.getAirVelRelativeToVehicle(rocketState, environment) dragForceMagnitude = self.chuteCds[self.currentStage] * self.chuteAreas[self.currentStage] * AeroParameters.getDynamicPressure(rocketState, environment) totalForce = airVel.normalize() * dragForceMagnitude return ForceMomentSystem(totalForce) def _deployNextStage(self): ''' Deploys the next stage of the recovery system If appropriate, will set the simulation mode to 3DoF. If appropriate, will set up the trigger to deploy the next stage of the recovery system, by calling this function again. If this is the final recovery system stage, records the main chute deployment time. ''' self.currentStage += 1 if self.currentStage > 0: print("Deployed Recovery Stage {}".format(self.currentStage)) if self.currentStage == 1: self.rocket.isUnderChute = True self.rocket._switchTo3DoF() if self.currentStage == self.numStages: self.rocket.mainChuteDeployTime = self.rocket.rigidBody.time if self.currentStage < self.numStages: nextTrigger = self.stageTriggers[self.currentStage + 1] nextTriggerValue = self.stageTriggerValues[self.currentStage + 1] nextTriggerDelay = self.delayTimes[self.currentStage + 1] # Translate trigger conditions into language simEventDetector can understand if nextTrigger == "Apogee": nextTrigger = EventTypes.Apogee if nextTrigger == "Altitude": nextTrigger = EventTypes.DescendingThroughAltitude if nextTrigger == "Time": nextTrigger = EventTypes.TimeReached # Set the trigger self.rocket.simEventDetector.subscribeToEvent(nextTrigger, self._deployNextStage, eventTriggerValue=nextTriggerValue, triggerDelay=nextTriggerDelay)
Ancestors
- FixedMass
- RocketComponent
- abc.ABC
Methods
def _deployNextStage(self)
-
Deploys the next stage of the recovery system
If appropriate, will set the simulation mode to 3DoF. If appropriate, will set up the trigger to deploy the next stage of the recovery system, by calling this function again. If this is the final recovery system stage, records the main chute deployment time.Expand source code
def _deployNextStage(self): ''' Deploys the next stage of the recovery system If appropriate, will set the simulation mode to 3DoF. If appropriate, will set up the trigger to deploy the next stage of the recovery system, by calling this function again. If this is the final recovery system stage, records the main chute deployment time. ''' self.currentStage += 1 if self.currentStage > 0: print("Deployed Recovery Stage {}".format(self.currentStage)) if self.currentStage == 1: self.rocket.isUnderChute = True self.rocket._switchTo3DoF() if self.currentStage == self.numStages: self.rocket.mainChuteDeployTime = self.rocket.rigidBody.time if self.currentStage < self.numStages: nextTrigger = self.stageTriggers[self.currentStage + 1] nextTriggerValue = self.stageTriggerValues[self.currentStage + 1] nextTriggerDelay = self.delayTimes[self.currentStage + 1] # Translate trigger conditions into language simEventDetector can understand if nextTrigger == "Apogee": nextTrigger = EventTypes.Apogee if nextTrigger == "Altitude": nextTrigger = EventTypes.DescendingThroughAltitude if nextTrigger == "Time": nextTrigger = EventTypes.TimeReached # Set the trigger self.rocket.simEventDetector.subscribeToEvent(nextTrigger, self._deployNextStage, eventTriggerValue=nextTriggerValue, triggerDelay=nextTriggerDelay)
def getAppliedForce(self, rocketState, time, environment, CG)
-
Calculates force/moment applied by the recovery system using a simple drag coefficient + area model
Expand source code
def getAppliedForce(self, rocketState, time, environment, CG): ''' Calculates force/moment applied by the recovery system using a simple drag coefficient + area model ''' #### Calculate Aero Force #### if self.currentStage == 0: # No recovery system deployed yet return ForceMomentSystem(Vector(0,0,0)) else: # 3DoF force-only aero airVel = AeroParameters.getAirVelRelativeToVehicle(rocketState, environment) dragForceMagnitude = self.chuteCds[self.currentStage] * self.chuteAreas[self.currentStage] * AeroParameters.getDynamicPressure(rocketState, environment) totalForce = airVel.normalize() * dragForceMagnitude return ForceMomentSystem(totalForce)