示例#1
0
    def test_burnTimeAdjustFactor(self):
        simDef = SimDefinition("MAPLEAF/Examples/Simulations/test2.mapleaf")

        # Create normal motor
        rocketDictReader1 = SubDictReader("Rocket", simDef)
        motorRocket1 = Rocket(rocketDictReader1)
        motor1 = motorRocket1.stages[0].getComponentsOfType(TabulatedMotor)[0]

        burnTimeAdjustFactor = "1.11"

        # Create impulse-adjusted motor
        simDef.setValue("Rocket.Sustainer.Motor.burnTimeAdjustFactor",
                        burnTimeAdjustFactor)
        rocketDictReader2 = SubDictReader("Rocket", simDef)
        motorRocket2 = Rocket(rocketDictReader2)
        motor2 = motorRocket2.stages[0].getComponentsOfType(TabulatedMotor)[0]

        # Check that total impulse hasn't changed
        impulse1 = motor1.getTotalImpulse()
        impulse2 = motor2.getTotalImpulse()
        self.assertAlmostEqual(impulse1, impulse2)

        # Check that burn time has changed
        burnTime1 = motor1.times[-1]
        burnTime2 = motor2.times[-1]
        self.assertAlmostEqual(burnTime2 / burnTime1,
                               float(burnTimeAdjustFactor))
示例#2
0
    def _createStages(self):
        ''' Initialize each of the stages and all of their subcomponents. '''
        stageDicts = self._getStageSubDicts()

        # If we're initializing a dropped stage, figure out which one
        if self.stage != None:
            stageNumbers = []
            stageNumberSet = set()
            for stageDict in stageDicts:
                stageNumber = self.rocketDictReader.getFloat(stageDict + ".stageNumber")
                stageNumbers.append(stageNumber)
                stageNumberSet.add(stageNumber)
            
            if len(stageNumbers) != len(stageNumberSet):
                raise ValueError("For multi-stage rockets, each stage must have a unique stage number. Set the Rocket.StageName.stageNumber value for each stage. 0 for first stage, 1 for second, etc...")
            
            stageNumbers.sort()
            stageToInitialize = stageNumbers[self.stage]

        # Initialize Stage(s)
        initializingAllStages = (self.stage == None)
        for stageDictionary in stageDicts:
            stageDictReader = SubDictReader(stageDictionary, self.simDefinition)
            stageNumber = stageDictReader.getFloat("stageNumber")

            if initializingAllStages or stageNumber == stageToInitialize:
                newStage = Stage(stageDictReader, self)
                self.stages.append(newStage)

                if newStage.name not in self.__dict__: # Avoid clobbering existing info
                    setattr(self, newStage.name, newStage) # Make stage available as rocket.stageName
    def setUp(self):
        configFilePath = "MAPLEAF/Examples/Simulations/Wind.mapleaf"
        self.simDef = SimDefinition(configFilePath, silent=True)
        self.simDef.setValue("Environment.MeanWindModel", "Constant")
        self.simDef.setValue("SimControl.loggingLevel", "0")
        rocketDictReader = SubDictReader("Rocket", self.simDef)
        envReader = SubDictReader("Environment", self.simDef)
        self.rocket = Rocket(rocketDictReader, silent=True)

        self.mWM = meanWindModelFactory(envReader, self.rocket)
