PID制御ライントレースロボット3 P制御成功
やっとこさPID制御のうちP制御と言えるものに成功した。この間RubyとオブジェクトCとかやってたのを含めてLEGO NXTを6ヶ月中断していた。正直長かった。頭の片隅でずうっとなんで出来なかったんだっておもってたもん。
以下のプログラムでは地面が白ければ白いほど早く黒いニチバンテープのラインに戻ろうとするがわかる。
後はP値の数値の見直しやバランシングで最適なタイムを出すことが出来るようになるだろう。
前々日から変更した点は
1、P値がマイナスにならないようにフィルターを設けたこと(マイナスになるとモータが逆転してしまう→ノッキングを繰り返す)
2、P値の係数をまずは1にしてセンサー値と目標値の差分を感覚的に分かりやすくしたこと
3、右モータと左モーターにプラマイ反対の数値を足している(細かくノッキングする原因となる?)
にある。特に1が見落としがちだが重要と思う。
要するに出力を現在センサーと目標値との差に比例させて制御するのがプロポーショナル制御なんだけど。センサーの仕様によってあるいはモーターのしようによってうまくその数値を可変モディファイしてあげないといけないということなんだよね。別に比例制御だから無段階の出力制御なんだ、式は美しいのでそのまま使うんだって難しく考えずに、途中数値に手を加えてあげて/2とか*3をしてあげるとかして)使いやすいようにラインに対して美味しい出力はなんだろうって考えればすぐに解けたのね。
task main()
{SetSensorColorRed(IN_2);
#define TIME 100
int standerd;
int POW;
int currentsensor;
int previoussensor;
int kp=1;
int ki;
int kd=5;
int P;
int I;
int D;
standerd=20;//変数standerdに初期の光量を入力するこれは以後の出力の基準点となる
previoussensor=Sensor(IN_2);//エラーを防ぐためセンサー値を初期化してからループ
while(true){
NumOut(80,LCD_LINE6,SENSOR_2);//ディスプレイにセンサー2の数値を表示
currentsensor=Sensor(IN_2);//現在の光量を計測する
P=(currentsensor-standerd)*kp;
if( P < 0 ){
P = 0 ; }
else{
P = P ;}
POW =P;
if(currentsensor<28){
OnFwd(OUT_C,60 + POW);
OnFwd(OUT_A,30 - POW );
Wait(TIME);}
else{
OnFwd(OUT_C,30 - POW);
OnFwd(OUT_A,60 + POW);
Wait(TIME);}
previoussensor=currentsensor;//モータ出力後現在の値を過去の値に代入し塗り替える
}}