LoginSignup
3
1

More than 5 years have passed since last update.

【OculusGo】Loranz方程式のカオスな振舞をVR♬

Last updated at Posted at 2018-07-15

先ほどDuffing振動子のカオスな振舞をVRしたが、今回はカオス研究の発端となったLorenz方程式のカオスな振舞をVRしようと思う。

こちらは、Duffing振動子は一次元二階常微分方程式を解いたが、今回は一階の3次元常微分方程式を解く必要がある。
ちょっと目先が異なるのでodeintで解けるものやらと思っていたが、解けたので記載しておこうと思う。

やったこと

(1)Lorenz方程式の解法
(2)Lorenz方程式の振舞
(3)OculusGoでVRしてみる

(1)Lorenz方程式の解と振舞

コードは以下に置いた
LSTM/duffing.py
大切なことは、どちらの考え方でも解けた。
つまり、通常の運動方程式と考えて、再度微分して3次元二階常微分方程式でもいいが、普通に3次元一階常微分方程式と考えて解けた。

def lorenz(var, t, p, r, b):
    """
    var = [x,y,z, x_dot,y_dot,z_dot]
    dx/dt = -px+py
    dy/dt = -xz+rx-y
    dz/dt = xy-bz
    """
    x_dot = -p*var[0]+p*var[1]
    y_dot = -var[0]*var[2]+r*var[0]-var[1]
    z_dot = var[0]*var[1]-b*var[2]
    px_dot= -p*x_dot +p*y_dot
    py_dot= -x_dot*var[2] - var[0]*z_dot +r*x_dot -y_dot
    pz_dot= x_dot*var[1] + var[0]*y_dot -b*z_dot
    return x_dot,y_dot,z_dot,px_dot,py_dot,pz_dot

あるいは、以下のようなものである。

def lorenz(var, t, p, r, b):
    """
    var = [x,y,z]
    dx/dt = -px+py
    dy/dt = -xz+rx-y
    dz/dt = xy-bz
    """
    x_dot = -p*var[0]+p*var[1]
    y_dot = -var[0]*var[2]+r*var[0]-var[1]
    z_dot = var[0]*var[1]-b*var[2]
    return x_dot,y_dot,z_dot
p = 10
b = 8/3
r = 28
y0 = [0,10,20]
t = np.linspace(0, 35, 3001)
sol = odeint(lorenz, y0, t, args=(p, r, b))
x, y, z = sol.T[0], sol.T[1], sol.T[2]

上記の二通りのやり方は、初期値を除いてほぼ同じようなものなので(二階部分は単なる検証程度の意味しかない)、実際一階の方程式が解けているにすぎなさそうである。

(2)Lorenz方程式の振舞

{\frac  {dx}{dt}}=-px+py
{\frac  {dy}{dt}}=-xz+rx-y
{\frac  {dz}{dt}}=xy-bz

結果は、以下の参考の動画像の通りだが、。。やってみると結構面白い結果になった。ここでは以下代表的と思われる初期値等のセットを掲載する。上記のコードで比較的簡単に適当な初期値で計算できるので試せると思う。
【参考】
ローレンツ方程式
File:A Trajectory Through Phase Space in a Lorenz Attractor.gif

まず、上記参考の通りの初期パラメータ
p = 10
b = 8/3
r = 28
y0 = [0,10,20]
t = np.linspace(0, 35,3001)
だと以下のとおりとなった。
plot_xy
plot_xy.png
plot_yz
plot_yz.png
plot_zx
plot_zx.png
そして時間変化は
plot_xt
plot_xt.png
plot_yt
plot_yt.png
plot_zt
plot_zt.png

一方、y0 = [0.1,0, 0.0]のとき
t = np.linspace(0, 20, 3001)とすると以下が得られる。
plot_xy
plot_xy.png
plot_yz
plot_yz.png
plot_zx
plot_zx.png
plot_xt
plot_xt.png
plot_yt
plot_yt.png
plot_zt
plot_zt.png

(3)OculusGoでVRしてみる

さて、いよいよVRで見えるかな??
ほぼ前回と同じなので見えるはず。。
今回は、3パラメータの授受だけど基本同じ手法でやりました。
OculusGoでLorenz方程式のカオスな運動を見る♬

※画像をクリックするとYouTube動画につながります

コードの主要な部分は以下のとおり
def lorenz(var, t, p, r, b):は上記と同じ、そしてgen_sin(t)は以下のとおり

def get_sin(t):
    p = 10
    b = 8/3
    r = 28
    #y0 = [1,0, 0]   #,0,0,0]
    y0 = [0,10,20]
    t1 = np.linspace(0, t-ts, 500)
    while len(t1)==0:
        t = time.time()
        t1 = np.linspace(0, t-ts, 500)
    try:
        sol = odeint(lorenz, y0, t1, args=(p, r, b))
    except:
        print('計算出来ませんでした!')
        print('t1= ',t1)
        print('y0= ',y0)
        sol = odeint(lorenz, y0, t1, args=(p, r, b))
    x, y, z = sol.T[0], sol.T[1], sol.T[2]
    return x,y,z

そして、これを受けるUnity側は前回のものと以下の部分のみ変更した。

float s = float.Parse(m_MyText.text.Substring(0,10)); 
float s1 = float.Parse(m_MyText.text.Substring(startIndex: 11, length: 10));
float s2 = float.Parse(m_MyText.text.Substring(startIndex: 22, length: 10));

まとめ

・Loranz方程式の数値解を求め、初期値の違いによる振舞をみた
・Lorenz方程式のカオスな振舞をOculusGoでVRした

・常微分方程式の解法とデータ授受が不安定であり、まとめて渡す方法を確立する必要がある

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1