harurobo_mbed_undercarriage_sub

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