示例#4
0
    def setUp(self):
        simDef = SimDefinition("MAPLEAF/Examples/Simulations/test3.mapleaf", silent=True)
        rocketDictReader = SubDictReader("Rocket", simDef)
        self.rocket = Rocket(rocketDictReader, silent=True)

        simDef = SimDefinition("MAPLEAF/Examples/Simulations/test6.mapleaf", silent=True)
        rocketDictReader = SubDictReader("Rocket", simDef)
        self.rocket2 = Rocket(rocketDictReader, silent=True)
        self.finSet1 = self.rocket2.stages[0].getComponentsOfType(FinSet)[0]
        self.finSet2 = self.rocket2.stages[0].getComponentsOfType(FinSet)[1]

        self.dummyVelocity1 = Vector(0, 0, 50)
        self.dummyVelocity2 = Vector(1, 0, 20)
        self.dummyVelocity3 = Vector(0, 0, -100)

        self.dummyOrientation1 = Quaternion(Vector(1, 0, 0), math.radians(2))
        self.dummyOrientation2 = Quaternion(Vector(1, 0, 0), math.radians(-2))
        self.dummyOrientation3 = Quaternion(Vector(0, 1, 0), math.radians(2))
        self.dummyOrientation4 = Quaternion(Vector(1, 0, 0), 0)
        self.dummyOrientation5 = Quaternion(Vector(1, 1, 0), math.radians(2))
        self.dummyOrientation6 = Quaternion(Vector(1,0,0), math.radians(90))

        self.dummyAngularVelocity1 = AngularVelocity(rotationVector = Vector(0,0,0))
        self.dummyAngularVelocity2 = AngularVelocity(rotationVector = Vector(0,0,1))
        self.dummyAngularVelocity3 = AngularVelocity(rotationVector = Vector(0,0,-1))
        self.dummyAngularVelocity4 = AngularVelocity(rotationVector = Vector(1,0,0))
        self.dummyAngularVelocity5 = AngularVelocity(rotationVector = Vector(-1,0,0))
        self.dummyAngularVelocity6 = AngularVelocity(rotationVector = Vector(0,1,0))
        self.dummyAngularVelocity7 = AngularVelocity(rotationVector = Vector(0,-1,0))
        self.dummyAngularVelocity8 = AngularVelocity(rotationVector = Vector(1,1,0))

        self.currentConditions = self.rocket2.environment.getAirProperties(Vector(0,0,200)) # m

        self.rocketState1 = RigidBodyState(Vector(0, 0, 200), Vector(0, 0, 200), Quaternion(Vector(0, 0, 1), 0), AngularVelocity(rotationVector=Vector(0, 0, 0)))
        self.rocketState2 = RigidBodyState(Vector(0, 0, 200), Vector(0, 0, 200), Quaternion(Vector(1, 0, 0), math.radians(2)), AngularVelocity(rotationVector=Vector(0, 0, 0)))
        self.rocketState3 = RigidBodyState(Vector(0, 0, 200), Vector(0, 0, 500), Quaternion(Vector(1, 0, 0), math.radians(2)), AngularVelocity(rotationVector=Vector(0, 0, 0)))
        self.rocketState4 = RigidBodyState(Vector(0, 0, 200), Vector(0, 0, -200), Quaternion(Vector(1, 0, 0), math.radians(180)), AngularVelocity(rotationVector=Vector(0, 0, 0)))
        self.rocketState5 = RigidBodyState(Vector(0, 0, 200), Vector(0, 0, -200), Quaternion(Vector(1, 0, 0), math.radians(178)), AngularVelocity(rotationVector=Vector(0, 0, 0)))
        self.rocketState6 = RigidBodyState(Vector(0, 0, 200), Vector(0, 0, -200), Quaternion(Vector(1, 0, 0), math.radians(182)), AngularVelocity(rotationVector=Vector(0, 0, 0)))
        self.rocketState7 = RigidBodyState(Vector(0, 0, 200), Vector(0, 0, -200), Quaternion(Vector(1, 0, 0), math.radians(90)), AngularVelocity(rotationVector=Vector(0, 0, 0)))
        self.rocketState8 = RigidBodyState(Vector(0, 0, 200), Vector(20.04, -0.12, -52.78), Quaternion(Vector(0, 1, 0), math.radians(90)), AngularVelocity(rotationVector=Vector(0, 0, 0)))
        self.rocketState9 = RigidBodyState(Vector(0, 0, 200), Vector(0, 0, 200), Quaternion(Vector(1, 0, 0), math.radians(-2)), AngularVelocity(rotationVector=Vector(0, 0, 0)))
        self.rocketState10 = RigidBodyState(Vector(0, 0, 200), Vector(0, 0, 200), Quaternion(Vector(0, 0, 1), 0), AngularVelocity(rotationVector=Vector(0, 0, 1)))
        self.rocketState11 = RigidBodyState(Vector(0, 0, 200), Vector(0, 0, 200), Quaternion(Vector(0, 1, 0), math.radians(2)), AngularVelocity(rotationVector=Vector(0, 0, 0)))
        self.rocketState12 = RigidBodyState(Vector(0, 0, 200), Vector(0, 0, 200), Quaternion(Vector(0, 1, 0), math.radians(-2)), AngularVelocity(rotationVector=Vector(0, 0, 0)))
        self.rocketState13 = RigidBodyState(Vector(0, 0, 200), Vector(0, 0, 500), Quaternion(Vector(1, 0, 0), math.radians(4)), AngularVelocity(rotationVector=Vector(0, 0, 0)))
        self.rocketState14 = RigidBodyState(Vector(0, 0, 200), Vector(0, 0, 500), Quaternion(Vector(1, 0, 0), math.radians(6)), AngularVelocity(rotationVector=Vector(0, 0, 0)))
        self.rocketState15 = RigidBodyState(Vector(0, 0, 200), Vector(0, 0, 500), Quaternion(Vector(1, 0, 0), math.radians(8)), AngularVelocity(rotationVector=Vector(0, 0, 0)))
        self.rocketState16 = RigidBodyState(Vector(0, 0, 200), Vector(0, 0, 344), Quaternion(Vector(1, 0, 0), math.radians(0)), AngularVelocity(rotationVector=Vector(0, 0, 0)))
    def test_TabulatedAeroForce(self):
        # Init rocket that uses tabulated aero data
        simDef = SimDefinition("MAPLEAF/Examples/Simulations/NASATwoStageOrbitalRocket.mapleaf", silent=True)
        rocketDictReader = SubDictReader("Rocket", simDef)
        rocket = Rocket(rocketDictReader, silent=True)

        comp1, comp2, comp3 = rocket.stages[0].getComponentsOfType(TabulatedAeroForce)

        if comp1.Lref == 3.0:
            tabMoment = comp1
            tabFOrce = comp2
        else:
            tabMoment = comp2
            tabForce = comp1

        zeroAOAState = RigidBodyState(Vector(0,0,0), Vector(0,0,100), Quaternion(1,0,0,0), Vector(0,0,0))
        
        # CD, CL, CMx, CMy, CMz
        expectedAero = [ 0.21, 0, 0, 0, 0 ]
        calculatedAero = tabForce._getAeroCoefficients(zeroAOAState, self.currentConditions)
        assertIterablesAlmostEqual(self, expectedAero, calculatedAero)

        expectedAero = [ 0, 0, 0, 0, 0 ]
        calculatedAero = tabMoment._getAeroCoefficients(zeroAOAState, self.currentConditions)
        assertIterablesAlmostEqual(self, expectedAero, calculatedAero)
示例#6
0
 def setUp(self):
     self.rocket = "fakeNewsRocket"  # May have to convert this into a real Rocket at some point, but it's faster this way
     self.simDefinition = SimDefinition(
         "MAPLEAF/Examples/Simulations/Wind.mapleaf", silent=True)
     self.simDefinition.setValue("Environment.MeanWindModel", "Constant")
     envReader = SubDictReader("Environment", self.simDefinition)
     self.mWM = meanWindModelFactory(envReader, self.rocket)
