about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBaitinq <you@example.com>2022-02-06 22:52:22 +0000
committerBaitinq <you@example.com>2022-02-06 22:52:22 +0000
commit521da01f6da6c32ccd834c20b7ea457a619361c8 (patch)
tree6f95f89ac0369f4c0e85e6b2a9b6f9c0a1f67008
downloadOSLS-521da01f6da6c32ccd834c20b7ea457a619361c8.tar.gz
OSLS-521da01f6da6c32ccd834c20b7ea457a619361c8.tar.bz2
OSLS-521da01f6da6c32ccd834c20b7ea457a619361c8.zip
Initial Commit
-rw-r--r--.gitignore1
-rw-r--r--atmosphere.py14
-rw-r--r--body.py21
-rw-r--r--engine.py7
-rw-r--r--fuel.py4
-rw-r--r--main.py84
-rw-r--r--rocket.py33
-rw-r--r--simulation.py85
-rw-r--r--universe.py8
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