22
15

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-02-01

 制御工学はなかなか人が寄り付かない。今時モーションコントロールなんて、モータ屋さんが自動調整できるアンプを付けて販売しているから、位置指令を与えるだけでいい感じに制御してくれる。
 PIDがなんとなくわかっていれば、仕事に支障はありません。みんなそこまでで満足しちゃう。
(追記)
PIDの説明で良い記事を見つけました。
https://qiita.com/RyosukeH/items/9e5ce2ebdadd90e3db00

制御工学の何が難しい?

 何が障害になってるのかなあと考えてみると、制御系をプログラム言語で書くところまでがわからないんじゃないか。僕もそう言えばそうだった。制御工学の本にも書いてない。
 普通プログラムと言ったら、書いたコードを順番にコンピュータが実行していきます。
この時、CPUのクロック周波数を意識することはないでしょう。そして入力した情報は最速で処理され、出力も最小のタイムラグで表示されます。
 制御工学の理論通りに動くプログラムを作る場合には、こういった動き方、一番短い処理時間で処理が終わる動き方をされると、理論通りに動きません。一定の時間ごとに入力を受け付け、計算をして、出力を出す。そういった動き方が求められるので、タイマー割り込みで一定の時間ごとに入力信号を受け取り、計算して出力を出すことが多いです。無限ループ内にSleepを入れて、一定時間ごとに実行する方法でも良いかもしれない。

今回の目的

 最終的な目標はPI制御器を作るところに設定しました。だいたいPIしか使わないから。
 この記事では比例制御を実装するところまでにしました。

ブロックのないブロック線図

制御工学の話なのでブロック線図を書きます!
スクリーンショット 2019-01-31 22.49.59.png
これです。ブロック、ないような・・・
真ん中にブロック欲しいなあ。

図の中のI(s)をinput、O(s)をoutputという変数にして、
これをCで書いてみましょう。

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

この関数をサンプリング周波数のタイミングに合わせて実行すると理論通りに・・・と言ってもまだ理論でてきません。
ここで理解してもらいたいのは、サンプリング周波数に合わせてウェイトを入れて実行するところです。
実際のマイコンなどではタイマーでサンプリング周波数の間隔で実行することが多いです。

比例制御

ブロックつきました。
スクリーンショット 2019-01-31 23.05.50.png

int filter(float input, float Kp)
{
   float output;
   output = Kp*input;
   return output;
}

出力に係数Kpをかけるだけです。

フィードバックつけてみよう!

ここからは新しい要素をつけてみます。モータの伝達関数Gm(s)を入れて、よくあるフィードバック制御のブロック線図にしてみます。
モータはハードウェアなので当然ソフトには影響しません。モータのフィードバック信号を
 あ、符号忘れた。
スクリーンショット 2019-01-31 23.29.50.png
対応するソースコードは何と無く想像ができたと思います。
O(s)がモータに渡す指令値で、モータの動きがR(s)=responseになります。
指令値と実際の動きの差分をとって、それを0にするように制御がかかります。

int filter(float input, float response, float Kp)
{
   float output;
   output = Kp*(input-response);
   return output;
}

長くなってきたので記事を分けます

 ここまで、入力信号に係数をかけて出力する比例制御のソースコードを紹介しました。
 なんだ、簡単じゃん。と思ってもらえたら嬉しいです。
 積分は過去の値を使って出力値を計算する要素が出てきますので、そちらの記事は別に分けて紹介しようと思います。

22
15
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
22
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?