倒立振子のシミュレーション2

  ここでは、レギュレーション制御(振子が倒立位置から傾いても、もとの倒立位置に戻す制御)を実現する制御手法
1) 状態オブザーバの出力をフィドバックする制御
2) ファジィ制御
について紹介する。

1) 状態オブザーバ利用のレギュレーション
  振子が倒立位置から傾いても、もとの倒立位置に戻す制御を状態オブザーバの出力をフィードバックする制御で実現できることを、数値シミュレーションで 確かめてみよう。制御対象は非線形システムであるので、オブザーバを設計するためには、もとのシステムを線形化するする必要がある。



この制御則を用いて元の非線形システムを制御した場合のシミュレーション 結果は以下に示すものである。
初期条件は、φ(0)=0.5[rad], dφ(0)/dt=0[rad/s], y(0)=-0.5[m], dy(0)/dt=0  とおいている。
この結果を出すのに用いたソフトをグラフの下に示すので、初期の振子の傾き角を変更して、どの角度までなら振子をもとの垂直 の位置へ戻せるのか、調べてみるのもおもしろいと思います。この限界の角度は、当然、アクチュエータのモータの能力に依存しま す。



Sub touritsu3()

Dim A(1 To 2, 1 To 2) As Double, Ainv(1 To 2, 1 To 2) As Double
Dim b(1 To 2, 1 To 2) As Double, dummy(1 To 2) As Double
Dim time(1001) As Double, dt As Double
Dim y(1001) As Double, dydt(1001) As Double, ddyddt(1001)
Dim phi(1001) As Double, dphidt(1001) As Double, ddphiddt(1001)
Dim u(1001) As Double
Dim mp As Double, mc As Double, lambda As Double, ny As Double
Dim leng As Double, inam As Double, ga As Double, g As Double
Dim i As Integer, j As Integer
Dim ey(1001) As Double, edydt(1001) As Double, eddyddt(1001)
Dim ephi(1001) As Double, edphidt(1001) As Double, eddphiddt(1001)
Dim f(1 To 4) As Double, k(1 To 4, 1 To 2) As Double
Dim AA(1 To 4, 1 To 4) As Double, AAkc(1 To 4, 1 To 4) As Double
Dim delta As Double, bb(1 To 4) As Double, c(1 To 2, 1 To 4) As Double
Dim dum(1 To 4) As Double

   Set WS = Worksheets("Sheet3")
   WS.Activate
   Range("A1:I1300").Select
   Selection.Clear

mp = 0.004735
mc = 0.628
lambda = 0.0001003
ny = 4.01
leng = 0.2465
inam = 0.0001155
ga = 3.18
g = 9.8

'  非線形システムの応答シミュレーション
'  差分時間     0.005
dt = 0.005
For i = 0 To 1000
time(i) = i * dt
u(i) = 0
Next
'  初期値
phi(0) = 0.5
dphidt(0) = 0
y(0) = -0.5
dydt(0) = 0
ddphiddt(0) = 0
ddyddt(0) = 0

ephi(0) = 0.5
edphidt(0) = 0
ey(0) = -0.5
edydt(0) = 0

' 近似線形システム
delta = (mp + mc) * inam + mp * mc * leng * leng
AA(1, 1) = 0
AA(1, 2) = 0
AA(1, 3) = 1
AA(1, 4) = 0
AA(2, 1) = 0
AA(2, 2) = 0
AA(2, 3) = 0
AA(2, 4) = 1
AA(3, 1) = 0
AA(3, 2) = -(mp * mp * leng * leng * g) / delta
AA(3, 3) = -ny * (inam + mp * leng * leng) / delta
AA(3, 4) = mp * leng * lambda / delta
AA(4, 1) = 0
AA(4, 2) = mp * leng * (mp + mc) * g / delta
AA(4, 3) = mp * leng * ny / delta
AA(4, 4) = -lambda * (mp + mc) / delta
bb(1) = 0
bb(2) = 0
bb(3) = (inam + mp * leng * leng) * ga / delta
bb(4) = -mp * leng * ga / delta
c(1, 1) = 1
c(1, 2) = 0
c(1, 3) = 0
c(1, 4) = 0
c(2, 1) = 0
c(2, 2) = 1
c(2, 3) = 0
c(2, 4) = 0

' フィードバックゲインf、オブザーバゲインk
f(1) = -10
f(2) = -26.2928
f(3) = -8.4844
f(4) = -4.5618

