diff options
author | Baitinq <you@example.com> | 2022-02-10 23:39:43 +0000 |
---|---|---|
committer | Baitinq <you@example.com> | 2022-02-10 23:39:43 +0000 |
commit | 9ebc639fb90a878e6b65800c689b89750b607b33 (patch) | |
tree | 8bc85900051de442743f9c802ac275a62cadaebd /src/simulation.py | |
parent | Started preparation to implement proper altitude calculations and gravity (diff) | |
download | OSLS-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.py | 133 |
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 |