main

Dependencies:   TextLCD mbed PID

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "TextLCD.h"
00003 #include "PID.h"
00004 #include "common.h"
00005 #include <math.h>
00006 #include <sstream>
00007 
00008 #define MOTOR_P 35
00009 #define HOME_P 30
00010 #define TURN_P 20
00011 #define BALL_P 25
00012 #define NO_BALL 45
00013 #define LINE_P 30
00014 #define LINE_PLR 17
00015 #define LINE_ON 0x2710  //10000
00016 #define LINE_TIME 0.6
00017 #define LINE_PING 40
00018 #define R 1.0
00019 #define S_MAX 5
00020 #define S1 15
00021 #define S2 10
00022 #define S3 5
00023 #define RATE 0.05
00024 #define P_GAIN 1.7
00025 #define I_GAIN 0.0
00026 #define D_GAIN 0.013
00027 #define HOME_BACK 30
00028 #define HOME 1
00029 #define KICK 25
00030 #define GOAL 30.0
00031 #define PING_LR 100
00032 #define BALL_FAR 43
00033 #define BALL_NEAR 40
00034 
00035 DigitalIn sw_wh(p5);
00036 DigitalIn start(p7);
00037 DigitalOut myled[4] = {LED1, LED2, LED3, LED4};
00038 Serial motor(p9,p10);
00039 Serial sensor(p13,p14);
00040 Serial xbee(p28,p27);
00041 Serial pc(USBTX, USBRX);
00042 TextLCD lcd(p26, p25, p24, p23, p22, p21);
00043 AnalogIn adcline[4] = {p16, p17, p19, p20};
00044 PID pid(P_GAIN,I_GAIN,D_GAIN, RATE);
00045 Timeout liner_F;
00046 Timeout liner_L;
00047 Timeout liner_B;
00048 Timeout liner_R;
00049 Ticker pidupdata;
00050 Ticker xbeetx;
00051 Ticker xbeerx;
00052 //HMC6352 dcompass(p9,p10);
00053 
00054 extern string StringFIN;
00055 extern void array(int,int,int,int);
00056 extern void xbee_tx(void);
00057 extern void xbee_rx(void);
00058 extern void micon_rx(void);
00059 
00060 //uint16_t  analogHex[4] = {0};
00061 int speed[4] = {0};
00062 uint8_t value_ir = 0, ir_num = 0, ir_dis = 0, ball_on = 0;
00063 uint8_t ping[4] = {0};
00064 uint8_t line[4] = {0}, line_stop[4] = {0}, line_ping[4] = {0};
00065 uint8_t kick = 0;
00066 //uint8_t robot_state = 0;
00067 int compass = 0;
00068 int x = 0, y = 0, s = 0, i = 0, line_on = 0;
00069 int compassdef = 0, data = 0;
00070 uint8_t pingdef[4] = {0};
00071 
00072 double pidinput = 180.0;
00073 double compasspid = 0.0;
00074 double goal = 0.0;
00075 
00076 double way[10][2] = {
00077     { 0    , 1    },    //FF
00078     {-0.707, 0.707},    //FL
00079     {-1    , 0    },    //LL
00080     {-0.707,-0.707},    //BL
00081     { 0    ,-1    },    //BB
00082     { 0.707,-0.707},    //BR
00083     { 1    , 0    },    //RR
00084     { 0.707, 0.707},    //FR
00085     {-0.500, 0.866},    //FFL
00086     { 0.500, 0.866}     //FFR
00087 };
00088 double ball_way[12][2] = {
00089     { 0.0  , 1.0  },    //FF
00090     {-0.866,-0.500},    //FL
00091     {-0.342,-0.940},    //LL
00092     { 0.342,-0.940},    //BL
00093     { 0.966, 0.259},    //BB
00094     {-0.342,-0.940},    //BR
00095     { 0.342,-0.940},    //RR
00096     { 0.985,-0.173},    //FR
00097     {-0.985, 0.174},    //FFL
00098     { 0.985, 0.174},    //FFR
00099     {-0.173, 0.985},    //FFFL
00100     { 0.173, 0.985}     //FFFR
00101 };
00102 
00103 void move(int vx, int vy, int vs){
00104     double pwm[4] = {0};
00105     
00106     pwm[0] = (double)((vx) + vs);
00107     pwm[1] = (double)((-0.5 * vx) + ((sqrt(3.0) / 2.0)  * vy) + vs);
00108     pwm[2] = (double)((-0.5 * vx) + ((-sqrt(3.0) / 2.0) * vy) + vs);
00109     pwm[3] = kick;
00110 
00111     for(i = 0; i < 4; i++){
00112         if(pwm[i] > 100){
00113             pwm[i] = 100;
00114         } else if(pwm[i] < -100){
00115             pwm[i] = -100;
00116         }
00117         speed[i] = pwm[i];
00118     }
00119 }
00120 
00121 //通信(モータ用)
00122 void tx_motor(){
00123     array(speed[0],speed[1],speed[3],speed[2]);
00124     motor.printf("%s",StringFIN.c_str());
00125 }
00126 
00127 //ライン判断
00128 void line_state(){    
00129     if(line[LEFT]){
00130         x = LINE_P;
00131     } else if(line[RIGHT]){
00132         x = -LINE_P;
00133     }
00134         
00135     if(line[FRONT]){
00136         if(line[LEFT] | line[RIGHT]){
00137             y = -LINE_PLR;
00138         } else {
00139             y = -LINE_P;
00140         }
00141     } else if(line[BACK]){
00142         if(line[LEFT] | line[RIGHT]){
00143             y = LINE_PLR;
00144         } else {
00145             y = LINE_P;
00146         }
00147     }
00148 }
00149 
00150 void line_stop_F(){
00151     line_stop[FRONT] = 0;
00152 }
00153 void line_stop_L(){
00154     line_stop[LEFT] = 0;
00155 }
00156 void line_stop_B(){
00157     line_stop[BACK] = 0;
00158 }
00159 void line_stop_R(){
00160     line_stop[RIGHT] = 0;
00161 }
00162 
00163 void line_check()
00164 {
00165     if(!line_stop[FRONT]){
00166         if(adcline[FRONT].read_u16() > LINE_ON){
00167             line[FRONT] = 1;
00168             line_stop[FRONT] = 1;
00169             line_stop[BACK] = 1;
00170             //line_ping[FRONT] = 1;
00171             myled[0] = 1;
00172             liner_F.attach(&line_stop_F,LINE_TIME);
00173             liner_B.attach(&line_stop_B,LINE_TIME);
00174         } else {
00175             line[FRONT] = 0;
00176             myled[0] = 0;
00177         }
00178     }
00179     if(!line_stop[LEFT]){
00180         if(adcline[LEFT].read_u16() > LINE_ON){
00181             line[LEFT] = 1;
00182             line_stop[LEFT] = 1;
00183             line_stop[RIGHT] = 1;
00184             //line_ping[LEFT] = 1;
00185             myled[1] = 1;
00186             liner_L.attach(&line_stop_L,LINE_TIME);
00187             liner_R.attach(&line_stop_R,LINE_TIME);
00188         } else {
00189             line[LEFT] = 0;
00190             myled[1] = 0;
00191         }
00192     }
00193     if(!line_stop[BACK]){
00194         if(adcline[BACK].read_u16() > LINE_ON){
00195             line[BACK] = 1;
00196             line_stop[BACK] = 1;
00197             line_stop[FRONT] = 1;
00198             //line_ping[BACK] = 1;
00199             myled[2] = 1;
00200             liner_B.attach(&line_stop_B,LINE_TIME);
00201             liner_F.attach(&line_stop_F,LINE_TIME);
00202         } else {
00203             line[BACK] = 0;
00204             myled[2] = 0;
00205         }
00206     }
00207     if(!line_stop[RIGHT]){
00208         if(adcline[RIGHT].read_u16() > LINE_ON){
00209             line[RIGHT] = 1;
00210             line_stop[RIGHT] = 1;
00211             line_stop[LEFT] = 1;
00212             //line_ping[RIGHT] = 1;
00213             myled[3] = 1;
00214             liner_R.attach(&line_stop_R,LINE_TIME);
00215             liner_L.attach(&line_stop_L,LINE_TIME);
00216         } else {
00217             line[RIGHT] = 0;
00218             myled[3] = 0;
00219         }
00220     }
00221 }
00222 
00223 
00224 void pidupdate()
00225 {
00226     //pid.setSetPoint(180.0 + goal);
00227     pidinput = compass;
00228     pid.setProcessValue(pidinput);
00229     
00230     compasspid = -pid.compute();
00231 }
00232 
00233 void home()
00234 {
00235     x = 0;
00236     y = 0;
00237     kick = 0;
00238     goal = 0.0;
00239     
00240   //  if((145 < ping[LEFT]+ping[RIGHT]) && (ping[LEFT]+ping[RIGHT] < 155)){    
00241         if(ping[LEFT] > PING_LR){
00242             x = -HOME_P;
00243             y = -5;
00244         } else if(ping[RIGHT] > PING_LR){
00245             x = HOME_P;
00246             y = -5;
00247         }
00248   //  }
00249 
00250     if(ping[BACK] > HOME_BACK){
00251         y = -HOME_P;
00252     } else if(ping[BACK] < 5){
00253         y = HOME_P;
00254     }
00255 }
00256 
00257 int main() {
00258     
00259     //dcompass.setOpMode(HMC6352_CONTINUOUS, 1, 20);
00260     //uint8_t num = 0;
00261     uint8_t dir = 0, power = 0, lcd_count = 0;
00262     int x_ball = 0, x_turn = 0, y_ball = 0, y_turn = 0;
00263     
00264     wait(1);
00265     
00266     motor.baud(115200);                             //ボーレート設定
00267     motor.printf("1F0002F0003F0004F000\r\n");       //モータ停止
00268     motor.attach(&tx_motor,Serial::TxIrq);          //送信空き割り込み(モータ用)
00269     sensor.attach(&micon_rx,Serial::RxIrq);         //送信空き割り込み(センサ用)
00270     xbeerx.attach(&xbee_rx,5);
00271     xbeetx.attach(&xbee_tx,5);
00272     //compassdef = (compass / 10);           //コンパス初期値保存
00273     //compassdef = (dcompass.sample() / 10);
00274     pid.setInputLimits(0.0,360.0);
00275     pid.setOutputLimits(-30.0,30.0);
00276     pid.setBias(0.0);
00277     pid.setMode(AUTO_MODE);
00278     pid.setSetPoint(180.0);
00279     pidupdata.attach(&pidupdate, 0.05);
00280     
00281     sw_wh.mode(PullUp);
00282     start.mode(PullDown);
00283     
00284     lcd.cls();
00285     lcd.locate(0,0);
00286     lcd.printf("Chronograph");    
00287     
00288     
00289     //move(x,y,s);
00290     
00291     myled[0] = 1;
00292     
00293     //スタート前チェック
00294     while(!start){
00295         if(lcd_count == 0){
00296             lcd.locate(6,1);
00297             lcd.printf("%3d", compass);
00298         } else if(lcd_count == 1){
00299             lcd.locate(0,1);
00300             lcd.printf("ir_dis = %3d", ir_dis);
00301         } else if(lcd_count == 2){
00302             lcd.locate(0,0);
00303             lcd.printf("ir_num = %3d\nir_val = %3d", ir_num, value_ir);
00304         } else if(lcd_count == 3){
00305             lcd.locate(0,0);
00306             lcd.printf("F:%3d   B:%3d\nL:%3d   R:%3d", ping[FRONT], ping[BACK], ping[LEFT], ping[RIGHT]);
00307         } else if(lcd_count == 4){
00308             lcd.locate(0,0);
00309             lcd.printf("F:%5d B:%5d\nL:%5d R:%5d", adcline[FRONT].read_u16(), adcline[BACK].read_u16(), adcline[LEFT].read_u16(), adcline[RIGHT].read_u16());
00310         }
00311         if(!sw_wh){
00312             lcd_count++;
00313             if(lcd_count == 5){
00314                 lcd_count = 0;
00315                 lcd.cls();
00316                 lcd.locate(0,0);
00317                 lcd.printf("Chronograph");
00318             }
00319             wait(0.5);
00320         }
00321         wait(0.1);
00322     }
00323     
00324     
00325     
00326     
00327     myled[0] = 0;
00328     lcd.cls();
00329     lcd.locate(0,0);
00330     lcd.printf("Chronograph");
00331     lcd.locate(7,1);
00332     lcd.printf("ABURASOBA");
00333     
00334     
00335     
00336     while(1){
00337         x = 0;
00338         y = 0;
00339         s = compasspid;        
00340         power = MOTOR_P;
00341         
00342         if((ir_dis < 35)/* && ( (ir_num == FF) || (ir_num == FFL) || (ir_num == FFR) )*/){
00343             kick = KICK;                
00344         } else {
00345             kick = 0;
00346             //goal = 0.0;
00347         }
00348         
00349         if((ir_num != FF) && (ir_num != FFL) && (ir_num != FFR)){
00350             if(ir_dis > BALL_FAR){
00351                 x_turn = TURN_P * way[ir_num][0];
00352                 y_turn = TURN_P * way[ir_num][1];
00353                 
00354                 x_ball = BALL_P * ball_way[ir_num][0];
00355                 y_ball = BALL_P * ball_way[ir_num][1];
00356                 
00357                 if(ir_num == BB){
00358                     if(ping[LEFT] > ping[RIGHT]){
00359                         x_ball = -x_ball;
00360                     }
00361                 }
00362                 
00363                 x = x_turn + x_ball;
00364                 y = y_turn + y_ball;
00365                 
00366             } else if(ir_dis < BALL_NEAR){
00367                 x_turn = -(TURN_P - 5) * way[ir_num][0];
00368                 y_turn = -(TURN_P - 5) * way[ir_num][1];
00369                 
00370                 x_ball = BALL_P * ball_way[ir_num][0];
00371                 y_ball = BALL_P * ball_way[ir_num][1];
00372                 
00373                 if(ir_num == BB){
00374                     if(ping[LEFT] > ping[RIGHT]){
00375                         x_ball = -x_ball;
00376                     }
00377                 }
00378                 
00379                 x = x_turn + x_ball;
00380                 y = y_turn + y_ball;
00381                 
00382             } else {
00383                 if((ir_num == FL) || (ir_num == FR)){
00384                     power = 20;
00385                 }
00386                 x = power * ball_way[ir_num][0];
00387                 y = power * ball_way[ir_num][1];
00388                 if(ir_num == BB){
00389                     if(ping[LEFT] > ping[RIGHT]){
00390                         x = -x;
00391                     }
00392                 }
00393             }
00394             
00395         } else {            
00396             if(ir_num == FF){
00397                 power = MOTOR_P + 10;
00398             }
00399             x = power * ball_way[ir_num][0];
00400             y = power * ball_way[ir_num][1];
00401             
00402         }
00403        
00404         line_check();
00405         
00406         if((ir_num == NO_BALL)/* || (ball_on < 40)*/){
00407             home();
00408         }
00409 
00410         //x = 30; y = 10;
00411         line_state();
00412         
00413         if((x == 0) && (y == 0)){
00414             if(ping[BACK] > 25){
00415                 y = -HOME_P;
00416             }
00417         }
00418         
00419         //x = 0; y = 0;
00420         
00421         move(x,y,s);
00422     }
00423     
00424 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////    
00425 
00426 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00427 
00428 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00429 
00430 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////    
00431 
00432 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00433 
00434 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00435 
00436 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00437 
00438 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00439 
00440 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00441     
00442     while(1){
00443         
00444         x = 0;
00445         y = 0;
00446         s = compasspid;        
00447         power = MOTOR_P;
00448         
00449         if(/*(ir_dis < 60) && */( (ir_num == FF) || (ir_num == FFL) || (ir_num == FFR) )){
00450             //kick = 25;
00451             //if(130 < ping[LEFT]+ping[RIGHT]){
00452                 //if(goal == 0){
00453                    /* if(ping[LEFT] > 100){
00454                         goal = -GOAL;
00455                     }*//* else if(ping[RIGHT] > 100){
00456                         //goal = GOAL;
00457                     }*/
00458                 //}
00459             //}
00460                 
00461         } else {
00462             kick = 0;
00463             goal = 0.0;
00464         }
00465         
00466         if((ir_dis > 130) && (ir_dis < 150) && (ir_num != BB) && (ir_num != FL) && (ir_num != FR) && (ir_num != BL) && (ir_num != BR)){
00467             x = power * way[ir_num][0];
00468             y = power * way[ir_num][1];
00469         } else {            
00470             if((ir_num == FF) || (ir_num == FFFL) || (ir_num == FFFR)){
00471                 power = MOTOR_P + 10;
00472             } else if((ir_num == FFL) || (ir_num == FFR)){
00473                 power = MOTOR_P;
00474             } else {
00475                 power = MOTOR_P + 5;
00476             }
00477             x = power * ball_way[ir_num][0];
00478             y = power * ball_way[ir_num][1];
00479             if(ir_num == BB){
00480                 if(ping[LEFT] > ping[RIGHT]){
00481                     x = -x;
00482                 }
00483             }
00484         }
00485        
00486         line_check();
00487         
00488         if((ir_num == NO_BALL)/* || (ball_on < 40)*/){
00489             home();
00490         }
00491 
00492         //x = 30; y = 10;
00493         line_state();
00494         
00495         if((x == 0) && (y == 0)){
00496             if(ping[BACK] > 25){
00497                 y = -HOME_P;
00498             }
00499         }
00500         
00501         //x = 0; y = 0;
00502         
00503         move(x,y,s);
00504     }
00505 }