Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: harurobo1006 harurobo_1026
Fork of EC by
Diff: EC.h
- Revision:
- 0:20fc96400ca3
- Child:
- 1:d10ca555a103
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/EC.h Thu Jun 16 07:36:15 2016 +0000
@@ -0,0 +1,219 @@
+#ifndef __INCLUDED_EC_H_
+#define __INCLUDED_EC_H_
+
+#ifndef M_pi
+#define M_pi 3.141592
+#endif
+/**increment型encoder用class*/
+
+class Ec{
+ private:
+ int S; //A相B相のパターン(1~4)
+ bool stateA,stateB; //A・B相の状態
+ int count; //カウント数 分解能分で一周
+ int pre_count; //一つ前のカウント
+ double precount; //4倍精度カウント
+ int solution; //分解能
+ double dt; //角速度の計算間隔
+
+
+ InterruptIn signalA_;
+ InterruptIn signalB_;
+
+ void upA();
+ void downA();
+ void upB();
+ void downB();
+
+ public:
+ double omega; //角速度
+ /** コンストラクタの定義
+ *
+ * main関数の前に必ず一度宣言する
+ *
+ * 使うエンコーダの数だけ設定する必要がある
+ *
+ * @param signalA エンコーダA相のピン名
+ * @param signalB エンコーダB相のピン名
+ * @param s エンコーダの分解能(省略可)
+ * @param t 角速度計算の間隔(省略可)
+ */
+ Ec(PinName signalA,PinName signalB,int s,double t);
+
+ ///countの値を返す関数(int型)
+ int getCount();
+ ///omega(角速度 rad/s)の値を計算する関数
+ /** @section CAUTION
+ * CalOmega関数は、一定時間ごと(dtごと)に計算される必要があるので、main関数内でタイマー割り込みを設定する必要がある。
+ * @code
+ * #include "mbed.h"
+ * #include "EC.h"
+ *
+ * Ec Ec1(PA_0,PA_1,1024,0.05); //分解能1024、計算間隔0.05秒に設定
+ * Ticker ticker;
+ * DigitalIn button(USER_BUTTON);
+ * Serial pc(USBTX,USBRX);
+ *
+ * void calOmega(){
+ * Ec1.CalOmega();
+ * }
+ *
+ * int main(){
+ * ticker.attach(&calOmega,0.05); //0.05秒間隔で角速度を計算
+ * while(1){
+ * pc.printf(" count1=%d ",Ec1.getCount());
+ * pc.printf(" omega1=%f\r\n ",Ec1.getOmega());
+ * if(button) Ec1.reset(); //USERボタンを押したらリセット
+ * }
+ * }
+ * @endcode
+ */
+ void CalOmega();
+ ///omega(角速度 rad/s)の値を返す関数(double型)
+ double getOmega();
+ ///四倍精度のcountの値を返す関数(double型)
+ double getPreCount();
+ ///エンコーダを初期状態に戻す関数 countやomegaの値を0にする
+ void reset();
+ ///角速度計算の間隔dtを決めることができる(デフォルトは0.05秒)
+ void setTime(double t);
+
+ ///角速度計算の間隔
+ static double deftime;
+ ///エンコーダの分解能のデフォルト値
+ static int defsolution;
+
+
+
+};
+
+///速度制御用class
+///Ec classを継承している
+/** @section Example
+ * @code
+ * #include "mbed.h"
+ * #include "EC.h" //ヘッダファイルをインクルード
+ *
+ * SpeedControl motor1(PA_0,PA_1,1024,0.05,PB_8,PB_9); //エンコーダ分解能1024、角速度計算間隔を0.05秒に設定
+ * Ticker ticker; //角速度計算用ticker
+ * DigitalIn button(USER_BUTTON);
+ * Serial pc(USBTX,USBRX);
+ *
+ * void calOmega() //角速度計算関数
+ * {
+ * motor1.CalOmega();
+ * }
+ *
+ * int main()
+ * {
+ * ticker.attach(&calOmega,0.05); //0.05秒間隔で角速度を計算
+ * motor1.setPIDparam(0.15,0.0,0.15); //PIDパラメータを設定
+ * motor1.setDOconstant(46.3); //duty比と角速度の変換係数を46.3に設定
+ *
+ * int kai=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(!button) break; //ボタンを押したら停止
+ * kai++;
+ * }
+ * motor1.stop();
+ * }
+ * @endcode
+ */
+
+
+class SpeedControl : public Ec{
+ private:
+ double Kv_p,Kv_d,Kv_i;
+ double diff,diff_old,integral;
+ double out_duty,out;
+
+ protected:
+ PwmOut pwm_F_;
+ PwmOut pwm_B_;
+
+ public:
+ /** constractorの定義
+ * @param signalA encoderA相のピン名
+ * @param signalB encoderB相のピン名
+ * @param s encoderの分解能(省略可)
+ * @param t 角速度計算の間隔(省略可)
+ * @param pwm_F motorを正転させるpwmピン名
+ * @param pwm_B motorを後転させるpwmピン名
+ * motorを正転させるとencoderのcountが正のほうに加算されるようにencoderとmotorを設置する
+ */
+ SpeedControl( PinName signalA , PinName signalB , int s, double t, PinName pwm_F , PinName pwm_B);
+ /** duty比を角速度に変換させるための定数
+ *
+ * 使うモーターやギア比や供給電圧によって変化するので一度duty比と角速度の関係を調べてグラフの傾きから求める
+ *
+ * 多少ずれてもPIDが何とかしてくれるのでそこまでの精度は必要ない
+ *
+ * デフォルトは45 これは380モータとエンコーダを直結して12V電圧で動かしたときの結果
+ *
+ *
+ */
+ double C;
+ /** 速度制御関数、引数は目標速度
+ *
+ * この目標角加速度になるようにモーターを回転させることができる
+ *
+ * 負の数を代入すれば逆回転することができる
+ *
+ * 出力できるduty比は最大で0.5までに設定してある
+ * @param target_omega 目標角速度
+ *
+ * @section CAUTION(printfについて)
+ *
+ * 上記のプログラムのように、速度制御ではループ500回ごとにprintfをしている。
+ *
+ * printfはプログラム的に大きな負担がかかり、かなり時間がかかってしまうものである。
+ *
+ * なのでループごとにいちいちprintfをさせると、速度の収束にかなり時間がかかってしまう。
+ *
+ * (どんなプログラムにも言えるが、)そのためこのようなprintfの頻度を少なくさせるような工夫が必要になる。
+ *
+ */
+ void Sc(double target_omega);
+ /** PIDパラメータ設定関数
+ *
+ * 引数はそれぞれp,i,dパラメータ
+ *
+ * デフォルトは全部0に設定してある
+ *
+ * だいたいp=0.15くらいでなんとかなる(知らんけど)
+ * @param p p制御パラメータ
+ * @param i i制御パラメータ
+ * @param d d制御パラメータ
+ */
+ void setPIDparam(double p,double i,double d);
+ /** 角速度・duty比変換定数(C)の設定関数
+ *
+ * 文字通りである
+ * @param c duty比を角速度に変換させるための定数
+ */
+ void setDOconstant(double c);
+
+ /** モーター停止用関数 */
+ void stop();
+
+ /** モーター正回転用関数
+ @param duty 回転duty比
+ */
+ void turnF(double duty);
+
+ /** モーター逆回転用関数
+ @param duty 回転duty比
+ */
+ void turnB(double duty);
+
+ /** 出力duty比
+ */
+ double duty;
+};
+#endif
\ No newline at end of file