示例#7
0
    def test_rocketCGCalculation(self):
        # Check actual CG Loc Calculation

        # Top stage CG: #
        # Nosecone: 1 kg @ 0m
        # Recovery: 5 kg @ -2m
        # BodyTube: 1 kg @ -0.762m
        # Mass:     50 kg @ -2.6m
        # Motor:    11.4885 kg @ 2.130434783
        # Fins:     1 kg @ -4.011m
        # Total Weight = 69.4885 kg
        # Stage 1 CG: -2.4564359077698

        expectedCG = Vector(0, 0, -1.731185736)

        # Remove overrides from rocket definition file
        simDef = SimDefinition("MAPLEAF/Examples/Simulations/Wind.mapleaf",
                               silent=True)
        simDef.removeKey("Rocket.Sustainer.constCG")
        simDef.removeKey("Rocket.Sustainer.constMass")
        simDef.removeKey("Rocket.Sustainer.constMOI")

        rocketDictReader = SubDictReader("Rocket", simDef)
        rocket = Rocket(rocketDictReader, silent=True)
        rocketInertia = rocket.getInertia(0, rocket.rigidBody.state)
        assertVectorsAlmostEqual(self, rocketInertia.CG, expectedCG, n=4)
    def test_customGust(self):
        simDef = SimDefinition("MAPLEAF/Examples/Simulations/Wind.mapleaf",
                               silent=True)
        simDef.setValue("Environment.TurbulenceModel", "customSineGust")
        simDef.setValue("Environment.CustomSineGust.startAltitude", "0")
        simDef.setValue("Environment.CustomSineGust.magnitude", "9")
        simDef.setValue("Environment.CustomSineGust.sineBlendDistance", "30")
        simDef.setValue("Environment.CustomSineGust.thickness", "200")
        simDef.setValue("Environment.CustomSineGust.direction", "(0 1 0)")
        envReader = SubDictReader("Environment", simDef)

        turbModel = turbulenceModelFactory(envReader)

        v1 = turbModel.getTurbVelocity(0, Vector(1, 0, 0), 0)
        assertVectorsAlmostEqual(self, v1, Vector(0, 0, 0))
        v1 = turbModel.getTurbVelocity(15, Vector(1, 0, 0), 0)
        assertVectorsAlmostEqual(self, v1, Vector(0, 4.5, 0))
        v1 = turbModel.getTurbVelocity(30, Vector(1, 0, 0), 0)
        assertVectorsAlmostEqual(self, v1, Vector(0, 9, 0))
        v1 = turbModel.getTurbVelocity(230, Vector(1, 0, 0), 0)
        assertVectorsAlmostEqual(self, v1, Vector(0, 9, 0))
        v1 = turbModel.getTurbVelocity(245, Vector(1, 0, 0), 0)
        assertVectorsAlmostEqual(self, v1, Vector(0, 4.5, 0))
        v1 = turbModel.getTurbVelocity(260, Vector(1, 0, 0), 0)
        assertVectorsAlmostEqual(self, v1, Vector(0, 0, 0))
    def test_fixedForceInit(self):
        simDef = SimDefinition("MAPLEAF/Examples/Simulations/FixedForce.mapleaf", silent=True)
        rocketDictReader = SubDictReader("Rocket", simDef)
        rocket = Rocket(rocketDictReader, silent=True)

        fixedForce = rocket.stages[0].getComponentsOfType(FixedForce)[0]

        expectedFMS = ForceMomentSystem(Vector(0,0,0), Vector(0,0,0), Vector(0,1,0))
        assertForceMomentSystemsAlmostEqual(self, fixedForce.force, expectedFMS)
示例#10
0
    def test_SolidMotor(self):
        simDef = SimDefinition("MAPLEAF/Examples/Simulations/Jake1.mapleaf")
        rocketDictReader = SubDictReader("Rocket", simDef)
        motorRocket = Rocket(rocketDictReader)

        motor = motorRocket.stages[0].motor
        # Try getting thrust, if it works with 0 oxidizer flow rate, then we're good
        t = motor.getAppliedForce('fakeState', 0.12, 'fakeEnv',
                                  'fakeCG').force.Z
 def test_getFixedForceInertia(self):
     simDef = SimDefinition("MAPLEAF/Examples/Simulations/FixedForce.mapleaf", silent=True)
     rocketDictReader = SubDictReader("Rocket", simDef)
     rocket = Rocket(rocketDictReader, silent=True)
     
     fixedForce = rocket.stages[0].getComponentsOfType(FixedForce)[0]
     
     inertia = fixedForce.getInertia(0, "fakeState")
     expectedInertia = Inertia(Vector(0,0,0), Vector(0,0,0), 0)
     self.assertEqual(inertia, expectedInertia)
示例#12
0
    def test_MotorMOI(self):
        motorRocket = self.motorRocket
        motor = self.motorRocket.stages[0].getComponentsOfType(
            TabulatedMotor)[0]

        ### Oxidizer MOI Tests ###
        def getOxMOI(time):
            return motor._getOxInertia(time).MOI

        ActualOxMOI = getOxMOI(0)
        expectedOxMOI = Vector(1.0, 1.0, 0.1)
        assertIterablesAlmostEqual(self, ActualOxMOI, expectedOxMOI)

        ActualOxMOI = getOxMOI(2.505)
        expectedOxMOI = Vector(0.5, 0.5, 0.05)
        assertIterablesAlmostEqual(self, ActualOxMOI, expectedOxMOI)

        ActualOxMOI = getOxMOI(5.0)
        expectedOxMOI = Vector(0, 0, 0)
        assertIterablesAlmostEqual(self, ActualOxMOI, expectedOxMOI)

        ActualOxMOI = getOxMOI(10)
        expectedOxMOI = Vector(0, 0, 0)
        assertIterablesAlmostEqual(self, ActualOxMOI, expectedOxMOI)

        ### Fuel MOI Tests ###
        def getFuelMOI(time):
            return motor._getFuelInertia(time).MOI

        ActualFuelMOI = getFuelMOI(0)
        expectedFuelMOI = Vector(0.15, 0.15, 0.02)
        assertIterablesAlmostEqual(self, ActualFuelMOI, expectedFuelMOI)

        ActualFuelMOI = getFuelMOI(2.505)
        expectedFuelMOI = Vector(0.075, 0.075, 0.01)
        assertIterablesAlmostEqual(self, ActualFuelMOI, expectedFuelMOI)

        ActualFuelMOI = getFuelMOI(5)
        expectedFuelMOI = Vector(0, 0, 0)
        assertIterablesAlmostEqual(self, ActualFuelMOI, expectedFuelMOI)

        ActualFuelMOI = getFuelMOI(10)
        expectedFuelMOI = Vector(0, 0, 0)
        assertIterablesAlmostEqual(self, ActualFuelMOI, expectedFuelMOI)

        simDef = SimDefinition("MAPLEAF/Examples/Simulations/Jake1.mapleaf")
        rocketDictReader = SubDictReader("Rocket", simDef)
        jakeRocket = Rocket(rocketDictReader)

        motor = jakeRocket.stages[0].motor
        motorInertia = motor.getInertia(3, jakeRocket.rigidBody.state)
        expectedInertiaAfterBurnout = Inertia(Vector(0, 0, 0), Vector(0, 0, 0),
                                              0.0)
        assertInertiasAlmostEqual(self, motorInertia,
                                  expectedInertiaAfterBurnout)
    def test_getFixedForce(self):
        simDef = SimDefinition("MAPLEAF/Examples/Simulations/FixedForce.mapleaf", silent=True)
        rocketDictReader = SubDictReader("Rocket", simDef)
        rocket = Rocket(rocketDictReader, silent=True)

        fixedForce = rocket.stages[0].getComponentsOfType(FixedForce)[0]

        force = fixedForce.getAppliedForce("fakeState", 0, "fakeEnv", Vector(0,0,0))
        expectedForce = ForceMomentSystem(Vector(0,0,0), moment=Vector(0,1,0))
        self.assertEqual(force.force, expectedForce.force)
        self.assertEqual(force.moment, expectedForce.moment)
