前提・実現したいこと
matplotlibの公式ドキュメントにある二重振り子のプログラムを少し改造して,
軌跡付きの二重振り子のシミュレーションプログラムを作りました.
↓「二重振り子」の公式ドキュメントのリンク
https://matplotlib.org/2.0.2/examples/animation/double_pendulum_animated.html
そして,その動画をmp4形式で保存しようとすると,保存は出来るのですが,
だいたい1周期20秒なのですが,最初の5秒分しか保存がされません.
1周期(20秒分)保存するにはどうしたらよいのでしょうか?
発生している問題・エラーメッセージ
保存は正しくされ,エラーメッセージは表示されません.
ただ,動画が5秒しか保存されていません.
該当のソースコード
Python
1"""二重振り子をシミュレーションするプログラム""" 2from numpy import sin, cos 3from scipy.integrate import solve_ivp 4from matplotlib.animation import FuncAnimation 5import numpy as np 6import matplotlib.pyplot as plt 7 8G = 9.8 # 重力加速度 [m/s^2] 9L1 = 1.0 # 単振り子1の長さ [m] 10L2 = 1.0 # 単振り子2の長さ [m] 11M1 = 1.0 # おもり1の質量 [kg] 12M2 = 1.0 # おもり2の質量 [kg] 13 14# 運動方程式 15def derivs(t, state): 16 17 dydx = np.zeros_like(state) 18 dydx[0] = state[1] 19 20 delta = state[2] - state[0] 21 den1 = (M1+M2) * L1 - M2 * L1 * cos(delta) * cos(delta) 22 dydx[1] = ((M2 * L1 * state[1] * state[1] * sin(delta) * cos(delta) 23 + M2 * G * sin(state[2]) * cos(delta) 24 + M2 * L2 * state[3] * state[3] * sin(delta) 25 - (M1+M2) * G * sin(state[0])) 26 / den1) 27 28 dydx[2] = state[3] 29 30 den2 = (L2/L1) * den1 31 dydx[3] = ((- M2 * L2 * state[3] * state[3] * sin(delta) * cos(delta) 32 + (M1+M2) * G * sin(state[0]) * cos(delta) 33 - (M1+M2) * L1 * state[1] * state[1] * sin(delta) 34 - (M1+M2) * G * sin(state[2])) 35 / den2) 36 37 return dydx 38 39# 時間生成 40t_span = [0,20] 41dt = 0.05 42t = np.arange(t_span[0], t_span[1], dt) 43 44# 初期条件 45th1 = 120.0 46w1 = 0.0 47th2 = -10.0 48w2 = 0.0 49state = np.radians([th1, w1, th2, w2]) 50 51# 運動方程式を解く 52sol = solve_ivp(derivs, t_span, state, t_eval=t) 53y = sol.y 54 55# ジェネレータ 56def gen(): 57 for tt, th1, th2 in zip(t,y[0,:], y[2,:]): 58 x1 = L1*sin(th1) 59 y1 = -L1*cos(th1) 60 x2 = L2*sin(th2) + x1 61 y2 = -L2*cos(th2) + y1 62 yield tt, x1, y1, x2, y2 63 64fig, ax = plt.subplots() 65ax.set_xlim(-(L1+L2), L1+L2) 66ax.set_ylim(-(L1+L2), L1+L2) 67ax.set_aspect('equal') 68ax.grid() 69 70locus, = ax.plot([], [], 'r-', linewidth=2) 71line, = ax.plot([], [], 'o-', linewidth=2) 72time_template = 'time = %.1fs' 73time_text = ax.text(0.05, 0.9, '', transform=ax.transAxes) 74 75xlocus, ylocus = [], [] 76def animate(data): 77 t, x1, y1, x2, y2 = data 78 xlocus.append(x2) 79 ylocus.append(y2) 80 81 locus.set_data(xlocus, ylocus) 82 line.set_data([0, x1, x2], [0, y1, y2]) 83 time_text.set_text(time_template % (t)) 84 85ani = FuncAnimation(fig, animate, gen, interval=100, repeat=False) 86 87ani.save('double_pendulum.mp4', writer='ffmpeg', fps=5) 88 89plt.show()
試したこと
公式ドキュメントにあるソースコードで動画を保存すると,確かに20秒分保存されるので,
それと比較して,intervalを変えてみたり,init()を定義してみたりしました.
結果的に,動画の長さは長く出来たときもあったのですが,タイマーは5秒まで
つまりスローモーションになっただけでした.
補足情報(FW/ツールのバージョンなど)
公式ドキュメントの動画は,きちんと保存できたのでffmpegのダウンロードはうまくいっていると思います.
公式ドキュメントと変更した点は主に後半で,
・微分方程式を解く関数をodeint()からslve_ivp()にしたこと.
・軌跡を描画するためにジェネレータを定義したこと.
の2点です.あとはそれに伴う細かな調整をしました.
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/08/08 01:24