version 3 通信方式,マイコン等に変更あり
Dependencies: AQM0802A PID Servo mbed
Diff: main.cpp
- Revision:
- 2:e84bb87eea71
- Parent:
- 1:f91d53098d57
- Child:
- 3:4a39486ff238
--- a/main.cpp Fri Mar 06 02:15:10 2015 +0000 +++ b/main.cpp Tue Mar 10 08:28:15 2015 +0000 @@ -39,9 +39,9 @@ #include "mbed.h" #include <math.h> #include <sstream> +#include "MultiSerial.h" #include "PID.h" #include "AQM0802A.h" -#include "MultiSerial.h" #include "Servo.h" #include "main.h" @@ -56,7 +56,7 @@ PingData[3] = rx_data[6]; Compass = rx_data[7]+rx_data[8]; - if(IrData[0] == 255){ + if((IrData[0] == 255)||(IrData[1] == 255)||(IrData[2] == 255)){ IrNum = 12; return; } @@ -65,13 +65,13 @@ } -void move(int vr,int vl, double vs ,double Rad){ +void move(int vr,int vl, double vs ,int Degree){ double pwm[4] = {0}; uint8_t i = 0; pwm[0] = vr - vs; pwm[1] = 0; pwm[2] = 0; - pwm[3] = vl*1.2 + vs; + pwm[3] = vl*1.1 + vs; for(i = 0; i < 4; i++){ if(pwm[i] > 100){ @@ -81,153 +81,275 @@ } speed[i] = pwm[i]; } - SetRad = Rad; + if(Degree > 110){ + Degree = 110; + }else if(Degree < -110){ + Degree = -110; + } + SetDegree = Degree; + S555.position(SetDegree); wait_ms(10); } -void fool (int *Rad, int *Power){ - static int Last_Rad = 0; + +uint8_t PingChange(uint8_t LineData){ + static uint8_t Last_Line; + static uint8_t Last_Ping; + uint8_t LinePing = 0; + + if(!LineData){ + return 0; + } + + if(PingData[0] <40) LinePing = LinePing + 1; + if(PingData[1] <40) LinePing = LinePing + 2; + if(PingData[2] <40) LinePing = LinePing + 4; + if(PingData[3] <40) LinePing = LinePing + 8; + + + if(LinePing&0x01){ + if((LineData&0x01) ||(Last_Line&0x01)||(Last_Ping&0x01)){ + Last_Ping = LinePing; + Last_Line = LineData; + return 1; + } + } + if(LinePing&0x02){ + if((LineData&0x02) ||(Last_Line&0x02)||(Last_Ping&0x02)){ + Last_Ping = LinePing; + Last_Line = LineData; + return 2; + } + } + if(LinePing&0x04){ + if((LineData&0x04) ||(Last_Line&0x04)||(Last_Ping&0x04)){ + Last_Ping = LinePing; + Last_Line = LineData; + return 4; + } + } + if(LinePing&0x08){ + if((LineData&0x08) ||(Last_Line&0x08)||(Last_Ping&0x08)){ + Last_Ping = LinePing; + Last_Line = LineData; + return 8; + } + } + Last_Ping = 0; + Last_Line = 0; + return 0; + +} + +void fool (int *Degree, int *Power){ + static int Last_Degree = 0; static int Last_Vector = 1; - int rad = *Rad; + int degree = *Degree; int Temp; - Temp = Last_Rad % 180; - - if((Temp>70) &&(Temp<110)){ - Temp = *Rad % 180; - if((Temp>70) &&(Temp<110)){ - Temp = abs(*Rad - Last_Rad); + + + if((*Degree <0)||(*Degree >=360)){ + *Degree = 0; + Last_Degree = 0; + Last_Vector = 1; + return ; + } + + Temp = Last_Degree % 180; + if((Temp==90)){ + Temp = *Degree % 180; + if((Temp==90)){ + Temp = abs(*Degree - Last_Degree); if(Temp>160){ Last_Vector = -1 * Last_Vector;//正転逆転切り替え - if(*Rad/180){ - *Rad = Angle[Last_Rad%180] -(Last_Rad - *Rad%180); + if(*Degree/180){ + *Degree = Angle[Last_Degree%180] -(Last_Degree - *Degree%180); *Power = *Power * Last_Vector; }else{ - *Rad = Angle[Last_Rad%180] -(Last_Rad%180 - *Rad); + *Degree = Angle[Last_Degree%180] -(Last_Degree%180 - *Degree); *Power = *Power * Last_Vector; } - Last_Rad = rad; + Last_Degree = degree; + if((*Degree <= -120)||(*Degree >=120)){ + *Degree = 0; + } return; }else if((Last_Vector+2) == 1){ /*逆転のまま角度拡張*/ - if(*Rad/180){ - *Rad = -360 + *Rad ; - *Power = *Power * Last_Vector; - }else{ - *Power = *Power * Last_Vector; + if(*Degree/180){ + *Degree = -360 + *Degree ; + } - Last_Rad = rad; + *Power = *Power * Last_Vector; + Last_Degree = degree; + if((*Degree <= -120)||(*Degree >=120)){ + *Degree = 0; + + } return; }else if((Last_Vector+2) == 3){ /*正転のまま*/ - if(*Rad/180){ - *Rad = -360 + *Rad ; - *Power = *Power * Last_Vector; - }else{ - *Power = *Power * Last_Vector; - Last_Rad = rad; + if(*Degree/180){ + *Degree = -360 + *Degree ; } - Last_Rad = rad; + *Power = *Power * Last_Vector; + Last_Degree = degree; + if((*Degree <= -120)||(*Degree >=120)){ + *Degree = 0; + } return; } } } /*通常動作*/ - Last_Vector = RadToVector[(*Rad-1)/90]; - *Rad = Angle[*Rad%180]; + if(*Degree == 0){ + Last_Vector = DegreeToVector[0]; + *Degree = Angle[*Degree%180]; + *Power = *Power * Last_Vector; + Last_Degree = degree; + return ; + } + Last_Vector = DegreeToVector[(*Degree-1)/90]; + *Degree = Angle[*Degree%180]; *Power = *Power * Last_Vector; - Last_Rad = rad; + Last_Degree = degree; + if((*Degree <= -120)||(*Degree >=120)){ + *Degree = 0; + } } -int IrRad(){ +int IrDegree(){ /*irの1位の値,2位の場所からirの360へ持っていく*/ - uint8_t IrF =IrData[0]/12,IrS = IrData[0]%12; - int irrad; - irrad = 359 - IrF*30; - - if(IrS){ - if(IrF == 0 ){ - if(IrS == 11){ - irrad = 15; + uint8_t IrF ,IrS; + unsigned int irdegree = 0; + if(IrNum >=12){ + return 0; + } + IrF = IrData[0]/12; + IrS = IrData[0]%12; + + if(IrF == 0 ){ + if(IrS == 11){ + irdegree = 15; - }else{ - irrad = 345; - } - - } - irrad = irrad - (IrF - IrS)*15; + }else if(IrS == 1){ + irdegree = 345; + } + return irdegree; + } + irdegree = 360 - IrF*30; + if(IrS&&(abs(IrF-IrS) == 1)){ + irdegree = irdegree - (IrF - IrS)*15; } - return irrad; + if(irdegree>=360){ + return 0; + } + + return irdegree; } -void IrFrontAction( uint8_t IrMemo[],double ReV)//ball 12 or 0 o-clock +void IrFrontAction()//ball 12 or 0 o-clock { + if(IrData[1]>700){ + if(abs(CompassPID)>10){ + move(0,0,CompassPID,0); + return; + } + move(30,30,CompassPID,0); + return; + } + if(IrData[1]>600){ + move(25,25,CompassPID,0); + return; + } + /*IrData[1]>500*/ + + if(PingData[0]<50){ + if((PingData[1]<60)&&(PingData[1]>40)){ + /*右側に居る*/ + move(25,40,0,10); + wait_ms(100); + move(30,30,0,0); + return; + } + if((PingData[1]<60)&&(PingData[1]>40)){ + /*左側に居る*/ + move(40,25,0,-10); + wait_ms(100); + move(30,30,0,0); + return; + } + /*それ以外*/ + move(10,10,CompassPID,0); + Receive(); + if(!(IrNum == 0)) return; + move(40,40,CompassPID,0); + return ; + } + move(20,20,CompassPID,0); + + } -void IrBackAction( uint8_t IrMemo[],double ReV)//ball found six o-clock +void IrBackAction()//ball found six o-clock { /*** * 6時にボールがある場合の処理.右と左のスペースを確認して広い方から回り込む * **/ - char Ping[2]={0}; - - //PingReceiveRL(Ping); - - - if(IrMemo[0] == 6){//check ir number - return ; - } - if(Ping[0]<Ping[1]){ + if(PingData[1]>PingData[3]){ /*右が大きい*/ - - + if(IrData[1]>700){ + move(-20,-20,CompassPID,45); + return; + } + if(IrData[1]>600){ + move(-20,-20,CompassPID,60); + return; + } + move(-20,-20,CompassPID,90); return; } /*左が大きい*/ - - + if(IrData[1]>700){ + move(-20,-20,CompassPID,-45); + return; } - -void GoHome( uint8_t IrMemo[],double ReV)//Ball is not found. -{ - //止まっとく - S555.position(0.0); + if(IrData[1]>600){ + move(-20,-20,CompassPID,-60); + return; + } + move(-20,-20,CompassPID,-90); + return; - move(0,0,ReV,0); - - /*line検知をしないバージョン*/ - /* - char Ping[2] = {0}; +} + +void GoHome()//Ball is not found. +{ - - PingReceiveFB(Ping); - if(Ping[1] >=60){//後ろからの距離60cm - move(-20,-20,ReV); - PingReceiveFB(Ping); + if(PingData[2] >=60){//後ろからの距離60cm + move(-20,-20,CompassPID,0); return ; } - move(0,0,ReV);//stop - */ + move(0,0,CompassPID,0);//stop + } void PidUpdate() { - - //Compass = ((hmc6352.sample() / 10) + 540 - CompassDef) % 360; - wait_ms(10); - - //pid.setSetPoint((int)((REFERENCE + SetC) / 1.0)); - //InputPID = Compass; - //pid.setProcessValue(InputPID); - //CompassPID = -(pid.compute()); + pid.setSetPoint((int)((REFERENCE + SetC) / 1.0)); + InputPID = Compass; + + pid.setProcessValue(InputPID); + CompassPID = -(pid.compute()); } @@ -269,7 +391,6 @@ void tx_motor(){ array(speed[0],speed[1],speed[3],speed[2]); Motor.printf("%s",StringFIN.c_str()); - S555.position(SetRad); } void SetUp(){ @@ -280,7 +401,7 @@ S555.calibrate(0.0005, 120.0); - S555.position(0.0); //初期位置にセット + //S555.position(0.0); //初期位置にセット move(0,0,0,0);//停止 Kick = 0; @@ -292,6 +413,7 @@ pid.setBias(PID_BIAS); //pid sed def pid.setMode(AUTO_MODE); //pid sed def pid.setSetPoint(REFERENCE); //pid sed def + pidupdate.attach(&PidUpdate, PID_CYCLE); @@ -300,11 +422,11 @@ void StartLoop(){ uint8_t State = 0; - uint8_t Irnum = 0; uint8_t LineData = 0; while(1){ Led[0] = Led[1] = Led[2] = Led[3] = 1; //Lcd.cls(); + State = SwRead(); if(State == 0) continue; @@ -327,8 +449,8 @@ } if(State == Debug2){ while((State == Debug2)){ - //Irnum = IrReceiveFast(); - Lcd.printf("%d\n",Irnum); + Receive(); + Lcd.printf("%d\n",IrNum); wait_ms(100); State = SwRead(); } @@ -338,7 +460,7 @@ if(State == Debug3){ while((State == Debug3)){ - //Lcd.printf("%d\n",Compass); + Lcd.printf("%d\n",Compass); wait_ms(100); State = SwRead(); } @@ -348,14 +470,14 @@ if(State == Kicker){ Led[0] = Led[1] = Led[2] = 0; - /*move(20,20,0,0); + move(20,20,0,0); while((State == Kicker)){ wait_ms(100); State = SwRead(); } move(0,0,0,0); - */ + continue; } } @@ -363,101 +485,127 @@ } int main() { - /*Ir*/ - uint8_t IrNum = 12;//場所によるirの数を表したもの0~11まではボールがある状態12はボールがない状態 //uint8_t IrNumOld = 0;//過去値 /*Line*/ uint8_t LineData = 0; - + uint8_t LinePing = 0; - /*PID補正move加算値 Revise */ - double ReV = 0.0; - double SetC; - + /*State */ uint8_t LineIr = 0; - uint8_t IrChange[13] ={0x01,0x01,0x02,0x02,0x02,0x04, - 0x04,0x04,0x08,0x08,0x08,0x01,0x00}; + uint8_t IrChange[13] ={0x01,0x01,0x03,0x02,0x02,0x06, + 0x04,0x04,0x0B,0x08,0x08,0x09,0x00}; + /*行動設定*/ int Power = 0; - int Rad = 0; - + int Degree = 0; /*楽しい変数達*/ - int nRad =0;//基礎角 - int addRad = 0;//追加角 + int nDegree =0;//基礎角 + int addDegree = 0;//追加角 /*関数ポインタ*/ - /* - void (*AnotherAction[3])(uint8_t [],double); + + + //void (*AnotherAction[3])(uint8_t [],double); + void (*AnotherAction[3])(); AnotherAction[0] = IrFrontAction; AnotherAction[1] = IrBackAction; AnotherAction[2] = GoHome; - */ + SetUp();/*set up routine*/ Mbed.read_data(rx_data, ADDRESS); Mbed.start_read(); //Mbed.check_rx_wait(); StartLoop(); /*loop strat, switch push end*/ + Led[0] = Led[1] = Led[2] = Led[3] = 0; + wait_ms(100); while(0){ - Power = 0; - Led[0] = 1; - Rad = 0; - ReV = 0; - SetC = 0.0; + - Receive(); - + + Receive(); + //Lcd.printf("%d\n",IrNum); /*白線を読んでいないか確認する*/ LineData = (~Line+0x00) & 0x0F; + if(LineData){ - while(LineData){ - move(0,0,0,0);// - Led[1] = Led[2] = Led[3] = 1; - LineData = (~Line+0x00) & 0x0F; - wait_ms(10); + LineIr = LineData & IrChange[IrNum]; + LinePing = PingChange(LineData); + if(LineIr){ + move(0,0,0,0); + while(LineIr){ + Led[1] = Led[2] = Led[3] = 1; + Receive(); + LineData = (~Line+0x00) & 0x0F; + LineIr = LineData & IrChange[IrNum]; + wait_ms(10); + } + }else if(LinePing){ + while(LinePing){ + Led[1] = Led[2] = Led[3] = 1; + Receive(); + LineData = (~Line+0x00) & 0x0F; + LinePing = PingChange(LineData); + wait_ms(10); + } } + + Led[1] = Led[2] = Led[3] = 0; } + Power = 0; + Led[0] = 1; + Degree = 0; + SetC = 0.0; + Led[3] = 1; + Receive(); + Degree = IrDegree(); - if(IrNum == 12){ - move(0,0,ReV,Rad); + if((Degree == 0)||(Degree == 180)||(IrNum == 12)){ + (AnotherAction[IrNum/6])(); continue; } - - Rad = IrRad(); - nRad = wrapRad[Rad/15]; + + /* + if(IrNum == 12){ + move(0,0,0,0); + wait_ms(10); + continue; + }*/ + + nDegree = wrapDegree[Degree/15]; Power = 20; - - - Rad = nRad + addRad; - fool(&Rad,&Power); - move(Power,Power,ReV,Rad); + Degree = nDegree + addDegree; + if((Degree <0)||(Degree>=360)){ + Degree = 0; + } + fool(&Degree,&Power); + move(Power,Power,0,Degree); + + //wait_ms(500); + Led[0] =0; wait_ms(10); - Led[0] =0; - - } - + int i; while(1){ //デモプログラム - Receive(); - wait(0.1); - pc.printf("%d %d %d %d %d\n",IrData[0],IrData[1],IrData[2],PingData[0],PingData[1]); - //pc.printf("%d %d %d %d %d\n",rx_data[0],rx_data[1],rx_data[2],rx_data[0],rx_data[1]); - + Receive(); + pc.printf("%d\t %d\t %d\t %d\t %d\t %d\t\n",rx_data[3],rx_data[4],rx_data[5],rx_data[6],rx_data[7],rx_data[8]); + + wait(0.1); }