示例#14
0
def optimizationRunnerFactory(simDefinitionFilePath=None, simDefinition=None, optimizationReader=None, silent=False, parallel=False) -> OptimizingSimRunner:
    ''' Provide a subdictionary reader pointed at an optimization dictionary. Will read the dictionary, initialize an optimizing simulation runner and return it. '''
    if simDefinition != None or simDefinitionFilePath != None:
        simDefinition = loadSimDefinition(simDefinitionFilePath, simDefinition, silent)
        optimizationReader = SubDictReader('Optimization', simDefinition)

        # Ensure no output is produced during each simulation (cost function evaluation)
        simDefinition.setValue("SimControl.plot", "None")
        simDefinition.setValue("SimControl.RocketPlot", "Off")
    else:
        if optimizationReader == None:
            raise ValueError('subDictReader not initialized for a nested optimization')

    method = optimizationReader.tryGetString('method', defaultValue='PSO')

    if method == 'PSO':
        return PSORunner(optimizationReader, silent=silent, parallel=parallel)
    elif 'scipy.optimize.minimize' in method:
        return ScipyMinimizeRunner(optimizationReader, silent=silent, parallel=parallel)
    else:
        raise ValueError('Optimization method: {} not implemented, try PSO'.format(method))
def rocketComponentFactory(subDictPath, rocket, stage):
    """
        Initializes a rocket component based on the stringNameToClassMap
        Inputs:
            subDictPath:        (string) Path to subDict in simulation definition, like "Rocket.Stage1.Nosecone"
            rocket:             (Rocket) that the component is a part of
            stage:              (Stage) That the component is a part of
        Also uses the stringNameToClassMap dictionary
    """
    # Create SubDictReader for the rocket component's dictionary
    componentDictReader = SubDictReader(subDictPath, rocket.simDefinition)

    # Figure out which class to initialize
    className = componentDictReader.getString("class")
    referencedClass = stringNameToClassMap[className]

    # Initialize the rocket component
    newComponent = referencedClass(componentDictReader, rocket, stage)

    # Initialize logging component forces (if desired)
    initializeForceLogging(newComponent, subDictPath, rocket)

    return newComponent
示例#16
0
def integratorFactory(integrationMethod="Euler", simDefinition=None, discardedTimeStepCallback=None):
    ''' 
        Returns a callable integrator object

        Inputs:
            * integrationMethod: (str) Name of integration method: Examples = "Euler", "RK4", "RK23Adaptive", and "RK45Adaptive"
            * simDefinition: (`MAPLEAF.IO.SimDefinition`) for adaptive integration, provide a simdefinition file with time step adaptation parameters
            * discardedTimeStepCallback: (1-argument function reference) for adaptive integration, this function (if provided) is called when a time step is computed,
                but then discarded and re-computed with a smaller timestep to remain below the max estimated error threshold. Used by MAPLEAF to remove
                force calculation logs from those discarded time steps
    '''
    if "Adapt" in integrationMethod:
        if simDefinition == None:
            raise ValueError("SimDefinition object required to initialize adaptive integrator")

        from MAPLEAF.IO import SubDictReader
        adaptDictReader = SubDictReader("SimControl.TimeStepAdaptation", simDefinition)

        # Adaptive Integration
        controller = adaptDictReader.getString("controller")
        if controller == "PID":
            PIDCoeffs = [ float(x) for x in adaptDictReader.getString("PID.coefficients").split() ]
            safetyFactor = None
        elif controller == "elementary":
            safetyFactor = adaptDictReader.getFloat("Elementary.safetyFactor")
            PIDCoeffs = None

        targetError = adaptDictReader.getFloat("targetError")
        minFactor = adaptDictReader.getFloat("minFactor")
        maxFactor = adaptDictReader.getFloat("maxFactor")
        maxTimeStep = adaptDictReader.getFloat("maxTimeStep")
        minTimeStep = adaptDictReader.getFloat("minTimeStep")
        
        return AdaptiveIntegrator(
            method=integrationMethod, 
            controller=controller, 
            targetError=targetError, 
            maxMinSafetyFactors=[maxFactor, minFactor, safetyFactor], 
            PIDCoeffs=PIDCoeffs, 
            maxTimeStep=maxTimeStep, 
            minTimeStep=minTimeStep, 
            discardedTimeStepCallback=discardedTimeStepCallback
        )
    
    else:
        # Constant time step integrator
        return ClassicalIntegrator(method=integrationMethod)
    def setUp(self):
        simDef = SimDefinition("MAPLEAF/Examples/Simulations/test3.mapleaf", silent=True)
        rocketDictReader = SubDictReader("Rocket", simDef)
        self.rocket = Rocket(rocketDictReader, silent=True)

        self.nosecone = self.rocket.stages[0].getComponentsOfType(NoseCone)[0]
        self.bodytube = self.rocket.stages[0].getComponentsOfType(BodyTube)[0]
        
        # Find the Fixed Mass component that's actually just a Fixed Mass, not a child class (Nosecone, Bodytube)
        fixedMassComponents = self.rocket.stages[0].getComponentsOfType(FixedMass)
        for comp in fixedMassComponents:
            if type(comp) == FixedMass:
                self.fixedMass = comp

        self.environment = Environment(silent=True)
        self.currentConditions = self.environment.getAirProperties(Vector(0,0,200)) # m
