Skip to content

Commit 838daf3

Browse files
Merge pull request #434 from RocketPy-Team/enh/liquid-motors-draw
ENH: liquid motors draw
2 parents 033e8d3 + 33c3116 commit 838daf3

File tree

4 files changed

+140
-0
lines changed

4 files changed

+140
-0
lines changed

rocketpy/motors/liquid_motor.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,9 @@ def add_tank(self, tank, position):
444444
self.positioned_tanks.append({"tank": tank, "position": position})
445445
reset_funcified_methods(self)
446446

447+
def draw(self):
448+
return self.plots.draw()
449+
447450
def info(self):
448451
"""Prints out basic data about the Motor."""
449452
self.prints.all()

rocketpy/motors/tank.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,9 @@ def inertia(self):
410410
"""
411411
return self.liquid_inertia + self.gas_inertia
412412

413+
def draw(self):
414+
"""Draws the tank geometry."""
415+
return self.plots.draw()
413416

414417
class MassFlowRateBasedTank(Tank):
415418
"""Class to define a tank based on mass flow rates inputs. This class

rocketpy/plots/liquid_motor_plots.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
import copy
2+
3+
import matplotlib.pyplot as plt
4+
import numpy as np
5+
from matplotlib.patches import Polygon
6+
7+
from rocketpy.plots import _generate_nozzle
8+
9+
110
class _LiquidMotorPlots:
211
"""Class that holds plot methods for LiquidMotor class.
312
@@ -256,6 +265,73 @@ def I_23(self, lower_limit=None, upper_limit=None):
256265

257266
return None
258267

268+
def _generate_positioned_tanks(self, translate=(0, 0), csys=1):
269+
"""Generates a list of patches that represent the tanks of the
270+
liquid_motor.
271+
272+
Parameters
273+
----------
274+
None
275+
276+
Returns
277+
-------
278+
patches : list
279+
List of patches that represent the tanks of the liquid_motor.
280+
"""
281+
colors = {
282+
0: ("black", "dimgray"),
283+
1: ("darkblue", "cornflowerblue"),
284+
2: ("darkgreen", "limegreen"),
285+
3: ("darkorange", "gold"),
286+
4: ("darkred", "tomato"),
287+
5: ("darkviolet", "violet"),
288+
}
289+
patches = []
290+
for idx, pos_tank in enumerate(self.liquid_motor.positioned_tanks):
291+
tank = pos_tank["tank"]
292+
position = pos_tank["position"]
293+
trans = (position + translate[0], translate[1])
294+
patch = tank.plots._generate_tank(trans, csys)
295+
patch.set_facecolor(colors[idx][1])
296+
patch.set_edgecolor(colors[idx][0])
297+
patches.append(patch)
298+
return patches
299+
300+
def _draw_center_of_interests(self, ax, translate=(0, 0)):
301+
# center of dry mass position
302+
# center of wet mass time = 0
303+
# center of wet mass time = end
304+
return None
305+
306+
def draw(self):
307+
fig, ax = plt.subplots(facecolor="#EEEEEE")
308+
309+
patches = self._generate_positioned_tanks()
310+
for patch in patches:
311+
ax.add_patch(patch)
312+
313+
# add the nozzle
314+
ax.add_patch(_generate_nozzle(self.liquid_motor, translate=(0, 0)))
315+
316+
# find the maximum and minimum x and y values of the tanks
317+
x_min = y_min = np.inf
318+
x_max = y_max = -np.inf
319+
for patch in patches:
320+
x_min = min(x_min, patch.xy[:, 0].min())
321+
x_max = max(x_max, patch.xy[:, 0].max())
322+
y_min = min(y_min, patch.xy[:, 1].min())
323+
y_max = max(y_max, patch.xy[:, 1].max())
324+
325+
ax.set_aspect("equal")
326+
ax.legend(bbox_to_anchor=(1.05, 1), loc="upper left")
327+
ax.grid(True, linestyle="--", linewidth=0.5)
328+
ax.set_ylim(y_min - 0.25, y_max + 0.25)
329+
ax.set_xlim(x_min - 0.10, x_max + 0.10)
330+
ax.set_xlabel("Position (m)")
331+
ax.set_ylabel("Radius (m)")
332+
ax.set_title("Liquid Motor Geometry")
333+
plt.show()
334+
259335
def all(self):
260336
"""Prints out all graphs available about the LiquidMotor. It simply calls
261337
all the other plotter methods in this class.

rocketpy/plots/tank_plots.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
import matplotlib.pyplot as plt
2+
import numpy as np
3+
from matplotlib.animation import FuncAnimation
4+
from matplotlib.patches import Polygon, Rectangle
5+
6+
17
class _TankPlots:
28
"""Class that holds plot methods for Tank class.
39
@@ -22,9 +28,61 @@ def __init__(self, tank):
2228
"""
2329

2430
self.tank = tank
31+
self.name = tank.name
32+
self.geometry = tank.geometry
2533

2634
return None
2735

36+
def _generate_tank(self, translate=(0, 0), csys=1):
37+
"""Generates a matplotlib patch object that represents the tank.
38+
39+
Parameters
40+
----------
41+
ax : matplotlib.axes.Axes, optional
42+
Axes object to plot the tank on. If None, a new figure and axes
43+
will be created.
44+
translate : tuple, optional
45+
Tuple of floats that represents the translation of the tank
46+
geometry.
47+
48+
Returns
49+
-------
50+
tank : matplotlib.patches.Polygon
51+
Polygon object that represents the tank.
52+
"""
53+
# get positions of all points
54+
x = csys * self.geometry.radius.x_array + translate[0]
55+
y = csys * self.geometry.radius.y_array + translate[1]
56+
x = np.concatenate([x, x[::-1]])
57+
y = np.concatenate([y, -y[::-1]])
58+
xy = np.column_stack([x, y])
59+
60+
tank = Polygon(
61+
xy,
62+
label=self.name,
63+
facecolor="dimgray",
64+
edgecolor="black",
65+
)
66+
# Don't set any plot config here. Use the draw methods for that
67+
return tank
68+
69+
def draw(self):
70+
fig, ax = plt.subplots(facecolor="#EEEEEE")
71+
72+
ax.add_patch(self._generate_tank())
73+
74+
ax.set_aspect("equal")
75+
ax.grid(True, linestyle="--", linewidth=0.5)
76+
77+
ax.set_xlabel("Length (m)")
78+
ax.set_ylabel("Radius (m)")
79+
ax.set_title("Tank Geometry")
80+
81+
x_max = self.geometry.radius.x_array.max()
82+
y_max = self.geometry.radius.y_array.max()
83+
ax.set_xlim(-1.2 * x_max, 1.2 * x_max)
84+
ax.set_ylim(-1.5 * y_max, 1.5 * y_max)
85+
2886
def all(self):
2987
"""Prints out all graphs available about the Tank. It simply calls
3088
all the other plotter methods in this class.

0 commit comments

Comments
 (0)