質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

0回答

1607閲覧

ライブライscipyのodeの使い方

NR4200

総合スコア41

Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2019/10/22 08:32

編集2019/10/24 03:07

前提・実現したいこと

質問を見てくださりありがとうございます.
質問内容が少し違いますが,odeに問題があると思っており,題名が思いつかなかったので上記の題名にしています.

微分方程式をodeで解いたものをグラフに出力したもの(プログラム内の u )と計算させてから余分なものを引いて出力させたもの(プログラム内の u_rec )をグラフに出力させたのですが(図1:uのグラフ,図2:u_recのグラフ)同じグラフが出ると思ったのですが違うグラフが出力されます.

uとu_recの出力をExcelに出力すると,確かに全体的にuとu_recの値が違っていましたが,uとu_recが同じ値になるようにプログラムを組んだのですが,どこが間違っているのかわかりません.

図1
イメージ説明

図2
イメージ説明
図1よりも図2はガタガタしたグラフが出力されます

発生している問題・エラーメッセージ

該当のソースコード

python

1import matplotlib.pyplot as plt 2import scipy.integrate as sp 3import numpy as np 4import random 5 6 7ms = 0.26 8mc = 0.85 9k = 177 10g = 9.8 11m = mc + (1/3)*ms 12 13u_rec = [] 14t_rec = [] 15 16def d(t): 17 18 if t < 20: 19 return 0 20 elif t >= 20: 21 return 5*np.sin(3.14*t) 22def μ(x2): 23 if x2==0: 24 return 0.24 25 else: 26 return 0.11 27# SMC制御系 28def f(x1,x2): 29 return -(k/m)*x1-μ(x2)*g*np.sign(x2) 30 31def df(x2,x3): 32 return -(k/m)*x2-μ(x3)*g*np.sign(x3) 33 34def dd(t): 35 if t < 20: 36 return 0 37 elif t >= 20: 38 return 5*3.14*np.cos(3.14*t) 39 40def du(x1,x2,x3,t): 41 return 7*(x2-0.02*np.cos(t))+0.01*(x3+0.02*np.sin(t))+30*(x1-0.02*np.sin(t)) 42 43def du_g(x1,x2,x3,t): 44 return 7*(x2-0.02*np.cos(t))+0.01*(x3+0.02*np.sin(t))+30*(x1-0.02*np.sin(t)) 45 46def heaviside(t): 47 if(t < 20): 48 return 0 49 elif(t >= 20): 50 return 1.5 51 52def system(t, x): 53 # 戻り値用のリスト 54 y = [0]*4 55 56 #ダイナミクスの記述 57 dx1 = x[1] 58 dx2 = -(k/m)*x[0] -μ(x[1])*g*np.sign(x[1]) - (k/m)*(7* (x[0]-0.02*np.sin(t)) + 0.1*(x[1]-0.02*np.cos(t))+ 30*x[2]) + d(t) 59 dx3 = x[0] - 0.02*np.sin(t) 60 dxu = 7*(x[1]-0.02*np.cos(t)) + 0.1*(x[2] + 0.02*np.sin(t)) + 30*(x[0]-0.02*np.sin(t)) 61 62 # 計算結果を返す 63 y[0] = dx1 64 y[1] = dx2 65 y[2] = dx3 66 y[3] = dxu 67 68 return y 69 70def simulation(x0, end, step): 71 x1 = [] 72 x2 = [] 73 t = [] 74 u = [] 75 76 ode = sp.ode(system) 77 ode.set_integrator('dopri5', method='bdf', atol=1.e-2) 78 ode.set_initial_value(x0, 0) 79 t.append(0) 80 x1.append(x0[0]) 81 x2.append(x0[1]) 82 u.append(0) 83 while ode.successful() and ode.t < end - step: 84 ode.integrate(ode.t + step) 85 t.append(ode.t) 86 x1.append(ode.y[0]) 87 x2.append(ode.y[1]) 88 u.append(ode.y[3])#積分して取り出したu 89 return x1, x2, u, t 90 91# パラメータ 92x0 = [0.0, 0.0, 0.0, 0.0] # 初期値 93end = 40 # シミュレーション時間 94step = 0.01 # 時間の刻み幅 95 96# シミュレーション 97x1, x2, u, t = simulation(x0, end, step) 98 99#u_recのリストを作成 100for i in range(len(t)): 101 u_rec.append(-(m/k)*(x2[i]+(k/m)*x1[i]-d(i*0.01)+μ(x2[i])*g*np.sign(x2[i]))) 102 103# 結果をグラフ表示 104 105traj_p = [] 106traj_v = [] 107for i in t: 108 traj_v.append(0.02*np.cos(i)) 109 traj_p.append(0.02*np.sin(i)) 110 111fig, ax = plt.subplots(2, 1, figsize=(10,6)) 112 113 114ax[0].set_xlabel('Time[s]') 115ax[0].set_ylabel('Position[m]') 116ax[0].grid() 117ax[0].set_ylim(-0.03, 0.08) 118ax[0].set_xlim(0.0, 40.0) 119ax[0].plot(t, x1, ls = '-',color = 'b', label = 'PID Controler') 120ax[0].plot(t, traj_p, ls = '--',color ='r', label = 'Desired Path') 121ax[0].legend() 122 123ax[1].set_xlabel('Time[s]') 124ax[1].set_ylabel('Velocity[m/s]') 125ax[1].grid() 126ax[1].set_ylim(-0.1, 0.2) 127ax[1].set_xlim(0.0, 40.0) 128ax[1].plot(t, x2, ls = '-', color='b', label = 'PID Controler') 129ax[1].plot(t, traj_v, ls = '--', color='r', label = 'Desired Velocity') 130ax[1].legend() 131#plt.savefig('position and Velocity PID+d.png') 132plt.show() 133 134 135fig, ax = plt.subplots(figsize=(10,4)) 136 137ax.set_xlabel('Time[s]') 138ax.set_ylabel('Base Position[m]') 139ax.grid() 140ax.set_ylim(-0.08, 0.18) 141ax.set_xlim(0.0, 40.0) 142ax.plot(t, u_rec, ls = '-', color='b', label = 'PID Controler') 143#ax.plot(t, u, ls = '-', color='b', label = 'PID Controler') 144plt.show() 145

