伝達関数とブロック線図
- 伝達関数
- ブロック線図
- 直列
- 並列
- フィードバック
- 補足
- 補足の補足
伝達関数
伝達関数とは、システムへの入力を出力に変換する関数のこと言う。
通常、伝達関数はラプラス変換によって変換された複素関数で表示されます。
出力、入力を順に時間の関数として$y(t), u(t)$とすると、これらをラプラス変換した関数を$Y(s), U(s)$としてやれば伝達関数$G(s)$は
$$ G(s) = \frac{Y(s)}{U(s)} $$
と書く。
考え方として分かりやすい書き方だと
$$ Y(s) = G(s)U(s) $$
と書く。つまり伝達関数$G(s)$とは、入力$U(s)$を$G(s)$倍するような増幅装置のような役割となっています。
続きを読む状態フィードバック制御
状態フィードバック制御とは
システム $$ \dot{x} = x + u $$ について考える。このシステムの極は、特性方程式により、
$$
(s-1) = 0
$$
$s=1$が極となる。
したがって、このシステムは不安定である。
$$ x = A \exp{(st)} $$
ここで入力$u$を工夫して
$$ u = kx + v $$
このようにすると、
新たなシステムが
$$ \begin{align} \dot{x} &= x + kx + v \\ &= (1+k)x + v \end{align} $$
この特性方程式
$$ (s-(1+k)) = 0 $$ により $$ s = 1+k $$ となり、$s$を任意の値に設定することが出来る。
続きを読む制御工学の基礎 目次
制御工学を勉強するためにこのページをまとめておきます。
Python-Controlモジュール関連のサイト
制御工学の基礎
制御工学とは、モノをコントロールする学問のことを指す。
Wikipediaを見るとなんとなく分かるかもしれない。
必要とする数学
制御工学は基本的に複素数の範囲でモノを考えます。
制御工学を理解・学ぶ上で基礎知識として欲しい数学が
- 微分積分(基本的な微分と積分ができれば良い)
- 線形代数(基本的な行列計算: rank, 行列式, 余因子展開, 固有値固有ベクトル, 対角化(できればジョルダン標準形))
- フーリエ変換
- ラプラス変換(フーリエ変換の拡張なのでフーリエを覚えれば扱いと計算は同じ)
の4つ程度だと思われます。
それぞれ特に難しいものでは無いのでちゃちゃっとやってしまえば3日ほどで必要なものはマスター出来るでしょう。
Kv言語の基本
PythonのGUIライブラリは色々あります。
Tk, Qt, GTK, Pyglet, Pygameなど。
しかしスマホアプリをPythonで作ろうと思った時に選択出来るものとしたらQtくらいしか無い上に、PythonとQtでスマホアプリを作るとなるとなかなか手間です。
そこで手軽にスマホアプリを作ってしまおうというライブラリがKivyというライブラリです。
KivyはクロスプラットフォームなのでWindows上で作ったものも、Andoird上で動きます。
特に今回は
- Windows上で開発
- AndoirdアプリのQPython上で動作確認
(3. 出来ればアプリとして1つにパックしたい)
としていこうと思います。
QPythonはAndroid上でPythonが使用出来るアプリです。デフォルトでKivyがGUIとして利用できます。
続きを読む
ボールの自由落下(衝突判定有り)
先日アップした
の続きで、ボールの自由落下に衝突判定を加えたバージョンになっています。
物理シミュレーションは衝突判定ができてなんぼです
衝突判定があると見た目的にもすごく面白いです。
では以下よりコードと結果を見てみましょう。
目次
- 目次
- 今回追加した部分
- コードの解説~衝突検出の設定~
- Geomオブジェクト:床とボールの作成
- GeomオブジェクトにBodyオブジェクトをセット + 接触グループの取得
- 衝突検出のコールバック関数
- コードの解説~シミュレーションループで衝突計算を反映させる~
ボールの自由落下(衝突判定無し)
まずは簡単なところから
床とボールを表示させ、ボールを落下させてみましょう
目次
[FreeFall.py]
# -*- coding:utf-8 -*- import visual as vs import ode vs.scene.center = (0, 2, 0) """ ODE環境の設定 """ # ODEワールドの作成 + ワールドの重力設定 world = ode.World() world.setGravity((0, -9.81, 0)) # 剛体の作成 + 質量特性の設定 Ball_Body = ode.Body(world) M = ode.Mass() M.setSphere(2500.0, 0.5) Ball_Body.setMass(M) Ball_Body.setPosition((0, 4, 0)) """ VPython環境の設定 """ Floor = vs.box(length=4, height=0.2, width=4) Floor.pos = vs.vector(0, 0, 0) Ball_VS = vs.sphere(pos=Ball_Body.getPosition(), radius=0.5, color=vs.color.red) if __name__=="__main__": dt = 0.05 total_time = 0.0 while total_time<2.0: """ ODEによってVPythonのボールの位置を更新 """ Ball_VS.pos = Ball_Body.getPosition() vs.rate(1/dt) # VPythonのアニメーションを進める world.step(dt) # ODEの計算を進める total_time += dt vs.exit()
床をすり抜けてしまいました。
これは床とボールの衝突判定をしていないためすり抜けてしまいます。
コードを解説していきますが、その前にまずODEの概略について説明しましょう。
ODEの基本の2つ: 剛体と形状
ODEはまず、剛体(Body)と形状(Geom)の2つの要素から成ります。
剛体は質量特性を管理するオブジェクト
形状は衝突判定を管理するオブジェクトです
剛体も形状も、それぞれが一つのモノを表しますのでこれらを複数管理するオブジェクトが必要になります。
それがWorld(剛体の世界)とSpace(形状の世界)です。
以下に対応表を書いておきます。
種類 | 空間 | 含まれるオブジェクト |
---|---|---|
剛体・質量特性 | World | Body |
形状・衝突判定 | Space | Geom |
コードの解説~ODEの設定~
今回はODEの設定で
""" ODE環境の設定 """ # ODEワールドの作成 + ワールドの重力設定 world = ode.World() world.setGravity((0, -9.81, 0)) # 剛体の作成 + 質量特性の設定 Ball_Body = ode.Body(world) M = ode.Mass() M.setSphere(2500.0, 0.5) Ball_Body.setMass(M) Ball_Body.setPosition((0, 4, 0))
としてWorld(剛体の世界)しか作成していないので衝突判定ができなかったため、床をすり抜ける事態が起きました。
衝突判定についてはまた別の機会で上げます。
Worldの作成
剛体を計算させるためにはまず剛体が含まれる世界、Worldを作る必要があります。
# ODEワールドの作成 + ワールドの重力設定 world = ode.World() world.setGravity((0, -9.81, 0))
ode.WorldでWorldのインスタンスworldを作成し、world.setGravityで重力を設定します。
この時、world.setGravityの引数は(x, y, z)という3次元のデータにしましょう。
タプル、リスト、VPythonのvector、numpyのndarrayのどれかにするといいでしょう。
VPythonではvector, ODEではタプルなどとするのは面倒なので、VPythonとODEの連携をするなら色々な高速な関数が入ってるnumpyを使うのがいいかもしれません。
今回は多くの例に習ってタプルにしました。
剛体の作成・配置
worldを作成したのでこの中に剛体を作成・配置していきましょう。
# 剛体の作成 + 質量特性の設定 Ball_Body = ode.Body(world) M = ode.Mass() M.setSphere(2500.0, 0.5) Ball_Body.setMass(M) Ball_Body.setPosition((0, 4, 0))
ode.Body(world)で、作成したworldにBody(剛体)を作成します。
剛体は質量特性を設定するオブジェクトなのでこのBodyにode.Massで質量特性を設定します。
M.setSphere(密度[kg/m3], 半径[m])としてMに球状の質量特性=密度+半径を設定します。
この場合、半径0.5[m]の質量分布は2500.0[kg/m3]で一定です。
次に作成した質量特性Mを剛体Ball_BodyにBall_Body.setMass(M)で設定します。
最後にBall_Body.setPosition*1で剛体の初期位置を設定します。
コードの解説~VPythonの設定~
VPythonの設定は完全に見た目だけのものです。
内部的な計算は全てODEでなされているのでVPythonではODEの設定をどう反映させるかだけが問題となります。
""" VPython環境の設定 """ Floor = vs.box(length=4, height=0.2, width=4) Floor.pos = vs.vector(0, 0, 0) Ball_VS = vs.sphere(pos=Ball_Body.getPosition(), radius=0.5, color=vs.color.red)
床とボールの作成・設定
FloorとBall_VSを作成します。
vs.box(length, height, width)という形で引数を受け付けています。
(length, height, width)=(x, y, z)という形で軸が対応しています。
作成したFloorの位置をFloor.pos=vs.vector(x, y, z)という形で設定します。タプル、リスト、numpyのndarray、VPythonのvectorでも大丈夫です。今回はVPythonのvectorにしてみました。
この位置はboxの中心ではなく、6面のうちのどこかの面の中心が(x, y, z)に一致するようになっています。それだけではもちろんボックスの向きが分かりません。そこでFloor.axis=(x, y, z)という形でボックスの向きのベクトルを設定できます。
コードの解説~シミュレーションループ:VPythonとODEの連携~
実は連携というほど大げさなものじゃないです。
ODEで計算 → VPythonで見た目を描画
を繰り返すだけです。
if __name__=="__main__": dt = 0.05 total_time = 0.0 while total_time<2.0: """ ODEによってVPythonのボールの位置を更新 """ Ball_VS.pos = Ball_Body.getPosition() vs.rate(1/dt) # VPythonのアニメーションを進める world.step(dt) # ODEの計算を進める total_time += dt vs.exit()
dtはODEを計算するための時間ステップです。
dt=0.05[sec]ごとに計算が進むことになります。
Ball_VS.pos = Ball_Body.getPosition()によってODEで計算した結果をVPythonに渡します。
vs.rate(1/dt)によってVPythonの描画スピードを1/0.05=20[frames/sec]と設定します。
world.step(dt)によってODEの計算をdtだけ進めます。
whileループを外れたあと、vs.exit()によってVPythonの描画を終了しウィンドウを閉じます。
*1:0, 4, 0
PyODEとVPythonのインストール
それぞれ特に難しくはありません。
私はWindowsなのでwhlファイルでインストールしました。
LinuxやMacの場合はpipで入れられるのかな?
- PyODEのインストール
まず上記の公式サイト、ではなく!
Windows用Python拡張パッケージ 非公式版(英語)
に飛んで、ページ内検索(CTRL+F)で「ode」と入力しましょう。
現在(2016/6/2)ではode-0.13.1が最新版です。
私はPython2.7 Windows7 64bitなのでode-0.13.1-cp27-none-win_amd64.whlをダウンロードしました。私はwhlファイルをよくインストールするのでC:\PythonPackageに一箇所に集めています。
今回も C:\PythonPackage\ode-0.13.1-cp27-none-win_amd64.whlとなるようにダウンロードしました。
[C:\PythonPackage] $ ls ode-0.13.1-cp27-none-win_amd64.whl
となっているので
[C:\PythonPackage] $ pip install ode-0.13.1-cp27-none-win_amd64.whl
とすれば正常にインストールされます。
インストールされたか確認しておきましょう。
[C:\PythonPackage] $ ipython Python 2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500 64 bit (AMD64)] Type "copyright", "credits" or "license" for more information. IPython 4.1.1 -- An enhanced Interactive Python. ? -> Introduction and overview of IPython's features. %quickref -> Quick reference. help -> Python's own help system. object? -> Details about 'object', use 'object??' for extra details. In [1]: import ode In [2]: world = ode.World()
worldを生成するときにエラーがでなければ大丈夫です。
- VisualPythonのインストール
まずVPythonWindows用ダウンロードページに飛びます。
あとはご自分のPythonが64bit, 32bitで適当な方を選んでバイナリをダウンロードしてダブルクリックすればインストーラーが勝手にインストールしてくれます。