k(1, 1) = 12.9799
k(2, 1) = 11.1386
k(3, 1) = 9.4331
k(4, 1) = 158.7787
k(1, 2) = 0.2396
k(2, 2) = 22.4001
k(3, 2) = 0.9293
k(4, 2) = 154.2044

For i = 1 To 4
     For j = 1 To 4
     AAkc(i, j) = AA(i, j) - k(i, 1) * c(1, j) - k(i, 2) * c(2, j)
     Next
Next

For i = 1 To 1000
   phi(i) = phi(i - 1) + dphidt(i - 1) * dt
   y(i) = y(i - 1) + dydt(i - 1) * dt

   dphidt(i) = dphidt(i - 1) + ddphiddt(i - 1) * dt
   dydt(i) = dydt(i - 1) + ddyddt(i - 1) * dt
  
   A(1, 1) = mp + mc
   A(1, 2) = mp * leng * Cos(phi(i - 1))
   A(2, 1) = mp * leng * Cos(phi(i - 1))
   A(2, 2) = inam + mp * leng * leng
   Ainv(1, 1) = A(2, 2) / (A(1, 1) * A(2, 2) - A(1, 2) * A(2, 1))
   Ainv(2, 2) = A(1, 1) / (A(1, 1) * A(2, 2) - A(1, 2) * A(2, 1))
   Ainv(1, 2) = -A(1, 2) / (A(1, 1) * A(2, 2) - A(1, 2) * A(2, 1))
   Ainv(2, 1) = -A(2, 1) / (A(1, 1) * A(2, 2) - A(1, 2) * A(2, 1))

dummy(1) = Ainv(1, 1) * (mp * leng * Sin(phi(i - 1)) * dphidt(i - 1) * dphidt(i - 1) - ny * dydt(i - 1)) + Ainv(1, 2) * (-lambda * dphidt(i - 1) + mp * leng * g * Sin(phi(i - 1))) + Ainv(1, 1) * ga * u(i - 1)
dummy(2) = Ainv(2, 1) * (mp * leng * Sin(phi(i - 1)) * dphidt(i - 1) * dphidt(i - 1) - ny * dydt(i - 1)) + Ainv(2, 2) * (-lambda * dphidt(i - 1) + mp * leng * g * Sin(phi(i - 1))) + Ainv(2, 1) * ga * u(i - 1)
ddyddt(i) = dummy(1)
ddphiddt(i) = dummy(2)

Cells(3 + i, 12) = Ainv(1, 1)
Cells(3 + i, 13) = Ainv(1, 2)
Cells(3 + i, 14) = Ainv(2, 1)
Cells(3 + i, 15) = Ainv(2, 2)

'  状態オブザーバFBのレギュレータ
'%  オブザーバの固有値   -9  -10   -11   -12
     For j = 1 To 4
     dum(j) = AAkc(j, 1) * ey(i - 1) + AAkc(j, 2) * ephi(i - 1) + AAkc(j, 3) * edydt(i - 1) + AAkc(j, 4) * edphidt(i - 1)
     Next

ey(i) = ey(i - 1) + (dum(1) + k(1, 1) * y(i - 1) + k(1, 2) * phi(i - 1) + bb(1) * u(i - 1)) * dt
ephi(i) = ephi(i - 1) + (dum(2) + k(2, 1) * y(i - 1) + k(2, 2) * phi(i - 1) + bb(2) * u(i - 1)) * dt
edydt(i) = edydt(i - 1) + (dum(3) + k(3, 1) * y(i - 1) + k(3, 2) * phi(i - 1) + bb(3) * u(i - 1)) * dt
edphidt(i) = edphidt(i - 1) + (dum(4) + k(4, 1) * y(i - 1) + k(4, 2) * phi(i - 1) + bb(4) * u(i - 1)) * dt

u(i) = -f(1) * ey(i) - f(2) * ephi(i) - f(3) * edydt(i) - f(4) * edphidt(i)

Next
  
Cells(1, 2) = "時刻t(sec)"
Cells(2, 3) = "y(t)"
Cells(2, 4) = "Φ(t)"
Cells(2, 5) = "u(t)"

For i = 0 To 1000
Cells(3 + i, 2) = time(i)
Cells(3 + i, 3) = y(i)
Cells(3 + i, 4) = phi(i)
Cells(3 + i, 5) = u(i)
Next

    Range("B2:D1003").Select
    Charts.Add
    ActiveChart.ChartType = xlLineMarkers
    ActiveChart.SetSourceData Source:=Sheets("Sheet3").Range("B2:D1003"), PlotBy _
        :=xlColumns
    ActiveChart.Location Where:=xlLocationAsObject, Name:="Sheet3"
    With ActiveChart
        .HasTitle = True
        .ChartTitle.Characters.Text = "振子の倒立制御(オブザーバ出力FB制御)"
        .Axes(xlCategory, xlPrimary).HasTitle = True
        .Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "time(sec)"
        .Axes(xlValue, xlPrimary).HasTitle = True
        .Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "y(t)[m],Φ(t)[rad]"
    End With

