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

     ここでは、振子の振り上げ+レギュレーション制御を実現する制御手法について紹介する。初期の振子の状態は、真下に自然に垂れ下がっており、台車は原 点で静止している場合を扱うものとする。(φ(0)=3.14,dφ(t)/dt=0,y(0)=0,dy(0)/dt=0)

1)振子の振り上げは、台車を前後に動かすことで実現し(剣玉のイメージ)、
2)振子が直立に近くなったら、オブザーバ利用のFB制御(シミュレーション2で用いたもの)でレギュレーションを行う
というシーケンス制御(決まった順番で操作する制御の名称)を使うことを考えてみよう。

このときの、応答グラフは以下であり、そのソフトはグラフの下に示すものである。ただし、シーケンス制御の最初の台車を前後に動かす操作量としては、
u(t) = 3 * Sin(5 * t)
を用いており、初めて傾き角が0.9[rad]以内に入ってから、オブザーバFB制御に切り替えている。


Sub touritsu7()

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, flag 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("Sheet6")
   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

flag = 1  ' 1:sin入力、2:オブザーバFB制御

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

ephi(0) = 3.14
edphidt(0) = 0
ey(0) = 0
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)

If flag = 2 Then
     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)
'ElseIf flag = 1 And phi(i) < 0.5 And phi(i) > -0.5 Then
'ElseIf flag = 1 And phi(i) < 0.3 And phi(i) > -0.3 Then
'ElseIf flag = 1 And phi(i) < 0.7 And phi(i) > -0.7 Then
ElseIf flag = 1 And phi(i) < 0.9 And phi(i) > -0.9 Then
flag = 2
u(i) = 3 * Sin(5 * i * dt)
ey(i) = y(i)
ephi(i) = phi(i)
edydt(i) = (y(i) - y(i - 1)) / dt
edphidt(i) = (phi(i) - phi(i - 1)) / dt
Else
u(i) = 3 * Sin(5 * i * dt)
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("Sheet6").Range("B2:D1003"), PlotBy _
        :=xlColumns
    ActiveChart.Location Where:=xlLocationAsObject, Name:="Sheet6"
    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   へメールで依頼があれば、上記エクセルのソフトをメールの添付ファイルで送ります。

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

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

ホー ムページのトップへ