14
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

制御工学をCで実現する(積分制御)

Last updated at Posted at 2019-03-10

 今回の記事は積分をCで表現します。
 手法としては「双一次変換」あるいは「bilinear transform」と呼ばれる手法です。
この辺の技術が書いてある本はデジタルフィルタの本なので、制御工学を勉強してもなかなか出てきません。
 今から制御工学を学ぶ時にはデジタルフィルタの勉強も一緒にやっていくと良いと思います。

 ちなみにデジタルフィルタについては以下の記事がまとまっています。
https://qiita.com/fukuroder/items/e1cd551b7492020da992

###積分の伝達関数

積分をラプラス変換して伝達関数にすると、教科書的には以下の通り

G(s) = \frac{1}{s}\qquad(1)

sが分母にきます。

###双一次変換

双一次変換はZ変換を簡単にしたようなものです。詳細については別に解説します。
変換方法としては以下の式でsを置き換えることになります。


s=\frac{2}{T}\frac{1-z^{-1}}{1+z^{-1}}\qquad(2)

G(s)に代入すると、分子分母が逆になるので以下のように変換できます。
ここでT[s]はサンプリング周期です。前回のmain関数と合わせるためにT=0.1[s]としました。

G(z)=\frac{1}{\frac{2}{T}\frac{1-z^{-1}}{1+z^{-1}}}=\frac{T}{2}\frac{1+z^{-1}}{1-z^{-1}}\qquad(3)

これで離散時間領域の伝達関数ができました。

###具体的な係数
 ここまでで、伝達関数は完成しました。伝達関数は多項式の分子と分母を持つ分数の形で表されますが、
実際の数値を計算してみます。
 必要とされるのはサンプリング周波数です。今回は0.1秒で計算しますが、実際のシステムに合わせないと破綻します。
 $\frac{2}{T}$は分子分母どこにかけても問題はないのですが、分母の1に係数がかかると後の計算が面倒になるので、分子の方にかけます。

G(z)=\frac{T}{2}\frac{1+z^{-1}}{1-z^{-1}}=\frac{0.1}{2}\frac{1+z^{-1}}{1-z^{-1}}=\frac{0.05+0.05z^{-1}}{1-z^{-1}}\qquad(4)

この伝達関数はIIRフィルタと呼ばれるデジタルフィルタの伝達関数になるため、
以下の式で与えられます。

H(z)=\frac{\sum_{k=0}^{K} b_kz^{-k}}{1-\sum_{m=1}^Ma_mz^{-m}}\qquad(5)

普通のデジタルフィルタだとKとMが長くなっていくのですが、今回の伝達関数ではK=1,M=1となります。したがって以下の式になります。

H(z)=\frac{b_0+b_1z^{-1}}{1-a_1z^{-1}}\qquad(6)

(6)式の係数に(4)式の係数が代入されます。
$b_0=0.05$,$b_1=0.05$,$a_1=-1$です。

###伝達関数と差分方程式の関係
 次は伝達関数を差分方程式に変換していきます。
差分方程式とは現在の出力値を、現在の入力値、過去の入力値、加工の出力値から計算する式になります。

y[n]=\sum_{m=1}^Ma_my[n-m]+\sum_{k=0}^{K} b_kx[n-k]\qquad(7)

aは1から、bは0からの多項式になるので注意です。

(7)式も使う項だけ取り出すと以下の式になります。

y[n]=a_1y[n-1]+b_0x[n]+b_1x[n-1]\qquad(8)

###Cで実装する

前回と同じようにfilter()に積分の処理を実装します。

float x_1 = 0.0;
float y_1 = 0.0;

int filter(float input)
{
   const float Ki=1.0;
   const float T = 0.1;
   const float a_1 = -1;
   const float b_0 = 0.05;
   const float b_1 = 0.05;

   float output;
   output = a_1 *y_1 + b_0 * input +b_1 * x_1;
   y_1 = output;
   x_1 = input;

   return output;
}
void main()
{
   float input,output;
   while(1)
   {
      input = get_input_signal();
      output = filter(input);
      set_output_signal(output);
      sleep(100);
   }
}

###実使用上の注意
前回の比例制御ではなかなか起こらないのですが、積分制御では出力値が+かーに大きくなりすぎて、出力の範囲を超えてしまう場合があります。
積分は入力した信号の面積を計算するようなものなので、収束する方向で系が動いている場合には0に近づいていきますが、発散する方向に信号が動いている場合には簡単に出力信号の範囲を超えてしまいます。
この場合、収束するようにPIDのゲインを調整しますが、積分の値が大きくなりすぎると、収束するようなゲインになっても値がなかなか小さくならないので、どんなに待っても安定しないような状態になります。
試行錯誤を繰り返すPIDのゲイン調整では、こういう状態は困ります。そこで、出力信号の範囲を超える出力が出た時に、次の積分計算を止めます。
それ以上積分の出力が大きくならないようにすることで、安定状態になった時に正常な積分計算ができます。

###まとめ
これまでにPID制御のPとIについて述べてきました。積分はデジタルフィルタの知識がないと、実装ができないのですが、それを教えてくれる制御工学の本は皆無です。
どなたか、そのあたりの記述がある本を見つけたら、ご一報ください。

###参考文献

  • 三上直樹、初めて学ぶディジタル・フィルタと高速フーリエ変換
14
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?