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_dualUniformXMotion(self): movingXState = RigidBodyState(self.zeroVec, Vector(1, 0, 0), self.zeroQuat, self.zeroAngVel) constInertia = Inertia(self.oneVec, self.zeroVec, 1) def constInertiaFunc(*allArgs): return constInertia def zeroForceFunc(*allArgs): return self.zeroForce movingXBody = StatefulRigidBody(movingXState, zeroForceFunc, constInertiaFunc, simDefinition=self.simDefinition) # Add the same rigid body state and state derivative function as a second state variable to be integrated movingXBody.addStateVariable("secondRigidBodyState", movingXState, movingXBody.getRigidBodyStateDerivative) movingXBody.timeStep(1) # Check that both rigid body states have been integrated correctly newPos = movingXBody.state[0].position newPos2 = movingXBody.state[1].position assertVectorsAlmostEqual(self, newPos, Vector(1, 0, 0)) assertVectorsAlmostEqual(self, newPos2, Vector(1, 0, 0))
def test_UniformXMotionAndScalarIntegration(self): movingXState = RigidBodyState(self.zeroVec, Vector(1, 0, 0), self.zeroQuat, self.zeroAngVel) constInertia = Inertia(self.oneVec, self.zeroVec, 1) def constInertiaFunc(*allArgs): return constInertia def zeroForceFunc(*allArgs): return self.zeroForce movingXBody = StatefulRigidBody(movingXState, zeroForceFunc, constInertiaFunc, integrationMethod="RK4", simDefinition=self.simDefinition) movingXBody.addStateVariable("scalarVar", 3, sampleDerivative) movingXBody.timeStep(0.2) # Check that the rigid body state has been integrated correctly newPos = movingXBody.state[0].position assertVectorsAlmostEqual(self, newPos, Vector(0.2, 0, 0)) # Check that the scalar function has been integrated correctly finalVal = movingXBody.state[1] self.assertAlmostEqual(finalVal, 2.0112)
def test_RigidBodyState_add(self): pos = Vector(0, 0, 0) vel = Vector(0, 0, 0) orientation = Quaternion(axisOfRotation=Vector(0, 0, 1), angle=0) angVel = AngularVelocity(rotationVector=Vector(0, 0, 0)) state1 = RigidBodyState(pos, vel, orientation, angVel) pos2 = Vector(0, 0, 0.1) vel2 = Vector(0, 0, 0.2) orientation2 = Quaternion(axisOfRotation=Vector(0, 0, 1), angle=pi / 2) angVel2 = AngularVelocity(rotationVector=Vector(0, 0, 0.3)) state2 = RigidBodyState(pos2, vel2, orientation2, angVel2) result = state1 + state2 assertRigidBodyStatesalmostEqual(self, result, state2) pos3 = Vector(0, 0, 0.1) vel3 = Vector(0, 0, 0.2) orientation3 = Quaternion(axisOfRotation=Vector(0, 1, 0), angle=pi / 2) angVel3 = AngularVelocity(rotationVector=Vector(0, 0, 0.3)) state3 = RigidBodyState(pos3, vel3, orientation3, angVel3) result = state3 + state2 testVec = result.orientation.rotate(Vector(0, 0, 1)) assertVectorsAlmostEqual(self, testVec, Vector(0, 1, 0))
def test_zeroSag(self): unadjustedForce = ForceMomentSystem(Vector(10, 9, -10), moment=Vector(10, 11, 12)) adjustedForce = self.rail.applyLaunchTowerForce( self.initState, 0, unadjustedForce) # Check that force is zero (don't let object sag/fall) assertVectorsAlmostEqual(self, adjustedForce.force, Vector(0, 0, 0)) # Check moments are zero assertVectorsAlmostEqual(self, adjustedForce.moment, Vector(0, 0, 0))
def test_LeaveRail(self): unadjustedForce = ForceMomentSystem(Vector(10, 9, 11), moment=Vector(10, 11, 12)) self.initState.position = Vector(4, 0, 4) # Greater than 5m away adjustedForce = self.rail.applyLaunchTowerForce( self.initState, 0, unadjustedForce) # Check that forces/moments are unaffected assertVectorsAlmostEqual(self, adjustedForce.force, Vector(10, 9, 11)) assertVectorsAlmostEqual(self, adjustedForce.moment, Vector(10, 11, 12))
def test_alignForceWithRail(self): unadjustedForce = ForceMomentSystem(Vector(10, 9, 11), moment=Vector(10, 11, 12)) adjustedForce = self.rail.applyLaunchTowerForce( self.initState, 0, unadjustedForce) # Check that force direction is now aligned with rail forceDirection = adjustedForce.force.normalize() assertVectorsAlmostEqual(self, self.rail.initialDirection, forceDirection) # Check moments are zero assertVectorsAlmostEqual(self, adjustedForce.moment, Vector(0, 0, 0))
def test_parseRadioSondeData(self): reader = RadioSondeDataSampler() datasetStartLines, data = reader._readRadioSondeDataFile( "MAPLEAF/Examples/Wind/RadioSondetestLocation_filtered.txt") header, data2 = reader._extractRadioSondeDataSet( datasetStartLines, data, 0) altitudes, windVectors = reader._parseRadioSondeData(data2, 0) self.assertEqual(altitudes[0], 1361) self.assertEqual(altitudes[-1], 32280) assertVectorsAlmostEqual(self, Vector(*windVectors[0]), Vector(0.819152044, 0.573576436, 0) * 8.2) assertVectorsAlmostEqual(self, Vector(*windVectors[-1]), Vector(0.866025403, -0.5, 0) * 52.5) # Test ASL location adjustment altitudes, windVectors = reader._parseRadioSondeData(data2, 100) self.assertAlmostEqual(altitudes[0], 1261) self.assertAlmostEqual(altitudes[-1], 32180) assertVectorsAlmostEqual(self, Vector(*windVectors[0]), Vector(0.819152044, 0.573576436, 0) * 8.2) assertVectorsAlmostEqual(self, Vector(*windVectors[-1]), Vector(0.866025403, -0.5, 0) * 52.5)
def test_initPosition(self): # Modify file to include a launch rail simDef = SimDefinition( "MAPLEAF/Examples/Simulations/AdaptTimeStep.mapleaf") simDef.setValue("Environment.LaunchSite.railLength", "10") # Initialize environment with launch rail env = Environment(simDef) # Check that launch rail has been created self.assertTrue(env.launchRail != None) # Check initial launch rail position and direction initPos = Vector(0, 0, 15 + 755) # Rocket position + launch site elevation assertVectorsAlmostEqual(self, initPos, env.launchRail.initialPosition)
def test_convertWindHeadingToXYPlaneWindDirection(self): assertVectorsAlmostEqual(self, _convertWindHeadingToXYPlaneWindDirection(0), Vector(0, -1, 0)) assertVectorsAlmostEqual(self, _convertWindHeadingToXYPlaneWindDirection(90), Vector(-1, 0, 0)) assertVectorsAlmostEqual( self, _convertWindHeadingToXYPlaneWindDirection(180), Vector(0, 1, 0)) assertVectorsAlmostEqual( self, _convertWindHeadingToXYPlaneWindDirection(270), Vector(1, 0, 0)) assertVectorsAlmostEqual( self, _convertWindHeadingToXYPlaneWindDirection(360), Vector(0, -1, 0))
def test_Initialization_NASASphere(self): simRunner = Simulation("./MAPLEAF/Examples/Simulations/NASASphere.mapleaf") sphere = simRunner.createRocket() # Should be at an altitude of 9144 m above earth's surface distanceFromEarthCenter = sphere.rigidBody.state.position.length() expected = sphere.environment.earthModel.a + 9144 self.assertAlmostEqual(distanceFromEarthCenter, expected) # Should have zero angular velocity in inertial frame angVel = sphere.rigidBody.state.angularVelocity.length() self.assertAlmostEqual(angVel, 0.0) # Velocity should be zero in earth-fixed frame rotationVel = distanceFromEarthCenter * sphere.environment.earthModel.rotationRate inertialVel = sphere.rigidBody.state.velocity assertVectorsAlmostEqual(self, inertialVel, Vector(0, rotationVel, 0))
def test_getMeanWind_CustomProfile(self): # Make sure custom profile model is used self.simDefinition.setValue("Environment.MeanWindModel", "CustomWindProfile") self.simDefinition.setValue( "Environment.CustomWindProfile.filePath", "MAPLEAF/Examples/Wind/testWindProfile.txt") # Re-initialize mWM mWM = meanWindModelFactory(self.envReader, self.rocket) assertVectorsAlmostEqual(self, mWM.getMeanWind(8000), Vector(-5, -4, -2)) assertVectorsAlmostEqual(self, mWM.getMeanWind(7000), Vector(-5, -4, -2)) assertVectorsAlmostEqual(self, mWM.getMeanWind(6500), Vector(10, -2, -1)) assertVectorsAlmostEqual(self, mWM.getMeanWind(1000), Vector(10, 0, 0)) assertVectorsAlmostEqual(self, mWM.getMeanWind(0), Vector(10, 0, 0))
def test_instantTurn(self): simulationDefinition = SimDefinition("MAPLEAF/Examples/Simulations/Canards.mapleaf", silent=True) # Use an ideal moment controller simulationDefinition.setValue("Rocket.ControlSystem.MomentController.Type", "IdealMomentController") # Set initial direction to be pointing directly upwards simulationDefinition.setValue("Rocket.initialDirection", "(0 0 1)") # Ask for an Immediate Turn simulationDefinition.setValue("Rocket.ControlSystem.desiredFlightDirection", "(0 1 1)") runner = Simulation(simDefinition=simulationDefinition, silent=True) rocket = runner.createRocket() # Take a time step and check that the desired direction has been achieved immediately rocket.timeStep(0.01) currentDirection = rocket.rigidBody.state.orientation.rotate(Vector(0,0,1)) expectedDirection = Vector(0,1,1).normalize() assertVectorsAlmostEqual(self, currentDirection, expectedDirection, 5)
def test_quaternionMult(self): self.assertEqual(self.q4 * self.q5, Quaternion(components=[0.5, 1.25, 1.5, 0.25])) self.assertEqual(self.q4 * self.q4, Quaternion(components=[0, 0, 2, 0])) # Check that order of rotations is left to right rot1 = Quaternion(axisOfRotation=Vector(0, 0, 1), angle=(pi / 2)) rot2 = Quaternion(axisOfRotation=Vector(1, 0, 0), angle=(pi / 2)) totalRotation = rot1 * rot2 initZAxis = Vector(0, 0, 1) finalZAxis = totalRotation.rotate(initZAxis) initXAxis = Vector(1, 0, 0) finalXAxis = totalRotation.rotate(initXAxis) assertVectorsAlmostEqual(self, finalXAxis, Vector(0, 1, 0)) assertVectorsAlmostEqual(self, finalZAxis, Vector(1, 0, 0))
def test_bodyTubeDampingMoment(self): simRunner = Simulation("MAPLEAF/Examples/Simulations/test3.mapleaf", silent=True) rocket = simRunner.createRocket() bodyTube = rocket.stages[0].getComponentsOfType(BodyTube)[0] # Create a rigid body state rotating at 2 rad/s about the x-axis pos = Vector(0, 0, 0) vel = Vector(0, 0, 0) orientation = Quaternion(1, 0, 0, 0) angVel = AngularVelocity(2, 0, 0) xRotatingState = RigidBodyState(pos, vel, orientation, angVel) envConditions = rocket.environment.getAirProperties(Vector(0, 0, 0)) #### CoR = Middle of the body tube #### fakeRocketCG = Vector(0, 0, -1.762) # Get computed (numerically-integrated) result calculatedDampingMoment = bodyTube._computeLongitudinalDampingMoments( xRotatingState, envConditions, fakeRocketCG, nSegments=100) # Compute analytical result (Niskanen Eqn 3.58) * 2 for both halves of the body tube (above and below center of rotation) expectedXDampingMoment = 2 * 0.275 * envConditions.Density * ( bodyTube.outerDiameter / 2) * 4 expectedTotalDampingMoment = Vector(-expectedXDampingMoment, 0, 0) # Compare assertVectorsAlmostEqual(self, calculatedDampingMoment, expectedTotalDampingMoment, 4) #### Case 2: CoR at End of Body Tube #### fakeRocketCG = Vector(0, 0, -2.762) # Get computed (numerically-integrated) result calculatedDampingMoment = bodyTube._computeLongitudinalDampingMoments( xRotatingState, envConditions, fakeRocketCG, nSegments=150) # Factor of 16 from moving to a tube length of two (2^4 = 16), but dividing by two (one half instead of two) expectedTotalDampingMoment *= 8 # Compare assertVectorsAlmostEqual(self, calculatedDampingMoment, expectedTotalDampingMoment, 4)
def test_BarrowmanCPLocation(self): length = 1 xArea_top = 1 xArea_bottom = 2 vol = 1.5 expected = Vector(0, 0, -0.5) assertVectorsAlmostEqual( self, expected, AeroFunctions.Barrowman_GetCPLocation(length, xArea_top, xArea_bottom, vol)) xArea_top = 1 xArea_bottom = 1 expected = Vector(0, 0, -0.5) assertVectorsAlmostEqual( self, expected, AeroFunctions.Barrowman_GetCPLocation(length, xArea_top, xArea_bottom, vol))
def test_BarrowmanCPLocation(self): # Check that for a cone, XCP = 0.666 Length length = 1 baseArea = 1 tipArea = 0 volume = baseArea * length / 3 XCP_cone = AeroFunctions.Barrowman_GetCPLocation( length, tipArea, baseArea, volume) self.assertAlmostEqual(XCP_cone.Z, -0.666666666) # Check that for a tangent ogive nosecone, XCP = 0.466 Length SimRunner = Simulation("MAPLEAF/Examples/Simulations/test3.mapleaf", silent=True) rocket = SimRunner.createRocket() rocketNosecone = rocket.stages[0].getComponentsOfType(NoseCone)[0] noseconeLength = rocketNosecone.length expectedCp = rocketNosecone.position + Vector( 0, 0, -0.46666 * noseconeLength) actualCp = rocketNosecone.CPLocation assertVectorsAlmostEqual(self, expectedCp, actualCp, 2)
def uniformXMotionTest(self, integrationMethod): movingXState = RigidBodyState(self.zeroVec, Vector(1, 0, 0), self.zeroQuat, self.zeroAngVel) constInertia = Inertia(self.oneVec, self.zeroVec, 1) def constInertiaFunc(*allArgs): return constInertia def zeroForceFunc(*allArgs): return self.zeroForce movingXBody = RigidBody(movingXState, zeroForceFunc, constInertiaFunc, integrationMethod=integrationMethod, simDefinition=self.simDefinition) movingXBody.timeStep(1) newPos = movingXBody.state.position assertVectorsAlmostEqual(self, newPos, Vector(1, 0, 0))
def test_sampleDistribution_vectorValue(self): self.simDef.setValue("vector1", "(10, 11, 12)") self.simDef.setValue("vector1_stdDev", "(1, 2, 3)") self.simDef.rng.seed(1000) self.simDef.resampleProbabilisticValues() resultVec = Vector(self.simDef.getValue("vector1")) expectedVec = Vector(10.254632116649685, 8.066448705920658, 14.27360999981685) assertVectorsAlmostEqual(self, expectedVec, resultVec) # Check does not change without resampling resultVec = Vector(self.simDef.getValue("vector1")) assertVectorsAlmostEqual(self, expectedVec, resultVec) # Check different value after resampling self.simDef.resampleProbabilisticValues() resultVec = Vector(self.simDef.getValue("vector1")) for i in range(3): self.assertNotAlmostEqual(expectedVec[i], resultVec[i]) self.resetSimDef()
def uniformXAccelerationTest(self, integrationMethod): constantXForce = ForceMomentSystem(Vector(1, 0, 0)) movingXState = RigidBodyState(self.zeroVec, self.zeroVec, self.zeroQuat, self.zeroAngVel) def constInertiaFunc(*allArgs): return self.constInertia def constXForceFunc(*allArgs): return constantXForce movingXBody = RigidBody(movingXState, constXForceFunc, constInertiaFunc, integrationMethod=integrationMethod, simDefinition=self.simDefinition) movingXBody.timeStep(1) newPos = movingXBody.state.position newVel = movingXBody.state.velocity assertVectorsAlmostEqual(self, newVel, Vector(1, 0, 0)) if integrationMethod == "Euler": assertVectorsAlmostEqual(self, newPos, Vector(0, 0, 0)) else: assertVectorsAlmostEqual(self, newPos, Vector(0.5, 0, 0))
def test_init(self): # Modify file to include a launch rail simDef = SimDefinition( "MAPLEAF/Examples/Simulations/NASATwoStageOrbitalRocket.mapleaf") simDef.setValue("Environment.LaunchSite.railLength", "15") # Initialize environment with launch rail env = Environment(simDef) # Check that launch rail has been created self.assertTrue(env.launchRail != None) # Check initial launch rail position and direction r = 6378137 + 13.89622 initPos = Vector(r, 0, 0) assertVectorsAlmostEqual(self, initPos, env.launchRail.initialPosition) initDir = Vector(math.cos(math.radians(34.78)), math.sin(math.radians(34.78)), 0).normalize() assertVectorsAlmostEqual(self, initDir, env.launchRail.initialDirection) self.assertAlmostEqual(env.launchRail.length, 15)
def test_getMeanWind_Hellman(self): # Make sure custom profile model is used self.simDefinition.setValue("Environment.MeanWindModel", "Hellman") self.simDefinition.setValue("Environment.Hellman.alphaCoeff", "0.1429") self.simDefinition.setValue("Environment.Hellman.altitudeLimit", "1000") # Set ground velocity self.simDefinition.setValue("Environment.Hellman.groundWindModel", "Constant") self.simDefinition.setValue("Environment.ConstantMeanWind.velocity", "(5 1 0)") # Re-initialize mWM mWM = meanWindModelFactory(self.envReader, self.rocket) assertVectorsAlmostEqual(self, mWM.getMeanWind(8000), Vector(9.655394088, 1.931078818, 0)) assertVectorsAlmostEqual(self, mWM.getMeanWind(2000), Vector(9.655394088, 1.931078818, 0)) assertVectorsAlmostEqual(self, mWM.getMeanWind(1000), Vector(9.655394088, 1.931078818, 0)) assertVectorsAlmostEqual(self, mWM.getMeanWind(500), Vector(8.744859132, 1.748971826, 0)) assertVectorsAlmostEqual(self, mWM.getMeanWind(0), Vector(5, 1, 0))
def test_Initialization_Velocity(self): # Zero velocity in launch tower frame simDef = SimDefinition("MAPLEAF/Examples/Simulations/NASATwoStageOrbitalRocket.mapleaf", silent=True) simDef.setValue("Rocket.velocity", "(0 0 0)") simRunner = Simulation(simDefinition=simDef, silent=True) rocket = simRunner.createRocket() computedInitGlobalFrameVel = rocket.rigidBody.state.velocity expectdedVel = Vector(0, 465.1020982258931, 0) # Earth's surface velocity at 0 lat, 0 long assertVectorsAlmostEqual(self, computedInitGlobalFrameVel, expectdedVel) # Velocity in the +x (East) direction in the launch tower frame simDef.setValue("Rocket.velocity", "(1 0 0)") simRunner = Simulation(simDefinition=simDef, silent=True) rocket = simRunner.createRocket() computedInitGlobalFrameVel = rocket.rigidBody.state.velocity expectdedVel = Vector(0, 466.1020982258931, 0) # Earth's surface velocity at 0 lat, 0 long + 1m/s east assertVectorsAlmostEqual(self, computedInitGlobalFrameVel, expectdedVel) # Velocity in the +y (North) direction in the launch tower frame simDef.setValue("Rocket.velocity", "(0 1 0)") simRunner = Simulation(simDefinition=simDef, silent=True) rocket = simRunner.createRocket() computedInitGlobalFrameVel = rocket.rigidBody.state.velocity expectdedVel = Vector(0, 465.1020982258931, 1) # Earth's surface velocity at 0 lat, 0 long + 1m/s north assertVectorsAlmostEqual(self, computedInitGlobalFrameVel, expectdedVel) # Velocity in the +z (Up) direction in the launch tower frame simDef.setValue("Rocket.velocity", "(0 0 1)") simRunner = Simulation(simDefinition=simDef, silent=True) rocket = simRunner.createRocket() computedInitGlobalFrameVel = rocket.rigidBody.state.velocity expectdedVel = Vector(1, 465.1020982258931, 0) # Earth's surface velocity at 0 lat, 0 long + 1m/s up assertVectorsAlmostEqual(self, computedInitGlobalFrameVel, expectdedVel)
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)
def test_combineForceMomentSystems_2(self): # Example Question 16 - http://www.ce.siue.edu/examples/Worked_examples_Internet_text-only/Data_files-Worked_Exs-Word_&_pdf/Equivalent_forces.pdf # Define Force-Moment 1 force1 = Vector(0, -3.464, -2) m1 = Vector(0, -51.962, -30) location1 = Vector(4, 1.5, 4.402) fms1 = ForceMomentSystem(force1, location1, m1) # Define Force-Moment 2 force2 = Vector(-6, 0, 0) m2 = Vector(-80, 0, 0) location2 = Vector(8, 1.5, 1) fms2 = ForceMomentSystem(force2, location2, m2) # Combine combinedForce = fms1 + fms2 combinedForceAtOrigin = combinedForce.getAt(Vector(0, 0, 0)) # Define correct/expected result expectedResultantForce = Vector(-6, -3.464, -2) expectedResultantMoment = Vector( 12.249, 2, -4.856 ) # Only includes moments generated by forces, not the moments applied resultantLocation = Vector(0, 0, 0) expectedResult = ForceMomentSystem(expectedResultantForce, resultantLocation, expectedResultantMoment) # Compare from test.testUtilities import assertVectorsAlmostEqual assertVectorsAlmostEqual(self, combinedForceAtOrigin.force, expectedResult.force) assertVectorsAlmostEqual(self, combinedForceAtOrigin.location, expectedResult.location) assertVectorsAlmostEqual(self, combinedForceAtOrigin.moment - m1 - m2, expectedResult.moment, 3)
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_staging(self): stagingSimRunner = self.stagingRunner twoStageRocket = stagingSimRunner.createRocket() #### Combined (two-stage) rocket checks #### # Check that two stages have been created self.assertEqual(len(twoStageRocket.stages), 2) # Check combined inertia is correct inertia = twoStageRocket.getInertia(0, "fakeState") self.assertEqual(inertia.mass, 60) assertVectorsAlmostEqual(self, inertia.CG, Vector(0, 0, -4.6555)) assertVectorsAlmostEqual(self, inertia.MOI, Vector(411.321815, 411.321815, 1.0)) # Check that the first stage motor will ignite and the second wont self.assertEqual(twoStageRocket.stages[-1].motor.ignitionTime, 0) self.assertTrue(twoStageRocket.stages[0].motor.ignitionTime > 100) # Set up simRunner so it's able to create the detached (dropped) stage stagingSimRunner.rocketStages = [twoStageRocket] stagingSimRunner.dts = [0.05] stagingSimRunner.endDetectors = [ stagingSimRunner._getEndDetectorFunction( twoStageRocket, stagingSimRunner.simDefinition) ] stagingSimRunner.stageFlightPaths = [ stagingSimRunner._setUpCachingForFlightAnimation(twoStageRocket) ] # Trigger stage separation twoStageRocket._stageSeparation() #### Upper stage checks #### self.assertEqual(len(twoStageRocket.stages), 1) topStageInertia = twoStageRocket.getInertia(2, "fakeState") self.assertEqual(topStageInertia.mass, 30) assertVectorsAlmostEqual(self, topStageInertia.CG, Vector(0, 0, -2.65)) assertVectorsAlmostEqual(self, topStageInertia.MOI, Vector(85, 85, 0.5)) self.assertEqual(twoStageRocket.stages[0].motor.ignitionTime, 0) self.assertEqual(len(twoStageRocket.stages[0].components), 7) # Originally 6 - added 1 for zero-length boattail #### Dropped stage checks #### self.assertEqual(len(stagingSimRunner.rocketStages), 2) droppedStage = stagingSimRunner.rocketStages[1] droppedStageInertia = droppedStage.getInertia(2, "fakeState") self.assertEqual(droppedStageInertia.mass, topStageInertia.mass) self.assertEqual(droppedStageInertia.MOI, topStageInertia.MOI) self.assertNotEqual(droppedStageInertia.CG, topStageInertia.CG) self.assertNotEqual(droppedStageInertia.MOICentroidLocation, topStageInertia.MOICentroidLocation) self.assertTrue(droppedStage.stages[0].motor.ignitionTime < 0) self.assertEqual(len(droppedStage.stages[0].components), 6) # Originally 5 - added 1 for zero-length boattail
def test_rotate(self): assertVectorsAlmostEqual(self, self.rotQ2.rotate(Vector(1, 1, 1)), Vector(-1, 1, 1)) assertVectorsAlmostEqual(self, self.rotQ3.rotate(Vector(1, 1, 1)), Vector(1, 1, -1)) assertVectorsAlmostEqual(self, self.rotQ4.rotate(Vector(1, 1, 1)), Vector(1, -1, 1)) assertVectorsAlmostEqual(self, self.rotQ5.rotate(Vector(1, 1, 1)), Vector(-1, -1, 1)) assertVectorsAlmostEqual(self, self.rotQ6.rotate(Vector(1, 1, 1)), Vector(-1, 1, -1)) assertVectorsAlmostEqual(self, self.rotQ7.rotate(Vector(1, 1, 1)), Vector(1, -1, -1))
def test_getNormalAeroForceDirection(self): zeroAngVel = AngularVelocity(0,0,0) zeroPos = Vector(0,0,0) state1 = RigidBodyState(zeroPos, self.dummyVelocity1, self.dummyOrientation1, zeroAngVel) assertVectorsAlmostEqual(self, AeroParameters.getNormalAeroForceDirection(state1, self.currentConditions), Vector(0, -1, 0)) state2 = RigidBodyState(zeroPos, self.dummyVelocity1, self.dummyOrientation2, zeroAngVel) assertVectorsAlmostEqual(self, AeroParameters.getNormalAeroForceDirection(state2, self.currentConditions), Vector(0, 1, 0)) state3 = RigidBodyState(zeroPos, self.dummyVelocity1, self.dummyOrientation3, zeroAngVel) assertVectorsAlmostEqual(self, AeroParameters.getNormalAeroForceDirection(state3, self.currentConditions), Vector(1, 0, 0)) state4 = RigidBodyState(zeroPos, self.dummyVelocity1, self.dummyOrientation4, zeroAngVel) assertVectorsAlmostEqual(self, AeroParameters.getNormalAeroForceDirection(state4, self.currentConditions), Vector(1, 0, 0)) state5 = RigidBodyState(zeroPos, self.dummyVelocity1, self.dummyOrientation5, zeroAngVel) assertVectorsAlmostEqual(self, AeroParameters.getNormalAeroForceDirection(state5, self.currentConditions), Vector(0.707, -0.707, 0),3) assertVectorsAlmostEqual(self, AeroParameters.getNormalAeroForceDirection(self.rocketState8, self.currentConditions), Vector(-0.99999, 0.0022736, 0),3) # Prep rocket by calling getLocalFrameAirVel first to cache AOA result, then get cached result from getTotalAOA def testLocalFrameAirVelNormalForceDir(vel, orientation, expectedResult, precision=7): state = RigidBodyState(Vector(0,0,0), vel, orientation, AngularVelocity(0,0,0)) assertVectorsAlmostEqual(self, AeroParameters.getNormalAeroForceDirection(state, self.currentConditions), expectedResult, precision) testLocalFrameAirVelNormalForceDir(self.dummyVelocity1, self.dummyOrientation1, Vector(0, -1, 0)) testLocalFrameAirVelNormalForceDir(self.dummyVelocity1, self.dummyOrientation2, Vector(0, 1, 0)) testLocalFrameAirVelNormalForceDir(self.dummyVelocity1, self.dummyOrientation3, Vector(1, 0, 0)) testLocalFrameAirVelNormalForceDir(self.dummyVelocity1, self.dummyOrientation4, Vector(1, 0, 0)) testLocalFrameAirVelNormalForceDir(self.dummyVelocity1, self.dummyOrientation5, Vector(0.707, -0.707, 0), 3) testLocalFrameAirVelNormalForceDir(self.rocketState8.velocity, self.rocketState8.orientation, Vector(-0.99999, 0.0022736, 0),3)
def testLocalFrameAirVelNormalForceDir(vel, orientation, expectedResult, precision=7): state = RigidBodyState(Vector(0,0,0), vel, orientation, AngularVelocity(0,0,0)) assertVectorsAlmostEqual(self, AeroParameters.getNormalAeroForceDirection(state, self.currentConditions), expectedResult, precision)