前提・実現したいこと
図1のようにな摩擦のあるマスバネ系の運動方程式を微分方程式でしめして,図1に示す台車の位置と速度ををグラフにしようとしています.
運動方程式は
mx''= -Kx - μmgsgn(x')-ku
(x''は時間における2階微分,x'は1階微分を表します,sgn(.)は符号関数)
SciPy の odeモジュールは1階の微分方程式しか解けないので,上式を
x = x1
x1' = x2の関係を利用して,
x1' = x2
x2' = -(k/m)x1 - μgsgn(x2) - (k/m)u
に式変形してからプログラム上のvector関数内に記述しています.
(プログラム上ではu=((7*(x1-0.02np.sin(t)))+(0.1(x2-0.02np.cos(t)))+30e_integ) )- (m/k)d(t)が代入されています.)
図1
発生している問題・エラーメッセージ
摩擦をいれなければ(プログラム中のvector関数の中のコメントアウトしているnext2を使ったとき)図2のようにグラフが出るのですが
摩擦(プログラム中のvector関数の中のコメントアウトしていないnext2を使ったとき)を入れると図3のように常に0のグラフが出ます.
また警告が出ているので,図4にコマンドプロンプトを示しておきます.
該当のソースコード
python
1import matplotlib 2#matplotlib.use('Agg') 3import matplotlib.pyplot as plt 4from scipy.integrate import odeint 5import numpy as np 6import pylab 7 8 9ms = 0.26 10mc = 0.85 11k = 177 12g = 9.8 13μs = 0.24 14μk = 0.11 15 16m = mc + (1/3)*ms 17e_integ = 0 18 19def μ(x2): 20 if x2==0: 21 return 0.24 22 else: 23 return 0.11 24 25def d(t): 26 27 if t < 20: 28 return 0 29 elif t >= 20: 30 return 5*np.sin(3.14*t) 31 32def vector(state, t, g, k, m, e_integ): 33 34 x1, x2 = state 35 36 e_integ += x1 - 0.02*np.sin(t) 37 nextx1 = x2 38 nextx2 = -(k/m)*x1 - (k/m)*((7*(x1-0.02*np.sin(t)))+(0.1*(x2-0.02*np.cos(t)))+30*e_integ) + d(t) - μ(x2)*g*np.sign(x2) 39 #nextx2 = -(k/m)*x1 - (k/m)*((7*(x1-0.02*np.sin(t)))+(0.1*(x2-0.02*np.cos(t)))+30*e_integ) + d(t) 40 41 42 return nextx1, nextx2 43 44 45x1_f = 0 46x2_f = 0 47 48t = np.arange(0.0, 40.0, 0.01) 49 50v = odeint(vector, [x1_f, x2_f ], t, args=(g, k, m, e_integ)) 51print(v) 52x1_vec = v[:,0] 53x2_vec = v[:,1] 54''' 55traj_p = [] 56traj_v = [] 57for i in t: 58 traj_v.append(0.02*np.cos(i)) 59 traj_p.append(0.02*np.sin(i)) 60''' 61fig, ax = plt.subplots(2, 1, figsize=(10,6)) 62#fig.tight_layout() 63 64ax[0].set_xlabel('Time[s]') 65ax[0].set_ylabel('Position[m]') 66ax[0].grid() 67ax[0].set_ylim(-0.03, 0.08) 68ax[0].set_xlim(0.0, 40.0) 69ax[0].plot(t, x1_vec, ls = '-', label = 'PID Controler') 70#ax[0].plot(t, traj_p, ls = '--', label = 'Desired Path') 71ax[0].legend() 72 73ax[1].set_xlabel('Time[s]') 74ax[1].set_ylabel('Velocity[m/s]') 75ax[1].grid() 76ax[1].set_ylim(-0.1, 0.2) 77ax[1].set_xlim(0.0, 40.0) 78ax[1].plot(t, x2_vec, ls = '-', label = 'PID Controler') 79#ax[1].plot(t, traj_v, ls = '--', label = 'Desired Velocity') 80ax[1].legend() 81plt.show()
試したこと
pythonライブライブscipyのodeintが間違っているのかと思い調べてみましたが,間違った使い方はしていませんでした.
また正しい結果が図3のようになるのかと思い色々調べてみましたが,ほとんど図2と同じ結果になるそうです