CatPot 2015-2016 / Mbed 2 deprecated CatPot_Main_F

Dependencies:   AQM0802A HMC6352 L6470_lib PID mbed

Fork of CatPot_Main_ver1 by CatPot 2015-2016

main.cpp

Committer:
ryuna
Date:
2014-12-27
Revision:
3:8d718ddb84c9
Parent:
2:054444aa1990
Child:
4:8444360f08e2

File content as of revision 3:8d718ddb84c9:

/***********************************
 *RoboCupJunior Soccer B Open 2014 
 *Koshinestu progrum
 *
 *このプログラムでは以下の処理をする.
 * LPC1114FN28/102からI2Cを用いて各種センサデータを収集
 * 
 * データからロボットの移動やキッカー等のモータの動作を決定する処理を行う
 *
 * MotorDriverにmaxonに命令
 * 
 * SteppingMotorDriverにステアリング命令
 * 
 * LCDでデバック
 *
 * スイッチ4つとスタートスイッチで処理を実行
 *  
 * キッカーのスイッチがどこかに入る
 *
 ************************* 
 * 
 *Pin Map
 *
 *  p5,p6,p7,p29,p30 >> SPI >>Stepping
 *  
 *  p9,p10 >> I2C orSerial >> LPC1114FN28/102 read
 *
 *  p13,p14 >> Serial >> Motor
 *
 *  p22~p26 >> DebugSw and StartSw 
 *
 *  p27,p28 >> I2C  >> DebugLCD
 *
 *
 *
 ******************************/


/*

****以下IRはNighは距離が近いものとする.

*/






#include "mbed.h"
#include "L6470.h"
#include "PID.h"
#include "AQM0802A.h"
#include "HMC6352.h"
#include <math.h>
#include <sstream>

#define ADDRESS_R 0xA0
#define ADDRESS_L 0xC0

#define READ_IR 0x01 //送る物指定
#define READ_PING 0x02


DigitalIn   DebugSw[4] = {p22,p23,p24,p25};
DigitalIn   StartSw(p26,PullUp);
DigitalOut  Led[4] = {LED1,LED2,LED3,LED4};

I2C         Sensor(p9,p10);//sda,scl
HMC6352     hmc6352(p9,p10);
AQM0802A    Lcd(p28,p27);//sda,scl
L6470       Step(p5,p6,p7,p29,p30);//mosi,miso,sck,#cs,busy(PullUp)
Serial      Motor(p13,p14);//tx,rx
Serial      pc(USBTX,USBRX);

DigitalOut  Kick(p21);

extern string StringFIN;
extern void array(int,int,int,int);

int speed[4] = {0};            

typedef enum {FRONT = 1, RIGHT, BACK, LEFT, NA} Direction;


unsigned int IrReceiveR(uint8_t *far){
    /*順位解析版
    Slave側はIRを要求した場合IRのみを返してくるとする.
    irは値が大きいほうが近いと仮定する
    
    
    */
    char data_r[3],data_l[3];
    bool val;
    Sensor.write(READ_IR);//一斉送信のつもり//コンパスへの影響はどのくらいですか
    
    val = Sensor.read(ADDRESS_R|1, data_r, 3);// IRデータを受信
    Led[0] = val;
    wait_ms(5);
    val = Sensor.read(ADDRESS_L|1, data_l, 3);
    Led[0] = !val;
    
    if(data_r[2]>data_l[2]){
        if(data_r[2]>data_l[1]){   
            return data_r[0]/6*12*12 + (data_r[0]%6)*12 + data_l[0]/6+6;
        }else{
            return data_r[0]/6*12*12 +(data_l[0]/6+6)*12+ data_r[0]%6;
        }
    }else{
        if(data_l[2]>data_r[1]){   
            return (data_l[0]/6+6)*12*12 + (data_l[0]%6+6)*12 + data_r[0]/6;
        }else{
            return (data_l[0]/6+6)*12*12 +(data_r[0]/6)*12+ (data_l[0]%6+6);
        }
        
    }
    
}