End Sub


2) ファジィ制御
  上記のオブザーバ利用FB制御では、線形化された数式モデルに立脚して制御アルゴリズムが導かれたものである。しかし、制御対象のモデルを知らなくて も人間の持つ知識に基づいて倒立制御が実現できるだろうと思われる。
人は箒を手の上で立たせることができる。このアナロジーから、次のような知識が導かれる。
ルール1’) 振子が大きく傾いており、さらに大きく傾く方向に動いているときには、立てる方向に台車を大きく動かす方向に操作量を加える。
ルール2’) 振子が小さく傾いており、さらに傾きがゼロになる方向に大きく動いているときには、オーバーシュートして逆方向に傾くことを避けるために、 傾 き是正と反する方向に台車を中くらい動かす方向に操作量を加える。
ルール3’) 振子が小さく傾いており、傾きの変化速度がほぼゼロならば、立てる方向に台車を動かす方向に小さく操作量を加える。
このルールを数式で表現すると、以下であり、
   If Φ is PB and dΦ/dt is P  then u is PB  (ルール1’対応)   ・・・ これを新たにルール1と呼ぶ。
   If Φ is NB and dΦ/dt is N  then u is NB  (ルール1’対応)   ・・・ これを新たにルール2と呼ぶ。
   If Φ is PS and dΦ/dt is NB then u is NM  (ルール2’対応)   ・・・ これを新たにルール3と呼ぶ。
   If Φ is NS and dΦ/dt is PB then u is PM  (ルール2’対応)   ・・・ これを新たにルール4と呼ぶ。
   If Φ is PS and dΦ/dt is ZO then u is PS  (ルール3’対応)   ・・・ これを新たにルール5と呼ぶ。
   If Φ is NS and dΦ/dt is ZO then u is NS  (ルール3’対応)   ・・・ これを新たにルール6と呼ぶ。
これらのルールにもとづくファジィ制御の操作量は次式で表される。
       u(t) = (10 * kar1 - 10 * kar2 - 3 * kar3 + 3 * kar4 + 1*kar5 - 1*kar6) / (dum = kar1 + kar2 + kar3 + kar4 + kar5 + kar6)
上式における、10 * kar1の10は(u is PB)を簡易的に表したものであり、以下同様に、- 10 * kar2のー10は(u is NB)を、- 3 * kar3のー3は(u is NM)を、3 * kar4の3は(u is PM)を、1*kar5の1は(u is PS)を、- 1*kar6のー1は(u is NS)をそれぞれ簡易に表したものである。また、kar1、からkar6は上記6個の各ルールの(Φ、 dΦ/dt )における適合度のことで、
    kar1 = min{ Φ is PBのメンバーシップ関数(Φ)、dΦ/dt is Pのメンバーシップ関数(dΦ/dt) }
    kar2 = min{ Φ is NBのメンバーシップ関数(Φ)、dΦ/dt is Nのメンバーシップ関数(dΦ/dt) }
    kar3 = min{ Φ is PSのメンバーシップ関数(Φ)、dΦ/dt is NBのメンバーシップ関数(dΦ/dt) }
    kar4 = min{ Φ is NSのメンバーシップ関数(Φ)、dΦ/dt is PBのメンバーシップ関数(dΦ/dt) }
    kar5 = min{ Φ is PSのメンバーシップ関数(Φ)、dΦ/dt is ZOのメンバーシップ関数(dΦ/dt) }
    kar6 = min{ Φ is NSのメンバーシップ関数(Φ)、dΦ/dt is ZOのメンバーシップ関数(dΦ/dt) }
で計算されるものである。各メンバーシップ関数は、以下に示すものである。



これらのファジィ制御を行ったときの応答は、以下のグラフに示すものであり、そのソフトはグラフの下に現すものである。ただし、 初期条件は、φ(0)=0.5[rad], dφ(0)/dt=0[rad/s], y(0)=-0.5[m], dy(0)/dt=0  とおいている。

Sub touritsu4()

Dim A(1 To 2, 1 To 2) As Double, Ainv(1 To 2, 1 To 2) As Double
Dim b(1 To 2, 1 To 2) As Double, dummy(1 To 2) As Double
Dim time(1001) As Double, dt As Double
Dim y(1001) As Double, dydt(1001) As Double, ddyddt(1001)
Dim phi(1001) As Double, dphidt(1001) As Double, ddphiddt(1001)
Dim u(1001) As Double
Dim mp As Double, mc As Double, lambda As Double, ny As Double
Dim leng As Double, inam As Double, ga As Double, g As Double
Dim i As Integer, j As Integer
Dim f(1 To 4) As Double

Dim kspbphi As Double, ksnbphi As Double, kszophi As Double
Dim kspdphi As Double, ksndphi As Double, kszodphi As Double
Dim dum As Double, kar1 As Double, kar2 As Double
Dim kar3 As Double, kar4 As Double, kar5 As Double, kar6 As Double
Dim kspsphi As Double, ksnsphi As Double
Dim kspbdphi As Double, ksnbdphi As Double

   Set WS = Worksheets("Sheet4")
   WS.Activate
   Range("A1:I1300").Select
   Selection.Clear

mp = 0.004735
mc = 0.628
lambda = 0.0001003
ny = 4.01
leng = 0.2465
inam = 0.0001155
ga = 3.18
g = 9.8

'  非線形システムの応答シミュレーション
'  差分時間     0.005
dt = 0.005
For i = 0 To 1000
time(i) = i * dt
u(i) = 0
Next
'  初期値
phi(0) = 0.5
dphidt(0) = 0
y(0) = -0.5
dydt(0) = 0
ddphiddt(0) = 0
ddyddt(0) = 0

For i = 1 To 1000

   phi(i) = phi(i - 1) + dphidt(i - 1) * dt
   y(i) = y(i - 1) + dydt(i - 1) * dt

   dphidt(i) = dphidt(i - 1) + ddphiddt(i - 1) * dt
   dydt(i) = dydt(i - 1) + ddyddt(i - 1) * dt
  
   A(1, 1) = mp + mc
   A(1, 2) = mp * leng * Cos(phi(i - 1))
   A(2, 1) = mp * leng * Cos(phi(i - 1))
   A(2, 2) = inam + mp * leng * leng
   Ainv(1, 1) = A(2, 2) / (A(1, 1) * A(2, 2) - A(1, 2) * A(2, 1))
   Ainv(2, 2) = A(1, 1) / (A(1, 1) * A(2, 2) - A(1, 2) * A(2, 1))
   Ainv(1, 2) = -A(1, 2) / (A(1, 1) * A(2, 2) - A(1, 2) * A(2, 1))
   Ainv(2, 1) = -A(2, 1) / (A(1, 1) * A(2, 2) - A(1, 2) * A(2, 1))

dummy(1) = Ainv(1, 1) * (mp * leng * Sin(phi(i - 1)) * dphidt(i - 1) * dphidt(i - 1) - ny * dydt(i - 1)) + Ainv(1, 2) * (-lambda * dphidt(i - 1) + mp * leng * g * Sin(phi(i - 1))) + Ainv(1, 1) * ga * u(i - 1)
dummy(2) = Ainv(2, 1) * (mp * leng * Sin(phi(i - 1)) * dphidt(i - 1) * dphidt(i - 1) - ny * dydt(i - 1)) + Ainv(2, 2) * (-lambda * dphidt(i - 1) + mp * leng * g * Sin(phi(i - 1))) + Ainv(2, 1) * ga * u(i - 1)
ddyddt(i) = dummy(1)
ddphiddt(i) = dummy(2)

Cells(3 + i, 12) = Ainv(1, 1)
Cells(3 + i, 13) = Ainv(1, 2)
Cells(3 + i, 14) = Ainv(2, 1)
Cells(3 + i, 15) = Ainv(2, 2)

'    ファジィ制御
'    If Φ is PB and dΦdt is P  then u is PB
'    If Φ is NB and dΦdt is N  then u is NB
'    If Φ is PS and dΦdt is NB then u is NM
'    If Φ is NS and dΦdt is PB then u is PM
'    If Φ is PS and dΦdt is ZO then u is PS
'    If Φ is NS and dΦdt is ZO then u is NS

       If phi(i) > 0.4 Then
       kspbphi = 1
       ElseIf phi(i) > 0 Then
       kspbphi = phi(i) * 2.5
       Else
       kspbphi = 0
       End If
      
       If phi(i) > 0 Then
       ksnbphi = 0
       ElseIf phi(i) > -0.4 Then
       ksnbphi = -phi(i) * 2.5
       Else
       ksnbphi = 1
       End If

       If phi(i) > 0.1 Then
       kspsphi = 0
       ElseIf phi(i) > 0.05 Then
       kspsphi = 1 - (phi(i) - 0.05) / 0.05
       ElseIf phi(i) > 0 Then
       kspsphi = phi(i) / 0.05
       Else
       kspsphi = 0
       End If
      
       If phi(i) > 0 Then
       ksnsphi = 0
       ElseIf phi(i) > -0.05 Then
       ksnsphi = -phi(i) / 0.05
       ElseIf phi(i) > -0.1 Then
       ksnsphi = (phi(i) + 0.1) / 0.05
       Else
       ksnsphi = 1
       End If
      
       If phi(i) > 0.2 Then
       kszophi = 0
       ElseIf phi(i) > 0 Then
       kszophi = 1 - phi(i) * 5
       ElseIf phi(i) > -0.2 Then
       kszophi = 1 + phi(i) * 5
       Else
       kszophi = 0
       End If
      
       If dphidt(i) > 4 Then
       kszodphi = 0
       kspdphi = 1
       ksndphi = 0
       kspbdphi = 1
       ksnbdphi = 0
       ElseIf dphidt(i) > 0 Then
       kszodphi = 1 - dphidt(i) / 4
       kspdphi = 1
       ksndphi = 1 - dphidt(i) / 4
       kspbdphi = dphidt(i) / 4
       ksnbdphi = 0
       ElseIf dphidt(i) > -4 Then
       kszodphi = 1 + dphidt(i) / 4
       kspdphi = 1 + dphidt(i) / 4
       ksndphi = 1
       kspbdphi = 0
       ksnbdphi = -dphidt(i) / 4
       Else
       kszodphi = 0
       kspdphi = 0
       ksndphi = 1
       kspbdphi = 0
       ksnbdphi = 1
       End If
      
       kar1 = kspbphi
       If kar1 > kspdphi Then
       kar1 = kspdphi
       End If
       kar2 = ksnbphi
       If kar2 > ksndphi Then
       kar2 = ksndphi
       End If
       kar3 = kspsphi
       If kar3 > ksnbdphi Then
       kar3 = ksnbdphi
       End If
       kar4 = ksnsphi
       If kar4 > kspbdphi Then
       kar4 = kspbdphi
       End If
       kar5 = kspsphi
       If kar5 > kszodphi Then
       kar5 = kszodphi
       End If
       kar6 = ksnsphi
       If kar6 > kszodphi Then
       kar6 = kszodphi
       End If
       dum = kar1 + kar2 + kar3 + kar4 + kar5 + kar6
       If dum > 0 Then
       u(i) = (10 * kar1 - 10 * kar2 - 3 * kar3 + 3 * kar4 + kar5 - kar6) / dum
       Else
       u(i) = 0
       End If
Next
  
Cells(1, 2) = "時刻t(sec)"
Cells(2, 3) = "y(t)"
Cells(2, 4) = "Φ(t)"
Cells(2, 5) = "u(t)"
Cells(2, 6) = "dy(t)/dt"
Cells(2, 7) = "dΦ(t)/dt"
For i = 0 To 1000
Cells(3 + i, 2) = time(i)
Cells(3 + i, 3) = y(i)
Cells(3 + i, 4) = phi(i)
Cells(3 + i, 5) = u(i)
Cells(3 + i, 6) = dydt(i)
Cells(3 + i, 7) = dphidt(i)
Next

    Range("B2:D1003").Select
    Charts.Add
    ActiveChart.ChartType = xlLineMarkers
    ActiveChart.SetSourceData Source:=Sheets("Sheet4").Range("B2:D1003"), PlotBy _
        :=xlColumns
    ActiveChart.Location Where:=xlLocationAsObject, Name:="Sheet4"
    With ActiveChart
        .HasTitle = True
        .ChartTitle.Characters.Text = "振子の倒立制御(ファジィ制御)"
        .Axes(xlCategory, xlPrimary).HasTitle = True
        .Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "time(sec)"
        .Axes(xlValue, xlPrimary).HasTitle = True
        .Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "y(t)[m],Φ(t)[rad]"
    End With

End Sub


(注) m-adachi@02.246.ne.jp   へメールで依頼があれば、上記エクセルのソフトをメールの添付ファイルで送ります。

数 値シミュレーションの最初のページへ

簡単な常微分方程式の解を求めるシミュレーションへ

ホー ムページのトップへ