Last active
August 29, 2015 14:00
-
-
Save Sonictherocketman/11339552 to your computer and use it in GitHub Desktop.
A piece of a Rocket simulation I made for AE 530 "Rocket Propulsion"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## | |
# RocketSolver.py | |
# | |
# Created by Brian Schrader on 4/25/14. | |
# | |
# | |
## | |
import Point | |
class Rocket: | |
""" Put comment here. """ | |
# Constants | |
__speedOfSound = 340.29 # m/s @ sea level | |
# Bookkeeping | |
__points = [] | |
__previousPoint = Point.Point(0, 0, 0, 0, 0, "Launch Point") | |
__apogeePoint = Point.Point(0, 0, 0, 0, 0, "") | |
__burnoutPoint = Point.Point(0, 0, 0, 0, 0, "") | |
__impactPoint = Point.Point(0, 0, 0, 0, 0, "") | |
__flightTime = 0 # seconds | |
__dt = 0.1 # seconds | |
# Data | |
drag = [] | |
thrust = [] | |
flightStats = [] | |
# Status | |
hasReachedApogee = False | |
hasLaunched = False | |
isPowered = True | |
isCruising = False | |
# Structure and Configuration | |
payloadMass = 0.0 # kg | |
structuralMass = 0.0 # kg | |
propellantMass = 0.0 # kg | |
burnTime = 0.0 # s | |
currentMass = 0.0 # kg | |
frontalArea = 0.1 # m^2 | |
# Private Methods | |
def __init__(self): | |
""" Default Constructor """ | |
self.ready = True | |
def __dragForMach(self, mach, powered): | |
""" Determines the drag value for the given mach number. The mach number is accurate to 5% | |
:param mach: float Mach Number | |
:param powered: bool Whether or not the flight is powered. | |
:rtype : float Drag Value | |
""" | |
acceptableError = 0.05 | |
for drag in self.drag: | |
try: | |
machFromDrag = float(drag[0]) | |
except FloatingPointError: | |
print "Value {0} could not be made into a number.".format(drag[0]) | |
percentError = abs(mach - machFromDrag) / (mach + machFromDrag) | |
if percentError <= acceptableError: | |
# Result found | |
if powered: | |
return float(drag[2]) | |
if not powered: | |
return float(drag[1]) | |
return -1 | |
def __thrust(self, time): | |
""" Returns the thrust value for the given time value. """ | |
for moment in self.flightStats: | |
if time == moment[0]: # Find the correct time in the list of thrust profile info. | |
return int(moment[1]) | |
return -1 | |
def __massflow(self, time): | |
""" Returns the mass flow value for the given time. | |
:param time: int Burn time in seconds | |
:rtype : int | |
""" | |
for moment in self.flightStats: | |
if time == moment[0]: # Find the correct time in the list of mass flow profile info. | |
return int(moment[2]) | |
return -1 | |
def __fuelMass(self, time): | |
""" Returns the mass value for the given time. | |
:param time: int Burn time in seconds | |
:rtype : int | |
""" | |
for moment in self.flightStats: | |
if time == moment[0]: # Find the correct time in the list of mass profile info. | |
return int(moment[3]) | |
return -1 | |
def __burnTime(self): | |
moment = self.flightStats[-1] | |
self.burnTime = moment[0] | |
return int(moment[0]) | |
# Public Methods | |
def launch(self): | |
""" Launches the rocket. Once this is finished the points are available for use. """ | |
self.hasLaunched = True | |
while not self.hasReachedApogee: | |
self.__flightTime += self.__dt | |
self.__points.append(self.getNextPoint()) | |
def getAllPoints(self): | |
return self.__points | |
def getNextPoint(self): | |
""" This method does the actual calculations for the rocket's location and trajectory. | |
:rtype : Point | |
:type self: Rocket | |
:rtype Point: Point the next point in the trajectory. | |
""" | |
point = Point.Point(0, 0, 0, 0, 0, "") | |
if len(self.__points) > 0: | |
prevPoint = self.__previousPoint = self.__points[-1] | |
else: | |
prevPoint = self.__previousPoint | |
rho = 1.225 # kg/m^3 | |
mach = prevPoint.velocity / self.__speedOfSound | |
self.currentMass = self.__fuelMass(self.__flightTime) + self.structuralMass + self.payloadMass | |
self.currentMass = self.__fuelMass(self.__flightTime) + self.structuralMass + self.payloadMass | |
drag = self.__dragForMach(mach, self.isPowered) * 0.5 * rho * self.frontalArea * prevPoint.velocity.__pow__( | |
2) - 9.81 | |
if self.isPowered: | |
# Powered Climb | |
thrust = self.__thrust(self.__flightTime) | |
acceleration = (thrust - drag) / self.currentMass | |
vel = prevPoint.velocity + 0.5 * self.__dt * (acceleration + prevPoint.acceleration) | |
y = self.__dt * vel + prevPoint.y | |
x = 0 # The rocket is being launched at a 90 degree angle to the ground. Ignoring wind, there is no | |
# horizontal travel. | |
else: | |
# Cruising Upward | |
thrust = 0 | |
acceleration = (-drag) / self.currentMass | |
vel = prevPoint.velocity + 0.5 * self.__dt * (prevPoint.acceleration + acceleration) | |
y = vel * self.__dt * prevPoint.velocity # We can do this since there is no horizontal motion. | |
x = 0 | |
point.x = x | |
point.y = y | |
point.velocity = vel | |
point.acceleration = acceleration | |
point.drag = drag | |
point.thrust = thrust | |
point.time = self.__flightTime | |
# Update Mission Status | |
if prevPoint.y > point.y: | |
self.hasReachedApogee = True | |
point.comment = "Apogee" | |
if self.__flightTime > self.__burnTime() and not self.isCruising: | |
self.isPowered = False | |
self.isCruising = True | |
point.comment = "Burnout Reached" | |
return point |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment