main

Dependencies:   TextLCD mbed PID

main.cpp

Committer:
com3
Date:
2014-03-17
Revision:
5:6604ec9044a0
Parent:
4:536cd493a337

File content as of revision 5:6604ec9044a0:

#include "mbed.h"
#include "TextLCD.h"
#include "PID.h"
#include "common.h"
#include <math.h>
#include <sstream>

#define MOTOR_P 35
#define HOME_P 30
#define TURN_P 20
#define BALL_P 25
#define NO_BALL 45
#define LINE_P 30
#define LINE_PLR 17
#define LINE_ON 0x2710  //10000
#define LINE_TIME 0.6
#define LINE_PING 40
#define R 1.0
#define S_MAX 5
#define S1 15
#define S2 10
#define S3 5
#define RATE 0.05
#define P_GAIN 1.7
#define I_GAIN 0.0
#define D_GAIN 0.013
#define HOME_BACK 30
#define HOME 1
#define KICK 25
#define GOAL 30.0
#define PING_LR 100
#define BALL_FAR 43
#define BALL_NEAR 40

DigitalIn sw_wh(p5);
DigitalIn start(p7);
DigitalOut myled[4] = {LED1, LED2, LED3, LED4};
Serial motor(p9,p10);
Serial sensor(p13,p14);
Serial xbee(p28,p27);
Serial pc(USBTX, USBRX);
TextLCD lcd(p26, p25, p24, p23, p22, p21);
AnalogIn adcline[4] = {p16, p17, p19, p20};
PID pid(P_GAIN,I_GAIN,D_GAIN, RATE);
Timeout liner_F;
Timeout liner_L;
Timeout liner_B;
Timeout liner_R;
Ticker pidupdata;
Ticker xbeetx;
Ticker xbeerx;
//HMC6352 dcompass(p9,p10);

extern string StringFIN;
extern void array(int,int,int,int);
extern void xbee_tx(void);
extern void xbee_rx(void);
extern void micon_rx(void);

//uint16_t  analogHex[4] = {0};
int speed[4] = {0};
uint8_t value_ir = 0, ir_num = 0, ir_dis = 0, ball_on = 0;
uint8_t ping[4] = {0};
uint8_t line[4] = {0}, line_stop[4] = {0}, line_ping[4] = {0};
uint8_t kick = 0;
//uint8_t robot_state = 0;
int compass = 0;
int x = 0, y = 0, s = 0, i = 0, line_on = 0;
int compassdef = 0, data = 0;
uint8_t pingdef[4] = {0};

double pidinput = 180.0;
double compasspid = 0.0;
double goal = 0.0;

double way[10][2] = {
    { 0    , 1    },    //FF
    {-0.707, 0.707},    //FL
    {-1    , 0    },    //LL
    {-0.707,-0.707},    //BL
    { 0    ,-1    },    //BB
    { 0.707,-0.707},    //BR
    { 1    , 0    },    //RR
    { 0.707, 0.707},    //FR
    {-0.500, 0.866},    //FFL
    { 0.500, 0.866}     //FFR
};
double ball_way[12][2] = {
    { 0.0  , 1.0  },    //FF
    {-0.866,-0.500},    //FL
    {-0.342,-0.940},    //LL
    { 0.342,-0.940},    //BL
    { 0.966, 0.259},    //BB
    {-0.342,-0.940},    //BR
    { 0.342,-0.940},    //RR
    { 0.985,-0.173},    //FR
    {-0.985, 0.174},    //FFL
    { 0.985, 0.174},    //FFR
    {-0.173, 0.985},    //FFFL
    { 0.173, 0.985}     //FFFR
};

