数値積分法

プログラムにより積分を実現する数値積分法について書いてみます。ここではp5.js(JavaScript)を使って書いていきます。

最初に数値積分の概要について説明します。

下の図のような速度曲線が与えられたとします。時間tの経過に従って速度vがグラフのように変化するということです。この速度曲線を積分すると位置を求めることができます。

さて図のような速度曲線が事前に分かっておらず、一定時間Δt(Δtは短い時間)毎に速度が分かるとしましょう。このような状況はデジタル制御の世界では普通ですね。例えば1msで制御される車輪型移動ロボットでは1msに一回車輪の回転速度を計測し、それを足し合わせて積分することによりトータルの移動量を計算します。

上の速度曲線が分かっていないとし、代わりにΔt毎に速度が計測できるとしてみましょう。

下の図のようにΔt時間だけ経過したときに、速度を計測し(図の速度曲線のt=Δtのときの値を読む)、そのときの値をv1とします。するとこの間に移動した距離は 

速度×時間

で計算できますので、

v1*Δt

となります。速度曲線をf(t)とすると(実際には関数fは分かっていないので毎回計測するわけですが)速度v1はf(Δt)となり、Δtの間の移動距離x1がv1*Δtとなるわけです。

次にさらにΔt時間が経過したときに、速度v2を計測した状態を示しましょう。下の図のように速度はv2=f(2Δt)となり、移動距離はx2=v2 Δt+x1として計算できます。

さらにΔt時間が経過したときに、速度v3を計測した状態を示しましょう。下の図のように速度はv3=f(3Δt)となり、移動距離はx3=v3 Δt+x2として計算できます。

これを繰り返し(n-1)Δt時間が経過したときに、速度v n-1を計測した状態を示しましょう。下の図のように速度はv n-1=f((n-1)Δt)となり、移動距離はx n-1=v n-1 Δt+x n-2として計算できます。

最後にnΔt時間が経過したときに、速度vnを計測した状態を示します。下の図のように速度はvn=f((n)Δt)となり、移動距離はxn=vn Δt+x n-1となります。

以上のようにすれば、Δt時間おきに計測した速度を使って、その間の移動距離xを求めることが出来るわけです。

以上のようにそこまでの移動距離に新たにΔtの間に移動する距離を足し加えるという式を辺々足し合わせまとめると、下の図に示すように xn が計測した時間ごとの速度を足し合わせた結果にΔtをかければ計算できることが分かります。

この計算をp5.jsで実装してみましょう。移動距離に使う変数をxとし、計測した速度をspeedとします。ここでは速度の計測用の関数をgetSpeed()としています。また計測時間間隔をdeltaTとしています。これでspeed*deltaTでdeltaT時間での移動距離が計算できますので、それをxに足し加えて新たなxを計算すれば、そのxが積分結果(移動距離)となります。

let x = 0; //積分結果を取っておく変数。積み重ねていくため、グローバル変数として宣言する。

let deltaT = 0.01; //delta t: 0.01 sec


function setup() {

x = 0; //x initialization xの初期化

}

function draw() {

let speed; //速度の変数

speed = getSpeed(); //calculate speed 速度の算出あるいは速度の取得

x += speed*deltaT; //integrate the speed 速度の積分

}


p5.jsのdraw()関数はframeRate()関数の戻り値で示されるフレームレートで実行されています。ですからdraw()関数ごとに速度を測定し、積分するのであればΔtを可変として、

Δt = 1/frameRate();

とすることでΔtを求めることが出来ます。この場合のプログラムを下記に示します。

let x = 0; //積分結果を取っておく変数。積み重ねていくため、グローバル変数として宣言する。


function setup() {

x = 0; //x initialization xの初期化

}

function draw() {

let speed; //速度の変数

speed = getSpeed(); //calculate speed 速度の算出あるいは速度の取得

x += speed/frameRate(); //integrate the speed 速度の積分

}