uint8_t IrReceiveS(){
    /*単純解析版 一番大きい位置だけ返す
    
    Slave側はIRを要求した場合IRのみを返してくるとする.
    irは値が大きいほうが近いと仮定する
    
    
    */
    char data_r[3],data_l[3];
    bool val;
    Sensor.write(READ_IR);//一斉送信のつもり//コンパスへの影響はどのくらいですか
    
    val = Sensor.read(ADDRESS_R|1, data_r, 3);// IRデータを受信
    Led[0] = val;
    wait_ms(5);
    val = Sensor.read(ADDRESS_L|1, data_l, 3);
    Led[0] = !val;

    if(data_r[2]>data_l[2]){   
        return data_r[0]/6;
    
    }else{
        return data_l[0]/6+6;
    }
    
}
uint8_t IrReceiveM(){
    /*値解析版 一番大きい場所の値を返す(位置はとりあえずない)
    Slave側はIRを要求した場合IRのみを返してくるとする.
    irは値が大きいほうが近いと仮定する
    
    
    */
    char data_r[3],data_l[3];
    bool val;
    Sensor.write(READ_IR);//一斉送信のつもり//コンパスへの影響はどのくらいですか
    
    val = Sensor.read(ADDRESS_R|1, data_r, 3);// IRデータを受信
    Led[0] = val;
    wait_ms(5);
    val = Sensor.read(ADDRESS_L|1, data_l, 3);
    Led[0] = !val;

    if(data_r[2]>data_l[2]){       
        return data_r[1];
        
    }else{ 
        return data_l[1];
        
    }
    
}
unsigned int IrReceiveSM(){
    /*値解析版 一番大きい値とその位置を返す
    Slave側はIRを要求した場合IRのみを返してくるとする.
    irは値が大きいほうが近いと仮定する
    
    
    */
    char data_r[3],data_l[3];
    bool val;
    Sensor.write(READ_IR);//一斉送信のつもり//コンパスへの影響はどのくらいですか
    
    val = Sensor.read(ADDRESS_R|1, data_r, 3);// IRデータを受信
    Led[0] = val;
    wait_ms(5);
    val = Sensor.read(ADDRESS_L|1, data_l, 3);
    Led[0] = !val;

    if(data_r[2]>data_l[2]){       
        return data_r[0]/6<<8 + data_r[1];
        
    }else{ 
        return ((data_l[0]/6)+6) <<8 + data_l[1];
        
    }
    
}
uint8_t  LineReceive(){
    //先に要求しない場合はLineの状況を送信すること.//4bit //前ー右ー後ろー左 
    char data_r[2],data_l[2];
    bool val;
    //example val = slave.read(address,data,length,repeat);
    val = Sensor.read(ADDRESS_R|1, data_r, 1);
    Led[1] = val;
    wait_ms(5);
    val = Sensor.read(ADDRESS_L|1, data_l, 1);
    Led[1] = !val;
    
    
    return data_r[0]<<2 + data_l[0];
    

}


void PingReceiveRL(char ping[]){//ping[0]==Right,ping[1]==Left
    char pingdata[1] = {READ_PING};
    bool val;
    val = Sensor.write(ADDRESS_R|0,pingdata , 1);
    Led[2] = val;
    val = Sensor.read(ADDRESS_R|1, ping, 2);
    Led[2] = !val;
    
                

    
}
void rotate(unsigned int times, bool dir){
    /*
     *回転速度,回転方向,回転角度等設定変更ののち回転.
     *
     */
     
     
     
         
    
}

void move(int vr, int vl){
    double pwm[4] = {0};
    uint8_t i = 0;
    pwm[0] = vr/10.0;
    pwm[1] = vl/10.0;
    pwm[2] = 0;
    pwm[3] = 0;

    for(i = 0; i < 4; i++){
            if(pwm[i] > 100){
                pwm[i] = 100;
            }else if(pwm[i] < -100){
                pwm[i] = -100;
            }
        speed[i] = pwm[i];
    }
}

void ControlRobo0(int *CompassDef)//LeftFront
{}
void ControlRobo1(int *CompassDef)//Front
{
/*前にボールがある場合の動作*/
    int Compass;
    char Ping[2];
    uint8_t Line,LineIr;
    unsigned int IrNumMax; 
    
    Compass = ((hmc6352.sample() / 10) + 540 - *CompassDef) % 360;
    if(!((Compass>=150)&&(Compass<=210))){
        while(!((Compass>=150)&&(Compass<=210))){
            move(20,-20);//適当な回転。
            Compass = ((hmc6352.sample() / 10) + 540 - *CompassDef) % 360;
        }
        return;
    }
    if(IrReceiveM()<=150){//適当な150
        /*ステッピングを正面に設定*/
        /*busy_wait()*/
        /*モーターを前進*/
        return;
    }
    PingReceiveRL(Ping);
    if((Ping[0]>90)&&(Ping[1]>40)){//数値は適当
        /*ステッピングを少しだけ傾ける*/
        /*モーターを左右差つけて回す(ロボットは少し傾く)*/
        /*busy_wait()*/
        /*モーターを前進*/
        while(1){
            Line = LineReceive();
        
            if(Line){ //ラインを検知していないか
                LineIr = Line & (IrReceiveS()/3 + 1);//計算により方位を合わせる。
                while(LineIr){
                    move(0,0);//
                    Led[1] = Led[2] = Led[3] = 1;  
                
                    LineIr = LineReceive() & (IrReceiveS()/3 + 1);
                }
                Led[1] = Led[2] = Led[3] = 0;
                
                Compass = ((hmc6352.sample() / 10) + 540 - *CompassDef) % 360;
                while(!((Compass>=150)&&(Compass<=210))){
                    move(20,-20);//適当な回転。
                    Compass = ((hmc6352.sample() / 10) + 540 - *CompassDef) % 360;
                }
                return;
            }
            Kick = 1;
            wait_ms(200);
            Kick = 0;
            
            IrNumMax = IrReceiveSM();//位置と大きさ
            
            if(!((IrNumMax&0x00)>>8) == 1){//この1はボールの関数の1を表す.
                Compass = ((hmc6352.sample() / 10) + 540 - *CompassDef) % 360;
                while(!((Compass>=150)&&(Compass<=210))){
                    move(20,-20);//適当な回転。
                    Compass = ((hmc6352.sample() / 10) + 540 - *CompassDef) % 360;
                }
                return;
            }    
            
            if((IrNumMax&0x00FF)<150){
                Compass = ((hmc6352.sample() / 10) + 540 - *CompassDef) % 360;
                while(!((Compass>=150)&&(Compass<=210))){
                    move(20,-20);//適当な回転。
                    Compass = ((hmc6352.sample() / 10) + 540 - *CompassDef) % 360;
                }
                return;
            }                    
            
        }
        
    }else if((Ping[0]>40)&&(Ping[1]>90)){
        
    }else{
        
    }
        
}
void ControlRobo2(int *CompassDef)//RightFront
{
    



}
void ControlRobo3(int *CompassDef)//RightFront
{}
void ControlRobo4(int *CompassDef)//Right
{
    


}
void ControlRobo5(int *CompassDef)//RightBack
{}
void ControlRobo6(int *CompassDef)//BackRight
{}
void ControlRobo7(int *CompassDef)//Back
{}
void ControlRobo8(int *CompassDef)//BackLeft
{}
void ControlRobo9(int *CompassDef)//LeftBack
{}
void ControlRobo10(int *CompassDef)//Left
{}
void ControlRobo11(int *CompassDef)//LeftFront
{}
void GoHome(int *CompassDef)//Ball is not found.
{}




//通信(モータ用)
void tx_motor(){
    array(speed[0],speed[1],speed[3],speed[2]);
    Motor.printf("%s",StringFIN.c_str());
}

void SetUp(int *compass_def){
    /*初期化*/
    int Compass;
    Kick = 0;
    DebugSw[0].mode(PullUp);
    DebugSw[1].mode(PullUp);
    DebugSw[2].mode(PullUp);
    DebugSw[3].mode(PullUp);
    Motor.baud(115200);                             //ボーレート設定
    Motor.printf("1F0002F0003F0004F000\r\n");       //モータ停止
    Motor.attach(&tx_motor,Serial::TxIrq);          //送信空き割り込み(モータ用)
    move(0,0);//停止

    Step.Resets();
    Step.ReleseSW(0,1);//記憶がない

    hmc6352.setOpMode(HMC6352_CONTINUOUS, 1, 20);
    *compass_def = (hmc6352.sample() / 10);
    
    Compass = ((hmc6352.sample() / 10) + 540 - *compass_def) % 360;
    /*前を向くように設定をするべき*/
    Lcd.cls();
    
    /*初期化終了*/
    
    
}
void StartLoop(){
    /*
     *スイッチが押されるまでロボットはスタートしない.
     *
     *待っている間にほかのスイッチが押された場合は押されている間その動作をする等.
     *
     *
     */
    
}
int main() {
    
    /*Ir*/
    uint8_t IrNum;//場所によるirの数を表したもの0~11まではボールがある状態12はボールがない状態
    
    /*Line*/
    uint8_t Line;
    
    /*Compass*/
    int CompassDef = 0, Compass = 0;
    
    /*State */ 
    //Direction LineIr = NA;//方位設定奴...エラーでてめんどくさいので後でまたやることにする。
    uint8_t LineIr = NA;
    
    
    
    /*関数ポインタ*/
    void (*ControlRobo[13])(int *);//irの位置による分岐
    ControlRobo[0] = ControlRobo0;
    ControlRobo[1] = ControlRobo1;
    ControlRobo[2] = ControlRobo2;
    ControlRobo[3] = ControlRobo3;
    ControlRobo[4] = ControlRobo4;
    ControlRobo[5] = ControlRobo5;
    ControlRobo[6] = ControlRobo6;
    ControlRobo[7] = ControlRobo7;
    ControlRobo[8] = ControlRobo8;
    ControlRobo[9] = ControlRobo9;
    ControlRobo[10] = ControlRobo10;
    ControlRobo[11] = ControlRobo11;
    ControlRobo[12] = GoHome;
    
    
    SetUp(&CompassDef);
    
    StartLoop();
    
    while(1) {
        
        Line = LineReceive();
        
        if(Line){ //ラインを検知していないか
            LineIr = Line & (IrReceiveS()/3 + 1);//計算により方位を合わせる。
            while(LineIr){
                move(0,0);//
                Led[1] = Led[2] = Led[3] = 1;  
                
                LineIr = LineReceive() & (IrReceiveS()/3 + 1);
            }
            Led[1] = Led[2] = Led[3] = 0;
            continue;
        
        }
        
        if(Step.BusyCheck()){//ステッピングが動いていないか
            continue;
            
        }
        
        IrNum = IrReceiveS();
        
        (*ControlRobo[IrNum])(&CompassDef);//irの位置によったループ等の処理に移る。
        
        //wait_ms(0);
        
    }
}