バネマスダンパ系のPIDシミュレーション
はじめに
前回記事のプログラムを改良してPIDシミュレーションしてみた negizoku.hatenablog.jp
この方程式をちょっと改造してPID制御を組み込む
時間微分すると変位になる変数を定義する
ここで外力は
このときなら
実装
from scipy.integrate import odeint import matplotlib.pyplot as plt import numpy as np class Simulation: def __init__(self, m, c, k, x0, v0): self.setSystem(m, c, k) self.intiVal(x0,v0) def setSystem(self, m, c, k): self.m=m self.c=c self.k=k def intiVal(self, x0, v0): self.u0 = [0, x0, v0] def exForce(self, t): return 0 def equationOfMotion(self, u, t): self.u=u f = self.exForce(t) A = np.array([ [0,1,0], [0,0,1], [0,-k/m, -c/m]]) b = np.array([0,0,f/m]) return np.dot(A, u) + b def do(self, times): u0 = np.copy(self.u0) orbit=odeint(self.equationOfMotion, u0, times) return (orbit[:,1], orbit[:,2]) class PID(Simulation): def __init__(self, m, c, k, x0, v0): super().__init__(m, c, k, x0, v0) def setCoefficients(self, kp, ki, kd): self.coefficients = np.array([ki, kp, kd]) def setTarget(self, target): self.target = target def exForce(self, t): errors = np.array([t*self.target, self.target, 0])-self.u return np.dot(self.coefficients, errors) if __name__ =="__main__": m=1 c=2 k=0 x0 = 0 v0 = 0 sim = PID(m,c,k,x0,v0) sim.setTarget(10) sim.setCoefficients(20, 20, 10) dt = 0.001 stop = 10 times=np.arange(0., stop+dt, dt) x,v = sim.do(times) plt.plot(times,x) plt.xlim(0,stop) plt.xlabel("t[s]") plt.ylabel("x[m]") plt.grid() plt.show()
結果
目標値を時間関数にする
'''python from scipy.integrate import odeint from scipy import integrate from scipy.misc import derivative import matplotlib.pyplot as plt import numpy as np from math import sin, pi
class Simulation: def init(self, m, c, k, x0, v0): self.setSystem(m, c, k) self.intiVal(x0,v0)
def setSystem(self, m, c, k):
self.m=m
self.c=c
self.k=k
def intiVal(self, x0, v0):
self.u0 = [0, x0, v0]
def exForce(self, t):
return 0
def equationOfMotion(self, u, t):
self.u=u
f = self.exForce(t)
A = np.array([
[0,1,0],
[0,0,1],
[0,-k/m, -c/m]])
b = np.array([0,0,f/m])
return np.dot(A, u) + b
def do(self, times):
u0 = np.copy(self.u0)
orbit=odeint(self.equationOfMotion, u0, times)
return (orbit[:,1], orbit[:,2])
class PID(Simulation): def init(self, m, c, k, x0, v0): super().init(m, c, k, x0, v0)
def setCoefficients(self, kp, ki, kd):
self.coefficients = np.array([ki, kp, kd])
def target(self,t):
return sin(t/5 *2*pi)
def exForce(self,t):
dt=0.00001
u_target=np.array([
integrate.quad(self.target, 0, t)[0],
self.target(t),
(self.target(t+dt)-self.target(t+dt))/2/dt
])
errors = u_target-self.u
return np.dot(self.coefficients, errors)
if name =="main": m=1 c=2 k=0 x0 = 0 v0 = 0 sim = PID(m,c,k,x0,v0) sim.setCoefficients(100, 0, 10)
dt = 0.001
stop = 20
times=np.arange(0., stop+dt, dt)
x,v = sim.do(times)
plt.plot(times,x)
plt.xlim(0,stop)
plt.xlabel("t[s]")
plt.ylabel("x[m]")
plt.grid()
plt.show()
# 出力結果 [f:id:negizoku:20211120215456p:plain] ##目標の書き換え
def target(self,t):
return float(int(t)%2)
[f:id:negizoku:20211120221213p:plain]
SciPyを使ってバネマスダンパ系のシミュレーションをやってみる
理論
scipy.integrate.odeintでは常微分方程式を解くことができる。 バネマスダンパ系の運動方程式をの形に書き換えれば解を得られる。
バネマスダンパ系の運動方程式は次の通り。ここでは外力
ここで両辺をで割る。
であることを考慮すれば、現代制御でおなじみの方程式が導かれる
実装
from scipy.integrate import odeint import matplotlib.pyplot as plt import numpy as np #外力 def exForce(u,t): return 0 #運動方程式 def equationOfMotion(u, t, m,c,k): f = exForce(u,t) A = np.array([ [0,1], [-k/m, -c/m]]) b = np.array([0,f/m]) return np.dot(A, u) + b if __name__ =="__main__": #バネマスダンパの係数 m=1 c=2 k=5 args= (m,c,k) #初期値 x0 = 10 v0 = 0 u0=[x0,v0] #計算時間 dt = 0.001 stop = 10 times=np.arange(0., stop+dt, dt) #解 orient = odeint(equationOfMotion, u0, times, args) x=orient[:,0] v=orient[:,1] #グラフ表示 plt.plot(times,x) plt.xlim(0,stop) plt.xlabel("t[s]") plt.ylabel("x[m]") plt.grid() plt.show()
出力結果
外力を変えてみる
ステップ入力
def exForce(u,t): if(t>2): f=4 else: f=0 return f
正弦波
from math import sin #外力 def exForce(u,t): return 0.5*sin(2*t)
読書記録「スポーツ・ルール学への序章」
説明
- 「野球はなぜ9人で行うのか」
- 「ラグビーのゴールはなぜ11人なのか」
- 「テニスの得点はなぜ0, 15, 30, 40, 60なのか」
といった誰もが抱く疑問の答えを探求するのが「スポーツ・ルール学」である。
本書ではまず「日本人の公認ルール神聖視」や「ルール変更の根拠は記録されにくい」といった問題点を指摘する。 その後野球、フットボールがスポーツ化していった経緯について紹介し、ルールの目的について整理した。 そして三章で近代社会のルール観から、アピールの意義と審判の役割拡大についてのべた。 最終章である四章では「スポーツ文化を発展させるために、ルールはどうあるべきか」といった観点から考察をしていった。
※ 公認ルール神聖視とは「ボールに4回触れてから相手に返球してもよいようなルールでやるバレーボールはレベルが低い」といった価値観のことである。そもそもルールは同意の下つくられた幻想にすぎないのだからこのような価値観は受動的だと筆者は批判する。
ロボコンとの関係性について考察
スポーツルール学的観点からスポーツとロボコンを比較する。
共通点1「共通のルールの基で競い勝利を目的とする」
ここでの「勝利を目的とする」というのは八百長などを禁止する意味合いが含まれる。スポーツは賭博や賞金など大金が関わることが多いためこれが発生しやすいのである。日本のロボコンは殆ど全て「学生がやるもの」や「趣味の延長線上」として捉えられているせいか、八百長問題などは耳にしない。将来的に職業としてロボコンができるようになれば同様に八百長問題がでてくると考えられる。高専ロボコンにおけるお飾り程度の「アイデアマンシップ」は、スポーツマンシップや非紳士的行為の禁止を参考にしたと思われる。幸か不幸か、この文言が役に立つ日はまだ遠いようである。
また競技である以上勝敗が存在するため全ての人が同時に同じように楽しむことができないという共通の課題も存在する。ロボコニストの中にはスポーツが下手で落ちこぼれとなってしまった人も多いのではないだろうか。
共通点2「ルール変更の根拠が記録されにくい」
ルールは競技の水準や安全性、組織の収入増など様々な理由で変更されるがその理由が説明されることは殆どないし、ましてやそれが世間で話題になることは滅多に無い。たいていのルール変更は競技委員会中心で行われる。これはロボコンも同じで、ルール変更の理由が説明されるのは専ら安全対策が理由となる場合のみである。
共通点3「審判の役割が大きい」
審判が大きな役割を果たすのもスポーツ(特に現代スポーツ)との共通点である。近代のスポーツは決闘などに代表される「法から外れた自己統治の意識」から、審判の役割が小さく選手のアピールや話し合いに依る部分が大きかった。しかし現代になるにつれ、参加者の増加や試合結果の社会的評価や利益との結びつきにより、審判の役割が大きくなっていった。これを参考にしたのか、多くのロボコンでは同様に審判の判断は絶対である。
相違点1「個人の力量を比較するため道具に制限を加える」
スポーツでは「飛びすぎるボール」や「体の筋肉の凹凸を減らす効果を持つ水着」など記録に有利な道具がが禁止されることがある。これはスポーツが肉体的闘争を重視しているからである。ロボコンではこういったことはあまり起こらない。「強いロボットに優れた技術が載っているのは当然」といった発想があるからかもしれない。
相違点2「文化である」
スポーツは様々な外圧の影響を受けながらも社会が発展させていったものである。しかしロボコンは生まれて間もないものであるし、外部からの圧力を受けた経験もほとんど無く、社会からの関心もスポーツと比べて小さい。
書籍情報
- 著者:中村敏雄
- 発行年:1995/07/10
- 発行所:大修館書店
OpenCVSharp4で細線化
いろいろプログラムを組もうとしたが、やっぱりライブラリには勝てなかったよ...
OpenCVとカメラを使ったフォームアプリケーション
はじめに
カメラで撮影した画像を、OpenCVで処理してからフォームアプリで表示させたかったので作成した。
撮影+画像処理はbackgroundWorker内で行い、timerでbackgroundWorkerを定期的に呼び出すことにした。
ツールのレイアウト
- TableLayoutPanel
- PictureBox
- label
- backgroundWorker
- timer
を配置する
コード
Nugetから「OpenCvSharp4」と「OpenCvSharp4.runtime.win」をインストール
backgroundWorkerやtimerの動作は、「Form1.cs[デザイン]」内の要素をダブルクリックするか、「Form1.Designer.cs」で追加する。
OpenCVSharp4で勾配構造テンソルを使った二値化
ODEのオブジェクトの作り方
-
オブジェクト用の構造体を作る
-
main関数で詳しく設定
-
drawstuffのシミュレーションループ関数内で描画