たけし備忘録

自分の好奇心の赴くままに勉強メモ LL系が大好き Python bash Julia C

伝達関数とブロック線図

  • 伝達関数
  • ブロック線図
    • 直列
    • 並列
    • フィードバック
      • 補足
      • 補足の補足

伝達関数

伝達関数とは、システムへの入力を出力に変換する関数のこと言う。
通常、伝達関数ラプラス変換によって変換された複素関数で表示されます。

出力、入力を順に時間の関数として$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を見るとなんとなく分かるかもしれない。

必要とする数学

制御工学は基本的に複素数の範囲でモノを考えます。
制御工学を理解・学ぶ上で基礎知識として欲しい数学が

の4つ程度だと思われます。
それぞれ特に難しいものでは無いのでちゃちゃっとやってしまえば3日ほどで必要なものはマスター出来るでしょう。

続きを読む

Kv言語の基本

PythonGUIライブラリは色々あります。
Tk, Qt, GTK, Pyglet, Pygameなど。
しかしスマホアプリをPythonで作ろうと思った時に選択出来るものとしたらQtくらいしか無い上に、PythonとQtでスマホアプリを作るとなるとなかなか手間です。

そこで手軽にスマホアプリを作ってしまおうというライブラリがKivyというライブラリです。

Kivy公式ホームページ

KivyクロスプラットフォームなのでWindows上で作ったものも、Andoird上で動きます。
特に今回は

  1. Windows上で開発
  2. AndoirdアプリのQPython上で動作確認
    (3. 出来ればアプリとして1つにパックしたい)

としていこうと思います。

QPythonAndroid上でPythonが使用出来るアプリです。デフォルトでKivyがGUIとして利用できます。

QPythonホームページ

続きを読む

ボールの自由落下(衝突判定有り)

先日アップした の続きで、ボールの自由落下に衝突判定を加えたバージョンになっています。 物理シミュレーションは衝突判定ができてなんぼです
衝突判定があると見た目的にもすごく面白いです。
では以下よりコードと結果を見てみましょう。

目次

  • 目次
  • 今回追加した部分
  • コードの解説~衝突検出の設定~
    • 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()

f:id:takeshiD:20160604125815g:plain

床をすり抜けてしまいました。
これは床とボールの衝突判定をしていないためすり抜けてしまいます。

コードを解説していきますが、その前にまず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ファイルでインストールしました。 LinuxMacの場合はpipで入れられるのかな?

  1. 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を生成するときにエラーがでなければ大丈夫です。

  1. VisualPythonのインストール まずVPythonWindows用ダウンロードページに飛びます。
    あとはご自分のPythonが64bit, 32bitで適当な方を選んでバイナリをダウンロードしてダブルクリックすればインストーラーが勝手にインストールしてくれます。