示例#18
0
    def createRocket(self, stage=None):
        ''' 
            Initializes a rocket, complete with an Environment object and logs, both owned by the instance of this class
            Returns an instance of Rocket with it's Environment/Logs initialized. Can be called by external classes to obtain a prepped rocket (used a lot this way in test cases).
        '''
        # Initialize Rocket
        rocketDictReader = SubDictReader("Rocket", self.simDefinition)  
        rocket = Rocket(rocketDictReader, silent=self.silent, stageToInitialize=stage, simRunner=self, environment=self.environment)       # Initialize Rocket

        if self.simDefinition.getValue('SimControl.RocketPlot') in [ 'On', 'on' ]:
            rocket.plotShape()  # Reference to this simRunner used to add to logs

        if stage == None:
            self._setUpConsoleLogging()
            self.stagingIndex = 0 # Initially zero, after dropping first stage: 1, after dropping second stage: 2, etc...
            
        return rocket
    def test_pinkNoiseStdDev(self):
        simDef = SimDefinition("MAPLEAF/Examples/Simulations/Wind.mapleaf",
                               silent=True)
        simDef.setValue("Environment.TurbulenceModel", "PinkNoise1D")
        simDef.setValue("Environment.PinkNoiseModel.velocityStdDeviation", "1")
        simDef.setValue("Environment.PinkNoiseModel.randomSeed1", "63583")
        simDef.setValue("Environment.turbulenceOffWhenUnderChute", "False")

        # Make sure turbulence intensity is not present since it overrides the given std deviation
        simDef.removeKey("Environment.PinkNoiseModel.turbulenceIntensity")
        envReader = SubDictReader("Environment", simDef)

        turbModel = turbulenceModelFactory(envReader)
        v1 = turbModel.getTurbVelocity(1, Vector(1, 0, 0), None)
        self.assertAlmostEqual(v1[0], 0.7946604314895807 / 2.26)
        v2 = turbModel.getTurbVelocity(1, Vector(1, 0, 0), None)
        self.assertAlmostEqual(v2[0], 0.5874110050866364 / 2.26)
示例#20
0
    def test_rocketInertiaOverrides(self):
        # Check CG Override
        simDef = SimDefinition("MAPLEAF/Examples/Simulations/Wind.mapleaf")
        rocketDictReader = SubDictReader("Rocket", simDef)
        rocket = Rocket(rocketDictReader, silent=True)
        cgLoc = rocket.getCG(0, rocket.rigidBody.state)
        expectedCGLoc = Vector(0, 0, -2.65)
        assertVectorsAlmostEqual(self, cgLoc, expectedCGLoc)

        # Check Mass override
        expectedMass = 50
        actualMass = rocket.getMass(0, rocket.rigidBody.state)
        self.assertAlmostEqual(actualMass, expectedMass)

        # Check MOI Override + getInertia function
        expectedMOI = Vector(85, 85, 0.5)
        actualInertia = rocket.getInertia(0, rocket.rigidBody.state)
        assertVectorsAlmostEqual(self, actualInertia.MOI, expectedMOI)
        assertVectorsAlmostEqual(self, actualInertia.CG, expectedCGLoc)
        self.assertAlmostEqual(actualInertia.mass, expectedMass)
示例#21
0
    def setUp(self):
        simDef = SimDefinition("MAPLEAF/Examples/Simulations/test3.mapleaf")
        rocketDictReader = SubDictReader("Rocket", simDef)
        self.rocket = Rocket(rocketDictReader)

        self.environment = Environment(silent=True)
        self.currentConditions = self.environment.getAirProperties(
            Vector(0, 0, 200))  # m

        self.rocketState1 = RigidBodyState(
            Vector(0, 0, 200), Vector(0, 0, 200),
            Quaternion(Vector(0, 0, 1), 0),
            AngularVelocity(rotationVector=Vector(0, 0, 0)))
        self.rocketState2 = RigidBodyState(
            Vector(0, 0, 200), Vector(0, 0, 200),
            Quaternion(Vector(1, 0, 0), math.radians(2)),
            AngularVelocity(rotationVector=Vector(0, 0, 0)))
        self.rocketState3 = RigidBodyState(
            Vector(0, 0, 200), Vector(0, 0, 500),
            Quaternion(Vector(1, 0, 0), math.radians(2)),
            AngularVelocity(rotationVector=Vector(0, 0, 0)))
        self.rocketState4 = RigidBodyState(
            Vector(0, 0, 200), Vector(0, 0, -200),
            Quaternion(Vector(1, 0, 0), math.radians(180)),
            AngularVelocity(rotationVector=Vector(0, 0, 0)))
        self.rocketState5 = RigidBodyState(
            Vector(0, 0, 200), Vector(0, 0, -200),
            Quaternion(Vector(1, 0, 0), math.radians(178)),
            AngularVelocity(rotationVector=Vector(0, 0, 0)))
        self.rocketState6 = RigidBodyState(
            Vector(0, 0, 200), Vector(0, 0, -200),
            Quaternion(Vector(1, 0, 0), math.radians(182)),
            AngularVelocity(rotationVector=Vector(0, 0, 0)))
        self.rocketState7 = RigidBodyState(
            Vector(0, 0, 200), Vector(0, 0, -200),
            Quaternion(Vector(1, 0, 0), math.radians(90)),
            AngularVelocity(rotationVector=Vector(0, 0, 0)))
        self.rocketState8 = RigidBodyState(
            Vector(0, 0, 200), Vector(20.04, -0.12, -52.78),
            Quaternion(Vector(0, 1, 0), math.radians(90)),
            AngularVelocity(rotationVector=Vector(0, 0, 0)))
