Skip to content

Commit 096f230

Browse files
committed
First implementation of wind into the simulator, turning it from 2 DOF to 3 DOF
1 parent 2671b1c commit 096f230

File tree

8 files changed

+386
-262
lines changed

8 files changed

+386
-262
lines changed

examples/example_configurations.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@
133133
""" https://maps.app.goo.gl/rZT6MRLqHneA7wNX7 """
134134
altitude_SA = 1401 # m, Spaceport America's elevation
135135
""" https://www.spaceportamerica.com/faq/#toggle-id-15 """
136-
launch_angle_SAC = 86 # deg from horizontal
136+
launch_rail_elevation_SAC = 86 # deg from horizontal
137137
""" How the standard launch angle at Spaceport America Cup was determined
138138
139139
ESRA changed it to 86° for 2024, as noted in the forum:
@@ -152,7 +152,7 @@
152152
launchpad_pressure = launchpad_pressure_SAC,
153153
launchpad_temp = launchpad_temp_SAC,
154154
L_launch_rail = L_launch_rail_ESRA_provided_SAC,
155-
launch_angle = launch_angle_SAC,
155+
launch_rail_elevation = launch_rail_elevation_SAC,
156156
local_T_lapse_rate = T_lapse_rate_SA,
157157
latitude = latitude_SA,
158158
altitude = altitude_SA
@@ -165,6 +165,7 @@
165165
Cd_brakes = 1,
166166
max_deployment_angle = 45, # deg
167167
max_deployment_rate = 5, # deg/s
168+
# TODO: add max retraction rate based on what ours can do
168169
)
169170

170171
if __name__ == "__main__":

rocketflightsim/flight_simulation.py

Lines changed: 235 additions & 133 deletions
Large diffs are not rendered by default.

rocketflightsim/rocket_classes.py

Lines changed: 55 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Define Motor, Rocket, LaunchConditions, and Airbrakes classes
1+
# Define classes used by the package
22

33
import numpy as np
44

@@ -10,13 +10,13 @@ class Motor:
1010
The Motor class is used to store the properties of a rocket motor. The properties are:
1111
1212
- dry_mass: mass of the motor without fuel (kg)
13-
- thrust_curve: dictionary of thrust (N) at time (s after ignition)
13+
- thrust_curve: dictionary of thrust (N) produced by the motor at time after ignition (s)
1414
- total_impulse: total impulse of the motor (Ns)
1515
- burn_time: time it takes for the motor to burn all of its fuel (s)
16-
- fuel_mass_curve: dictionary of mass (kg) at time (s after ignition)
16+
- fuel_mass_curve: dictionary of mass (kg) at time after ignition (s)
1717
- fuel_mass: total mass of fuel in the motor before ignition (kg)
1818
19-
If fuel_mass_curve is not provided but feul_mass is, fuel_mass_curve is calculated from the thrust_curve and fuel_mass (assuming fuel burn is proportional to thrust). If fuel_mass_curve is provided, fuel_mass is set to the initial mass in fuel_mass_curve. If neither are provided, fuel_mass and fuel_mass_curve are set to 0.
19+
If fuel_mass_curve is not provided but fuel_mass is, fuel_mass_curve is calculated from the thrust_curve and fuel_mass (assuming fuel burn is proportional to thrust). If fuel_mass_curve is provided, fuel_mass is set to the initial mass in fuel_mass_curve. If neither are provided, fuel_mass and fuel_mass_curve are set to 0.
2020
"""
2121

