Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
BUG: fix export ellipses to kml function
  • Loading branch information
Gui-FernandesBR committed Oct 12, 2024
commit 5208984631259efea37ba34876ba41d8a798103f
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"elevation": 113, "gravity": "'Function from R1 to R1 : (height (m)) \u2192 (gravity (m/s\u00b2))'", "latitude": 39.3897, "longitude": -8.288964, "wind_velocity_x_factor": 1.0, "wind_velocity_y_factor": 1.0, "datum": "SIRGAS2000", "timezone": "UTC", "ensemble_member": 12, "radius": 0.0635026504073287, "mass": 15.682085969389227, "I_11_without_motor": 6.321, "I_22_without_motor": 6.338988882158036, "I_33_without_motor": 0.03130204348386302, "I_12_without_motor": 0, "I_13_without_motor": 0, "I_23_without_motor": 0, "power_off_drag": "'Function from R1 to R1 : (Mach Number) \u2192 (Drag Coefficient with Power Off)'", "power_on_drag": "'Function from R1 to R1 : (Mach Number) \u2192 (Drag Coefficient with Power On)'", "power_off_drag_factor": 1.0, "power_on_drag_factor": 1.0, "center_of_mass_without_motor": 0.0, "coordinate_system_orientation": "tail_to_nose", "parachutes": [{"cd_s": 9.964579481480238, "trigger": 800, "sampling_rate": 105, "lag": 1.5400928421750208, "noise": [0, 8.3, 0.5], "name": "Main"}, {"cd_s": 1.053581347292585, "trigger": "apogee", "sampling_rate": 105, "lag": 1.547076677223584, "noise": [0, 8.3, 0.5], "name": "Drogue"}], "motors": [{"thrust_source": [[0, 0], [0.055, 100.0], [0.092, 1500.0], [0.1, 2000.0], [0.15, 2200.0], [0.2, 1800.0], [0.5, 1950.0], [1.0, 2034.0], [1.5, 2000.0], [2.0, 1900.0], [2.5, 1760.0], [2.9, 1700.0], [3.0, 1650.0], [3.3, 530.0], [3.4, 350.0], [3.9, 0.0]], "total_impulse": 6856.354770975974, "burn_start_time": 0, "burn_out_time": 3.9, "dry_mass": 1.815, "dry_I_11": 0.125, "dry_I_22": 0.125, "dry_I_33": 0.002, "dry_I_12": 0, "dry_I_13": 0, "dry_I_23": 0, "nozzle_radius": 0.032730650070270366, "grain_number": 5, "grain_density": 1759.0002074492309, "grain_outer_radius": 0.03242230462181787, "grain_initial_inner_radius": 0.014932033668244029, "grain_initial_height": 0.11986670781368569, "grain_separation": 0.0043804774372666125, "grains_center_of_mass_position": 0.39749334004739806, "center_of_dry_mass_position": 0.317, "nozzle_position": 0.00012776739944301812, "throat_radius": 0.011558987272317063, "interpolate": "linear", "coordinate_system_orientation": "nozzle_to_combustion_chamber", "position": -1.2554668494646906}], "aerodynamic_surfaces": [{"length": 0.5585738309196118, "kind": "vonKarman", "base_radius": 0.0635, "bluffness": 0, "rocket_radius": 0.0635, "name": "Nose Cone", "position": [0, 0, 1.133607250248703]}, {"n": 4, "root_chord": 0.11954751546671595, "tip_chord": 0.05966602935963838, "span": 0.10964031934715668, "rocket_radius": 0.0635, "cant_angle": 0.5, "sweep_length": 0.06, "sweep_angle": null, "airfoil": ["../../../data/calisto/NACA0012-radians.csv", "radians"], "name": "Fins", "position": [0, 0, -1.0514983708842365]}, {"top_radius": 0.06343918078680816, "bottom_radius": 0.04325007199856578, "length": 0.060394317313238605, "rocket_radius": 0.0635, "name": "Tail", "position": [0, 0, [0, 0, -1.194656]]}], "rail_buttons": [{"buttons_distance": 0.6974746622933771, "angular_position": 45, "name": "Rail Buttons", "lower_button_position": -0.6188258915052254, "upper_button_position": 0.07864877078815169}], "rail_length": 5, "inclination": 84.44167248190685, "heading": 54.43860091183173}

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

484 changes: 440 additions & 44 deletions docs/notebooks/monte_carlo_analysis/monte_carlo_class_usage.ipynb

Large diffs are not rendered by default.

26 changes: 19 additions & 7 deletions rocketpy/plots/monte_carlo_plots.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import matplotlib.pyplot as plt
import numpy as np

from ..tools import generate_monte_carlo_ellipses, import_optional_dependency

Expand Down Expand Up @@ -54,14 +55,27 @@ def ellipses(
"The image file was not found. Please check the path."
) from e

(
impact_ellipses,
apogee_ellipses,
try:
apogee_x = np.array(self.monte_carlo.results["apogee_x"])
apogee_y = np.array(self.monte_carlo.results["apogee_y"])
except KeyError:
print("No apogee data found. Skipping apogee ellipses.")
apogee_x = np.array([])
apogee_y = np.array([])
try:
impact_x = np.array(self.monte_carlo.results["x_impact"])
impact_y = np.array(self.monte_carlo.results["y_impact"])
except KeyError:
print("No impact data found. Skipping impact ellipses.")
impact_x = np.array([])
impact_y = np.array([])

Comment thread
Gui-FernandesBR marked this conversation as resolved.
impact_ellipses, apogee_ellipses = generate_monte_carlo_ellipses(
apogee_x,
apogee_y,
impact_x,
impact_y,
) = generate_monte_carlo_ellipses(self.monte_carlo.results)
)

