about summary refs log tree commit diff
path: root/src/simulation.py
diff options
context:
space:
mode:
authorBaitinq <you@example.com>2022-02-10 23:39:43 +0000
committerBaitinq <you@example.com>2022-02-10 23:39:43 +0000
commit9ebc639fb90a878e6b65800c689b89750b607b33 (patch)
tree8bc85900051de442743f9c802ac275a62cadaebd /src/simulation.py
parentStarted preparation to implement proper altitude calculations and gravity (diff)
downloadOSLS-9ebc639fb90a878e6b65800c689b89750b607b33.tar.gz
OSLS-9ebc639fb90a878e6b65800c689b89750b607b33.tar.bz2
OSLS-9ebc639fb90a878e6b65800c689b89750b607b33.zip
Structured source files into src folder
Diffstat (limited to 'src/simulation.py')
-rw-r--r--src/simulation.py133
1 files changed, 133 insertions, 0 deletions
diff --git a/src/simulation.py b/src/simulation.py
new file mode 100644
index 0000000..106c5a1
--- /dev/null
+++ b/src/simulation.py
@@ -0,0 +1,133 @@
+import math
+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.x = 0#TODO
+        self.y = 0 #TODO: we need to make it so there is height() to calc height based on x and y
+        self.speed_x = 0
+        self.speed_y = 0
+        self.acceleration_x = 0
+        self.acceleration_y = 0
+
+        self.heading = 0
+
+    #simulation logic
+    def tick(self, delta: int) -> None:
+        current_stage = self.rocket.current_stage()
+        #calculate upwards force by fuel       
+        fuel_used = current_stage.total_fuel_used(delta)
+        if current_stage.fuel_mass < fuel_used:
+            fuel_used = current_stage.fuel_mass
+        current_stage.fuel_mass -= fuel_used
+        print("Fuel remaining: " + str(current_stage.fuel_mass))
+                
+        force_x = 0
+        force_y = 0
+        if fuel_used > 0:
+            total_thrust = current_stage.current_thrust(self.body.g(self.universe.G, self.rocket_altitude()), self.heading)
+            force_x = total_thrust[0]
+            force_y = total_thrust[1]
+        
+        print("Thrust X: " + str(force_x))
+        print("Thrust Y: " + str(force_y))
+
+        print("BODY MASS: " + str(self.body.mass()))
+        print("ROCKET TOTAL MASS: " + str(self.rocket.total_mass()))
+
+        #calculate downwards force by drag and gravity
+        g = self.body.g(G=self.universe.G, height=self.rocket_altitude())
+        print("g: " + str(g))
+
+        gravitational_force = g * self.rocket.total_mass()
+        print("Gravity: " + str(gravitational_force))
+
+        #Remove gravity from force
+        force_y -= gravitational_force
+
+        curr_atmospheric_density = self.body.atmosphere.density_at_height(self.rocket_altitude(), g)
+        print("Atmosphere density: " + str(curr_atmospheric_density))
+
+        #TODO: cross sectional area and drag coef for x should b different
+        drag_force_x = (1/2) * curr_atmospheric_density * (self.speed_x ** 2) * self.rocket.s_drag_coefficient() * self.rocket.s_cross_sectional_area()
+        #drag goes against speed
+        if force_x < 0:
+            drag_force_x *= -1
+        print("Drag X: " + str(drag_force_x))
+
+        #https://www.grc.nasa.gov/www/k-12/airplane/drageq.html
+        drag_force_y = (1/2) * curr_atmospheric_density * (self.speed_y ** 2) * self.rocket.s_drag_coefficient() * self.rocket.s_cross_sectional_area()
+        #drag goes against speed
+        if force_y < 0:
+            drag_force_y *= -1
+        print("Drag Y: " + str(drag_force_y))
+
+        #remove drag
+        force_x -= drag_force_x
+        force_y -= drag_force_y
+
+        print("Total Force X: " + str(force_x))
+        print("Total Force Y: " + str(force_y))
+
+        self.acceleration_x = force_x / self.rocket.total_mass()
+        self.acceleration_y = force_y / self.rocket.total_mass()
+        print("Acceleration x: " + str(self.acceleration_x))
+        print("Acceleration y: " + str(self.acceleration_y))
+        
+        self.speed_x = self.speed_x + (self.acceleration_x * delta)
+        self.speed_y = self.speed_y + (self.acceleration_y * delta)
+
+        print("Speed x: " + str(self.speed_x))
+        print("Speed y: " + str(self.speed_y))
+
+        #TODO: WELL CALCULATED? (angle well?)
+        ref_vec = (0, 1)
+        acc_vec = (self.speed_x, self.speed_y)
+        dot = (acc_vec[0] * ref_vec[0]) + (acc_vec[1] * ref_vec[1])
+        det = (acc_vec[0] * ref_vec[1]) - (acc_vec[1] * ref_vec[0])
+        self.heading = math.degrees(math.atan2(det, dot))
+        print("Heading: " + str(self.heading))
+        
+        #update position based on velocity and delta
+        self.x += self.speed_x * delta
+
+        #in future u should be able to go negative y (y and height are different)
+        self.y += self.speed_y * delta
+        if self.y < 0:
+            self.y = 0
+            self.speed_y = 0
+            
+        print("X: " + str(self.x))
+        print("Y: " + str(self.y))
+
+        print("Total Simulation Time: " + str(self.time))
+        print("")
+
+        self.ticks += 1
+        self.time += delta
+
+    def rocket_altitude(self):
+        return self.y #TODO: take into account body and allow for 360 height
+
+    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