我一直试图将一组微分方程从Matlab R2014b移植到python 3.4。
我同时使用了odeint和ode,没有令人满意的结果。预期的结果是我从Matlab获得的结果,其中xi = xl和xj = xk,每组的相位偏移为180,如下图所示。
我在Matlab中运行的代码如下:
function Fv = cpg(t, ini_i);
freq = 2;
%fixed parameters
alpha = 5;
beta = 50;
miu = 1;
b = 1;
%initial conditions
xi = ini_i(1);
yi = ini_i(2);
xj = ini_i(3);
yj = ini_i(4);
xk = ini_i(5);
yk = ini_i(6);
xl = ini_i(7);
yl = ini_i(8);
ri = sqrt(xi^2 + yi^2);
rj = sqrt(xj^2 + yj^2);
rk = sqrt(xk^2 + yk^2);
rl = sqrt(xl^2 + yl^2);
%frequency for all oscillators
w_swing = 1;
w_stance = freq*w_swing;
%Coupling matrix, that determines a walking gate for
%a quadruped robot.
k = [ 0, -1, -1, 1;
-1, 0, 1, -1;
-1, 1, 0, -1;
1, -1, -1, 0];
%Hopf oscillator 1
omegai = w_stance/(exp(-b*yi)+1) + w_swing/(exp(b*yi)+1);
xi_dot = alpha*(miu - ri^2)*xi - omegai*yi;
yi_dot = beta*(miu - ri^2)*yi + omegai*xi + k(1,2)*yj + k(1,3)*yk + k(1,4)*yl;
%Hopf oscillator 2
omegaj = w_stance/(exp(-b*yj)+1) + w_swing/(exp(b*yj)+1);
xj_dot = alpha*(miu - rj^2)*xj - omegaj*yj;
yj_dot = beta*(miu - rj^2)*yj + omegaj*xj + k(2,1)*yi + k(2,3)*yk + k(2,4)*yl;
%Hopf oscillator 3
omegak = w_stance/(exp(-b*yk)+1) + w_swing/(exp(b*yj)+1);
xk_dot = alpha*(miu - rk^2)*xk - omegak*yk;
yk_dot = beta *(miu - rk^2)*yk + omegak*xk + k(3,4)*yl + k(3,2)*yj + k(3,1)*yi;
%Hopf oscillator 4
omegal = w_stance/(exp(-b*yl)+1) + w_swing/(exp(b*yl)+1);
xl_dot = alpha*(miu - rl^2)*xl - omegal*yl;
yl_dot = beta *(miu - rl^2)*yl + omegal*xl + k(4,3)*yk + k(4,2)*yj + k(4,1)*yi;
%Outputs
Fv(1,1) = xi_dot;
Fv(2,1) = yi_dot;
Fv(3,1) = xj_dot;
Fv(4,1) = yj_dot;
Fv(5,1) = xk_dot;
Fv(6,1) = yk_dot;
Fv(7,1) = xl_dot;
Fv(8,1) = yl_dot;
然而,当我将代码移动到python时,我得到了这样的输出。
在python中,我使用与Matlab相同的时间步长运行ODE求解器,并使用求解器'dopri5',它应该等同于我在Matlab中使用的那个,ode45。我在两种情况下使用相同的初始条件。我已经使用了odeint和ode两种类似的结果。
我刚开始用Python编程,这是我第一次使用Scipy和Numpy实现,所以也许我误解了一些东西?
def cpg(t, ini, k, freq):
alpha = 5
beta = 50
miu = 1
b = 1
assert freq == 2
'Initial conditions'
xi = ini[0]
yi = ini[1]
xj = ini[2]
yj = ini[3]
xk = ini[4]
yk = ini[5]
xl = ini[6]
yl = ini[7]
ri = sqrt(xi**2 + yi**2)
rj = sqrt(xj**2 + yj**2)
rk = sqrt(xk**2 + yk**2)
rl = sqrt(xl**2 + yl**2)
'Frequencies for each oscillator'
w_swing = 1
w_stance = freq * w_swing
'First Oscillator'
omegai = w_stance/(exp(-b*yi)+1) + w_swing/(exp(b*yi)+1)
xi_dot = alpha*(miu - ri**2)*xi - omegai*yi
yi_dot = beta*(miu - ri**2)*yi + omegai*xi + k[1]*yj + k[2]*yk + k[3]*yl
'Second Oscillator'
omegaj = w_stance/(exp(-b*yj)+1) + w_swing/(exp(b*yj)+1)
xj_dot = alpha*(miu - rj**2)*xj - omegaj*yj
yj_dot = beta*(miu - rj**2)*yj + omegaj*xj + k[4]*yi + k[6]*yk + k[7]*yl
'Third Oscillator'
omegak = w_stance/(exp(-b*yk)+1) + w_swing/(exp(b*yk)+1)
xk_dot = alpha*(miu - rk**2)*xk - omegak*yk
yk_dot = beta*(miu - rk**2)*yk + omegak*xk + k[8]*yi + k[9]*yj + k[11]*yl
'Fourth Oscillator'
omegal = w_stance/(exp(-b*yl)+1) + w_swing/(exp(b*yl)+1)
xl_dot = alpha*(miu - rl**2)*xl - omegal*yl
yl_dot = beta*(miu - rl**2)*yl + omegal*xl + k[12]*yi + k[13]*yj + k[14]*yk
return [xi_dot, yi_dot, xj_dot, yj_dot, xk_dot, yk_dot, xl_dot, yl_dot]
我打电话给ODE的方式如下:
X0 = [1,-1, 0,-1, 1,1, 0,1]
r = ode(cpg).set_integrator('dopri5')
r.set_initial_value(X0).set_f_params(k_trot, 2)
t1 = 30.
dt = .012
while r.successful() and r.t < (t1-dt):
r.integrate(r.t+dt)
我希望我足够清楚。 有什么建议吗?