示例#22
0
    def test_controlTimeStepChecking(self):
        simDef = SimDefinition("MAPLEAF/Examples/Simulations/Canards.mapleaf",
                               silent=True)
        simDef.setValue("SimControl.timeDiscretization", "Euler")
        simDef.setValue("SimControl.loggingLevel", "0")

        simDef.setValue("SimControl.timeStep", "0.01")
        simDef.setValue("Rocket.ControlSystem.updateRate", "101")

        rocketDictReader = SubDictReader("Rocket", simDef)
        # controlledCanardRocket = Rocket(rocketDictReader, silent=True)
        # self.assertAlmostEqual(controlledCanardRocket.controlSystem.controlTimeStep, 1/101)

        simDef.setValue("SimControl.timeStep", "0.011")
        simDef.setValue("Rocket.ControlSystem.updateRate", "100")
        controlledCanardRocket = Rocket(rocketDictReader, silent=True)
        self.assertAlmostEqual(
            controlledCanardRocket.controlSystem.controlTimeStep, 1 / 100)

        # simDef.setValue("SimControl.timeStep", "0.009")
        # controlledCanardRocket = Rocket(rocketDictReader, silent=True)
        # self.assertAlmostEqual(controlledCanardRocket.controlSystem.controlTimeStep, 1/100)

        # simDef.setValue("SimControl.timeStep", "0.1")
        # controlledCanardRocket = Rocket(rocketDictReader, silent=True)
        # self.assertAlmostEqual(controlledCanardRocket.controlSystem.controlTimeStep, 1/100)

        simDef.setValue("SimControl.timeStep", "0.001")
        simDef.setValue("SimControl.timeDiscretization", "RK45Adaptive")
        simDef.setValue("SimControl.TimeStepAdaptation.controller", "PID")
        simDef.setValue("Rocket.ControlSystem.updateRate", "100")
        controlledCanardRocket = Rocket(rocketDictReader, silent=True)
        self.assertEqual(controlledCanardRocket.rigidBody.integrate.method,
                         "RK4")
        self.assertEqual(type(controlledCanardRocket.rigidBody.integrate),
                         ClassicalIntegrator)
        self.assertEqual(controlledCanardRocket.controlSystem.controlTimeStep,
                         1 / 100)
示例#23
0
    def _createOptimizer(self):
        ''' 
            Reads the Optimization.ParticleSwarm dictionary and creates a pyswarms.GlobalBestPSO object 
            Returns the Optimizer, the user's desired number of iterations, and showConvergence (bool)
        '''
        pathToParticleSwarmDict = self.optimizationReader.simDefDictPathToReadFrom + '.ParticleSwarm'
        pSwarmReader = SubDictReader(pathToParticleSwarmDict, self.optimizationReader.simDefinition)

        nParticles = pSwarmReader.tryGetInt("nParticles", defaultValue=20)
        nIterations = pSwarmReader.tryGetInt("nIterations", defaultValue=50)
        
        c1 = pSwarmReader.tryGetFloat("cognitiveParam", defaultValue=0.5)
        c2 = pSwarmReader.tryGetFloat("socialParam", defaultValue=0.6)
        w = pSwarmReader.tryGetFloat("inertiaParam", defaultValue=0.9)
        pySwarmOptions = { 'c1':c1, 'c2':c2, 'w':w }

        nVars = len(self.varNames)
        varBounds = (self.minVals, self.maxVals)

        from pyswarms.single import \
            GlobalBestPSO  # Import here because for most sims it's not required
        optimizer = GlobalBestPSO(nParticles, nVars, pySwarmOptions, bounds=varBounds, init_pos=self.initPositions)
        
        if self.bestPosition != None and self.bestCost != None:
            optimizer.swarm.best_pos = self.bestPosition
            optimizer.swarm.best_cost = self.bestCost

        showConvergence = self.optimizationReader.tryGetBool("showConvergencePlot", defaultValue=False)

        if not self.silent:
            print("Optimization Parameters:")
            print("{} Particles".format(nParticles))
            print("{} Iterations".format(nIterations))
            print("c1 = {}, c2 = {}, w = {}\n".format(c1, c2, w))
            
            costFunctionDefinition = self.optimizationReader.getString("costFunction")
            print("Cost Function:")
            print(costFunctionDefinition + "\n")

        return optimizer, nIterations, showConvergence