# Create plot figure
plt.figure(figsize=(8, 6), dpi=150)
Expand Down Expand Up @@ -97,9 +111,7 @@ def ellipses(
)

plt.legend()
ax.set_title(
"1$\\sigma$, 2$\\sigma$ and 3$\\sigma$ Monte Carlo Ellipses: Apogee and Landing Points"
)
ax.set_title("1$\\sigma$, 2$\\sigma$ and 3$\\sigma$ Monte Carlo Ellipses")
ax.set_ylabel("North (m)")
ax.set_xlabel("East (m)")

Expand Down
92 changes: 66 additions & 26 deletions rocketpy/simulation/monte_carlo.py
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,7 @@ def export_ellipses_to_kml( # pylint: disable=too-many-statements
origin_lon,
type="all", # TODO: Don't use "type" as a parameter name, it's a reserved word # pylint: disable=redefined-builtin
resolution=100,
color="ff0000ff",
colors=("ffff0000", "ff00ff00"), # impact, apogee
):
"""
Generates a KML file with the ellipses on the impact point, which can be
Expand All @@ -793,9 +793,11 @@ def export_ellipses_to_kml( # pylint: disable=too-many-statements
Number of points to be used to draw the ellipse. Default is 100. You
can increase this number to make the ellipse smoother, but it will
increase the file size. It is recommended to keep it below 1000.
color : str, optional
Color of the ellipse. Default is 'ff0000ff', which is red. Kml files
use an 8 digit HEX color format, see its docs.
colors : tuple[str, str], optional
Colors of the ellipses. Default is ['ffff0000', 'ff00ff00'], which
are blue and green, respectively. The first element is the color of
the impact ellipses, and the second element is the color of the
apogee. The colors are in hexadecimal format (aabbggrr).

Returns
-------
Expand All @@ -812,50 +814,88 @@ def export_ellipses_to_kml( # pylint: disable=too-many-statements
large distances offsets, as the atmospheric conditions may change.
"""
# TODO: The lat and lon should be optional arguments, we can get it from the env
(
impact_ellipses,
apogee_ellipses,
*_,
) = generate_monte_carlo_ellipses(self.results)
# Retrieve monte carlo data por apogee and impact XY position
if type not in ["all", "impact", "apogee"]:
raise ValueError("Invalid type. Options are 'all', 'impact' and 'apogee'")

apogee_x = np.array([])
apogee_y = np.array([])
impact_x = np.array([])
impact_y = np.array([])
if type in ["all", "apogee"]:
try:
apogee_x = np.array(self.results["apogee_x"])
apogee_y = np.array(self.results["apogee_y"])
except KeyError as e:
raise KeyError("No apogee data found. Skipping apogee ellipses.") from e

if type in ["all", "impact"]:
try:
impact_x = np.array(self.results["x_impact"])
impact_y = np.array(self.results["y_impact"])
except KeyError as e:
raise KeyError("No impact data found. Skipping impact ellipses.") from e

(apogee_ellipses, impact_ellipses) = generate_monte_carlo_ellipses(
impact_x,
impact_y,
apogee_x,
apogee_y,
)

outputs = []

if type in ["all", "impact"]:
outputs = outputs + generate_monte_carlo_ellipses_coordinates(
impact_ellipses, origin_lat, origin_lon, resolution=resolution
outputs.extend(
generate_monte_carlo_ellipses_coordinates(
impact_ellipses, origin_lat, origin_lon, resolution=resolution
)
)

if type in ["all", "apogee"]:
outputs = outputs + generate_monte_carlo_ellipses_coordinates(
apogee_ellipses, origin_lat, origin_lon, resolution=resolution
outputs.extend(
generate_monte_carlo_ellipses_coordinates(
apogee_ellipses, origin_lat, origin_lon, resolution=resolution
)
)

# TODO: Non-iterable value output is used in an iterating context PylintE1133:
kml_data = [[(coord[1], coord[0]) for coord in output] for output in outputs]
if all(isinstance(output, list) for output in outputs):
kml_data = [
[(coord[1], coord[0]) for coord in output] for output in outputs
]
else:
raise ValueError("Each element in outputs must be a list")

kml = simplekml.Kml()

for i in range(len(outputs)):
if (type == "all" and i < 3) or (type == "impact"):
ellipse_name = "Impact \u03C3" + str(i + 1)
elif type == "all" and i >= 3:
ellipse_name = "Apogee \u03C3" + str(i - 2)
for i, points in enumerate(kml_data):
if i < len(impact_ellipses):
name = f"Impact Ellipse {i+1}"
ellipse_color = colors[0] # default is blue
else:
ellipse_name = "Apogee \u03C3" + str(i + 1)
name = f"Apogee Ellipse {i +1- len(impact_ellipses)}"
ellipse_color = colors[1] # default is green

mult_ell = kml.newmultigeometry(name=ellipse_name)
mult_ell = kml.newmultigeometry(name=name)
mult_ell.newpolygon(
outerboundaryis=kml_data[i],
name="Ellipse " + str(i),
outerboundaryis=points,
name=name,
)
# Setting ellipse style
mult_ell.tessellate = 1
mult_ell.visibility = 1
mult_ell.style.linestyle.color = color
mult_ell.style.linestyle.color = ellipse_color
mult_ell.style.linestyle.width = 3
mult_ell.style.polystyle.color = simplekml.Color.changealphaint(
100, simplekml.Color.blue
80, ellipse_color
)

kml.newpoint(
name="Launch Pad",
coords=[(origin_lon, origin_lat)],
description="Flight initial position",
)

kml.save(filename)

def info(self):
Expand Down
Loading