Skip to content

Commit e79345a

Browse files
Merge branch 'develop' into enh/environment_analysis
2 parents 6940ca5 + b7446e2 commit e79345a

35 files changed

+10817
-8890
lines changed

README.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,14 @@ RocketPy is the next-generation trajectory simulation solution for High-Power Ro
8282
</ul>
8383
</details>
8484

85+
<details>
86+
<summary>Integration with MATLAB®</summary>
87+
<ul>
88+
<li>Straightforward way to run RocketPy from MATLAB®</li>
89+
<li>Convert RocketPy results to MATLAB® variables so that they can be processed by MATLAB®</li>
90+
</ul>
91+
</details>
92+
8593
<br>
8694

8795
## Validation
@@ -91,11 +99,11 @@ RocketPy's features have been validated in our latest [research article publishe
9199
The table below shows a comparison between experimental data and the output from RocketPy.
92100
Flight data and rocket parameters used in this comparison were kindly provided by [EPFL Rocket Team](https://github.com/EPFLRocketTeam) and [Notre Dame Rocket Team](https://ndrocketry.weebly.com/).
93101

94-
| Mission | Result Paramater | RocketPy | Measured | Relative Error |
102+
| Mission | Result Parameter | RocketPy | Measured | Relative Error |
95103
|:-----------------------:|:-----------------------|:---------:|:---------:|:--------------:|
96104
| Bella Lui Kaltbrumn | Apogee altitude (m) | 461.03 | 458.97 | **0.45 %** |
97105
| Bella Lui Kaltbrumn | Apogee time (s) | 10.61 | 10.56 | **0.47 %** |
98-
| Bella Lui Kaltbrumn | Maximum velocity (m/s) | 86.18 | 90.00 | **4.24 %** |
106+
| Bella Lui Kaltbrumn | Maximum velocity (m/s) | 86.18 | 90.00 | **-4.24 %** |
99107
| NDRT launch vehicle | Apogee altitude (m) | 1,310.44 | 1,320.37 | **-0.75 %** |
100108
| NDRT launch vehicle | Apogee time (s) | 16.77 | 17.10 | **-1.90 %** |
101109
| NDRT launch vehicle | Maximum velocity (m/s) | 172.86 | 168.95 | **2.31 %** |

docs/conf.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@
2020

2121
project = "RocketPy"
2222
copyright = "2020, Projeto Jupiter"
23+
2324
author = "Giovani Hidalgo Ceotto"
2425

2526
# The full version, including alpha/beta/rc tags
26-
release = "0.9.9"
27+
release = "0.10.0"
2728

2829

2930
# -- General configuration ---------------------------------------------------

docs/matlab/Getting_Started.html

Lines changed: 530 additions & 0 deletions
Large diffs are not rendered by default.

docs/matlab/Getting_Started.m

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
%% Getting Started with RocketPy in MATLAB®
2+
% In this Live Script, you will learn how to run RocketPy using the MATLAB®
3+
% environment.
4+
%
5+
% First things first: clone/download RocketPy's repository and set it as your
6+
% MATLAB® working directory so that you can run this live script without any issues.
7+
%
8+
% After that, we start by configuring our Python environment. You can do so
9+
% by following the guidelines presented in the MATLAB® documentation: <https://www.mathworks.com/help/matlab/matlab_external/install-supported-python-implementation.html?searchHighlight=python&s_tid=srchtitle_python_4
10+
% Configure Your System to Use Python - MATLAB & Simulink (mathworks.com)>.
11+
%
12+
% Once the Python environment is configured, RocketPy needs to installed using
13+
% |pip| as outlined in RocketPy's documentation: <https://docs.rocketpy.org/en/latest/user/installation.html#quick-install-using-pip
14+
% Installation — RocketPy documentation>.
15+
%
16+
% Finally, all the prerequisites are complete and you can comeback to MATLAB®!
17+
% We just need to set the execution mode as out of process and start working.
18+
% MATLAB® can run Python scripts and functions in a separate process. Running
19+
% Python in a separate process enables you to:
20+
%%
21+
% * Use some third-party libraries in the Python code that are not compatible
22+
% with MATLAB®.
23+
% * Isolate the MATLAB® process from crashes in the Python code.
24+
25+
pyenv('ExecutionMode','OutOfProcess');
26+
%%
27+
% Note: if MATLAB® is not able to find Python automatically, you may have to
28+
% run the command line above including a path to the Python exectuable installed
29+
% on your computer:
30+
31+
% pyenv('ExecutionMode','OutOfProcess', 'Version', '/path/to/python/executable');
32+
%%
33+
% Now, we will go through a simplified rocket trajectory simulation to get you
34+
% started. Let's start by importing the rocketpy module.
35+
36+
rocketpy = py.importlib.import_module('rocketpy');
37+
%% Setting Up a Simulation
38+
% Creating an Environment for Spaceport America
39+
40+
% rocketpy.Environment(railLength, latitude, longitude, elevation);
41+
Env = rocketpy.Environment(pyargs(...
42+
'railLength', 5.2, ...
43+
'latitude', 32.990254, ...
44+
'longitude',-106.974998, ...
45+
'elevation', 1400 ...
46+
));
47+
%%
48+
% To get weather data from the GFS forecast, available online, we run the following
49+
% lines.
50+
%
51+
% First, we set tomorrow's date.
52+
53+
Tomorrow = datetime('tomorrow');
54+
Env.setDate({int32(Tomorrow.Year), int32(Tomorrow.Month), int32(Tomorrow.Day), int32(12)}) % Hour given in UTC time (noon UTC)
55+
%%
56+
% Now, we tell our Environment object to retrieve a weather forecast for our
57+
% specified location and date using GFS:
58+
59+
Env.setAtmosphericModel(pyargs( ...
60+
'type', "Forecast", ...
61+
'file', "GFS" ...
62+
))
63+
%%
64+
% We can see what the weather will look like by calling the info method!
65+
66+
Env.info()
67+
%%
68+
% Plots will open in a separate window, so be sure to run this last cell to
69+
% see them!
70+
%% Creating a Motor
71+
% A solid rocket motor is used in this case. To create a motor, the SolidMotor
72+
% class is used and the required arguments are given.
73+
%
74+
% The SolidMotor class requires the user to have a thrust curve ready. This
75+
% can come either from a .eng file for a commercial motor, such as below, or a
76+
% .csv file from a static test measurement.
77+
%
78+
% Besides the thrust curve, other parameters such as grain properties and nozzle
79+
% dimensions must also be given.
80+
81+
Pro75M1670 = rocketpy.SolidMotor(pyargs( ...
82+
'thrustSource', "../../data/motors/Cesaroni_M1670.eng", ...
83+
'burnOut', 3.9, ...
84+
'grainNumber', int32(5), ...
85+
'grainSeparation', 5 / 1000, ...
86+
'grainDensity', 1815, ...
87+
'grainOuterRadius', 33 / 1000, ...
88+
'grainInitialInnerRadius', 15 / 1000, ...
89+
'grainInitialHeight', 120 / 1000, ...
90+
'nozzleRadius', 33 / 1000, ...
91+
'throatRadius', 11 / 1000, ...
92+
'interpolationMethod', "linear" ...
93+
));
94+
%%
95+
% To see what our thrust curve looks like, along with other import properties,
96+
% we invoke the info method yet again. You may try the allInfo method if you want
97+
% more information all at once!
98+
99+
Pro75M1670.info()
100+
%%
101+
% Plots will open in a separate window, so be sure to run this last cell to
102+
% see them!
103+
%% Creating a Rocket
104+
% A rocket is composed of several components. Namely, we must have a motor (good
105+
% thing we have the Pro75M1670 ready), a couple of aerodynamic surfaces (nose
106+
% cone, fins and tail) and parachutes (if we are not launching a missile).
107+
%
108+
% Let's start by initializing our rocket, named Calisto, supplying it with the
109+
% Pro75M1670 engine, entering its inertia properties, some dimensions and also
110+
% its drag curves.
111+
112+
Calisto = rocketpy.Rocket(pyargs( ...
113+
'motor', Pro75M1670, ...
114+
'radius', 127 / 2000, ...
115+
'mass', 19.197 - 2.956, ...
116+
'inertiaI', 6.60, ...
117+
'inertiaZ', 0.0351, ...
118+
'distanceRocketNozzle', -1.255, ...
119+
'distanceRocketPropellant', -0.85704, ...
120+
'powerOffDrag', "../../data/calisto/powerOffDragCurve.csv", ...
121+
'powerOnDrag', "../../data/calisto/powerOnDragCurve.csv" ...
122+
));
123+
124+
Calisto.setRailButtons([0.2, -0.5])
125+
% Adding Aerodynamic Surfaces
126+
% Now we define the aerodynamic surfaces. They are really straight forward.
127+
128+
NoseCone = rocketpy.Rocket.addNose(pyargs( ...
129+
'self', Calisto, ...
130+
'length', 0.55829, ...
131+
'kind', "vonKarman", ...
132+
'distanceToCM', 0.71971 ...
133+
));
134+
135+
FinSet = rocketpy.Rocket.addFins(pyargs( ...
136+
'self', Calisto, ...
137+
'n', int32(4), ...
138+
'span', 0.100, ...
139+
'rootChord', 0.120, ...
140+
'tipChord', 0.040, ...
141+
'distanceToCM', -1.04956 ...
142+
));
143+
144+
Tail = rocketpy.Rocket.addTail(pyargs( ...
145+
'self', Calisto, ...
146+
'topRadius', 0.0635, ...
147+
'bottomRadius', 0.0435, ...
148+
'length', 0.060, ...
149+
'distanceToCM', -1.194656 ...
150+
));
151+
% Adding Parachutes
152+
% Finally, we have parachutes! Calisto will have two parachutes, Drogue and
153+
% Main.
154+
%
155+
% Both parachutes are activated by some special algorithm, which is usually
156+
% really complex and a trade secret. Most algorithms are based on pressure sampling
157+
% only, while some also use acceleration info.
158+
%
159+
% RocketPy allows you to define a trigger function which will decide when to
160+
% activate the ejection event for each parachute. This trigger function is supplied
161+
% with pressure measurement at a predefined sampling rate. This pressure signal
162+
% is usually noisy, so artificial noise parameters can be given. Call
163+
164+
% py.help(rocketpy.Rocket.addParachute)
165+
%%
166+
% for more details. Furthermore, the trigger function also receives the complete
167+
% state vector of the rocket, allowing us to use velocity, acceleration or even
168+
% attitude to decide when the parachute event should be triggered.
169+
%
170+
% Here, we define our trigger functions rather simply using Python. Unfortunately,
171+
% defining these with MATLAB® code is not yet possible.
172+
173+
% Drogue parachute is triggered when vertical velocity is negative, i.e. rocket is falling past apogee
174+
drogueTrigger = py.eval("lambda p, y: y[5] < 0", py.dict);
175+
176+
% Main parachute is triggered when vertical velocity is negative and altitude is below 800 AGL
177+
mainTrigger = py.eval("lambda p, y: (y[5] < 0) and (y[2] < 800 + 1400)", py.dict);
178+
%%
179+
% Now we add both the drogue and the main parachute to our rocket.
180+
181+
Main = rocketpy.Rocket.addParachute(pyargs( ...
182+
'self', Calisto, ...
183+
'name', "Main", ...
184+
'CdS', 10.0, ...
185+
'trigger', mainTrigger, ...
186+
'samplingRate', 105, ...
187+
'lag', 1.5, ...
188+
'noise', py.tuple({0, 8.3, 0.5}) ...
189+
));
190+
191+
Drogue = rocketpy.Rocket.addParachute(pyargs( ...
192+
'self', Calisto, ...
193+
'name', "Drogue", ...
194+
'CdS', 1.0, ...
195+
'trigger', drogueTrigger, ...
196+
'samplingRate', 105, ...
197+
'lag', 1.5, ...
198+
'noise', py.tuple({0, 8.3, 0.5}) ...
199+
));
200+
%%
201+
% |Just be careful if you run this last cell multiple times! If you do so, your
202+
% rocket will end up with lots of parachutes which activate together, which may
203+
% cause problems during the flight simulation. We advise you to re-run all cells
204+
% which define our rocket before running this, preventing unwanted old parachutes.
205+
% Alternatively, you can run the following lines to remove parachutes.|
206+
207+
% Calisto.parachutes.remove(Drogue)
208+
% Calisto.parachutes.remove(Main)
209+
%% |Simulating a Flight|
210+
% |Simulating a flight trajectory is as simple as initializing a Flight class
211+
% object givin the rocket and environnement set up above as inputs. The launch
212+
% rail inclination and heading are also given here.|
213+
214+
TestFlight = rocketpy.Flight(pyargs(...
215+
'rocket', Calisto, ...
216+
'environment',Env, ...
217+
'inclination', 85, ...
218+
'heading', 0 ...
219+
));
220+
%% |Analyzing the Results|
221+
% |RocketPy gives you many plots, thats for sure! They are divided into sections
222+
% to keep them organized. Alternatively, see the Flight class documentation to
223+
% see how to get plots for specific variables only, instead of all of them at
224+
% once.|
225+
226+
TestFlight.allInfo()
227+
%%
228+
% Plots will open in a separate window, so be sure to run this last cell to
229+
% see them!
230+
%% Working with Data Generated by RocketPy in MATLAB®
231+
% You can access the entire trajectory solution matrix with the following line
232+
% of code. The returned matrix contain the following columns: time $t$ (s), $x$
233+
% (m), $y$ (m), $z$ (m), $v_x$ (m/s), $v_y$ (m/s), $v_z$ (m/s), $q_0$, $q_1$,
234+
% $q_2$, $q_3$, $\omega_1$ (rad/s), $\omega_2$ (rad/s), $\omega_3$ (rad/s).
235+
236+
solution_matrix = double(py.numpy.array(TestFlight.solution))
237+
%%
238+
% Support for accessing secondary values calculated during post processing,
239+
% such as energy, mach number, and angle of attack, is also available for all
240+
% versions of RocketPy greater than or equal to version 0.11.0.
241+
%
242+
% To showcase this, let's get the angle of attack of the rocket and plot it
243+
% using MATLAB®:
244+
245+
angle_of_attack = double(TestFlight.angleOfAttack.source)
246+
plot(angle_of_attack(:,1), angle_of_attack(:,2)) % First column is time (s), second is the angle of attack
247+
ylabel('Angle of Attack (Deg)')
248+
xlabel('Time(s)')
249+
xlim([TestFlight.outOfRailTime, 10])
250+
%%
251+
% You can also convert data from other objects besides the Flight class, such
252+
% as from the Environment. For example, let's say you want to get the wind velocity,
253+
% both the x and y component:
254+
255+
wind_velocity_x = double(Env.windVelocityX.source) % First column is altitude (ASL m), while the second one is the speed (m/s)
256+
wind_velocity_y = double(Env.windVelocityY.source) % First column is altitude (ASL m), while the second one is the speed (m/s)
257+
%% Time to Fly!
258+
% This is all you need to get started using RocketPy in MATLAB®! Now it is time
259+
% to play around and create amazing rockets. Have a great launch!

docs/matlab/Getting_Started.mlx

29.9 KB
Binary file not shown.

docs/matlab/matlab.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
MATLAB® Tutorial
2+
================
3+
4+
RocketPy in MATLAB®
5+
--------------------
6+
Did you know you can run RocketPy inside MATLAB®?
7+
8+
MATLAB® provides a nice method to run Python libraries, allowing everyone familiar with MATLAB® to run RocketPy, getting the best of both worlds.
9+
10+
Below, you will find a quick tutorial created using Live Script which reproduces RocketPy's classic Getting Started tutorial.
11+
12+
Download Files
13+
--------------
14+
15+
.. only:: builder_html or readthedocs
16+
17+
You can download the :download:`Live Script <Getting_Started.mlx>` or the :download:`MATLAB® script <Getting_Started.m>` file to follow along.
18+
19+
Tutorial
20+
--------
21+
22+
.. raw:: html
23+
:file: Getting_Started.html

0 commit comments

Comments
 (0)