試したこと

ライブラリscipyのodeについて色々調べてみましたがわかりあせんでした.

補足情報(FW/ツールのバージョンなど)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tanishi_a

2019/10/22 13:26

`u` と `u_rec` の中身が同じはずというのであれば、 1. `u` と `u_rec` それぞれファイルに出して、diff を取る 2. 差の出てる行を確認 3. 差の出てる行で式と値が想定通りなのか確認 という感じで狭めて行くのが良さそうに思えますが。
NR4200

2019/10/24 02:54

excelに出力したところ全体的に違う値が出ていました.
NR4200

2019/10/24 02:55

しかし,プログラム上では同じ値が出るようにしているのですが,どこが間違っているのかわかりません
tanishi_a

2019/10/24 03:31

数式のことは全くわからないですが、3.14と書いているところは、math.piとかnp.piを使わないのは何か意味があるのですか。
NR4200

2019/10/24 03:54

特に意味はありませんが,np.piに変えたとしても変わりません
tanishi_a

2019/10/24 12:29 編集

u_rec がギザギザしているのが問題と言っているのですよね。 ギザギザさせているのは u_rec.append(-(m/k)*(x2[i]+(k/m)*x1[i]-d(i*0.01)+μ(x2[i])*g*np.sign(x2[i]))) の中の np.sign(x2[i]) の中の x2[i] のようですが、 そうしたら何か辿れたりしますか?
NR4200

2019/10/24 23:38

ギザギザしているのが問題というよりも,uの出力グラフとu_recのグラフが違っているのが問題です.(例えば,図1と図2を比べた時に5秒のところでは図1に対して図2がほぼ直角になっているなどが問題です). プログラム上のsystem関数の中のdxuと system関数内のdx2を出力してから for i in range(len(t)): u_rec.append(-(m/k)*(x2[i]+(k/m)*x1[i]-d(i*0.01)+μ(x2[i])*g*np.sign(x2[i]))) 上記プログラムで余分なものを引いたときと同じになるようにプログラムを組んだつもりです. 説明がわかりにくくてすいません. ちなみにx2[i]は問題なかったです.
tanishi_a

2019/10/24 23:41

問題ないというのは、どう確認しているのですか?
NR4200

2019/10/24 23:57

プログラム中 x1, x2, u, t ,u_s = simulation(x0, end, step) の戻り値x2とnp.sign(x2[i])をエクセルに保存し np.sign(x2[i])がx2の値によって-1,1,0の値を出力しているかの確認 エクセルに保存した数値でグラフを作成したx2のグラフとmatplotlibで出力されるグラフの比較し同じグラフだったため問題ないと判断しました. やり方が違うのであればtanishi_aさんのやり方を教えていただければ幸いです. よろしくお願いします.
tanishi_a

2019/10/25 01:01 編集

ありがとうございます。 答えは持ってないのですが、 グラフはいったん置いておいて、その式(appendで足してるやつ)のどこが違っているか、誤差が出てるのかとか式を分解?して検算していくしかないのかなと思ってます。 1行ずつprintして確認するイメージです。
NR4200

2019/10/28 01:02

tanishi_aさんへ printしたりしながら色々といじっりました. プログラム内ode.set_integratorの引数atolを1.e-4にしたらギザギザが少し収まったのですが, atolについて何か知っていることありますか? ちなみにpythonのホームページでは以下のように示されていました. rtol, atol float, optional The input parameters rtol and atol determine the error control performed by the solver. The solver will control the vector, e, of estimated local errors in y, according to an inequality of the form max-norm of (e / ewt) <= 1, where ewt is a vector of positive error weights computed as ewt = rtol * abs(y) + atol. rtol and atol can be either vectors the same length as y or scalars. Defaults to 1.49012e-8. 訳してみたも意味が分かりませんでした
tanishi_a

2019/10/28 01:20 編集

とある行で、引数の指定によって、 想定の値と出てくる結果の誤差が少なくなる、ということですよね? 絞れてきたように見えるので、そこだけに絞り込んだ内容を質問にして、具体的な値を出して質問文を書き直すか新しい質問として出すかすると、わかる人がいるかもしれないな、と思います。 (いつも一般的なことしか言えてなくてすみません)
NR4200

2019/10/28 01:23

tanishi_aさんへ 貴重なご意見ありがとうございます.tanishi_aさんのご意見にはいつも助けられています. atolについて新しい質問として挙げてみます.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問