示例#24
0
    def __init__(self, rocketDictReader, silent=False, stageToInitialize=None, simRunner=None, environment=None):
        '''
            Initialization of Rocket(s) is most easily completed through an instance of Simulation
            To get a single Rocket object, initialize a Simulation and call `MAPLEAF.SimulationRunners.Simulation.createRocket()`.  
            This will return a Rocket initialized on the pad with all its stages, ready for flight.

            If initializing manually, can either provide fileName or simDefinition. If a simDefinition is provided, it will be used and fileName will be ignored.

            Inputs:

            * rocketDictReader:     (`MAPLEAF.IO.SubDictReader`) SubDictReader pointed at the "Rocket" dictionary of the desired simulation definition file.  
            * silent:               (bool) controls console output  
            * stageToInitialize:    (int or None) controls whether to initialize a complete Rocket or a single (usually dropped) stage. None = initialize complete rocket. n = initialize only stage n, where n >= 1.  
            * simRunner:            (`MAPLEAF.SimulationRunners.Simulation`) reference to the current simulation driver/runner
            * environment:          (`MAPLEAF.ENV.Environment`) environment model from which the rocket will retrieve atmospheric properties and wind speeds
        '''
        self.rocketDictReader = rocketDictReader
        self.simDefinition = rocketDictReader.simDefinition

        self.simRunner = simRunner
        ''' Parent instance of `MAPLEAF.SimulationRunners.Simulation` (or derivative sim runner). This is usually the object that has created the current instance of Rocket. '''
        
        self.environment = environment
        ''' Instance of `MAPLEAF.ENV.Environment` '''
        if self.environment == None:
            # If no environment is passed in, create one
            self.environment = Environment(self.simDefinition, silent=silent)

        self.name = rocketDictReader.getString("name")

        self.silent = silent
        ''' Controls output to console '''

        self.stage = stageToInitialize
        ''' If controls whether the whole rocket is initialized (if == None), or a single stage is initialized (Integer stage number) '''

        self.stages = []
        '''
            A list of `MAPLEAF.Rocket.Stage` objects that make up the rocket, ordered from top to bottom.  
            Populated by `_initializeStages`.
        '''

        self.recoverySystem = None
        '''
            Reference to the current Rocket's (which can represent a dropped stage) recovery system. Only a single recovery system is allowed per stage.  
            Set in `MAPLEAF.Rocket.RecoverySystem.__init__`
        '''

        self.rigidBody = None            
        ''' 
            (`MAPLEAF.Motion.RigidBody` or `MAPLEAF.Motion.RigidBody_3DoF`) Responsible for motion integration.  
            Set in `_initializeRigidBody()`.
        '''

        self.isUnderChute = False
        ''' (bool) Controlled by `MAPLEAF.Rocket.Recovery.RecoverySystem._deployNextStage()` '''

        self.mainChuteDeployTime = None
        ''' (float) Filled in during flight by `MAPLEAF.Rocket.Recovery.RecoverySystem._deployNextStage()`  '''
        
        self.engineShutOffTime = None
        ''' (float) Filled in by `MAPLEAF.Rocket.Propulsion.TabulatedMotor.__init__()` upon initialization '''

        self.turbulenceOffWhenUnderChute = rocketDictReader.getBool("Environment.turbulenceOffWhenUnderChute")
        ''' (bool) '''

        self.maxDiameter = self._getMaxBodyTubeDiameter()     
        ''' (float) Holds maximum constant-size body tube diameter, from bodytube components in stages '''

        self.Aref = math.pi * self.maxDiameter**2 / 4
        ''' 
            Reference area for force and moment coefficients.
            Maximum rocket cross-sectional area. Remains constant during flight to retain a 1:1 relationship b/w coefficients in different parts of flight.
            Always based on the maximum body tube diameter in the fully-assembled rocket.
        '''
        
        # TODO: Remove
        self.targetLocation = None

        self.simEventDetector = SimEventDetector(self) 
        ''' (`MAPLEAF.Rocket.SimEventDetector`) Used to trigger things like recovery systems and staging '''

        self.eventTimeStep = rocketDictReader.getFloat("SimControl.TimeStepAdaptation.eventTimingAccuracy")
        ''' If using an adaptive time stepping method, the time step will be overridden near non-time-deterministic discrete events, possibly all the way down to this minimum value '''

        self.addZeroLengthBoatTailsToAccountForBaseDrag = rocketDictReader.getBool("Aero.addZeroLengthBoatTailsToAccountForBaseDrag")
        ''' Controls whether zero-length boat tails are automatically added to the bottom of rockets without them, to make sure base drag is accounted for '''

        self.fullyTurbulentBL = rocketDictReader.getBool("Aero.fullyTurbulentBL")
        ''' Controls whether skin friction is solved assuming a fully turbulent BL or using laminar/transitional flow at lower Reynolds numbers '''

        self.surfaceRoughness = rocketDictReader.getFloat("Aero.surfaceRoughness")
        ''' Default surface roughness for all rocket components '''

        self.finenessRatio = None
        ''' Used in some aerodynamic functions. Updated after initializing subcomponents, and throughout the flight. None if no BodyComponent(s) are present in the rocket '''
        
        self.engineShutOff = False
        '''Used to shut off engines in MAPLEAF.Rocket.Propulsion.DefinedMotor class. Currently set in MAPLE_AF.GNC.Navigation'''

        #### Init Hardware in the loop ####
        subDicts = rocketDictReader.getImmediateSubDicts()
        if "Rocket.HIL" in subDicts:
            self.hardwareInTheLoopControl = "yes"
            quatUpdateRate = rocketDictReader.getInt("HIL.quatUpdateRate")
            posUpdateRate = rocketDictReader.getInt("HIL.posUpdateRate")
            velUpdateRate = rocketDictReader.getInt("HIL.velUpdateRate")
            teensyComPort = rocketDictReader.getString("HIL.teensyComPort")
            imuComPort = rocketDictReader.getString("HIL.imuComPort")
            teensyBaudrate = rocketDictReader.getInt("HIL.teensyBaudrate")
            imuBaudrate = rocketDictReader.getInt("HIL.imuBaudrate")
            self.hilInterface = HILInterface(quatUpdateRate,posUpdateRate,velUpdateRate, teensyComPort, imuComPort, teensyBaudrate, imuBaudrate)
        else:
            self.hardwareInTheLoopControl = "no"

        #### Initialize Logging ####
        self.timeStepLog = None
        ''' Log containing one entry per time step, logs rocket state. None if logging level == 0 '''
        self.derivativeEvaluationLog = None
        ''' Log containing one entry per rocket motion derivative evaluation, contains component forces. None if logging level < 2 '''

        loggingLevel = int(self.simDefinition.getValue("SimControl.loggingLevel"))
        self.loggingLevel = loggingLevel

        if loggingLevel > 0:
            # Create the time step log and add columns to track the rocket state between each time step
            self.timeStepLog = TimeStepLog()
            zeroVector = Vector(0,0,0)
            self.timeStepLog.addColumn("Position(m)", zeroVector)
            self.timeStepLog.addColumn("Velocity(m/s)", zeroVector)
            self.timeStepLog.addColumn("OrientationQuaternion", Quaternion(0,0,0,0))
            self.timeStepLog.addColumn("EulerAngle(rad)", zeroVector)
            self.timeStepLog.addColumn("AngularVelocity(rad/s)", zeroVector)

            if "Adapt" in self.simDefinition.getValue("SimControl.timeDiscretization"):
                self.timeStepLog.addColumn("EstimatedIntegrationError", 0)

        if loggingLevel > 1:
            self.derivativeEvaluationLog = Log()
            zeroVector = Vector(0,0,0)

            self.derivativeEvaluationLog.addColumn("Position(m)", zeroVector)
            self.derivativeEvaluationLog.addColumn("Velocity(m/s)", zeroVector)
            self.derivativeEvaluationLog.addColumn("OrientationQuaternion", Quaternion(0,0,0,0))
            self.derivativeEvaluationLog.addColumn("AngularVelocity(rad/s)", zeroVector)

            self.derivativeEvaluationLog.addColumn("CG(m)", zeroVector)
            self.derivativeEvaluationLog.addColumn("MOI(kg*m^2)", zeroVector)
            self.derivativeEvaluationLog.addColumn("Mass(kg)", 0)
            
            self.derivativeEvaluationLog.addColumn("Wind(m/s)", zeroVector)
            self.derivativeEvaluationLog.addColumn("AirDensity(kg/m^3)", 0)
            self.derivativeEvaluationLog.addColumn("Mach", 0)
            self.derivativeEvaluationLog.addColumn("UnitRe", 0)
            self.derivativeEvaluationLog.addColumn("AOA(deg)", 0)
            self.derivativeEvaluationLog.addColumn("RollAngle(deg)", 0)

            self.derivativeEvaluationLog.addColumn("CPZ(m)", 0)
            self.derivativeEvaluationLog.addColumn("AeroF(N)", zeroVector)
            self.derivativeEvaluationLog.addColumn("AeroM(Nm)", zeroVector)
            self.derivativeEvaluationLog.addColumn("GravityF(N)", zeroVector)
            self.derivativeEvaluationLog.addColumn("TotalF(N)", zeroVector)
        
        #### Init Components ####
        self._createStages()
        self._initializeRigidBody()
        self._switchToStatefulRigidBodyIfRequired()
        self._sortStagesAndComponents()
        self._initializeStagingTriggers()
        self._precomputeComponentProperties()

        #### Init Parent classes ####
        CompositeObject.__init__(self, self.stages)
        self._updateFinenessRatio()

        # Adjust rigid body state position to correspond to the rocket's CG instead of nose cone tip position
        self._moveStatePositionToCG()

        #### Init Guidance/Navigation/Control System (if required) ####
        self.controlSystem = None
        ''' None for uncontrolled rockets. `MAPLEAF.GNC.ControlSystems.RocketControlSystem` for controlled rockets '''
        if ( rocketDictReader.tryGetString("ControlSystem.controlledSystem") != None or rocketDictReader.tryGetString("ControlSystem.MomentController.Type") == "IdealMomentController") and stageToInitialize == None:
            # Only create a control system if this is NOT a dropped stage
            ControlSystemDictReader = SubDictReader("Rocket.ControlSystem", simDefinition=self.simDefinition)
            controlSystemLogging = loggingLevel > 3
            self.controlSystem = RocketControlSystem(ControlSystemDictReader, self, log=controlSystemLogging, silent=silent)
