diff --git a/operations_const_LoD_in.svg b/operations_const_LoD_in.svg index af7b8b3..8d9596b 100644 --- a/operations_const_LoD_in.svg +++ b/operations_const_LoD_in.svg @@ -6,11 +6,11 @@ - 2023-11-17T08:34:50.752718 + 2024-06-12T16:14:31.101317 image/svg+xml - Matplotlib v3.7.2, https://matplotlib.org/ + Matplotlib v3.6.3, https://matplotlib.org/ @@ -30,8 +30,8 @@ z - - - + - + - - - - - + + + - + - + - - - - - + + + - + - - - - + + + + - + - + - - - - + + + - + - + - - - - - + + + + - + - - - - - + + + + + - + - - - - - + + + + + - + - - - - - + + + + + - + - - - - - + + + + + - + - - - - - - + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + @@ -605,648 +522,564 @@ z - - + - - - - + + + + - + - - - - + + + + - + - + - - - - + + + - + - + - - - - + + + - + - + - - - - + + + - + - - - - + + + + - + - - - - + + + + - + - - - - + + + + - + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - +" clip-path="url(#pf54363163d)" style="fill: none; stroke-dasharray: 1.5,2.475; stroke-dashoffset: 0; stroke: #000000; stroke-width: 1.5"/> - +" clip-path="url(#pf54363163d)" style="fill: none; stroke-dasharray: 1.5,2.475; stroke-dashoffset: 0; stroke: #000000; stroke-width: 1.5"/> - + - + - - - @@ -1256,7 +1089,7 @@ L 648 48.6 - + - - - + - - + - - + + - + - - - + + + - + - - - + + + - + - - - + + + - + - - - + + + - + - - - - + + + + - + - - - - + + + + - + - - - - + + + + - + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - + - - - @@ -1618,15 +1418,15 @@ L 648 48.6 - @@ -1660,27 +1460,6 @@ Q 1278 4363 1576 4613 Q 1875 4863 2516 4863 L 3059 4863 z -" transform="scale(0.015625)"/> - @@ -1688,14 +1467,14 @@ z - - + - @@ -1724,14 +1490,14 @@ z - - + - + + diff --git a/powercurve_const_LoD_in.py b/powercurve_const_LoD_in.py index 41c5577..23a2d3a 100644 --- a/powercurve_const_LoD_in.py +++ b/powercurve_const_LoD_in.py @@ -22,6 +22,7 @@ import matplotlib.pyplot as plt from scipy import optimize as op from pylab import np +from scipy.integrate import solve_ivp mpl.rcParams['font.family'] = "Open Sans" mpl.rcParams.update({'font.size': 18}) mpl.rcParams['figure.figsize'] = 10, 5.625 @@ -354,3 +355,42 @@ def objective_function_3(x, mu_P, f_nP): ax2.plot(wind_speed, np.asarray(elevation_angle_in), 'b', linestyle='-', label=r"$\beta_{\mathrm{i}}$") fig.legend(facecolor="white", edgecolor="white", loc="upper right", bbox_to_anchor=(1,1), bbox_transform=ax1.transAxes) fig.savefig("operations_const_LoD_in.svg") + + +plot_trajectory = True +v_trajectory = 12.5 # m/s wind speed where trajectory is plotted + +def l(t): # tether length + return tether_length_max + v_in*t + +def f(t, b): # db/dt + return v_trajectory/l(t) * ((kite_lift_coefficient_in/kite_drag_coefficient_in) * (np.cos(b) - f_in) - np.sin(b)) + +if plot_trajectory: + f_in = float(reeling_factor_in[int(v_trajectory/wind_speed_delta)]) # reel-in factor [-] + + v_in = v_trajectory*f_in + t_in_trajectory = (tether_length_min - tether_length_max)/(v_in) + b_ideal = np.arccos((np.sqrt(1 + E2in*(1 - f_in**2)) + f_in*E2in)/(1 + E2in)) + + tether_range = np.linspace(tether_length_min, tether_length_max, int(tether_length_max-tether_length_min+1)) + + # Solve ODE for elevation_angle_in + trajectory = solve_ivp(f, (0, t_in_trajectory), [np.deg2rad(elevation_angle_out)], t_eval=np.linspace(0, t_in_trajectory, 100)) + + # reel-out trajectory + fig, ax1 = plt.subplots() + ax1.plot(tether_range*np.cos(np.deg2rad(elevation_angle_out)), tether_range*np.sin(np.deg2rad(elevation_angle_out)), 'k', label="Reel-out") + # reel-in trajectory + ax1.plot(l(trajectory.t) * np.cos(trajectory.y)[0], l(trajectory.t) * np.sin(trajectory.y)[0], label="Reel-in") + # minimum tether length + ax1.plot(np.linspace(-tether_length_min, tether_length_min, int(2*tether_length_min+1)), np.sqrt(tether_length_min**2 - np.linspace(-tether_length_min, tether_length_min, int(2*tether_length_min+1))**2), 'k:', label="Minimum tether length") + # Ideal reel-in trajectory + ax1.plot(tether_range*np.cos(b_ideal), tether_range*np.sin(b_ideal), 'r--', label="Ideal reel-in") + ax1.set(xlabel=r"Horizontal distance, m") + ax1.set(ylabel=r"Height, m") + ax1.set_xlim(-tether_length_max, tether_length_max) + ax1.set_ylim(0, 3/4 * (2*tether_length_max+1)) + ax1.set_aspect("equal") + fig.legend(loc='upper left', bbox_to_anchor=(0.25, 0.9),facecolor="none", edgecolor="none", fontsize="small") + fig.savefig("trajectory.png") \ No newline at end of file diff --git a/powercurve_const_LoD_in.svg b/powercurve_const_LoD_in.svg index ba78306..a36bdf3 100644 --- a/powercurve_const_LoD_in.svg +++ b/powercurve_const_LoD_in.svg @@ -6,11 +6,11 @@ - 2023-11-17T08:34:50.667132 + 2024-06-12T16:14:30.878661 image/svg+xml - Matplotlib v3.7.2, https://matplotlib.org/ + Matplotlib v3.6.3, https://matplotlib.org/ @@ -30,8 +30,8 @@ z - - - + - + - - - - - + + + - + - + - - - - - + + + - + - - - - + + + + - + - + - - - - + + + - + - + - - - - - + + + + - + - - - - - + + + + + - + - - - - - + + + + + - + - - - - - + + + + + - + - - - - - + + + + + - + - - - - - - + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + @@ -605,601 +522,539 @@ z - - + - - + + - + - - + + - + - - - + + + - + - - - + + + - + - - - + + + - + - - - + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - +" clip-path="url(#p63c3242c47)" style="fill: none; stroke-dasharray: 1.5,2.475; stroke-dashoffset: 0; stroke: #000000; stroke-width: 1.5"/> - +" clip-path="url(#p63c3242c47)" style="fill: none; stroke-dasharray: 1.5,2.475; stroke-dashoffset: 0; stroke: #000000; stroke-width: 1.5"/> - + - + - + - + - - - @@ -1209,7 +1064,7 @@ L 648 48.6 - + - - - + - @@ -1345,53 +1172,6 @@ Q 3181 3784 2986 3965 Q 2791 4147 2438 4147 L 1613 4147 z -" transform="scale(0.015625)"/> - - - - - - - + - - + - @@ -1510,8 +1254,8 @@ z - - + + diff --git a/trajectory.png b/trajectory.png new file mode 100644 index 0000000..b5b6989 Binary files /dev/null and b/trajectory.png differ