ec

Dependents:   F3RC

Fork of EC by ROBOSTEP_LIBRARY

Committer:
jack0325suzu
Date:
Wed Jun 29 04:36:25 2016 +0000
Revision:
1:d10ca555a103
Parent:
0:20fc96400ca3
Child:
2:a9216df32be6
aaa

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jack0325suzu 0:20fc96400ca3 1 #ifndef __INCLUDED_EC_H_
jack0325suzu 0:20fc96400ca3 2 #define __INCLUDED_EC_H_
jack0325suzu 0:20fc96400ca3 3
jack0325suzu 0:20fc96400ca3 4 #ifndef M_pi
jack0325suzu 0:20fc96400ca3 5 #define M_pi 3.141592
jack0325suzu 0:20fc96400ca3 6 #endif
jack0325suzu 0:20fc96400ca3 7 /**increment型encoder用class*/
jack0325suzu 0:20fc96400ca3 8
jack0325suzu 0:20fc96400ca3 9 class Ec{
jack0325suzu 0:20fc96400ca3 10 private:
jack0325suzu 0:20fc96400ca3 11 int S; //A相B相のパターン(1~4)
jack0325suzu 0:20fc96400ca3 12 bool stateA,stateB; //A・B相の状態
jack0325suzu 0:20fc96400ca3 13 int count; //カウント数 分解能分で一周
jack0325suzu 0:20fc96400ca3 14 int pre_count; //一つ前のカウント
jack0325suzu 0:20fc96400ca3 15 double precount; //4倍精度カウント
jack0325suzu 0:20fc96400ca3 16 int solution; //分解能
jack0325suzu 0:20fc96400ca3 17 double dt; //角速度の計算間隔
jack0325suzu 0:20fc96400ca3 18
jack0325suzu 0:20fc96400ca3 19
jack0325suzu 0:20fc96400ca3 20 InterruptIn signalA_;
jack0325suzu 0:20fc96400ca3 21 InterruptIn signalB_;
jack0325suzu 0:20fc96400ca3 22
jack0325suzu 0:20fc96400ca3 23 void upA();
jack0325suzu 0:20fc96400ca3 24 void downA();
jack0325suzu 0:20fc96400ca3 25 void upB();
jack0325suzu 0:20fc96400ca3 26 void downB();
jack0325suzu 0:20fc96400ca3 27
jack0325suzu 0:20fc96400ca3 28 public:
jack0325suzu 0:20fc96400ca3 29 double omega; //角速度
jack0325suzu 0:20fc96400ca3 30 /** コンストラクタの定義
jack0325suzu 0:20fc96400ca3 31 *
jack0325suzu 0:20fc96400ca3 32 * main関数の前に必ず一度宣言する
jack0325suzu 0:20fc96400ca3 33 *
jack0325suzu 0:20fc96400ca3 34 * 使うエンコーダの数だけ設定する必要がある
jack0325suzu 0:20fc96400ca3 35 *
jack0325suzu 0:20fc96400ca3 36 * @param signalA エンコーダA相のピン名
jack0325suzu 0:20fc96400ca3 37 * @param signalB エンコーダB相のピン名
jack0325suzu 0:20fc96400ca3 38 * @param s エンコーダの分解能(省略可)
jack0325suzu 0:20fc96400ca3 39 * @param t 角速度計算の間隔(省略可)
jack0325suzu 0:20fc96400ca3 40 */
jack0325suzu 0:20fc96400ca3 41 Ec(PinName signalA,PinName signalB,int s,double t);
jack0325suzu 0:20fc96400ca3 42
jack0325suzu 0:20fc96400ca3 43 ///countの値を返す関数(int型)
jack0325suzu 0:20fc96400ca3 44 int getCount();
jack0325suzu 0:20fc96400ca3 45 ///omega(角速度 rad/s)の値を計算する関数
jack0325suzu 0:20fc96400ca3 46 /** @section CAUTION
jack0325suzu 0:20fc96400ca3 47 * CalOmega関数は、一定時間ごと(dtごと)に計算される必要があるので、main関数内でタイマー割り込みを設定する必要がある。
jack0325suzu 0:20fc96400ca3 48 * @code
jack0325suzu 0:20fc96400ca3 49 * #include "mbed.h"
jack0325suzu 0:20fc96400ca3 50 * #include "EC.h"
jack0325suzu 0:20fc96400ca3 51 *
jack0325suzu 0:20fc96400ca3 52 * Ec Ec1(PA_0,PA_1,1024,0.05); //分解能1024、計算間隔0.05秒に設定
jack0325suzu 0:20fc96400ca3 53 * Ticker ticker;
jack0325suzu 0:20fc96400ca3 54 * DigitalIn button(USER_BUTTON);
jack0325suzu 0:20fc96400ca3 55 * Serial pc(USBTX,USBRX);
jack0325suzu 0:20fc96400ca3 56 *
jack0325suzu 0:20fc96400ca3 57 * void calOmega(){
jack0325suzu 0:20fc96400ca3 58 * Ec1.CalOmega();
jack0325suzu 0:20fc96400ca3 59 * }
jack0325suzu 0:20fc96400ca3 60 *
jack0325suzu 0:20fc96400ca3 61 * int main(){
jack0325suzu 0:20fc96400ca3 62 * ticker.attach(&calOmega,0.05); //0.05秒間隔で角速度を計算
jack0325suzu 0:20fc96400ca3 63 * while(1){
jack0325suzu 0:20fc96400ca3 64 * pc.printf(" count1=%d ",Ec1.getCount());
jack0325suzu 0:20fc96400ca3 65 * pc.printf(" omega1=%f\r\n ",Ec1.getOmega());
jack0325suzu 1:d10ca555a103 66 * if(!button) Ec1.reset(); //USERボタンを押したらリセット
jack0325suzu 0:20fc96400ca3 67 * }
jack0325suzu 0:20fc96400ca3 68 * }
jack0325suzu 0:20fc96400ca3 69 * @endcode
jack0325suzu 0:20fc96400ca3 70 */
jack0325suzu 0:20fc96400ca3 71 void CalOmega();
jack0325suzu 0:20fc96400ca3 72 ///omega(角速度 rad/s)の値を返す関数(double型)
jack0325suzu 0:20fc96400ca3 73 double getOmega();
jack0325suzu 0:20fc96400ca3 74 ///四倍精度のcountの値を返す関数(double型)
jack0325suzu 0:20fc96400ca3 75 double getPreCount();
jack0325suzu 0:20fc96400ca3 76 ///エンコーダを初期状態に戻す関数 countやomegaの値を0にする
jack0325suzu 0:20fc96400ca3 77 void reset();
jack0325suzu 0:20fc96400ca3 78 ///角速度計算の間隔dtを決めることができる(デフォルトは0.05秒)
jack0325suzu 0:20fc96400ca3 79 void setTime(double t);
jack0325suzu 0:20fc96400ca3 80
jack0325suzu 0:20fc96400ca3 81 ///角速度計算の間隔
jack0325suzu 0:20fc96400ca3 82 static double deftime;
jack0325suzu 0:20fc96400ca3 83 ///エンコーダの分解能のデフォルト値
jack0325suzu 0:20fc96400ca3 84 static int defsolution;
jack0325suzu 0:20fc96400ca3 85
jack0325suzu 0:20fc96400ca3 86
jack0325suzu 0:20fc96400ca3 87
jack0325suzu 0:20fc96400ca3 88 };
jack0325suzu 0:20fc96400ca3 89
jack0325suzu 0:20fc96400ca3 90 ///速度制御用class
jack0325suzu 0:20fc96400ca3 91 ///Ec classを継承している
jack0325suzu 0:20fc96400ca3 92 /** @section Example
jack0325suzu 0:20fc96400ca3 93 * @code
jack0325suzu 0:20fc96400ca3 94 * #include "mbed.h"
jack0325suzu 0:20fc96400ca3 95 * #include "EC.h" //ヘッダファイルをインクルード
jack0325suzu 0:20fc96400ca3 96 *
jack0325suzu 0:20fc96400ca3 97 * SpeedControl motor1(PA_0,PA_1,1024,0.05,PB_8,PB_9); //エンコーダ分解能1024、角速度計算間隔を0.05秒に設定
jack0325suzu 0:20fc96400ca3 98 * Ticker ticker; //角速度計算用ticker
jack0325suzu 0:20fc96400ca3 99 * DigitalIn button(USER_BUTTON);
jack0325suzu 0:20fc96400ca3 100 * Serial pc(USBTX,USBRX);
jack0325suzu 0:20fc96400ca3 101 *
jack0325suzu 0:20fc96400ca3 102 * void calOmega() //角速度計算関数
jack0325suzu 0:20fc96400ca3 103 * {
jack0325suzu 0:20fc96400ca3 104 * motor1.CalOmega();
jack0325suzu 0:20fc96400ca3 105 * }
jack0325suzu 0:20fc96400ca3 106 *
jack0325suzu 0:20fc96400ca3 107 * int main()
jack0325suzu 0:20fc96400ca3 108 * {
jack0325suzu 0:20fc96400ca3 109 * ticker.attach(&calOmega,0.05); //0.05秒間隔で角速度を計算
jack0325suzu 0:20fc96400ca3 110 * motor1.setPIDparam(0.15,0.0,0.15); //PIDパラメータを設定
jack0325suzu 0:20fc96400ca3 111 * motor1.setDOconstant(46.3); //duty比と角速度の変換係数を46.3に設定
jack0325suzu 0:20fc96400ca3 112 *
jack0325suzu 0:20fc96400ca3 113 * int kai=0;
jack0325suzu 0:20fc96400ca3 114 *
jack0325suzu 0:20fc96400ca3 115 * while(1) {
jack0325suzu 0:20fc96400ca3 116 * motor1.Sc(-10); //角速度10rad/sで逆回転
jack0325suzu 0:20fc96400ca3 117 * if(kai>=500){ //ループ500回ごとに角速度・出力duty比を表示
jack0325suzu 0:20fc96400ca3 118 * pc.printf("omega=%f duty=%f \r\n",motor1.getOmega(),motor1.duty);
jack0325suzu 0:20fc96400ca3 119 * kai=0;
jack0325suzu 0:20fc96400ca3 120 * }
jack0325suzu 0:20fc96400ca3 121 * if(!button) break; //ボタンを押したら停止
jack0325suzu 0:20fc96400ca3 122 * kai++;
jack0325suzu 0:20fc96400ca3 123 * }
jack0325suzu 0:20fc96400ca3 124 * motor1.stop();
jack0325suzu 0:20fc96400ca3 125 * }
jack0325suzu 0:20fc96400ca3 126 * @endcode
jack0325suzu 0:20fc96400ca3 127 */
jack0325suzu 0:20fc96400ca3 128
jack0325suzu 0:20fc96400ca3 129
jack0325suzu 0:20fc96400ca3 130 class SpeedControl : public Ec{
jack0325suzu 0:20fc96400ca3 131 private:
jack0325suzu 0:20fc96400ca3 132 double Kv_p,Kv_d,Kv_i;
jack0325suzu 0:20fc96400ca3 133 double diff,diff_old,integral;
jack0325suzu 0:20fc96400ca3 134 double out_duty,out;
jack0325suzu 0:20fc96400ca3 135
jack0325suzu 0:20fc96400ca3 136 protected:
jack0325suzu 0:20fc96400ca3 137 PwmOut pwm_F_;
jack0325suzu 0:20fc96400ca3 138 PwmOut pwm_B_;
jack0325suzu 0:20fc96400ca3 139
jack0325suzu 0:20fc96400ca3 140 public:
jack0325suzu 0:20fc96400ca3 141 /** constractorの定義
jack0325suzu 0:20fc96400ca3 142 * @param signalA encoderA相のピン名
jack0325suzu 0:20fc96400ca3 143 * @param signalB encoderB相のピン名
jack0325suzu 0:20fc96400ca3 144 * @param s encoderの分解能(省略可)
jack0325suzu 0:20fc96400ca3 145 * @param t 角速度計算の間隔(省略可)
jack0325suzu 0:20fc96400ca3 146 * @param pwm_F motorを正転させるpwmピン名
jack0325suzu 0:20fc96400ca3 147 * @param pwm_B motorを後転させるpwmピン名
jack0325suzu 0:20fc96400ca3 148 * motorを正転させるとencoderのcountが正のほうに加算されるようにencoderとmotorを設置する
jack0325suzu 0:20fc96400ca3 149 */
jack0325suzu 0:20fc96400ca3 150 SpeedControl( PinName signalA , PinName signalB , int s, double t, PinName pwm_F , PinName pwm_B);
jack0325suzu 0:20fc96400ca3 151 /** duty比を角速度に変換させるための定数
jack0325suzu 0:20fc96400ca3 152 *
jack0325suzu 0:20fc96400ca3 153 * 使うモーターやギア比や供給電圧によって変化するので一度duty比と角速度の関係を調べてグラフの傾きから求める
jack0325suzu 0:20fc96400ca3 154 *
jack0325suzu 0:20fc96400ca3 155 * 多少ずれてもPIDが何とかしてくれるのでそこまでの精度は必要ない
jack0325suzu 0:20fc96400ca3 156 *
jack0325suzu 0:20fc96400ca3 157 * デフォルトは45 これは380モータとエンコーダを直結して12V電圧で動かしたときの結果
jack0325suzu 0:20fc96400ca3 158 *
jack0325suzu 0:20fc96400ca3 159 *
jack0325suzu 0:20fc96400ca3 160 */
jack0325suzu 0:20fc96400ca3 161 double C;
jack0325suzu 0:20fc96400ca3 162 /** 速度制御関数、引数は目標速度
jack0325suzu 0:20fc96400ca3 163 *
jack0325suzu 0:20fc96400ca3 164 * この目標角加速度になるようにモーターを回転させることができる
jack0325suzu 0:20fc96400ca3 165 *
jack0325suzu 0:20fc96400ca3 166 * 負の数を代入すれば逆回転することができる
jack0325suzu 0:20fc96400ca3 167 *
jack0325suzu 0:20fc96400ca3 168 * 出力できるduty比は最大で0.5までに設定してある
jack0325suzu 0:20fc96400ca3 169 * @param target_omega 目標角速度
jack0325suzu 0:20fc96400ca3 170 *
jack0325suzu 0:20fc96400ca3 171 * @section CAUTION(printfについて)
jack0325suzu 0:20fc96400ca3 172 *
jack0325suzu 0:20fc96400ca3 173 * 上記のプログラムのように、速度制御ではループ500回ごとにprintfをしている。
jack0325suzu 0:20fc96400ca3 174 *
jack0325suzu 0:20fc96400ca3 175 * printfはプログラム的に大きな負担がかかり、かなり時間がかかってしまうものである。
jack0325suzu 0:20fc96400ca3 176 *
jack0325suzu 0:20fc96400ca3 177 * なのでループごとにいちいちprintfをさせると、速度の収束にかなり時間がかかってしまう。
jack0325suzu 0:20fc96400ca3 178 *
jack0325suzu 0:20fc96400ca3 179 * (どんなプログラムにも言えるが、)そのためこのようなprintfの頻度を少なくさせるような工夫が必要になる。
jack0325suzu 0:20fc96400ca3 180 *
jack0325suzu 0:20fc96400ca3 181 */
jack0325suzu 0:20fc96400ca3 182 void Sc(double target_omega);
jack0325suzu 0:20fc96400ca3 183 /** PIDパラメータ設定関数
jack0325suzu 0:20fc96400ca3 184 *
jack0325suzu 0:20fc96400ca3 185 * 引数はそれぞれp,i,dパラメータ
jack0325suzu 0:20fc96400ca3 186 *
jack0325suzu 0:20fc96400ca3 187 * デフォルトは全部0に設定してある
jack0325suzu 0:20fc96400ca3 188 *
jack0325suzu 0:20fc96400ca3 189 * だいたいp=0.15くらいでなんとかなる(知らんけど)
jack0325suzu 0:20fc96400ca3 190 * @param p p制御パラメータ
jack0325suzu 0:20fc96400ca3 191 * @param i i制御パラメータ
jack0325suzu 0:20fc96400ca3 192 * @param d d制御パラメータ
jack0325suzu 0:20fc96400ca3 193 */
jack0325suzu 0:20fc96400ca3 194 void setPIDparam(double p,double i,double d);
jack0325suzu 0:20fc96400ca3 195 /** 角速度・duty比変換定数(C)の設定関数
jack0325suzu 0:20fc96400ca3 196 *
jack0325suzu 0:20fc96400ca3 197 * 文字通りである
jack0325suzu 0:20fc96400ca3 198 * @param c duty比を角速度に変換させるための定数
jack0325suzu 0:20fc96400ca3 199 */
jack0325suzu 0:20fc96400ca3 200 void setDOconstant(double c);
jack0325suzu 0:20fc96400ca3 201
jack0325suzu 0:20fc96400ca3 202 /** モーター停止用関数 */
jack0325suzu 0:20fc96400ca3 203 void stop();
jack0325suzu 0:20fc96400ca3 204
jack0325suzu 0:20fc96400ca3 205 /** モーター正回転用関数
jack0325suzu 0:20fc96400ca3 206 @param duty 回転duty比
jack0325suzu 0:20fc96400ca3 207 */
jack0325suzu 0:20fc96400ca3 208 void turnF(double duty);
jack0325suzu 0:20fc96400ca3 209
jack0325suzu 0:20fc96400ca3 210 /** モーター逆回転用関数
jack0325suzu 0:20fc96400ca3 211 @param duty 回転duty比
jack0325suzu 0:20fc96400ca3 212 */
jack0325suzu 0:20fc96400ca3 213 void turnB(double duty);
jack0325suzu 0:20fc96400ca3 214
jack0325suzu 0:20fc96400ca3 215 /** 出力duty比
jack0325suzu 0:20fc96400ca3 216 */
jack0325suzu 0:20fc96400ca3 217 double duty;
jack0325suzu 0:20fc96400ca3 218 };
jack0325suzu 0:20fc96400ca3 219 #endif