2222
def __init__(
@@ -111,34 +111,33 @@ def Cd_A_rocket_fn(Ma): return Cd_rocket_at_Ma * A_rocket
111111
# TODO: make it actually operate as a constant if it's not a function
112112
self.Cd_A_rocket = Cd_A_rocket_fn
113113

114-
""" TODO Adding wind to the simulation
114+
""" TODO Improve wind in the simulation
115115
116-
For first implementation:
117-
- wind will only act in directions parallel to the ground
118-
- wind will have a constant speed and direction for the entire flight
119-
- wind will only affect the rocket's relative airspeed
120-
- lateral forces will not be considered
121-
- wind will not affect flight from ignition to launch rail clearance
122-
- at launch rail clearance, the rocket will instantly have the wind's velocity added to its velocity vector (instantly weathercock the rocket, keeping the 0 angle of attack assumption used in the simulator)
116+
First (current) implementation:
117+
- wind only acts in directions parallel to the ground
118+
- wind has constant speed and direction for the entire flight
119+
- wind only affects a rocket's airspeed, affecting drag and angle of attack
120+
- lateral forces not considered
121+
- wind has no effect on flight from ignition to launch rail clearance
122+
- at rail clearance, a rocket instantly has 20% of the wind's velocity added to its velocity vector to get the new airspeed, then the full vector added at burnout. Placeholder for a better mode of transition from the angle of attack leaving the launch rail to a 0 deg AoA
123123
124+
Next up:
125+
- Use this to get data for Spaceport America for the example configuration: https://www.dropbox.com/sh/swi7jrl14evqmap/AADW6GMVIv87KkOBY1-flsoIa?e=1
126+
- Note that time is in UTC
127+
- Also use it to add to the Prometheus launch conditions in the airbrakes repo
128+
- Remember that launches can't happen if wind > 20mph, so don't consider data with wind speeds above that when trying to find an average
129+
- after comp, incorporate looking at/recording/visualizing flightpath moving in 3D/relative to the launchpad
124130
125-
In the simulation, need to add the wind speed to the rocket's velocity vector and have that relative airspeed vector used to determine the drag force and the rocket's angle of attack (but not the rocket's displacement, which should still be calculated using the rocket's velocity vector).
126-
127-
Use this to get data for Spaceport America for the example configuration: https://www.dropbox.com/sh/swi7jrl14evqmap/AADW6GMVIv87KkOBY1-flsoIa?e=1
128-
Note that time is in UTC
129-
Also use it to add to the Prometheus launch conditions in the airbrakes repo
130-
Remember that launches can't happen if wind > 20mph, so don't consider data with wind speeds above that when trying to find an average
131-
132-
Is it worth describing the wind as None when not specified and having the simulator run faster by not having to add the wind speed to the velocity vector if it's None?
133-
134-
Could be added later:
135-
Varying wind speed and direction with altitude or time, gusts, etc
136-
- varying_wind_speed: list of tuples
137-
- Each tuple contains the time (s after ignition) and the wind speed (m/s) at that time. Wind speed is relative to the ground.
138-
- varying_wind_direction: list of tuples
139-
- Each tuple contains the time (s after ignition) and the direction of the wind (deg). 0 is a headwind, 90 is a crosswind from the right, 180 is a tailwind, 270 is a crosswind from the left.
140-
- wind_gusts: list of tuples
141-
- Each tuple contains the time (s after ignition) and the wind speed (m/s) at that time. Wind speed is relative to the ground.
131+
Could be added later:
132+
- possibly set windspeed as None when not specified and have the simulator run faster by not having to deal with wind. Likely after the break up of the simulation function into different functions for different phases of flight. Maybe a series of sim functions will be chosen from?
133+
- Varying wind speed and direction with altitude or time, gusts, etc
134+
- varying_wind_speed: list of tuples
135+
- Each tuple contains the time (s after ignition) and the wind speed (m/s) at that time. Wind speed is relative to the ground.
136+
- varying_wind_heading: list of tuples
137+
- Each tuple contains the time (s after ignition) and the direction of the wind (deg). 0 is a headwind, 90 is a crosswind from the right, 180 is a tailwind, 270 is a crosswind from the left.
138+
- wind_gusts: list of tuples
139+
- Each tuple contains the time (s after ignition) and the wind speed (m/s) at that time. Wind speed is relative to the ground.
140+
- vertical wind/updrafts/downdrafts
142141
"""
143142

144143
class LaunchConditions:
@@ -152,31 +151,33 @@ class LaunchConditions:
152151
Temperature at the launchpad (°C).
153152
L_launch_rail : float
154153
Length of the launch rail (m).
155-
launch_angle : float
156-
Launch angle from horizontal (deg).
154+
launch_rail_elevation : float
155+
Angle of the launch rail from horizontal (deg).
156+
launch_driection : float
157+
Direction of the launch rail (deg). 0 is north, 90 is east, 180 is south, 270 is west.
157158
local_gravity : float
158159
Acceleration due to gravity at the launch site (m/s^2).
159160
local_T_lapse_rate : float
160161
Temperature lapse rate at the launch site (°C/m, K/m).
161162
mean_wind_speed : float
162163
Mean wind speed relative to the ground (m/s).
163-
wind_direction : float
164-
Direction of the (mean) wind relative to the launch direction (deg). 0 is a headwind, 90 is a crosswind from the right, 180 is a tailwind, 270 is a crosswind from the left.
164+
wind_heading : float
165+
Direction the (mean) wind is headed towards (deg). 0 is north, 90 is east, 180 is south, 270 is west.
165166
"""
166-
167+
# TODO: maybe have it calculate the atmospheric conditions on the ground in init?
167168
def __init__(
168169
self,
169170
launchpad_pressure: float,
170171
launchpad_temp: float,
171172
L_launch_rail: float,
172-
launch_angle: float = 90,
173+
launch_rail_elevation: float = 90,
174+
launch_rail_direction: float = 0,
173175
local_gravity: float = None,
174176
local_T_lapse_rate: float = con.T_lapse_rate,
175177
latitude: float = None,
176178
altitude: float = 0,
177-
# better way to do wind, take a launch direction and a wind direction and calculate the angle between them, then could use the sim for looking at flightpath moving in 3D/relative to the launchpad, but still use the same computational power as just a relative wind direction
178-
mean_wind_speed = None,
179-
wind_direction = 0,
179+
mean_wind_speed = 0,
180+
wind_heading = 0,
180181
):
181182
"""Initializes the LaunchConditions object.
182183
@@ -188,8 +189,10 @@ def __init__(
188189
Temperature at the launchpad (°C).
189190
L_launch_rail : float
190191
Length of the launch rail (m).
191-
launch_angle : float, optional
192-
Launch angle from horizontal (deg). Defaults to 90 (vertical launch).
192+
launch_rail_elevation : float
193+
Angle of the launch rail from horizontal (deg). Defaults to 90 (vertical launch rail).
194+
launch_driection : float
195+
Direction of the launch rail (deg). 0 is north, 90 is east, 180 is south, 270 is west. Defaults to 0 (north).
193196
local_gravity : float, optional
194197
Acceleration due to gravity at the launch site (m/s^2). Defaults to 9.80665.
195198
local_T_lapse_rate : float, optional
@@ -199,14 +202,15 @@ def __init__(
199202
altitude : float, optional
200203
Altitude of the launch site (m ASL). Used along with latitude to calculate local gravity if local_gravity is not provided. Defaults to 0.
201204
mean_wind_speed : float, optional
202-
Mean wind speed relative to the ground (m/s). Defaults to None.
203-
wind_direction : float, optional
204-
Direction of the (mean) wind relative to the launch direction (deg). 0 is a headwind, 90 is a crosswind from the right, 180 is a tailwind, 270 is a crosswind from the left. Defaults to 0 (headwind).
205+
Mean wind speed relative to the ground (m/s). Defaults to 0.
206+
wind_heading : float, optional
207+
Direction the (mean) wind is headed towards (deg). 0 is north, 90 is east, 180 is south, 270 is west. Defaults to 0.
205208
"""
206209
self.launchpad_pressure = launchpad_pressure
207210
self.launchpad_temp = launchpad_temp + 273.15
208211
self.L_launch_rail = L_launch_rail
209-
self.launch_angle = launch_angle
212+
self.launch_rail_elevation = launch_rail_elevation
213+
self.launch_rail_direction = launch_rail_direction
210214

211215
self.local_T_lapse_rate = local_T_lapse_rate
212216

@@ -218,7 +222,7 @@ def __init__(
218222
self.local_gravity = con.F_gravity
219223

220224
self.mean_wind_speed = mean_wind_speed
221-
self.wind_direction = wind_direction
225+
self.wind_heading = wind_heading
222226

223227
class Airbrakes:
224228
"""
@@ -233,7 +237,7 @@ class Airbrakes:
233237
Cd_brakes : float
234238
Coefficient of drag of the airbrakes.
235239
max_deployment_angle : float
236-
Maximum angle that the flaps can deploy to (deg).
240+
Maximum angle that the flaps can deploy to (deg).
237241
max_deployment_rate : float
238242
Maximum rate at which the airbrakes can be deployed (deg/s).
239243
max_retraction_rate : float
@@ -280,19 +284,19 @@ class StateVector:
280284
"""
281285
The StateVector class is used to store the state of the rocket at a given time. The state is stored as a dictionary with the following keys:
282286
287+
- launch_conditions: The LaunchConditions object associated with the flight.
283288
- t: time (s)
284-
# do this after adding wind, before breaking stages of flight simulator into separate functions
289+
# do this for breaking stages of flight simulator into separate functions
285290
"""
286-
287-
291+
288292

289293
class PastFlight ():
290294
"""
291295
Stores the rocket, launch conditions, and apogee of a past flight
292-
likely add more things like max speed, max acceleration later
296+
likely add more things like max speed, max acceleration later. Also the option to feed a full flightpath, good for comparisons of sim projection to actual flightpaths
293297
"""
294298

295-
def __init__(self, rocket, launch_conditions, apogee, name = None):
299+
def __init__(self, rocket, launch_conditions, apogee = None, name = None):
296300
self.rocket = rocket
297301
self.launch_conditions = launch_conditions
298302
self.apogee = apogee

rocketflightsim/tools/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
### `/rocketflightsim/tools/`
22
Contains tools that perform various tasks that use the main library.
3+
4+
TODO: add a script that uses the thrustcurve.org API for motor selection

0 commit comments

Comments
 (0)