void move(int vx, int vy, int vs){
    double pwm[4] = {0};
    
    pwm[0] = (double)((vx) + vs);
    pwm[1] = (double)((-0.5 * vx) + ((sqrt(3.0) / 2.0)  * vy) + vs);
    pwm[2] = (double)((-0.5 * vx) + ((-sqrt(3.0) / 2.0) * vy) + vs);
    pwm[3] = kick;

    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 tx_motor(){
    array(speed[0],speed[1],speed[3],speed[2]);
    motor.printf("%s",StringFIN.c_str());
}

//ライン判断
void line_state(){    
    if(line[LEFT]){
        x = LINE_P;
    } else if(line[RIGHT]){
        x = -LINE_P;
    }
        
    if(line[FRONT]){
        if(line[LEFT] | line[RIGHT]){
            y = -LINE_PLR;
        } else {
            y = -LINE_P;
        }
    } else if(line[BACK]){
        if(line[LEFT] | line[RIGHT]){
            y = LINE_PLR;
        } else {
            y = LINE_P;
        }
    }
}

void line_stop_F(){
    line_stop[FRONT] = 0;
}
void line_stop_L(){
    line_stop[LEFT] = 0;
}
void line_stop_B(){
    line_stop[BACK] = 0;
}
void line_stop_R(){
    line_stop[RIGHT] = 0;
}

void line_check()
{
    if(!line_stop[FRONT]){
        if(adcline[FRONT].read_u16() > LINE_ON){
            line[FRONT] = 1;
            line_stop[FRONT] = 1;
            line_stop[BACK] = 1;
            //line_ping[FRONT] = 1;
            myled[0] = 1;
            liner_F.attach(&line_stop_F,LINE_TIME);
            liner_B.attach(&line_stop_B,LINE_TIME);
        } else {
            line[FRONT] = 0;
            myled[0] = 0;
        }
    }
    if(!line_stop[LEFT]){
        if(adcline[LEFT].read_u16() > LINE_ON){
            line[LEFT] = 1;
            line_stop[LEFT] = 1;
            line_stop[RIGHT] = 1;
            //line_ping[LEFT] = 1;
            myled[1] = 1;
            liner_L.attach(&line_stop_L,LINE_TIME);
            liner_R.attach(&line_stop_R,LINE_TIME);
        } else {
            line[LEFT] = 0;
            myled[1] = 0;
        }
    }
    if(!line_stop[BACK]){
        if(adcline[BACK].read_u16() > LINE_ON){
            line[BACK] = 1;
            line_stop[BACK] = 1;
            line_stop[FRONT] = 1;
            //line_ping[BACK] = 1;
            myled[2] = 1;
            liner_B.attach(&line_stop_B,LINE_TIME);
            liner_F.attach(&line_stop_F,LINE_TIME);
        } else {
            line[BACK] = 0;
            myled[2] = 0;
        }
    }
    if(!line_stop[RIGHT]){
        if(adcline[RIGHT].read_u16() > LINE_ON){
            line[RIGHT] = 1;
            line_stop[RIGHT] = 1;
            line_stop[LEFT] = 1;
            //line_ping[RIGHT] = 1;
            myled[3] = 1;
            liner_R.attach(&line_stop_R,LINE_TIME);
            liner_L.attach(&line_stop_L,LINE_TIME);
        } else {
            line[RIGHT] = 0;
            myled[3] = 0;
        }
    }
}


void pidupdate()
{
    //pid.setSetPoint(180.0 + goal);
    pidinput = compass;
    pid.setProcessValue(pidinput);
    
    compasspid = -pid.compute();
}

void home()
{
    x = 0;
    y = 0;
    kick = 0;
    goal = 0.0;
    
  //  if((145 < ping[LEFT]+ping[RIGHT]) && (ping[LEFT]+ping[RIGHT] < 155)){    
        if(ping[LEFT] > PING_LR){
            x = -HOME_P;
            y = -5;
        } else if(ping[RIGHT] > PING_LR){
            x = HOME_P;
            y = -5;
        }
  //  }

    if(ping[BACK] > HOME_BACK){
        y = -HOME_P;
    } else if(ping[BACK] < 5){
        y = HOME_P;
    }
}

int main() {
    
    //dcompass.setOpMode(HMC6352_CONTINUOUS, 1, 20);
    //uint8_t num = 0;
    uint8_t dir = 0, power = 0, lcd_count = 0;
    int x_ball = 0, x_turn = 0, y_ball = 0, y_turn = 0;
    
    wait(1);
    
    motor.baud(115200);                             //ボーレート設定
    motor.printf("1F0002F0003F0004F000\r\n");       //モータ停止
    motor.attach(&tx_motor,Serial::TxIrq);          //送信空き割り込み(モータ用)
    sensor.attach(&micon_rx,Serial::RxIrq);         //送信空き割り込み(センサ用)
    xbeerx.attach(&xbee_rx,5);
    xbeetx.attach(&xbee_tx,5);
    //compassdef = (compass / 10);           //コンパス初期値保存
    //compassdef = (dcompass.sample() / 10);
    pid.setInputLimits(0.0,360.0);
    pid.setOutputLimits(-30.0,30.0);
    pid.setBias(0.0);
    pid.setMode(AUTO_MODE);
    pid.setSetPoint(180.0);
    pidupdata.attach(&pidupdate, 0.05);
    
    sw_wh.mode(PullUp);
    start.mode(PullDown);
    
    lcd.cls();
    lcd.locate(0,0);
    lcd.printf("Chronograph");    
    
    
    //move(x,y,s);
    
    myled[0] = 1;
    
    //スタート前チェック
    while(!start){
        if(lcd_count == 0){
            lcd.locate(6,1);
            lcd.printf("%3d", compass);
        } else if(lcd_count == 1){
            lcd.locate(0,1);
            lcd.printf("ir_dis = %3d", ir_dis);
        } else if(lcd_count == 2){
            lcd.locate(0,0);
            lcd.printf("ir_num = %3d\nir_val = %3d", ir_num, value_ir);
        } else if(lcd_count == 3){
            lcd.locate(0,0);
            lcd.printf("F:%3d   B:%3d\nL:%3d   R:%3d", ping[FRONT], ping[BACK], ping[LEFT], ping[RIGHT]);
        } else if(lcd_count == 4){
            lcd.locate(0,0);
            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());
        }
        if(!sw_wh){
            lcd_count++;
            if(lcd_count == 5){
                lcd_count = 0;
                lcd.cls();
                lcd.locate(0,0);
                lcd.printf("Chronograph");
            }
            wait(0.5);
        }
        wait(0.1);
    }
    
    
    
    
    myled[0] = 0;
    lcd.cls();
    lcd.locate(0,0);
    lcd.printf("Chronograph");
    lcd.locate(7,1);
    lcd.printf("ABURASOBA");
    
    
    
    while(1){
        x = 0;
        y = 0;
        s = compasspid;        
        power = MOTOR_P;
        
        if((ir_dis < 35)/* && ( (ir_num == FF) || (ir_num == FFL) || (ir_num == FFR) )*/){
            kick = KICK;                
        } else {
            kick = 0;
            //goal = 0.0;
        }
        
        if((ir_num != FF) && (ir_num != FFL) && (ir_num != FFR)){
            if(ir_dis > BALL_FAR){
                x_turn = TURN_P * way[ir_num][0];
                y_turn = TURN_P * way[ir_num][1];
                
                x_ball = BALL_P * ball_way[ir_num][0];
                y_ball = BALL_P * ball_way[ir_num][1];
                
                if(ir_num == BB){
                    if(ping[LEFT] > ping[RIGHT]){
                        x_ball = -x_ball;
                    }
                }
                
                x = x_turn + x_ball;
                y = y_turn + y_ball;
                
            } else if(ir_dis < BALL_NEAR){
                x_turn = -(TURN_P - 5) * way[ir_num][0];
                y_turn = -(TURN_P - 5) * way[ir_num][1];
                
                x_ball = BALL_P * ball_way[ir_num][0];
                y_ball = BALL_P * ball_way[ir_num][1];
                
                if(ir_num == BB){
                    if(ping[LEFT] > ping[RIGHT]){
                        x_ball = -x_ball;
                    }
                }
                
                x = x_turn + x_ball;
                y = y_turn + y_ball;
                
            } else {
                if((ir_num == FL) || (ir_num == FR)){
                    power = 20;
                }
                x = power * ball_way[ir_num][0];
                y = power * ball_way[ir_num][1];
                if(ir_num == BB){
                    if(ping[LEFT] > ping[RIGHT]){
                        x = -x;
                    }
                }
            }
            
        } else {            
            if(ir_num == FF){
                power = MOTOR_P + 10;
            }
            x = power * ball_way[ir_num][0];
            y = power * ball_way[ir_num][1];
            
        }
       
        line_check();
        
        if((ir_num == NO_BALL)/* || (ball_on < 40)*/){
            home();
        }

        //x = 30; y = 10;
        line_state();
        
        if((x == 0) && (y == 0)){
            if(ping[BACK] > 25){
                y = -HOME_P;
            }
        }
        
        //x = 0; y = 0;
        
        move(x,y,s);
    }
    
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////    

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////    

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    while(1){
        
        x = 0;
        y = 0;
        s = compasspid;        
        power = MOTOR_P;
        
        if(/*(ir_dis < 60) && */( (ir_num == FF) || (ir_num == FFL) || (ir_num == FFR) )){
            //kick = 25;
            //if(130 < ping[LEFT]+ping[RIGHT]){
                //if(goal == 0){
                   /* if(ping[LEFT] > 100){
                        goal = -GOAL;
                    }*//* else if(ping[RIGHT] > 100){
                        //goal = GOAL;
                    }*/
                //}
            //}
                
        } else {
            kick = 0;
            goal = 0.0;
        }
        
        if((ir_dis > 130) && (ir_dis < 150) && (ir_num != BB) && (ir_num != FL) && (ir_num != FR) && (ir_num != BL) && (ir_num != BR)){
            x = power * way[ir_num][0];
            y = power * way[ir_num][1];
        } else {            
            if((ir_num == FF) || (ir_num == FFFL) || (ir_num == FFFR)){
                power = MOTOR_P + 10;
            } else if((ir_num == FFL) || (ir_num == FFR)){
                power = MOTOR_P;
            } else {
                power = MOTOR_P + 5;
            }
            x = power * ball_way[ir_num][0];
            y = power * ball_way[ir_num][1];
            if(ir_num == BB){
                if(ping[LEFT] > ping[RIGHT]){
                    x = -x;
                }
            }
        }
       
        line_check();
        
        if((ir_num == NO_BALL)/* || (ball_on < 40)*/){
            home();
        }

        //x = 30; y = 10;
        line_state();
        
        if((x == 0) && (y == 0)){
            if(ping[BACK] > 25){
                y = -HOME_P;
            }
        }
        
        //x = 0; y = 0;
        
        move(x,y,s);
    }
}