PS3下の階
Dependencies: FatFileSystem PS3_BlueUSB QEI RoboClaw_mine_ mbed
Fork of PS3_BlueUSB by
omni.cpp
- Committer:
- e5115026
- Date:
- 2018-01-11
- Revision:
- 1:b2063ffa4927
File content as of revision 1:b2063ffa4927:
#include "mbed.h" #include "RoboClaw.h" #include "QEI.h" //位置PID #define Kp 100 #define Ki 7 #define Kd 0 //回転角度PID #define a_Kp 100 #define a_Ki 7 #define a_Kd 0 //オドメトリ用輪(mm #define omni1 40.9401 #define omni2 41.0987 #define omni3 40.6526 #define radius 101.6 //駆動輪直径(mm #define gaisetuen 121.24355652982 //オドメトリ用車輪の外接円 #define Pi 3.141592 //円周率 #define dt 0.001 //動作周期時間(s) #define resolution 200 //オドメトリエンコーダーの分解能 #define en_bai 2 //エンコーダーの倍する変数 //縦:X 横:Y Ticker tick_odo; //オドメトリ関数を時間割り込みさせる宣言 //オドメトリ用エンコーダープルアップ抵抗有効化 DigitalIn Enc1_A(p26); DigitalIn Enc1_B(p25); DigitalIn Enc2_A(p24); DigitalIn Enc2_B(p23); DigitalIn Enc3_A(p22); DigitalIn Enc3_B(p21); QEI odo1(p26, p25,NC,resolution); QEI odo2(p24, p23,NC,resolution); QEI odo3(p22, p21,NC,resolution); RoboClaw roboclaw1(0x80,230400, p13, p14); RoboClaw roboclaw2(0x81,115200, p9, p10); //グローバル変数宣言 double x_global=0.0,y_global=0.0,angle=0.0,t=0.0,vertical_degree=0.0; //サブ関数宣言 double d_r(double degree); //度数法→ラジアン double r_d(double radian); //ラジアン→度数法 double max_min(double val,double max,double min); //最大最小値設定関数.math.hでいうmax関数とmin関数を統合した関数 double odo_way(int mode); //オドメトリ用エンコーダーからとったpulseをmmに変換 double mms_qpps(double millimeter_sec); //mmsからqpps(秒あたりのパルス数)に変換する関数 void omni_move(double x_speed,double y_speed,double angle); void odometry(); //オドメトリ関数 //動作コード void setup_omni(){ //オドメトリ用エンコーダープルアップ抵抗有効化 Enc1_A.mode(PullUp); Enc1_B.mode(PullUp); Enc2_A.mode(PullUp); Enc2_B.mode(PullUp); Enc3_A.mode(PullUp); Enc3_B.mode(PullUp); //オドメトリ関数の時間割り込み有効化 tick_odo.attach(&odometry,dt); //モーター初期化 omni_move(0.0,0.0,0.0); } /* int main() { setup(); wait(4.0); while(1){ omni_move(100.0,100.0,0.0); pc.printf("\nx_global:%lf\ty_global:%lf\tangle:%lf\t\n",x_global,y_global,angle); wait(dt); } } */ //-------以下サブ関数-------// double d_r(double degree){//度数→ラジアン return degree*Pi/180.0; } double r_d(double radian){//ラジアン→度数 return radian*180.0/Pi; } double max_min(double val,double max,double min){//限度設定関数 if(val>max)return max; else if(val<min)return min; else return val; } double mms_qpps(double millimeter_sec){//mm/sにqppsを変換 return millimeter_sec*((2024.0*4.0)/(radius*Pi)); } double odo_way(int mode){//pulseからmmに変換 if(mode==1) return ((double)odo1.getPulses()*omni1*Pi)/(resolution*en_bai); else if(mode==2) return ((double)odo2.getPulses()*omni2*Pi)/(resolution*en_bai); else if(mode==3) return ((double)odo3.getPulses()*omni3*Pi)/(resolution*en_bai); else return 0; } void odometry(){ //単位時間あたりの移動量を積分して自己位置を推定する,神が書いた領域である関数 static double radian,pre_odo_way1=0.0,pre_odo_way2=0.0,pre_odo_way3=0.0; static double xg_dot, yg_dot, prev_xg_dot = 0, prev_yg_dot = 0, prev_theta_dot = 0; double x_dot,y_dot,v1,v2,v3,theta_dot; double dw[4]; dw[1] = odo_way(1); dw[2] = odo_way(2); dw[3] = odo_way(3); //三角関数式 radian=(dw[1]+dw[2]+dw[3])/(3*gaisetuen); //way_y=(dw[1]*cos(radian) + dw[2]*cos(radian+d_r(120.0)) + dw[3]*cos(radian+d_r(240.0)))/2.0; //way_x=(dw[1]*sin(radian) + dw[2]*sin(radian+d_r(120.0)) + dw[3]*sin(radian+d_r(240.0)))/2.0; //積分式 v1 = (dw[1] - pre_odo_way1)/dt; v2 = (dw[2] - pre_odo_way2)/dt; v3 = (dw[3] - pre_odo_way3)/dt; x_dot=(v2-v3)/1.7320508; y_dot=(-v1 + 2.0*(v2 + v3))/3.0; theta_dot=(v1+v2+v3)/(3.0*gaisetuen/2.0); xg_dot=x_dot*cos(radian) - y_dot*sin(radian); yg_dot=x_dot*sin(radian) + y_dot*cos(radian) - theta_dot/(gaisetuen/2.0); y_global += ((xg_dot + prev_xg_dot)/2.0)*dt; x_global -= ((yg_dot + prev_yg_dot)/2.0)*dt; radian += ((theta_dot + prev_theta_dot)/2.0)*dt; //y_global=(-1.0) * y_global;//値が常に0になるエラー発生 prev_xg_dot = xg_dot; prev_yg_dot = yg_dot; prev_theta_dot = theta_dot; pre_odo_way1=dw[1]; pre_odo_way2=dw[2]; pre_odo_way3=dw[3]; angle=(-1.0)*r_d(radian); } void omni_move(double x_speed,double y_speed,double angle){ x_speed=mms_qpps(x_speed); y_speed=mms_qpps(y_speed); angle=mms_qpps(angle); roboclaw1.SpeedM2((int32_t)(x_speed*sin(d_r(90.0)) + y_speed*cos(d_r(90.0)) + angle)); roboclaw2.SpeedM1((int32_t)(x_speed*sin(d_r(330.0)) + y_speed*cos(d_r(330.0)) + angle)); roboclaw1.SpeedM1((int32_t)(-1.0*(x_speed*sin(d_r(210.0)) + y_speed*cos(d_r(210.0)) + angle))); }