diff options
author | Baitinq <you@example.com> | 2022-02-06 22:52:22 +0000 |
---|---|---|
committer | Baitinq <you@example.com> | 2022-02-06 22:52:22 +0000 |
commit | 521da01f6da6c32ccd834c20b7ea457a619361c8 (patch) | |
tree | 6f95f89ac0369f4c0e85e6b2a9b6f9c0a1f67008 | |
download | OSLS-521da01f6da6c32ccd834c20b7ea457a619361c8.tar.gz OSLS-521da01f6da6c32ccd834c20b7ea457a619361c8.tar.bz2 OSLS-521da01f6da6c32ccd834c20b7ea457a619361c8.zip |
Initial Commit
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | atmosphere.py | 14 | ||||
-rw-r--r-- | body.py | 21 | ||||
-rw-r--r-- | engine.py | 7 | ||||
-rw-r--r-- | fuel.py | 4 | ||||
-rw-r--r-- | main.py | 84 | ||||
-rw-r--r-- | rocket.py | 33 | ||||
-rw-r--r-- | simulation.py | 85 | ||||
-rw-r--r-- | universe.py | 8 |
9 files changed, 257 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c18dd8d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__/ diff --git a/atmosphere.py b/atmosphere.py new file mode 100644 index 0000000..48f9bd1 --- /dev/null +++ b/atmosphere.py @@ -0,0 +1,14 @@ +import math + +class Atmosphere(): + def __init__(self, avg_sea_level_pressure: int, molar_mass_air: float, standard_temp: float): + self.avg_sea_level_pressure = avg_sea_level_pressure + self.molar_mass_air = molar_mass_air + self.standard_temp = standard_temp + + #https://math24.net/barometric-formula.html + def density_at_height(self, height: int, g: float) -> None: + R = 8.3144598 #universal gas constant + pressure = self.avg_sea_level_pressure * math.e ** (-(self.molar_mass_air * g * height)/(R * self.standard_temp)) + density = pressure / (R * 10000) + return density \ No newline at end of file diff --git a/body.py b/body.py new file mode 100644 index 0000000..3be2c5e --- /dev/null +++ b/body.py @@ -0,0 +1,21 @@ +import math + +from atmosphere import Atmosphere + +class Body(): + def __init__(self, name: str, density: int, radius: int, atmosphere: type[Atmosphere]): + self.name = name + self.density = density + self.radius = radius + self.atmosphere = atmosphere + + def mass(self): + body_volume = (4/3) * math.pi * (self.radius**3) + return body_volume * self.density * 1000 + + def g(self, G: float, height: int): + return (G * self.mass()) / ((self.radius + height) ** 2) + + + def __str__(self): + return "uwu" \ No newline at end of file diff --git a/engine.py b/engine.py new file mode 100644 index 0000000..26a5bab --- /dev/null +++ b/engine.py @@ -0,0 +1,7 @@ +import fuel + +class Engine(): + def __init__(self, name: str, thrust: int, flow_rate: float): + self.name = name + self.thrust = thrust + self.flow_rate = flow_rate \ No newline at end of file diff --git a/fuel.py b/fuel.py new file mode 100644 index 0000000..11fc233 --- /dev/null +++ b/fuel.py @@ -0,0 +1,4 @@ +class Fuel(): + def __init__(self, name: str, energy_density: float): + self.name = name + self.energy_density = energy_density \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..d322193 --- /dev/null +++ b/main.py @@ -0,0 +1,84 @@ +import sys +import math +from time import sleep + +from engine import Engine +from fuel import Fuel +from rocket import Rocket +from atmosphere import Atmosphere +from body import Body +from universe import Universe +from simulation import Simulation + +import pygame +from pygame.locals import * + +def main(argv): + rocket = Rocket(name="starship", + rocket_mass=240000, #thrust=245000 + engine=Engine(name="raptor", thrust=2.3E6, flow_rate=1000), #https://en.wikipedia.org/wiki/SpaceX_Raptor + engine_number=33, + fuel_type=Fuel(name="methane", energy_density=None), + fuel_mass=4000000, + drag_coefficient=1.18, + cross_sectional_area=(math.pi * (9**2)) + ) + + body = Body(name="earth", + density=5.51, + radius=6371000, + atmosphere=Atmosphere( + avg_sea_level_pressure=101325, + molar_mass_air=0.02896, + standard_temp=288.15 + ) + ) + + universe = Universe(name="conventional", + G=6.67E-11, + plank=None + ) + + simulation = Simulation(universe, body, rocket) + + pygame.init() + simulation_display = pygame.display.set_mode((400,500)) + while(True): + delta = 0.01 + sleep(delta) + + for event in pygame.event.get(): + if event.type == pygame.QUIT: + pygame.quit() + quit() + elif event.type == pygame.KEYDOWN: + if event.key == pygame.K_SPACE: + simulation.rocket.engines_on = not simulation.rocket.engines_on + elif event.key == pygame.K_LEFT: + sys.exit(0) + elif event.key == pygame.K_RIGHT: + sys.exit(0) + + simulation.tick(delta=delta) + draw_simulation(simulation_display, simulation) + + pygame.display.update() + + #TODO: do max load on rocket so it blows up + #TODO: display sim info on screen + #TODO: allow for x movement, speed, accel etc + #TODO: draw floor, flame + #TODO: allow multilanguage api for landing algorithms etc + +def draw_simulation(simulation_display: type[pygame.Surface], simulation: type[Simulation]) -> None: + simulation_display.fill(get_color_for_height(simulation.y)) #gradient for atmosphere TODO + + pygame.draw.rect(simulation_display, (0, 125, 255), pygame.Rect(30, 30, 60, 60)) + if simulation.rocket.engines_on: + pygame.draw.circle(simulation_display, (255, 125, 100), (60, 100), 10) + +def get_color_for_height(height: int) -> (int, int, int): + return (255, 255, 255) + +if __name__ == "__main__": + main(sys.argv) \ No newline at end of file diff --git a/rocket.py b/rocket.py new file mode 100644 index 0000000..eb73c7c --- /dev/null +++ b/rocket.py @@ -0,0 +1,33 @@ +from engine import Engine +from fuel import Fuel + +class Rocket(): + def __init__(self, name: str, rocket_mass: int, engine: type[Engine], engine_number: int, fuel_type: type[Fuel], fuel_mass: int, drag_coefficient: float, cross_sectional_area: float): + self.name = name + self.rocket_mass = rocket_mass + self.engine = engine + self.engine_number = engine_number + self.fuel_type = fuel_type + self.fuel_mass = fuel_mass + self.drag_coefficient = drag_coefficient + self.cross_sectional_area = cross_sectional_area + + self.engines_on = True + + def total_mass(self): + return self.rocket_mass + self.fuel_mass + + def total_thrust(self): + if(self.engines_on): + return self.engine.thrust * self.engine_number + else: + return 0 + + def total_fuel_used(self, delta: int): + if(self.engines_on): + return self.engine.flow_rate * self.engine_number * delta + else: + return 0 + + def __str__(self): + return "eue" \ No newline at end of file diff --git a/simulation.py b/simulation.py new file mode 100644 index 0000000..a93a263 --- /dev/null +++ b/simulation.py @@ -0,0 +1,85 @@ +from dataclasses import dataclass + +from universe import Universe +from body import Body +from rocket import Rocket + +@dataclass +class Simulation_Snapshot: + universe: type[Universe] + body: type[Body] + rocket: type[Rocket] + +class Simulation(): + def __init__(self, universe: type[Universe], body: type[Body], rocket: type[Rocket]): + self.ticks = 0 + self.time = 0 + self.universe = universe + self.body = body + self.rocket = rocket + self.y = 0 + self.speed_y = 0 + + #simulation logic + def tick(self, delta: int) -> None: + #calculate upwards force by fuel + # TODO able to turn engine on and off + fuel_used = self.rocket.total_fuel_used(delta) + if self.rocket.fuel_mass < fuel_used: + fuel_used = self.rocket.fuel_mass + self.rocket.fuel_mass -= fuel_used + print("Fuel remaining: " + str(self.rocket.fuel_mass)) + + #upwards_force = fuel_used * self.rocket.fuel_type.energy_density #we should calculate thrust based on this + upwards_force = 0 + if fuel_used > 0: + upwards_force = self.rocket.total_thrust() + print("Upwards force: " + str(upwards_force)) + + print("g: " + str(self.body.g(G=self.universe.G, height=self.y))) + + #calculate downwards force by drag and gravity + gravitational_force = self.body.g(G=self.universe.G, height=self.y) * self.rocket.total_mass() + print("Gravity: " + str(gravitational_force)) + + print("BODY MASS: " + str(self.body.mass())) + print("ROCKET TOTAL MASS: " + str(self.rocket.total_mass())) + + print("Atmosphere density: " + str(self.body.atmosphere.density_at_height(self.y, self.body.g(G=self.universe.G, height=self.y)))) + + #https://www.grc.nasa.gov/www/k-12/airplane/drageq.html + drag_force = (1/2) * self.body.atmosphere.density_at_height(self.y, self.body.g(G=self.universe.G, height=self.y)) * (self.speed_y ** 2) * self.rocket.drag_coefficient * self.rocket.cross_sectional_area + print("Drag: " + str(drag_force)) #drag can be negative too? + + downwards_force = gravitational_force + drag_force #shouldnt delta influence, TODO: WAIT DRAG COULD BE POSITIVE OR NEGATIVE + print("Downwards force: " + str(downwards_force)) + + #update velocity based on resultant force + total_force = upwards_force - downwards_force + print("Total force: " + str(total_force)) + + acceleration = total_force / self.rocket.total_mass() #mayb we need momentum?? + print("Acceleration: " + str(acceleration)) + self.speed_y = self.speed_y + (acceleration * delta) #i think thir swrong + + #update position based on velocity and delta + self.y += self.speed_y * delta + if self.y < 0: + self.y = 0 + self.speed_y = 0 + + print("Speed: " + str(self.speed_y)) + print("Height: " + str(self.y)) + + print("") + + self.ticks += 1 + self.time += delta + + def snapshot(self) -> Simulation_Snapshot: + return Simulation_Snapshot(self.universe, self.body, self.rocket) + + def str_snapshot(self) -> str: + return str(self.universe) + "\n" + \ + str(self.body) + "\n" + \ + str(self.rocket) \ No newline at end of file diff --git a/universe.py b/universe.py new file mode 100644 index 0000000..2d859e8 --- /dev/null +++ b/universe.py @@ -0,0 +1,8 @@ +class Universe(): + def __init__(self, name: str, G: float, plank: float): + self.name = name + self.G = G + self.plank = plank + + def __str__(self): + return "kuu" \ No newline at end of file |