For an assignment I need to calculate the angle beta for the launch of a rocket. This rocket should hit a skeet in the air and the rocket is just accelerating in the first 0,5s. In my first part of the exercise I already calculated the trajectory of the skeet. Next to the given parameters there is a wind in x-direction as well. I am trying to calculate the angle beta by minimizing a wrapper function for the distance of both trajectories. I always get the TypeError: loop of ufunc does not support argument 0 of type int which has no callable sqrt method I dont know what is my mistake and i hope someone can help me. The experiment is looking like this: Picture - rocket - skeet
from scipy.optimize import minimize
from scipy.optimize import fsolve
from scipy.integrate import solve_ivp
import numpy as np
import matplotlib.pyplot as plt
v_wind = 3.5 #m / s in positive x direction
rho_l = 1.2 # kg/m3
# skeet params
cw_skeet_top = 1.11
cw_skeet_side = 0.5
A_skeet_top = 0.0086
A_skeet_side = 0.00432
m_skeet = 0.105 #kg
v0_skeet = 40
x0_skeet = 60
y0_skeet = 0
# rocket params
cw_rocket_side = 1
cw_rocket_front = 0.5
A_rocket_side = 0.08
A_rocket_front = 0.0312
m_rocket = 2
v0_rocket = 0
x0_rocket = 20
y0_rocket = 0
F_accel_rocket = 120 #in Newton, divide by m_rocket to find accel in m/s^2
t_accel_end = 0.5
def drag(v_rel, rho_l, cw, A):
Fw = rho_l * cw * A * v_rel**2/2.0
if (v_rel < 0):
Fw = -Fw
return Fw
def skeet(t,y,rho_l,cw_skeet_side, cw_skeet_top,A_skeet_side,A_skeet_top,m_skeet):
# Zur Übersichtlichkeit:
# y[0] - x-position
# y[1] - x-velocity
# y[2] - y-position
# y[3] - y-velocity
d2xdt2 = -drag(y[1]-v_wind, rho_l, cw_skeet_side , A_skeet_side)/m_skeet
dxdt = -y[1]
d2ydt2 = -9.81 - drag(y[3], rho_l, cw_skeet_top, A_skeet_top)/m_skeet
dydt = y[3]
return dxdt, d2xdt2, dydt, d2ydt2
def hit_ground(t,y, *args):
return y[2]
hit_ground.terminal = True
hit_ground.direction = -1
final_x = 0 #m
DGLargs=(rho_l,cw_skeet_side, cw_skeet_top,A_skeet_side,A_skeet_top,m_skeet)
def wrapperAlpha(alpha,final_x,DGLargs):
tspan = [0, 100]
maxStep=tspan[1]/1000
start_vec = [x0_skeet, v0_skeet*np.cos(alpha/180*np.pi), y0_skeet, v0_skeet*np.sin(alpha/180*np.pi)]
sol = solve_ivp(skeet,tspan,start_vec,args=(DGLargs),max_step=maxStep,events=(hit_ground))
return np.abs(sol.y[0,-1] - final_x)
starting_guess = 10 #deg
res = fsolve(wrapperAlpha, x0 = starting_guess, args = (final_x,DGLargs))
angle = res
print(angle)
tspan = [0, 100]
maxStep=tspan[1]/1000
start_vec = [x0_skeet, v0_skeet*np.cos(angle/180*np.pi), y0_skeet, v0_skeet*np.sin(angle/180*np.pi)]
sol = solve_ivp(skeet,tspan,start_vec,args=(DGLargs),max_step=maxStep,events=(hit_ground))
x_skeet = sol.y[0,:]
y_skeet = sol.y[2,:]
plt.plot(x_skeet,y_skeet)
#important exercise:
RocketArgs = (rho_l,cw_rocket_side, cw_rocket_front,A_rocket_side,A_rocket_front,m_rocket,F_accel_rocket,t_accel_end)
def rocket(t,y,beta, rho_l,cw_rocket_side, cw_rocket_front,A_rocket_side,A_rocket_front,m_rocket,F_accel_rocket,t_accel_end):
if t_accel_end > t:
d2xdt2 = (-drag(y[1]-v_wind, rho_l, cw_rocket_side , A_rocket_side)+(F_accel_rocket*np.cos(beta/180*np.pi)))/m_rocket
dxdt = y[1]
d2ydt2 = (-9.81 - drag(y[3], rho_l, cw_rocket_front, A_rocket_front)+(F_accel_rocket*np.sin(beta/180*np.pi)))/m_rocket
dydt = y[3]
else:
d2xdt2 = (-drag(y[1]-v_wind, rho_l, cw_rocket_side , A_rocket_side))/m_rocket
dxdt = y[1]
d2ydt2 = (-9.81 - drag(y[3], rho_l, cw_rocket_front, A_rocket_front))/m_rocket
dydt = y[3]
return dxdt, d2xdt2, dydt, d2ydt2
def wrapperRocket(beta,x_skeet,y_skeet,RocketArgs):
tspan = [0, 100]
maxStep = 0.01
start_vec = [x0_rocket, v0_rocket*np.cos(beta/180*np.pi), y0_rocket, v0_rocket*np.sin(beta/180*np.pi)]
sol2 = solve_ivp(rocket,tspan,start_vec,args=(beta,rho_l,cw_rocket_side, cw_rocket_front,A_rocket_side,A_rocket_front,m_rocket,F_accel_rocket,t_accel_end),max_step=maxStep,dense_output=True)
for i in range(len(x_skeet)):
distance = np.sqrt((sol2.y[0,i]-x_skeet)**2+(sol2.y[2,i]-y_skeet)**2)
return distance
starting_guess = 20 #deg
res = minimize(wrapperRocket, x0 = starting_guess, args = (x_skeet,y_skeet,RocketArgs))
angle = res
print(angle)