春ロボ1班(元F3RC4班+) / PathFollowing_2_26
Committer:
yuki0701
Date:
Mon Feb 25 15:27:10 2019 +0000
Revision:
12:0d84e47bb8a0
Parent:
11:8407c616b1a8
a

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yuki0701 7:48af3a9c5bdd 1 #include "PathFollowing.h"
la00noix 0:591749f315ac 2 #include <mbed.h>
la00noix 0:591749f315ac 3 #include <math.h>
yuki0701 6:efe1bc381434 4 #include "EC.h"
yuki0701 6:efe1bc381434 5 #include "R1370P.h"
yuki0701 6:efe1bc381434 6 #include "move4wheel.h"
yuki0701 6:efe1bc381434 7 #include <stdarg.h>
yuki0701 6:efe1bc381434 8 #include "Maxon_setting.h"
yuki0701 9:135bbd007509 9 #include "Harurobo_CAN.h"
yuki0701 6:efe1bc381434 10
yuki0701 6:efe1bc381434 11 #define PI 3.141592
yuki0701 6:efe1bc381434 12
la00noix 0:591749f315ac 13
yuki0701 1:d438093cb464 14 double p_out,r_out_max;
la00noix 0:591749f315ac 15 double Kvq_p,Kvq_d,Kvr_p,Kvr_d;
la00noix 0:591749f315ac 16 double diff_old,diffangle,diffangle_old;
la00noix 0:591749f315ac 17 double out_dutyQ,out_dutyR;
la00noix 0:591749f315ac 18 double now_angle,target_angle;
la00noix 0:591749f315ac 19 double now_timeQ,old_timeQ,now_timeR,old_timeR;
la00noix 0:591749f315ac 20 double now_x, now_y;
yuki0701 4:69775231687c 21 double diff_st,diff_tgt,diff_st_tgt,p_param;
yuki0701 6:efe1bc381434 22 double usw_data1,usw_data2,usw_data3,usw_data4;
la00noix 0:591749f315ac 23
yuki0701 1:d438093cb464 24
yuki0701 6:efe1bc381434 25 Ticker motor_tick; //角速度計算用ticker
yuki0701 6:efe1bc381434 26 //Ticker ticker; //for enc
la00noix 0:591749f315ac 27 Timer timer;
la00noix 0:591749f315ac 28
yuki0701 10:107386dd097b 29 Ec EC1(p8,p26,NC,1024,0.05);
yuki0701 10:107386dd097b 30 Ec EC2(p21,p22,NC,1024,0.05);
yuki0701 6:efe1bc381434 31 R1370P gyro(p28,p27);
yuki0701 6:efe1bc381434 32
yuki0701 6:efe1bc381434 33 double new_dist1=0,new_dist2=0;
yuki0701 6:efe1bc381434 34 double old_dist1=0,old_dist2=0;
yuki0701 6:efe1bc381434 35 double d_dist1=0,d_dist2=0; //座標計算用関数
yuki0701 6:efe1bc381434 36 double d_x,d_y;
yuki0701 6:efe1bc381434 37 //現在地X,y座標、現在角度については、PathFollowingでnow_x,now_y,now_angleを定義済
yuki0701 6:efe1bc381434 38 double start_x=0,start_y=0; //スタート位置
yuki0701 6:efe1bc381434 39
yuki0701 6:efe1bc381434 40 double x_out,y_out,r_out; //出力値
yuki0701 6:efe1bc381434 41
yuki0701 6:efe1bc381434 42 static int16_t m_1=0, m_2=0, m_3=0, m_4=0; //int16bit = int2byte
yuki0701 6:efe1bc381434 43
yuki0701 12:0d84e47bb8a0 44 int xy_type;
yuki0701 12:0d84e47bb8a0 45 double pm_typeX,pm_typeY,x_base,y_base;
yuki0701 6:efe1bc381434 46
yuki0701 6:efe1bc381434 47
yuki0701 7:48af3a9c5bdd 48 ///////////////////機体情報をメンバとする構造体"robo_data"と構造体型変数info(←この変数に各センサーにより求めた機体情報(機体位置/機体角度)を格納する)の宣言/////////////////
yuki0701 7:48af3a9c5bdd 49
yuki0701 7:48af3a9c5bdd 50 /*「info.(機体情報の種類).(使用センサーの種類)」に各情報を格納する
yuki0701 7:48af3a9c5bdd 51 *状況に応じて、どのセンサーにより算出した情報を信用するかを選択し、その都度now_angle,now_x,now_yに代入する。(何種類かのセンサーの情報を混ぜて使用することも可能)
yuki0701 7:48af3a9c5bdd 52 *(ex)
yuki0701 7:48af3a9c5bdd 53 *info.nowX.enc → エンコーダにより算出した機体位置のx座標
yuki0701 7:48af3a9c5bdd 54 *info.nowY.usw → 超音波センサーにより求めた機体位置のy座標
yuki0701 7:48af3a9c5bdd 55 */
yuki0701 7:48af3a9c5bdd 56
yuki0701 7:48af3a9c5bdd 57 typedef struct{ //使用センサーの種類
yuki0701 7:48af3a9c5bdd 58 double usw; //超音波センサー
yuki0701 7:48af3a9c5bdd 59 double enc; //エンコーダ
yuki0701 7:48af3a9c5bdd 60 double gyro; //ジャイロ
yuki0701 7:48af3a9c5bdd 61 //double line;//ラインセンサー
yuki0701 7:48af3a9c5bdd 62 }robo_sensor;
yuki0701 7:48af3a9c5bdd 63
yuki0701 7:48af3a9c5bdd 64 typedef struct{ //機体情報の種類
yuki0701 7:48af3a9c5bdd 65 robo_sensor angle; //←機体角度は超音波センサーやラインセンサーからも算出可能なので一応格納先を用意したが、ジャイロの値を完全に信用してもいいかも
yuki0701 7:48af3a9c5bdd 66 robo_sensor nowX;
yuki0701 7:48af3a9c5bdd 67 robo_sensor nowY;
yuki0701 7:48af3a9c5bdd 68 }robo_data;
yuki0701 7:48af3a9c5bdd 69
yuki0701 7:48af3a9c5bdd 70 robo_data info={{0,0,0},{0,0,0},{0,0,0}}; //全てのデータを0に初期化
yuki0701 7:48af3a9c5bdd 71
yuki0701 7:48af3a9c5bdd 72
yuki0701 7:48af3a9c5bdd 73 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
yuki0701 7:48af3a9c5bdd 74
yuki0701 6:efe1bc381434 75
yuki0701 6:efe1bc381434 76 void UserLoopSetting2(){
yuki0701 6:efe1bc381434 77
yuki0701 6:efe1bc381434 78 gyro.initialize();
yuki0701 8:524d86b2073f 79 motor_tick.attach(&calOmega,0.05); //0.05秒間隔で角速度を計算
yuki0701 11:8407c616b1a8 80 EC1.setDiameter_mm(51);
yuki0701 11:8407c616b1a8 81 EC2.setDiameter_mm(51); //測定輪半径//後で測定
yuki0701 6:efe1bc381434 82
yuki0701 6:efe1bc381434 83 }
yuki0701 6:efe1bc381434 84
la00noix 0:591749f315ac 85 //初期座標:A, 目標座標:B、機体位置:C、点Cから直線ABに下ろした垂線の足:H
yuki0701 4:69775231687c 86 void XYRmotorout(double plot_x1, double plot_y1, double plot_x2, double plot_y2, double *ad_x_out, double *ad_y_out, double *ad_r_out, double speed1, double speed2 ) //プログラム使用時、now_x,now_yはグローバル変数として定義する必要あり
yuki0701 4:69775231687c 87 //plot_x1,plot_y1:出発地点の座標
yuki0701 4:69775231687c 88 //plot_x2,plot_y2:目標地点の座標
yuki0701 4:69775231687c 89 //speed1:初期速度
yuki0701 4:69775231687c 90 //speed2:目標速度
la00noix 0:591749f315ac 91 {
la00noix 0:591749f315ac 92 double Vector_P[2] = {(plot_x2 - plot_x1), (plot_y2 - plot_y1)}; //ベクトルAB
la00noix 0:591749f315ac 93 double A_Vector_P = hypot(Vector_P[0], Vector_P[1]); //ベクトルABの大きさ(hypot(a,b)で√(a^2+b^2)を計算できる <math.h>))
la00noix 0:591749f315ac 94 double UnitVector_P[2] = {Vector_P[0]/A_Vector_P, Vector_P[1]/A_Vector_P}; //ベクトルABの単位ベクトル
la00noix 0:591749f315ac 95 double UnitVector_Q[2] = {UnitVector_P[1], -UnitVector_P[0]}; //ベクトルCHの単位ベクトル
la00noix 0:591749f315ac 96 double Vector_R[2] = {(now_x - plot_x1), (now_y - plot_y1)}; //ベクトルAC
la00noix 0:591749f315ac 97 double diff = UnitVector_P[0]*Vector_R[1] - UnitVector_P[1]*Vector_R[0]; //機体位置と直線ABの距離(外積を用いて計算)
la00noix 0:591749f315ac 98
yuki0701 4:69775231687c 99
yuki0701 4:69775231687c 100 //double VectorOut_P[2]= {0}; //ベクトルABに平行方向の出力をx軸方向、y軸方向の出力に分解*/
la00noix 0:591749f315ac 101
la00noix 0:591749f315ac 102 ///////////////////<XYRmotorout関数内>以下、ベクトルABに垂直な方向の誤差を埋めるPD制御(ベクトルABに垂直方向の出力を求め、x軸方向、y軸方向の出力に分解)//////////////////////
la00noix 0:591749f315ac 103
la00noix 0:591749f315ac 104 timer.start();
la00noix 0:591749f315ac 105 now_timeQ=timer.read();
la00noix 0:591749f315ac 106 out_dutyQ=Kvq_p*diff+Kvq_d*(diff-diff_old)/(now_timeQ-old_timeQ); //ベクトルABに垂直方向の出力を決定
la00noix 0:591749f315ac 107 diff_old=diff;
la00noix 0:591749f315ac 108
yuki0701 2:32362343f091 109 if(out_dutyQ>500)out_dutyQ=500;
yuki0701 2:32362343f091 110 if(out_dutyQ<-500)out_dutyQ=-500;
la00noix 0:591749f315ac 111
la00noix 0:591749f315ac 112 old_timeQ=now_timeQ;
la00noix 0:591749f315ac 113
la00noix 0:591749f315ac 114 double VectorOut_Q[2] = {out_dutyQ*UnitVector_Q[0], out_dutyQ*UnitVector_Q[1]}; //ベクトルABに垂直方向の出力をx軸方向、y軸方向の出力に分解
la00noix 0:591749f315ac 115
la00noix 0:591749f315ac 116 ///////////////////////////////<XYRmotorout関数内>以下、機体角度と目標角度の誤差を埋めるPD制御(旋回のための出力値を決定)//////////////////////////////////
la00noix 0:591749f315ac 117
la00noix 0:591749f315ac 118 now_timeR=timer.read();
la00noix 0:591749f315ac 119 diffangle=target_angle-now_angle;
yuki0701 1:d438093cb464 120 out_dutyR=-(Kvr_p*diffangle+Kvr_d*(diffangle-diffangle_old)/(now_timeR-old_timeR));
la00noix 0:591749f315ac 121 diffangle_old=diffangle;
la00noix 0:591749f315ac 122
yuki0701 1:d438093cb464 123 if(out_dutyR>r_out_max)out_dutyR=r_out_max;
yuki0701 1:d438093cb464 124 if(out_dutyR<-r_out_max)out_dutyR=-r_out_max;
la00noix 0:591749f315ac 125
la00noix 0:591749f315ac 126 old_timeR=now_timeR;
la00noix 0:591749f315ac 127
la00noix 0:591749f315ac 128 //////////////////////////<XYRmotorout関数内>以下、x軸方向、y軸方向、旋回の出力をそれぞれad_x_out,ad_y_out,ad_r_outの指すアドレスに書き込む/////////////////////////////
la00noix 0:591749f315ac 129 ////////////////////////////////////////////その際、x軸方向、y軸方向の出力はフィールドの座標系から機体の座標系に変換する。///////////////////////////////////////////////
yuki0701 4:69775231687c 130
yuki0701 4:69775231687c 131 diff_st = hypot(now_x-plot_x1,now_y-plot_y1); //出発座標と機体の位置の距離
yuki0701 4:69775231687c 132 diff_tgt = hypot(now_x - plot_x2, now_y - plot_y2); //機体の位置と目標座標の距離
yuki0701 4:69775231687c 133 diff_st_tgt = hypot(plot_x1-plot_x2,plot_y1-plot_y2); //出発座標と目標座標の距離
yuki0701 4:69775231687c 134
yuki0701 4:69775231687c 135 if(speed1 == speed2) { //等速移動
yuki0701 4:69775231687c 136
yuki0701 4:69775231687c 137 double VectorOut_P[2] = {speed1*UnitVector_P[0], speed1*UnitVector_P[1]};
yuki0701 4:69775231687c 138
yuki0701 4:69775231687c 139 *ad_x_out = (VectorOut_P[0]+VectorOut_Q[0])*cos(-now_angle*3.141592/180)-(VectorOut_P[1]+VectorOut_Q[1])*sin(-now_angle*3.141592/180);
yuki0701 4:69775231687c 140 *ad_y_out = (VectorOut_P[0]+VectorOut_Q[0])*sin(-now_angle*3.141592/180)+(VectorOut_P[1]+VectorOut_Q[1])*cos(-now_angle*3.141592/180);
yuki0701 4:69775231687c 141 *ad_r_out = out_dutyR;
la00noix 0:591749f315ac 142
yuki0701 4:69775231687c 143 } else if(speed2 == 0) { //減速移動(目標速度が0)→ベクトルABに垂直な方向の出力にもP制御をかける。
yuki0701 4:69775231687c 144
yuki0701 4:69775231687c 145 double VectorOut_P[2] = {speed1*UnitVector_P[0], speed1*UnitVector_P[1]};
yuki0701 4:69775231687c 146
yuki0701 4:69775231687c 147 if(diff_tgt > diff_st_tgt) {
yuki0701 4:69775231687c 148 diff_tgt = diff_st_tgt;
yuki0701 4:69775231687c 149 }
yuki0701 2:32362343f091 150
yuki0701 4:69775231687c 151 p_param=(diff_tgt/diff_st_tgt);
yuki0701 4:69775231687c 152
yuki0701 4:69775231687c 153 *ad_x_out = p_param*((VectorOut_P[0]+VectorOut_Q[0])*cos(-now_angle*3.141592/180)-(VectorOut_P[1]+VectorOut_Q[1])*sin(-now_angle*3.141592/180));
yuki0701 4:69775231687c 154 *ad_y_out = p_param*((VectorOut_P[0]+VectorOut_Q[0])*sin(-now_angle*3.141592/180)+(VectorOut_P[1]+VectorOut_Q[1])*cos(-now_angle*3.141592/180));
yuki0701 4:69775231687c 155 *ad_r_out = out_dutyR;
yuki0701 4:69775231687c 156
yuki0701 4:69775231687c 157 } else if(speed1 > speed2) { //減速移動(目標速度が0でない)
yuki0701 2:32362343f091 158
yuki0701 4:69775231687c 159 if(diff_tgt > diff_st_tgt) {
yuki0701 4:69775231687c 160 diff_tgt = diff_st_tgt;
yuki0701 4:69775231687c 161 }
yuki0701 4:69775231687c 162
yuki0701 4:69775231687c 163 p_param=(diff_tgt/diff_st_tgt);
yuki0701 4:69775231687c 164
yuki0701 4:69775231687c 165 double speed3 = speed2 + (speed1-speed2)*p_param;
yuki0701 4:69775231687c 166
yuki0701 4:69775231687c 167 double VectorOut_P[2] = {speed3*UnitVector_P[0], speed3*UnitVector_P[1]};
yuki0701 4:69775231687c 168
yuki0701 4:69775231687c 169 *ad_x_out = (VectorOut_P[0]+VectorOut_Q[0])*cos(-now_angle*3.141592/180)-(VectorOut_P[1]+VectorOut_Q[1])*sin(-now_angle*3.141592/180);
yuki0701 4:69775231687c 170 *ad_y_out = (VectorOut_P[0]+VectorOut_Q[0])*sin(-now_angle*3.141592/180)+(VectorOut_P[1]+VectorOut_Q[1])*cos(-now_angle*3.141592/180);
yuki0701 4:69775231687c 171 *ad_r_out = out_dutyR;
yuki0701 2:32362343f091 172
yuki0701 4:69775231687c 173 } else if(speed1 < speed2) { //加速移動(speed1)
yuki0701 4:69775231687c 174
yuki0701 4:69775231687c 175 if(diff_st > diff_st_tgt) {
yuki0701 4:69775231687c 176 diff_st = diff_st_tgt;
yuki0701 4:69775231687c 177 }
yuki0701 4:69775231687c 178
yuki0701 4:69775231687c 179 p_param=(diff_st/diff_st_tgt);
yuki0701 2:32362343f091 180
yuki0701 4:69775231687c 181 double speed4 = speed1 + (speed2-speed1)*p_param;
yuki0701 4:69775231687c 182
yuki0701 4:69775231687c 183 double VectorOut_P[2] = {speed4*UnitVector_P[0], speed4*UnitVector_P[1]};
yuki0701 4:69775231687c 184
yuki0701 4:69775231687c 185 *ad_x_out = (VectorOut_P[0]+VectorOut_Q[0])*cos(-now_angle*3.141592/180)-(VectorOut_P[1]+VectorOut_Q[1])*sin(-now_angle*3.141592/180);
yuki0701 4:69775231687c 186 *ad_y_out = (VectorOut_P[0]+VectorOut_Q[0])*sin(-now_angle*3.141592/180)+(VectorOut_P[1]+VectorOut_Q[1])*cos(-now_angle*3.141592/180);
yuki0701 4:69775231687c 187 *ad_r_out = out_dutyR;
yuki0701 2:32362343f091 188 }
la00noix 0:591749f315ac 189 }
la00noix 0:591749f315ac 190
la00noix 0:591749f315ac 191 ////////////////////////////////////////////////////////////<XYRmotorout関数は以上>////////////////////////////////////////////////////////////////
la00noix 0:591749f315ac 192
la00noix 0:591749f315ac 193
yuki0701 4:69775231687c 194 /*void set_p_out(double p) //ベクトルABに平行方向の出力値設定関数
la00noix 0:591749f315ac 195 {
la00noix 0:591749f315ac 196 p_out = p;
yuki0701 4:69775231687c 197 }*/
la00noix 0:591749f315ac 198
la00noix 0:591749f315ac 199 void q_setPDparam(double q_p,double q_d) //ベクトルABに垂直な方向の誤差を埋めるPD制御のパラメータ設定関数
la00noix 0:591749f315ac 200 {
la00noix 0:591749f315ac 201 Kvq_p=q_p;
la00noix 0:591749f315ac 202 Kvq_d=q_d;
la00noix 0:591749f315ac 203 }
la00noix 0:591749f315ac 204
la00noix 0:591749f315ac 205 void r_setPDparam(double r_p,double r_d) //機体角度と目標角度の誤差を埋めるPD制御のパラメータ設定関数
la00noix 0:591749f315ac 206 {
la00noix 0:591749f315ac 207 Kvr_p=r_p;
la00noix 0:591749f315ac 208 Kvr_d=r_d;
la00noix 0:591749f315ac 209 }
la00noix 0:591749f315ac 210
la00noix 0:591749f315ac 211 void set_r_out(double r) //旋回時の最大出力値設定関数
la00noix 0:591749f315ac 212 {
yuki0701 1:d438093cb464 213 r_out_max = r;
la00noix 0:591749f315ac 214 }
la00noix 0:591749f315ac 215
la00noix 0:591749f315ac 216 void set_target_angle(double t) //機体の目標角度設定関数
la00noix 0:591749f315ac 217 {
la00noix 0:591749f315ac 218 target_angle = t;
la00noix 0:591749f315ac 219 }
yuki0701 6:efe1bc381434 220
yuki0701 6:efe1bc381434 221
yuki0701 6:efe1bc381434 222 void UserLoopSetting(); // initialize setting
yuki0701 6:efe1bc381434 223 void DAC_Write(int16_t data, DigitalOut* DAC_cs);
yuki0701 6:efe1bc381434 224 void MotorControl(int16_t val_md1, int16_t val_md2, int16_t val_md3, int16_t val_md4);
yuki0701 6:efe1bc381434 225
yuki0701 6:efe1bc381434 226 void calOmega() //角速度計算関数
yuki0701 6:efe1bc381434 227 {
yuki0701 6:efe1bc381434 228 EC1.CalOmega();
yuki0701 6:efe1bc381434 229 EC2.CalOmega();
yuki0701 6:efe1bc381434 230 }
yuki0701 6:efe1bc381434 231
yuki0701 6:efe1bc381434 232 void output(double FL,double BL,double BR,double FR)
yuki0701 6:efe1bc381434 233 {
yuki0701 7:48af3a9c5bdd 234 m_1=FL;
yuki0701 7:48af3a9c5bdd 235 m_2=BL;
yuki0701 7:48af3a9c5bdd 236 m_3=BR;
yuki0701 7:48af3a9c5bdd 237 m_4=FR;
yuki0701 6:efe1bc381434 238 }
yuki0701 6:efe1bc381434 239
yuki0701 6:efe1bc381434 240 void base(double FL,double BL,double BR,double FR,double Max)
yuki0701 6:efe1bc381434 241 //いろんな加算をしても最大OR最小がMaxになるような補正//絶対値が一番でかいやつで除算
yuki0701 6:efe1bc381434 242 //DCモーターならMax=1、マクソンは-4095~4095だからMax=4095にする
yuki0701 6:efe1bc381434 243 {
yuki0701 6:efe1bc381434 244 if(fabs(FL)>=Max||fabs(BL)>=Max||fabs(BR)>=Max||fabs(FR)>=Max) {
yuki0701 6:efe1bc381434 245
yuki0701 6:efe1bc381434 246 if (fabs(FL)>=fabs(BL)&&fabs(FL)>=fabs(BR)&&fabs(FL)>=fabs(FR))output(Max*FL/fabs(FL),Max*BL/fabs(FL),Max*BR/fabs(FL),Max*FR/fabs(FL));
yuki0701 6:efe1bc381434 247 else if(fabs(BL)>=fabs(FL)&&fabs(BL)>=fabs(BR)&&fabs(BL)>=fabs(FR))output(Max*FL/fabs(BL),Max*BL/fabs(BL),Max*BR/fabs(BL),Max*FR/fabs(BL));
yuki0701 6:efe1bc381434 248 else if(fabs(BR)>=fabs(FL)&&fabs(BR)>=fabs(BL)&&fabs(BR)>=fabs(FR))output(Max*FL/fabs(BR),Max*BL/fabs(BR),Max*BR/fabs(BR),Max*FR/fabs(BR));
yuki0701 6:efe1bc381434 249 else output(Max*FL/fabs(FR),Max*BL/fabs(FR),Max*BR/fabs(FR),Max*FR/fabs(FR));
yuki0701 6:efe1bc381434 250 } else {
yuki0701 6:efe1bc381434 251 output(FL,BL,BR,FR);
yuki0701 6:efe1bc381434 252 }
yuki0701 6:efe1bc381434 253 }
yuki0701 6:efe1bc381434 254
yuki0701 7:48af3a9c5bdd 255 void calc_xy_enc() //エンコーダによる座標計算
yuki0701 6:efe1bc381434 256 {
yuki0701 6:efe1bc381434 257 now_angle=gyro.getAngle(); //ジャイロの値読み込み
yuki0701 6:efe1bc381434 258
yuki0701 6:efe1bc381434 259 new_dist1=EC1.getDistance_mm();
yuki0701 6:efe1bc381434 260 new_dist2=EC2.getDistance_mm();
yuki0701 6:efe1bc381434 261 d_dist1=new_dist1-old_dist1;
yuki0701 6:efe1bc381434 262 d_dist2=new_dist2-old_dist2;
yuki0701 6:efe1bc381434 263 old_dist1=new_dist1;
yuki0701 6:efe1bc381434 264 old_dist2=new_dist2; //微小時間当たりのエンコーダ読み込み
yuki0701 6:efe1bc381434 265
yuki0701 6:efe1bc381434 266 d_x=d_dist2*sin(now_angle*PI/180)-d_dist1*cos(now_angle*PI/180);
yuki0701 6:efe1bc381434 267 d_y=d_dist2*cos(now_angle*PI/180)+d_dist1*sin(now_angle*PI/180); //微小時間毎の座標変化
yuki0701 7:48af3a9c5bdd 268 info.nowX.enc = info.nowX.enc + d_x;
yuki0701 7:48af3a9c5bdd 269 info.nowY.enc = info.nowY.enc - d_y; //微小時間毎に座標に加算
yuki0701 7:48af3a9c5bdd 270 }
yuki0701 7:48af3a9c5bdd 271
yuki0701 7:48af3a9c5bdd 272 void set_cond(int t, int px, double bx, int py, double by){ //超音波センサーを使用するときの条件設定関数
yuki0701 8:524d86b2073f 273 //引数の詳細は関数"calc_xy_usw"参照
yuki0701 7:48af3a9c5bdd 274
yuki0701 7:48af3a9c5bdd 275 xy_type = t;
yuki0701 7:48af3a9c5bdd 276
yuki0701 7:48af3a9c5bdd 277 pm_typeX = px;
yuki0701 7:48af3a9c5bdd 278 x_base = bx;
yuki0701 7:48af3a9c5bdd 279
yuki0701 7:48af3a9c5bdd 280 pm_typeY = py;
yuki0701 7:48af3a9c5bdd 281 y_base = by;
yuki0701 7:48af3a9c5bdd 282
yuki0701 7:48af3a9c5bdd 283 }
yuki0701 7:48af3a9c5bdd 284
yuki0701 7:48af3a9c5bdd 285
yuki0701 7:48af3a9c5bdd 286 void calc_xy_usw(double tgt_angle){ //超音波センサーによる座標計算(機体が旋回する場合はこの方法による座標計算は出来ない)
yuki0701 7:48af3a9c5bdd 287 //tgt_angle:機体の目標角度(運動初期角度と同じ/今大会では0,90,180のみ)
yuki0701 7:48af3a9c5bdd 288 //xy_type:(0:Y軸平行の壁を読む/1:X軸平行の壁を読む/2:X,Y軸平行の壁を共に読む)
yuki0701 7:48af3a9c5bdd 289 //pm_typeX,pm_typeY:(0:各軸正方向側の壁を読む/1:各軸負方向側の壁を読む)
yuki0701 7:48af3a9c5bdd 290 //x_base,y_base:超音波センサーで読む壁の座標(y軸並行の壁のx座標/x軸平行の壁のy座標)
yuki0701 7:48af3a9c5bdd 291
yuki0701 7:48af3a9c5bdd 292 double R1=240,R2=240,R3=240,R4=240; //機体の中心から各超音波センサーが付いている面までの距離
yuki0701 7:48af3a9c5bdd 293 double D1=30,D2=30,D3=30,D4=30; //各超音波センサーが付いている面の中心から各超音波センサーまでの距離
yuki0701 7:48af3a9c5bdd 294
yuki0701 7:48af3a9c5bdd 295 now_angle=gyro.getAngle();
yuki0701 7:48af3a9c5bdd 296
yuki0701 7:48af3a9c5bdd 297 if(tgt_angle==0){
yuki0701 7:48af3a9c5bdd 298 if((xy_type==0 || xy_type==2) && pm_typeX==0){
yuki0701 7:48af3a9c5bdd 299
yuki0701 7:48af3a9c5bdd 300 info.nowX.usw = x_base - (usw_data4 + R4*cos(now_angle*PI/180) + D4*sin(now_angle*PI/180));
yuki0701 7:48af3a9c5bdd 301
yuki0701 7:48af3a9c5bdd 302 }else if((xy_type==0 || xy_type==2) && pm_typeX==1){
yuki0701 7:48af3a9c5bdd 303
yuki0701 7:48af3a9c5bdd 304 info.nowX.usw = x_base + (usw_data3 + R3*cos(now_angle*PI/180) + D3*sin(now_angle*PI/180));
yuki0701 7:48af3a9c5bdd 305
yuki0701 7:48af3a9c5bdd 306 }
yuki0701 7:48af3a9c5bdd 307 if((xy_type==1 || xy_type==2) && pm_typeY==0){
yuki0701 7:48af3a9c5bdd 308
yuki0701 7:48af3a9c5bdd 309 info.nowY.usw = y_base - (usw_data2 + R2*cos(now_angle*PI/180) + D2*sin(now_angle*PI/180));
yuki0701 7:48af3a9c5bdd 310
yuki0701 7:48af3a9c5bdd 311 }else if((xy_type==1 || xy_type==2) && pm_typeY==1){
yuki0701 7:48af3a9c5bdd 312
yuki0701 7:48af3a9c5bdd 313 info.nowY.usw = y_base + (usw_data1 + R1*cos(now_angle*PI/180) + D1*sin(now_angle*PI/180));
yuki0701 7:48af3a9c5bdd 314
yuki0701 7:48af3a9c5bdd 315 }
yuki0701 7:48af3a9c5bdd 316
yuki0701 7:48af3a9c5bdd 317 }else if(tgt_angle==90){
yuki0701 7:48af3a9c5bdd 318 if((xy_type==0 || xy_type==2) && pm_typeX==0){
yuki0701 7:48af3a9c5bdd 319
yuki0701 7:48af3a9c5bdd 320 info.nowX.usw = x_base - (usw_data1 + R1*cos(now_angle*PI/180) + D1*sin(now_angle*PI/180));
yuki0701 7:48af3a9c5bdd 321
yuki0701 7:48af3a9c5bdd 322 }else if((xy_type==0 || xy_type==2) && pm_typeX==1){
yuki0701 7:48af3a9c5bdd 323
yuki0701 7:48af3a9c5bdd 324 info.nowX.usw = x_base + (usw_data2 + R2*cos(now_angle*PI/180) + D2*sin(now_angle*PI/180));
yuki0701 7:48af3a9c5bdd 325
yuki0701 7:48af3a9c5bdd 326 }
yuki0701 7:48af3a9c5bdd 327 if((xy_type==1 || xy_type==2) && pm_typeY==0){
yuki0701 7:48af3a9c5bdd 328
yuki0701 7:48af3a9c5bdd 329 info.nowY.usw = y_base - (usw_data4 + R4*cos(now_angle*PI/180) + D4*sin(now_angle*PI/180));
yuki0701 7:48af3a9c5bdd 330
yuki0701 7:48af3a9c5bdd 331 }else if((xy_type==1 || xy_type==2) && pm_typeY==1){
yuki0701 7:48af3a9c5bdd 332
yuki0701 7:48af3a9c5bdd 333 info.nowY.usw = y_base + (usw_data3 + R3*cos(now_angle*PI/180) + D3*sin(now_angle*PI/180));
yuki0701 7:48af3a9c5bdd 334
yuki0701 7:48af3a9c5bdd 335 }
yuki0701 7:48af3a9c5bdd 336
yuki0701 7:48af3a9c5bdd 337 }else if(tgt_angle==180){
yuki0701 7:48af3a9c5bdd 338 if((xy_type==0 || xy_type==2) && pm_typeX==0){
yuki0701 7:48af3a9c5bdd 339
yuki0701 7:48af3a9c5bdd 340 info.nowX.usw = x_base - (usw_data3 + R3*cos(now_angle*PI/180) + D3*sin(now_angle*PI/180));
yuki0701 7:48af3a9c5bdd 341
yuki0701 7:48af3a9c5bdd 342 }else if((xy_type==0 || xy_type==2) && pm_typeX==1){
yuki0701 7:48af3a9c5bdd 343
yuki0701 7:48af3a9c5bdd 344 info.nowX.usw = x_base + (usw_data4 + R4*cos(now_angle*PI/180) + D4*sin(now_angle*PI/180));
yuki0701 7:48af3a9c5bdd 345
yuki0701 7:48af3a9c5bdd 346 }
yuki0701 7:48af3a9c5bdd 347 if((xy_type==1 || xy_type==2) && pm_typeY==0){
yuki0701 7:48af3a9c5bdd 348
yuki0701 7:48af3a9c5bdd 349 info.nowY.usw = y_base - (usw_data1+ R1*cos(now_angle*PI/180) + D1*sin(now_angle*PI/180));
yuki0701 7:48af3a9c5bdd 350
yuki0701 7:48af3a9c5bdd 351 }else if((xy_type==1 || xy_type==2) && pm_typeY==1){
yuki0701 7:48af3a9c5bdd 352
yuki0701 7:48af3a9c5bdd 353 info.nowY.usw = y_base + (usw_data2 + R2*cos(now_angle*PI/180) + D2*sin(now_angle*PI/180));
yuki0701 7:48af3a9c5bdd 354
yuki0701 7:48af3a9c5bdd 355 }
yuki0701 7:48af3a9c5bdd 356
yuki0701 7:48af3a9c5bdd 357 }
yuki0701 7:48af3a9c5bdd 358
yuki0701 7:48af3a9c5bdd 359 }
yuki0701 7:48af3a9c5bdd 360
yuki0701 7:48af3a9c5bdd 361 void calc_xy(double target_angle, double u,double v){ //エンコーダにより求めた機体の座標と超音波センサーにより求めた機体の座標を(エンコーダ : 超音波 = u : i-u / v : i-v)の割合で混ぜて now_x,now_y に代入する。
yuki0701 7:48af3a9c5bdd 362
yuki0701 7:48af3a9c5bdd 363 calc_xy_enc();
yuki0701 7:48af3a9c5bdd 364
yuki0701 12:0d84e47bb8a0 365 if(u != 1 || v != 1){
yuki0701 7:48af3a9c5bdd 366 calc_xy_usw(target_angle); //エンコーダの値しか使用しない場合は超音波センサーによる座標計算は行わずに計算量を減らす。
yuki0701 7:48af3a9c5bdd 367 }
yuki0701 7:48af3a9c5bdd 368
yuki0701 7:48af3a9c5bdd 369 now_x = u * info.nowX.enc + (1-u) * info.nowX.usw;
yuki0701 7:48af3a9c5bdd 370 now_y = v * info.nowY.enc + (1-v) * info.nowY.usw;
yuki0701 7:48af3a9c5bdd 371
yuki0701 6:efe1bc381434 372 }
yuki0701 6:efe1bc381434 373
yuki0701 6:efe1bc381434 374 //ここからそれぞれのプログラム/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
yuki0701 6:efe1bc381434 375 //now_x(現在のx座標),now_y(現在のy座標),now_angle(機体角度(ラジアンではない)(0~360や-180~180とは限らない))(反時計回りが正)
yuki0701 6:efe1bc381434 376 //ジャイロの出力は角度だが三角関数はラジアンとして計算する
yuki0701 6:efe1bc381434 377 //通常の移動+座標のずれ補正+機体の角度補正(+必要に応じさらに別補正)
yuki0701 6:efe1bc381434 378 //ジャイロの仕様上、角度補正をするときに計算式内で角度はそのままよりsinをとったほうがいいかもね
yuki0701 6:efe1bc381434 379
yuki0701 7:48af3a9c5bdd 380 void purecurve2(int type,double u,double v, //正面を変えずに円弧or楕円を描いて曲がる
yuki0701 6:efe1bc381434 381 double point_x1,double point_y1,
yuki0701 6:efe1bc381434 382 double point_x2,double point_y2,
yuki0701 6:efe1bc381434 383 int theta,
yuki0701 10:107386dd097b 384 double speed,
yuki0701 6:efe1bc381434 385 double q_p,double q_d,
yuki0701 6:efe1bc381434 386 double r_p,double r_d,
yuki0701 6:efe1bc381434 387 double r_out_max,
yuki0701 6:efe1bc381434 388 double target_angle)
yuki0701 6:efe1bc381434 389 //type:動きの種類(8パターン) point_x1,point_y1=出発地点の座標 point_x2,point_x2=目標地点の座標 theta=plotの間隔(0~90°) speed=速度
yuki0701 6:efe1bc381434 390 {
yuki0701 6:efe1bc381434 391 //-----PathFollowingのパラメーター設定-----//
yuki0701 6:efe1bc381434 392 q_setPDparam(q_p,q_d); //ベクトルABに垂直な方向の誤差を埋めるPD制御のパラメータ設定関数
yuki0701 6:efe1bc381434 393 r_setPDparam(r_p,r_d); //機体角度と目標角度の誤差を埋めるPD制御のパラメータ設定関数
yuki0701 6:efe1bc381434 394 set_r_out(r_out_max); //旋回時の最大出力値設定関数
yuki0701 6:efe1bc381434 395 set_target_angle(target_angle); //機体目標角度設定関数
yuki0701 6:efe1bc381434 396
yuki0701 6:efe1bc381434 397 int s;
yuki0701 6:efe1bc381434 398 int t = 0;
yuki0701 6:efe1bc381434 399 double X,Y;//X=楕円の中心座標、Y=楕円の中心座標
yuki0701 6:efe1bc381434 400 double a,b; //a=楕円のx軸方向の幅の半分,b=楕円のy軸方向の幅の半分
yuki0701 6:efe1bc381434 401 double plotx[(90/theta)+1]; //楕円にとるplotのx座標
yuki0701 6:efe1bc381434 402 double ploty[(90/theta)+1];
yuki0701 6:efe1bc381434 403
yuki0701 6:efe1bc381434 404 double x_out,y_out,r_out;
yuki0701 6:efe1bc381434 405
yuki0701 6:efe1bc381434 406 a=fabs(point_x1-point_x2);
yuki0701 6:efe1bc381434 407 b=fabs(point_y1-point_y2);
yuki0701 6:efe1bc381434 408
yuki0701 6:efe1bc381434 409 switch(type) {
yuki0701 6:efe1bc381434 410
yuki0701 6:efe1bc381434 411 case 1://→↑移動
yuki0701 6:efe1bc381434 412 X=point_x1;
yuki0701 6:efe1bc381434 413 Y=point_y2;
yuki0701 6:efe1bc381434 414
yuki0701 6:efe1bc381434 415 for(s=0; s<((90/theta)+1); s++) {
yuki0701 6:efe1bc381434 416 plotx[s] = X + a * cos(-PI/2 + s * (PI*theta/180));
yuki0701 6:efe1bc381434 417 ploty[s] = Y + b * sin(-PI/2 + s * (PI*theta/180));
yuki0701 6:efe1bc381434 418 //debug_printf("plotx[%d]=%f ploty[%d]=%f\n\r",s,plotx[s],s,ploty[s]);
yuki0701 6:efe1bc381434 419 }
yuki0701 6:efe1bc381434 420 break;
yuki0701 6:efe1bc381434 421
yuki0701 6:efe1bc381434 422 case 2://↑→移動
yuki0701 6:efe1bc381434 423 X=point_x2;
yuki0701 6:efe1bc381434 424 Y=point_y1;
yuki0701 6:efe1bc381434 425
yuki0701 6:efe1bc381434 426 for(s=0; s<((90/theta)+1); s++) {
yuki0701 6:efe1bc381434 427 plotx[s] = X + a * cos(PI - s * (PI*theta/180));
yuki0701 6:efe1bc381434 428 ploty[s] = Y + b * sin(PI - s * (PI*theta/180));
yuki0701 6:efe1bc381434 429 //debug_printf("plotx[%d]=%f ploty[%d]=%f\n\r",s,plotx[s],s,ploty[s]);
yuki0701 6:efe1bc381434 430 }
yuki0701 6:efe1bc381434 431 break;
yuki0701 6:efe1bc381434 432
yuki0701 6:efe1bc381434 433 case 3://↑←移動
yuki0701 6:efe1bc381434 434 X=point_x2;
yuki0701 6:efe1bc381434 435 Y=point_y1;
yuki0701 6:efe1bc381434 436
yuki0701 6:efe1bc381434 437 for(s=0; s<((90/theta)+1); s++) {
yuki0701 6:efe1bc381434 438 plotx[s] = X + a * cos(s * (PI*theta/180));
yuki0701 6:efe1bc381434 439 ploty[s] = Y + b * sin(s * (PI*theta/180));
yuki0701 6:efe1bc381434 440 //debug_printf("plotx[%d]=%f ploty[%d]=%f\n\r",s,plotx[s],s,ploty[s]);
yuki0701 6:efe1bc381434 441 }
yuki0701 6:efe1bc381434 442 break;
yuki0701 6:efe1bc381434 443
yuki0701 6:efe1bc381434 444 case 4://←↑移動
yuki0701 6:efe1bc381434 445 X=point_x1;
yuki0701 6:efe1bc381434 446 Y=point_y2;
yuki0701 6:efe1bc381434 447
yuki0701 6:efe1bc381434 448 for(s=0; s<((90/theta)+1); s++) {
yuki0701 6:efe1bc381434 449 plotx[s] = X + a * cos(-PI/2 - s * (PI*theta/180));
yuki0701 6:efe1bc381434 450 ploty[s] = Y + b * sin(-PI/2 - s * (PI*theta/180));
yuki0701 6:efe1bc381434 451 //debug_printf("plotx[%d]=%f ploty[%d]=%f\n\r",s,plotx[s],s,ploty[s]);
yuki0701 6:efe1bc381434 452 }
yuki0701 6:efe1bc381434 453 break;
yuki0701 6:efe1bc381434 454
yuki0701 6:efe1bc381434 455 case 5://←↓移動
yuki0701 6:efe1bc381434 456 X=point_x1;
yuki0701 6:efe1bc381434 457 Y=point_y2;
yuki0701 6:efe1bc381434 458
yuki0701 6:efe1bc381434 459 for(s=0; s<((90/theta)+1); s++) {
yuki0701 6:efe1bc381434 460 plotx[s] = X + a * cos(PI/2 + s * (PI*theta/180));
yuki0701 6:efe1bc381434 461 ploty[s] = Y + b * sin(PI/2 + s * (PI*theta/180));
yuki0701 6:efe1bc381434 462 //debug_printf("plotx[%d]=%f ploty[%d]=%f\n\r",s,plotx[s],s,ploty[s]);
yuki0701 6:efe1bc381434 463 }
yuki0701 6:efe1bc381434 464 break;
yuki0701 6:efe1bc381434 465
yuki0701 6:efe1bc381434 466 case 6://↓←移動
yuki0701 6:efe1bc381434 467 X=point_x2;
yuki0701 6:efe1bc381434 468 Y=point_y1;
yuki0701 6:efe1bc381434 469
yuki0701 6:efe1bc381434 470 for(s=0; s<((90/theta)+1); s++) {
yuki0701 6:efe1bc381434 471 plotx[s] = X + a * cos(-s * (PI*theta/180));
yuki0701 6:efe1bc381434 472 ploty[s] = Y + b * sin(-s * (PI*theta/180));
yuki0701 6:efe1bc381434 473 //debug_printf("plotx[%d]=%f ploty[%d]=%f\n\r",s,plotx[s],s,ploty[s]);
yuki0701 6:efe1bc381434 474 }
yuki0701 6:efe1bc381434 475 break;
yuki0701 6:efe1bc381434 476
yuki0701 6:efe1bc381434 477 case 7://↓→移動
yuki0701 6:efe1bc381434 478 X=point_x2;
yuki0701 6:efe1bc381434 479 Y=point_y1;
yuki0701 6:efe1bc381434 480
yuki0701 6:efe1bc381434 481 for(s=0; s<((90/theta)+1); s++) {
yuki0701 6:efe1bc381434 482 plotx[s] = X + a * cos(PI + s * (PI*theta/180));
yuki0701 6:efe1bc381434 483 ploty[s] = Y + b * sin(PI + s * (PI*theta/180));
yuki0701 6:efe1bc381434 484 //debug_printf("plotx[%d]=%f ploty[%d]=%f\n\r",s,plotx[s],s,ploty[s]);
yuki0701 6:efe1bc381434 485 }
yuki0701 6:efe1bc381434 486 break;
yuki0701 6:efe1bc381434 487
yuki0701 6:efe1bc381434 488 case 8://→↓移動
yuki0701 6:efe1bc381434 489 X=point_x1;
yuki0701 6:efe1bc381434 490 Y=point_y2;
yuki0701 6:efe1bc381434 491
yuki0701 6:efe1bc381434 492 for(s=0; s<((90/theta)+1); s++) {
yuki0701 6:efe1bc381434 493 plotx[s] = X + a * cos(PI/2 - s * (PI*theta/180));
yuki0701 6:efe1bc381434 494 ploty[s] = Y + b * sin(PI/2 - s * (PI*theta/180));
yuki0701 6:efe1bc381434 495 //debug_printf("plotx[%d]=%f ploty[%d]=%f\n\r",s,plotx[s],s,ploty[s]);
yuki0701 6:efe1bc381434 496 }
yuki0701 6:efe1bc381434 497 break;
yuki0701 6:efe1bc381434 498 }
yuki0701 6:efe1bc381434 499
yuki0701 6:efe1bc381434 500 while(1) {
yuki0701 6:efe1bc381434 501
yuki0701 7:48af3a9c5bdd 502 calc_xy(target_angle,u,v);
yuki0701 6:efe1bc381434 503
yuki0701 6:efe1bc381434 504 XYRmotorout(plotx[t],ploty[t],plotx[t+1],ploty[t+1],&x_out,&y_out,&r_out,speed,speed);
yuki0701 6:efe1bc381434 505 CalMotorOut(x_out,y_out,r_out);
yuki0701 6:efe1bc381434 506 //debug_printf("t=%d now_x=%f now_y=%f x_out=%f y_out=%f\n\r",t,now_x,now_y,x_out,y_out);
yuki0701 6:efe1bc381434 507
yuki0701 6:efe1bc381434 508 base(GetMotorOut(0),GetMotorOut(1),GetMotorOut(2),GetMotorOut(3),4095); //m1~m4に代入
yuki0701 6:efe1bc381434 509 //debug_printf("t=%d (0)=%f (1)=%f (2)=%f (3)=%f\n\r",t,GetMotorOut(0),GetMotorOut(1),GetMotorOut(2),GetMotorOut(3));
yuki0701 6:efe1bc381434 510
yuki0701 6:efe1bc381434 511 if(((plotx[t+1] - now_x)*(plotx[t+1] - plotx[t]) + (ploty[t+1] - now_y)*(ploty[t+1] - ploty[t])) < 0)t++;
yuki0701 6:efe1bc381434 512
yuki0701 6:efe1bc381434 513 MotorControl(m_1,m_2,m_3,m_4); //出力
yuki0701 6:efe1bc381434 514 debug_printf("t=%d m1=%d m2=%d m3=%d m4=%d x=%f y=%f angle=%f\n\r",t,m_1,m_2,m_3,m_4,now_x,now_y,now_angle);
yuki0701 6:efe1bc381434 515
yuki0701 6:efe1bc381434 516 if(t == (90/theta))break;
yuki0701 6:efe1bc381434 517 }
yuki0701 6:efe1bc381434 518 }
yuki0701 6:efe1bc381434 519
yuki0701 6:efe1bc381434 520
yuki0701 7:48af3a9c5bdd 521 void gogo_straight(double u,double v,
yuki0701 7:48af3a9c5bdd 522 double x1_point,double y1_point, //直線運動プログラム
yuki0701 6:efe1bc381434 523 double x2_point,double y2_point,
yuki0701 6:efe1bc381434 524 double speed1,double speed2,
yuki0701 6:efe1bc381434 525 double q_p,double q_d,
yuki0701 6:efe1bc381434 526 double r_p,double r_d,
yuki0701 6:efe1bc381434 527 double r_out_max,
yuki0701 7:48af3a9c5bdd 528 double target_angle)
yuki0701 6:efe1bc381434 529 //引数:出発地点の座標(x,y)、目標地点の座標(x,y)、初速度(speed1)、目標速度(speed2)//speed1=speed2 のとき等速運動
yuki0701 6:efe1bc381434 530 {
yuki0701 6:efe1bc381434 531 //-----PathFollowingのパラメーター設定-----//
yuki0701 6:efe1bc381434 532 q_setPDparam(q_p,q_d); //ベクトルABに垂直な方向の誤差を埋めるPD制御のパラメータ設定関数
yuki0701 6:efe1bc381434 533 r_setPDparam(r_p,r_d); //機体角度と目標角度の誤差を埋めるPD制御のパラメータ設定関数
yuki0701 6:efe1bc381434 534 set_r_out(r_out_max); //旋回時の最大出力値設定関数
yuki0701 6:efe1bc381434 535 set_target_angle(target_angle); //機体目標角度設定関数
yuki0701 6:efe1bc381434 536
yuki0701 6:efe1bc381434 537 while (1) {
yuki0701 6:efe1bc381434 538
yuki0701 9:135bbd007509 539 //can_read();
yuki0701 9:135bbd007509 540
yuki0701 10:107386dd097b 541 //printf("%f\n",usw_data3);
yuki0701 9:135bbd007509 542
yuki0701 7:48af3a9c5bdd 543 calc_xy(target_angle,u,v);
yuki0701 6:efe1bc381434 544
yuki0701 6:efe1bc381434 545 XYRmotorout(x1_point,y1_point,x2_point,y2_point,&x_out,&y_out,&r_out,speed1,speed2);
yuki0701 6:efe1bc381434 546 //printf("x = %f, y = %f,angle = %f,x_out=%lf, y_out=%lf, r_out=%lf\n\r",now_x,now_y,now_angle,x_out, y_out,r_out);
yuki0701 6:efe1bc381434 547
yuki0701 6:efe1bc381434 548 CalMotorOut(x_out,y_out,r_out);
yuki0701 6:efe1bc381434 549 //printf("out1=%lf, out2=%lf, out3=%lf, out4=%lf\n",GetMotorOut(0),GetMotorOut(1),GetMotorOut(2),GetMotorOut(3));
yuki0701 6:efe1bc381434 550
yuki0701 6:efe1bc381434 551 base(GetMotorOut(0),GetMotorOut(1),GetMotorOut(2),GetMotorOut(3),4095);
yuki0701 6:efe1bc381434 552 //printf("m1=%d, m2=%d, m3=%d, m4=%d\r\n",m_1,m_2,m_3,m_4);
yuki0701 6:efe1bc381434 553
yuki0701 7:48af3a9c5bdd 554 MotorControl(m_1,m_2,m_3,m_4);
yuki0701 6:efe1bc381434 555 debug_printf("m1=%d m2=%d m3=%d m4=%d x=%f y=%f angle=%f\n\r",m_1,m_2,m_3,m_4,now_x,now_y,now_angle);
yuki0701 6:efe1bc381434 556
yuki0701 6:efe1bc381434 557 if(((x2_point - now_x)*(x2_point - x1_point) + (y2_point - now_y)*(y2_point - y1_point)) < 0)break;
yuki0701 10:107386dd097b 558 }
yuki0701 6:efe1bc381434 559 }
yuki0701 6:efe1bc381434 560
yuki0701 9:135bbd007509 561 void pos_correction(double tgt_x, double tgt_y, double tgt_angle, double u, double v){ //位置補正(使用前にMotorControl(0,0,0,0)を入れる)
yuki0701 9:135bbd007509 562
yuki0701 9:135bbd007509 563 double r, R=10; // r:一回補正が入るごとの機体の位置と目標位置の距離(ズレ) R:補正終了とみなす目標位置からの機体の位置のズレ
yuki0701 9:135bbd007509 564 double out;
yuki0701 9:135bbd007509 565
yuki0701 9:135bbd007509 566 calc_xy(tgt_angle, u, v);
yuki0701 9:135bbd007509 567
yuki0701 9:135bbd007509 568 while(1){ //機体の位置を目標領域(目標座標+許容誤差)に収める
yuki0701 11:8407c616b1a8 569 gogo_straight(u,v,now_x,now_y,tgt_x,tgt_y,200,130,5,0.1,10,0.1,500,tgt_angle);
yuki0701 9:135bbd007509 570 MotorControl(0,0,0,0);
yuki0701 9:135bbd007509 571
yuki0701 9:135bbd007509 572 calc_xy(tgt_angle, u, v);
yuki0701 9:135bbd007509 573
yuki0701 9:135bbd007509 574 r=hypot(now_x - tgt_x, now_y - tgt_y);
yuki0701 9:135bbd007509 575
yuki0701 11:8407c616b1a8 576
yuki0701 9:135bbd007509 577 if(r < R) break;
yuki0701 9:135bbd007509 578
yuki0701 9:135bbd007509 579 }
yuki0701 9:135bbd007509 580
yuki0701 9:135bbd007509 581 while(1){
yuki0701 9:135bbd007509 582
yuki0701 9:135bbd007509 583 now_angle=gyro.getAngle();
yuki0701 9:135bbd007509 584
yuki0701 9:135bbd007509 585 out = 10 * (tgt_angle - now_angle);
yuki0701 9:135bbd007509 586
yuki0701 11:8407c616b1a8 587 if(out > 300) {
yuki0701 11:8407c616b1a8 588 MotorControl(-300,-300,-300,-300);
yuki0701 9:135bbd007509 589 }else if(out < -300){
yuki0701 11:8407c616b1a8 590 MotorControl(300,300,300,300);
yuki0701 11:8407c616b1a8 591 }else if((out <= 300 && out >= 30) || (out <= -30 && out > -300)) {
yuki0701 11:8407c616b1a8 592 MotorControl(-out,-out,-out,-out);
yuki0701 11:8407c616b1a8 593 }else if(0 <= out && out < 30){
yuki0701 11:8407c616b1a8 594 MotorControl(-30,-30,-30,-30);
yuki0701 11:8407c616b1a8 595 }else if(-30 < out && out < 0){
yuki0701 11:8407c616b1a8 596 MotorControl(30,30,30,30);
yuki0701 9:135bbd007509 597 }
yuki0701 9:135bbd007509 598
yuki0701 11:8407c616b1a8 599 if(tgt_angle - 0.5 < now_angle && now_angle < tgt_angle + 0.5){ // 目標角度からの許容誤差内に機体の角度が収まった時、補正終了
yuki0701 11:8407c616b1a8 600 printf("end\n\r");
yuki0701 10:107386dd097b 601 break;
yuki0701 10:107386dd097b 602 }
yuki0701 11:8407c616b1a8 603 printf("continue\n\r");
yuki0701 10:107386dd097b 604 printf("pos_correction// now_angle = %f",now_angle);
yuki0701 9:135bbd007509 605 }
yuki0701 9:135bbd007509 606 MotorControl(0,0,0,0);
yuki0701 9:135bbd007509 607 }
yuki0701 9:135bbd007509 608
yuki0701 10:107386dd097b 609