示例#25
0
 def setUp(self):
     simDef = SimDefinition("MAPLEAF/Examples/Simulations/test2.mapleaf")
     rocketDictReader = SubDictReader("Rocket", simDef)
     self.motorRocket = Rocket(rocketDictReader)
示例#26
0
    def __init__(self, simDefinition=None, silent=False):
        ''' Sets up the Wind, Atmospheric, and Earth models requested in the Sim Definition file '''
        self.launchRail = None

        if simDefinition != None:
            # Whenever we're running a real simulation, should always end up here
            envDictReader = SubDictReader("Environment", simDefinition)

            self.meanWindModel = meanWindModelFactory(envDictReader, silent=silent)
            self.turbulenceModel = turbulenceModelFactory(envDictReader, silent=silent)
            self.atmosphericModel = atmosphericModelFactory(envDictReader=envDictReader)
            self.earthModel = earthModelFactory(envDictReader)

            self.launchSiteElevation = envDictReader.tryGetFloat("LaunchSite.elevation")
            self.launchSiteLatitude = envDictReader.tryGetFloat("LaunchSite.latitude")
            self.launchSiteLongitude = envDictReader.tryGetFloat("LaunchSite.longitude")

            # Check if being launched from a launch rail
            launchRailLength = envDictReader.getFloat("LaunchSite.railLength")
            
            if launchRailLength > 0:
                # Initialize a launch rail, aligned with the rocket's initial direction
                initialRocketPosition_towerFrame = envDictReader.getVector("Rocket.position")

                # Check whether precise initial orientation has been specified
                rotationAxis = envDictReader.tryGetVector("Rocket.rotationAxis", defaultValue=None)
                if rotationAxis != None:
                    rotationAngle = math.radians(envDictReader.getFloat("Rocket.rotationAngle"))
                    initOrientation = Quaternion(rotationAxis, rotationAngle)
                else:
                    # Calculate initial orientation quaternion in launch tower frame
                    rotationAxis = envDictReader.tryGetVector("Rocket.rotationAxis", defaultValue=None)
                    if rotationAxis != None:
                        rotationAngle = math.radians(self.rocketDictReader.getFloat("Rocket.rotationAngle"))
                        initOrientation = Quaternion(rotationAxis, rotationAngle)
                    else:
                        # Calculate initial orientation quaternion in launch tower frame
                        initialDirection = envDictReader.getVector("Rocket.initialDirection").normalize()
                        angleFromVertical = Vector(0,0,1).angle(initialDirection)
                        rotationAxis = Vector(0,0,1).crossProduct(initialDirection)
                        initOrientation = Quaternion(rotationAxis, angleFromVertical)

                    # TODO: Get from rocket, or calculate the same way - so that it works with rotationAxis + Angle
                    initialDirection = envDictReader.getVector("Rocket.initialDirection").normalize()
                    angleFromVertical = Vector(0,0,1).angle(initialDirection)
                    rotationAxis = Vector(0,0,1).crossProduct(initialDirection)
                    initOrientation = Quaternion(rotationAxis, angleFromVertical)

                initPosition_seaLevelENUFrame = initialRocketPosition_towerFrame + Vector(0, 0, self.launchSiteElevation)
                launchTowerState_local = RigidBodyState(position=initPosition_seaLevelENUFrame, orientation=initOrientation)
                launchTowerState_global = self.earthModel.convertIntoGlobalFrame(launchTowerState_local, self.launchSiteLatitude, self.launchSiteLongitude)
                towerDirection_global = launchTowerState_global.orientation.rotate(Vector(0, 0, 1))                
                self.launchRail = LaunchRail(launchTowerState_global.position, towerDirection_global, launchRailLength, earthRotationRate=self.earthModel.rotationRate)
                
        else:
            # Construct default environment from default parameters when no sim definition is passed in
            # Need additional default value here in case a SimDefinition is not passed in (otherwise SimDefinition takes care of default values)
            self.meanWindModel = meanWindModelFactory()
            self.turbulenceModel = None
            self.atmosphericModel = atmosphericModelFactory()
            self.earthModel = earthModelFactory()

            self.launchSiteElevation = float(defaultConfigValues["Environment.LaunchSite.elevation"])
            self.launchSiteLatitude = float(defaultConfigValues["Environment.LaunchSite.latitude"])
            self.launchSiteLongitude = float(defaultConfigValues["Environment.LaunchSite.longitude"])
示例#27
0
 def setUp(self):
     self.rocket = "fakeNewsRocket"  # May have to convert this into a real Rocket at some point, but it's faster this way
     self.simDefinition = SimDefinition(
         "MAPLEAF/Examples/Simulations/Wind.mapleaf", silent=True)
     self.envReader = SubDictReader("Environment", self.simDefinition)
示例#28
0
 def _createNestedOptimization(self, simDef):
     innerOptimizationReader = SubDictReader(self.optimizationReader.simDefDictPathToReadFrom + '.InnerOptimization', simDef)
     return optimizationRunnerFactory(optimizationReader=innerOptimizationReader, silent=self.silent, parallel=self.parallel)