Мне нужно решить систему ОДУ, состоящую из 13 уравнений (фактически 4 дифференциальных уравнения в форме матрицы), определить так:
def rigidBoomrang(att_vec, t, I, invI, m, f, torque):
q = att_vec[0:4]
w = att_vec[4:7]
v = att_vec[7:10]
p = att_vec[10:13]
qp = 0.5*np.dot(np.array([[0,w[2], -w[1], w[0]], [-w[2], 0, w[0], w[1]], [w[1], -w[0], 0, w[2]], [-w[0], -w[2], -w[2], 0]]), q)
wp = np.dot(invI,(torque-np.cross(w, np.dot(I, w))))
vp = f/m
pp = v
qp = np.array(qp)
wp = np.array(wp)
vp = np.array(vp)
pp = np.array(p)
return np.concatenate((qp, wp, vp, pp))
Дело в том, что два параметра (f икрутящий момент, который моделировал силу и ... крутящий момент) зависит от переменных, участвующих в системе ODES: сила и крутящий момент, используемые для интегрирования од в момент времени t + dt, зависят от значений w и v в момент временит, а интеграция q, w, v, p требует f и крутящего момента.
Это то, что я пробовал до сих пор (полный код):
import numpy as np
from pyquaternion import Quaternion
import scipy.integrate as spi
def MatRotX3d(theta):
return np.array([[1,0,0], [0, np.cos(theta), -np.sin(theta)], [0, np.sin(theta), np.cos(theta)]])
def MatRotY3d(theta):
return np.array([[np.cos(theta), 0, -np.sin(theta)], [0, 1, 0], [np.sin(theta), 0, np.cos(theta)]])
def MatRotZ3d(theta):
return np.array([[np.cos(theta), -np.sin(theta), 0], [np.sin(theta), np.cos(theta), 0], [0,0,1]])
def ezxzrmx(euler_angles):
"""Transformer angles d'une rotation Z-X-Z en une matrice de rotation"""
return np.dot(np.dot(MatRotZ3d(euler_angles[2]), MatRotX3d(euler_angles[1])), MatRotZ3d(euler_angles[0]))
def rigidBoomrang(att_vec, t, I, invI, m, f, torque):
q = att_vec[0:4]
w = att_vec[4:7]
v = att_vec[7:10]
p = att_vec[10:13]
qp = 0.5*np.dot(np.array([[0,w[2], -w[1], w[0]], [-w[2], 0, w[0], w[1]], [w[1], -w[0], 0, w[2]], [-w[0], -w[2], -w[2], 0]]), q)
wp = np.dot(invI,(torque-np.cross(w, np.dot(I, w))))
vp = f/m
pp = v
qp = np.array(qp)
wp = np.array(wp)
vp = np.array(vp)
pp = np.array(p)
return np.concatenate((qp, wp, vp, pp))
#paramètres du boomerang
L = 0.4
l = 0.035
b = 0.015
e = 0.005
Sz = L*l
Sc = l**2
S = 2*Sz+Sc
m = 0.075
sigma = m/S
I = np.array([[14,8,0], [8,14,0], [0,0,27]])*10**-4
invI = np.linalg.inv(I)
#coefficients aérodynamiques
roAir = 1.2
Caero = 0.5*roAir*S
Cz = 1.5
#entrées
betha0 = 180*np.pi/180
incl0 = 80*np.pi/180
theta0 = 90*np.pi/180
RZbetha = MatRotZ3d(betha0)
RXi = MatRotX3d(incl0)
RZtheta = MatRotZ3d(theta0)
Rot = np.dot(np.dot(RZbetha, RXi), RZtheta)
##CONDITIONS INITIALES
#angles initiaux
eulzxz = np.array([betha0, incl0, theta0])
#quaternion initial
quat1 = Quaternion(matrix=ezxzrmx(eulzxz))
quat = quat1.elements
#vitesse angulaire initale
w_ang = [0,0,10*2*np.pi]
#Vitesse initiale
V0 = 25
angle0 = 20*np.pi/180
v = V0*np.array([np.cos(angle0), 0, np.sin(angle0)])
#angle d'attaque
alpha = 0
#position initale
h0 = 2 #hauteur de lancer = 2m
p = [0,0,h0]
#matrice Rbi
Rbi = quat1.rotation_matrix
Rib = np.linalg.inv(Rbi)
#données relatives au temps
tstart = 0
tstep = 0.1 #pas d'intégration
tstop = 15
temps = np.linspace(tstart, tstop, int((tstop-tstart)/tstep))
#vecteurs initiaux
# ~ t = tstart
euler = eulzxz*180/np.pi
omeg = w_ang
vit = v
pos = p
attack = alpha #angle d'incidence, 0 a priori
momentang = I*omeg
#force de gravite
g = [0,0,-9.81*m]
#valeurs successives
T = []
VAL = []
##INTEGRATION
for t in temps:
if p[2] > 0: #si le boomerang ne touche pas le sol
#matrice de rotation
Rbi = quat1.rotation_matrix
Rib = np.linalg.inv(Rbi)
#forces aerodynamiques dans le plan du boomerang
vb = np.dot(Rbi, v)
Vx = vb[0]
Vy = vb[1]
f1 = np.array([0,0, Caero*Cz*(((w_ang[2]*(L-b) + Vy)**3 - Vy**3)/(3*w_ang[2]))])
f2 = np.array([0,0, Caero*Cz*(((w_ang[2]*(L-b) + Vx)**3 - Vx**3)/(3*w_ang[2]))])
fb = f1+f2
fRi = np.dot(Rib,fb) #force dans le référentiel initial
f = fRi+g #résultantes totales
#couples issus des forces aérodynamiques
P1 = [3*(L-b)/4, -b-l/2, 0] #pt d'application de f1
P2 = [-b-l/2, 3*(L-b)/4, 0] #pt d'application de f2
torque = np.cross(P1, f1)+np.cross(P2,f2)
#vecteur d'attitude inital
att_vec = np.concatenate((quat, w_ang, v, p))
#paramètres de résolution du système d'ODE
tspan = [t]
ode = spi.odeint(rigidBoomrang, att_vec, tspan, args=(I, invI, m, f, torque))
quat = np.array(ode[0][0:4])
w_ang = np.array(ode[0][4:7])
v = np.array(ode[0][7:10])
p = np.array(ode[0][10:13])
Когда я отображаюПри каждой интеграции я вижу, что ничего не было интегрировано: каждая переменная сохраняет свое начальное значение.Я думаю, это потому, что параметры не являются постоянными.Тем не менее, я не могу найти обходного пути к этому.Есть ли простой способ справиться с этим?
Заранее спасибо