ec
Fork of EC by
Diff: EC.h
- Revision:
- 30:087ad7703445
- Parent:
- 29:b8de333facd4
- Child:
- 31:05e37fea072b
--- a/EC.h Tue Aug 15 07:26:28 2017 +0000 +++ b/EC.h Thu Aug 17 04:27:00 2017 +0000 @@ -150,16 +150,21 @@ }; -/*! - * 速度制御用ライブラリ +/**速度制御用ライブラリ + * + * サンプルプログラム * * @section 基本的な速度制御の実用までの流れ * * 1. モーター・エンコーダ・モータードライバ・マイコン・バッテリーを適切につなげる * + * 接続のイメージ↓ + * + * https://www.fastpic.jp/images.php?file=0391548523.png + * * 注意!!! リポ用のスイッチと電圧計を必ずつけること!!! - * - * + * + * / * * 2. 実際にモーターを回転させてみて不備なく動作するか確認する * @@ -173,6 +178,8 @@ * * などなど。コードは下の一つ目のものを使えばいい * + * / + * * 3. Cの値を見つける * * このライブラリでは、「モーターにかかる電圧(duty比)と回転速度はある程度比例の関係にあるだろう」という考え方をしている(もちろん実際のモデルはもっと複雑である)。 @@ -187,10 +194,26 @@ * * 具体的なこの係数の求め方は、duty比を0.05くらいずつで変化させ、その時のduty比と回転角速度を記録し、excelからグラフの傾きを求めればよい。 * - * @image html https://www.fastpic.jp/images.php?file=2416798781.gif + * こんな感じになるよっていう画像↓ + * + * https://www.fastpic.jp/images.php?file=2416798781.gif * * コードは下の一つ目のものを使えばいい * + * / + * + * 4. pd係数を見つける + * + * 上記の通り、最終的にはpd制御(精確にはi+pd制御)によって目標角速度に収束させる。 + * + * ここではそのpd制御の操作量を決定する係数を見つける。これも実験的に求めるほかなく、値を変えて挙動を見てを繰り返して最適な係数を見つける。 + * + * 値の評価は、目標に達するまでの速さ、オーバーシュートの少なさ、収束後の値の振動の小ささなどである。 + * + * 重要度的にはp制御>d制御(場合によってはd制御が不必要なことも)なので、まずdの係数を0にした状態で先にpの係数を見つける。 + * + * コードは下の二つ目のものを使えばいい + * * @code * //2,3で使えるサンプルコード * //入力はTera Termで行う @@ -241,42 +264,78 @@ * @endcode * * @code + * //PDの係数を探したいときに使えるサンプル + * //入力はTera Termで行う * #include "mbed.h" * #include "EC.h" //ヘッダファイルをインクルード * - * SpeedControl motor1(PA_0,PA_1,NC,1024,0.05,PB_8,PB_9); //エンコーダ分解能1024、角速度計算間隔を0.05秒に設定 - * Ticker ticker; //角速度計算用ticker - * DigitalIn button(USER_BUTTON); + * #define TARGET_OMEGA 20 //目標角速度を20rad/sに設定 + * + * SpeedControl motor(PF_0,PB_1,NC,1048,0.05,PA_8,PB_5); //エンコーダ分解能1024、角速度計算間隔を0.05秒に設定 + * Ticker motor_tick; //角速度計算用ticker * Serial pc(USBTX,USBRX); - * + * * void calOmega() //角速度計算関数 * { - * motor1.CalOmega(); + * motor.CalOmega(); * } * * int main() * { - * ticker.attach(&calOmega,0.05); //0.05秒間隔で角速度を計算 - * motor1.setPDparam(0.01,0); //PDパラメータを設定 - * motor1.setDOconstant(46.3); //duty比と角速度の変換係数を46.3に設定 - * - * int kai=0; + * motor_tick.attach(&calOmega,0.05); //0.05秒間隔で角速度を計算 + * motor.setDOconstant(46.3); //求めたCの値を設定 + * + * int kai=0; + * double target_omega=0; + * double P=0.0,D=0.0; * - * while(1) { - * motor1.Sc(-10); //角速度10rad/sで逆回転 - * if(kai>=500){ //ループ500回ごとに角速度・出力duty比を表示 - * pc.printf("omega=%f duty=%f \r\n",motor1.getOmega(),motor1.duty); - * kai=0; - * } - * if(pc.readable()) { - * char sel=pc.getc(); - * if(sel=='q') break; //qを押したらリセット - * } - * kai++; - * } - * motor1.stop(); + * while(1) { + * motor.Sc(target_omega); //速度制御のコア関数 + * if(kai>=500) { + * pc.printf("count=%d omega=%f target_omega=%f dutyF=%f dutyB=%f P=%f D=%f\r\n",motor.getCount(),motor.getOmega(),target_omega,(double)motor.pwm_F_,(double)motor.pwm_B_,P,D); + * //エンコーダのカウント、角速度、目標角速度、正方向出力duty比、負方向出力duty比、Pの係数、Dの係数を表示 + * kai=0; + * } + * //係数探しの流れとしては、係数変更→速度制御開始→収束具合を観察・比較→モーター停止の繰り返し + * if(pc.readable()) { + * char sel=pc.getc(); + * + * switch (sel) { + * case 'k': //kでpの係数に0.01加算 + * P+=0.01; + * break; + * case 'm': //mでpの係数に0.01減算 + * P-=0.01; + * break; + * case 'j': //jでdの係数に0.01加算 + * D+=0.01; + * break; + * case 'n': //nでdの係数に0.01減算 + * D-=0.01; + * break; + * case 's': + * motor.stop(); //sでモーター停止 + * target_omega=0; + * break; + * case 'x': + * target_omega=TARGET_OMEGA; //xで速度制御開始 + * break; + * default: + * break; + * } + * + * if(sel=='q'){ + * break; //qを押したら終了 + * } + * + * motor.setPDparam(P,D); //変更したパラメータをセット + * } + * kai++; + * } + * motor1.stop(); * } * @endcode + * */