For our Robot

Dependencies:   JY901 Make_Sequencer_3 PID PacketSerial QEI_simple SensorBar mbed

main.cpp

Committer:
sgrsn
Date:
2018-11-14
Revision:
0:08b48d8e6eab

File content as of revision 0:08b48d8e6eab:

#include "mbed.h"
#include "JY901.h"
#include "QEI.h"
#include "PID.h"
#include "SensorBar.h"
#include "pitches.h"
#include "PacketSerial.h"
#include "MakeSequencer.h"

// IIC Address
#define Arduino_Address 0x20<<1
#define SX1509_ADDRESS  0x3E<<1

// Arduino Register Map
#define TARGET_X 0x10
#define TARGET_Y 0x11
#define TARGET_Z 0x12
#define TARGET_R 0x13
#define TARGET_H 0x14
#define SERVO_ENABLE 0x20
#define SERVO_DELAY 0x21

//RaspberryPi Register Map
#define SENSOR_ENABLE 0x00
#define FRONT_OBJ_DISTANCE 0x01
#define FRONT_OBJ_POSITION 0x02
#define BACK_DISTANCE1 0x03
#define BACK_DISTANCE2 0x04
#define RIGHT_DISTANCE1 0x05
#define RIGHT_DISTANCE2 0x06
#define LEFT_DISTANCE1 0x07
#define LEFT_DISTANCE2 0x08


float pi = 3.14159265359;
float wheel_r = 38.0/2.0;   //接地エンコーダのオムニ
float wheel_x_g = 50.0;      //x軸接地エンコーダの重心からのずれ
float DEG_TO_RAD = pi / 180;
float RAD_TO_DEG = 180.0 / pi;

const int Gcode_size = 6;    //gコードの種類の数

I2C i2c(p28, p27);
Timer timer;
Timer timer2;
QEI RE[] = { QEI(p26, p25, 100, &timer), QEI(p23, p24, 100, &timer) };
SensorBar line(&i2c, SX1509_ADDRESS);
PwmOut buzzer(p21);
DigitalIn button(p12);
BusIn modeChange(p15, p16, p17);
BusOut LED(p18, p19, p20);
LocalFileSystem local("local");

int32_t Register[10] = {};
PacketSerial Raspi(USBTX, USBRX, Register, 115200);

PID pid_x(&timer);
PID pid_y(&timer);
PID pid_yaw(&timer);
JY901 jy901(&i2c, &timer2);

bool writeSomeData(char addr, char reg, int32_t data ,int size);

int PATH[1500][3] = {};
//int *PATH = new int[1000][3];
int makePath(int targetX, int targetY, int targetR, int x, int y, int angleZ);

void alarm(int n = 5);
void motorStop();
float sign(float val);

void robotGuide(FILE *fp)
{
    MakeSequencer code(fp);
    const int seq_size = code.getGcodeSize();
    int Gcode[Gcode_size] = {};
    int awayCode[Gcode_size] = {};
    int awayFlag = 0;   //0:awayなし, 1:awayあり, 2,前方に物体なし, 3:通過
    int objectSide = 0;
    int laserSW = 0;
    int laserSWFlag[2] = {};
    int deltaX = 0, deltaY = 0;
    code.getGcode(0, Gcode_size, Gcode);
    pid_x.setParameter(2.0, 0.57851);//(6.0, 0.57851);
    pid_y.setParameter(2.0, 0.58);//(2.0, 0.7155);
    pid_yaw.setParameter(7, 0.6579);
    float x = 0, y = 0, angleZ = 0;
    int objectX = 0, objectY = 2000;
    int seq = 0;
    int path = 0;
    int path_size = makePath(Gcode[seq], Gcode[seq], Gcode[2], x, y, angleZ);
    
    float vx = 0, vy = 0, vo = 0;
    
    while(seq < seq_size)
    {
        //自己位置推定
        angleZ = jy901.calculateAngleOnlyGyro();
        float dx = RE[0].getDisAngle() * DEG_TO_RAD * wheel_r;
        float dy = RE[1].getDisAngle() * DEG_TO_RAD * wheel_r;
        x += dx * cos(angleZ * DEG_TO_RAD) + dy * sin(-angleZ * DEG_TO_RAD);
        y += dy * cos(angleZ * DEG_TO_RAD) + dx * sin(angleZ * DEG_TO_RAD);
        
        //障害物相対位置取得
        objectX = Register[FRONT_OBJ_POSITION];
        objectY = Register[FRONT_OBJ_DISTANCE];
        
        //壁除外処理
        if( (y > 1000/* && angleZ < 10 && angleZ > -10*/) || (y < 500 && angleZ > 170 && angleZ < 190) )
        {
        }
        
        //障害物発見 
        else if(objectY < 250)
        {
            if(awayFlag != 1)
            {
                motorStop();
                wait_ms(500);
                alarm();
                //waitがあるのでジャイロのリセット
                jy901.reset();
                //一応pidもリセットしとく
                pid_x.reset();
                pid_y.reset();
                pid_yaw.reset();
                //経路の再作成
                //左側
                if(objectX*cos(angleZ*DEG_TO_RAD) > 0 && angleZ < 10 && angleZ > -10) deltaX = -100, objectSide = 3;
                //右側
                else if(objectX*cos(angleZ*DEG_TO_RAD) <= 0 && angleZ < 10 && angleZ > -10) deltaX = 100, objectSide = 2;
                awayCode[0] = x + deltaX;
                awayCode[1] = y;        //yは維持
                awayCode[2] = angleZ;   //角度も維持
                awayFlag = 1;
                path_size = makePath(awayCode[0], awayCode[1], Gcode[2], x, y, angleZ);
                path = 0;
            }
        }
        else if(awayFlag == 2)
        {
            deltaX = 0;
            //正方向
            if((Gcode[1]-y)*cos(angleZ*DEG_TO_RAD) > 0) deltaY = 100;
            //負方向
            if((Gcode[1]-y)*cos(angleZ*DEG_TO_RAD) < 0) deltaY = -100;
            awayCode[0] = x;
            awayCode[1] = Gcode[1];//y+deltaY;
            awayCode[2] = angleZ;   //角度も維持
            path_size = makePath(awayCode[0], awayCode[1], Gcode[2], x, y, angleZ);
            path = 0;
            awayFlag = 3;
        }
        //左側
        if(objectSide == 2)
        {
            if(Register[LEFT_DISTANCE1] < 200)
            {
                if(laserSWFlag[0] == 1)
                {
                    laserSW++;
                    laserSWFlag[0] = 0;
                }
            }
            else
            {
                laserSWFlag[0] = 1;
            }
            if(Register[LEFT_DISTANCE2] < 200)
            {
                if(laserSWFlag[1] == 1)
                {
                    laserSW++;
                    laserSWFlag[1] = 0;
                }
            }
            else
            {
                laserSWFlag[1] = 1;
            }
        }
        if(objectSide == 3)
        {
            if(Register[RIGHT_DISTANCE1] < 200)
            {
                if(laserSWFlag[0] == 1)
                {
                    laserSW++;
                    laserSWFlag[0] = 0;
                }
            }
            else
            {
                laserSWFlag[0] = 1;
            }
            if(Register[RIGHT_DISTANCE2] < 200)
            {
                if(laserSWFlag[1] == 1)
                {
                    laserSW++;
                    laserSWFlag[1] = 0;
                }
            }
            else
            {
                laserSWFlag[1] = 1;
            }
        }
        
        /*if(laserSW < 2 && awayFlag == 3)
        {
            awayFlag = 2;
        }*/
        /*if(laserSW >= 2 && awayFlag == 3)
        {
            laserSW = 0;
            awayCode[0] = Gcode[0];
            awayCode[1] = Gcode[1];        //yは維持
            awayCode[2] = angleZ;   //角度も維持
            awayFlag = 4;
            path_size = makePath(awayCode[0], awayCode[1], awayCode[2], x, y, angleZ);
        }*/
        if(laserSW >= 2 && awayFlag == 3)
        {
            laserSW = 0;
            awayCode[0] = x;
            awayCode[1] = y+200;
            awayCode[2] = angleZ;
            awayFlag = 4;
            path_size = makePath(awayCode[0], awayCode[1], awayCode[2], x, y, angleZ);
        }
        
        //目標位置取得
        int targetX = PATH[path][0];
        int targetY = PATH[path][1];
        int targetR = PATH[path][2];
        
        //経路更新
        path++;
        if(path >= path_size)path = path_size-1;
        
        //目標速度ベクトル計算
        float xd = targetX - x;
        float yd = targetY - y;
        float r = sqrt(xd*xd + yd*yd);
        float fai = atan2(yd, xd) - angleZ*DEG_TO_RAD;
        float target_dx = r*cos(fai);
        float target_dy = r*sin(fai);
        vx = pid_x.controlPID(target_dx, 0);
        vy = pid_y.controlPID(target_dy, 0);
        vo = pid_yaw.controlPID(targetR, angleZ);
        
        if(awayFlag == 1)
        {
            if(abs(awayCode[0]-x)<5 && abs(awayCode[1]-y)<5 && abs(awayCode[2]-angleZ)<2 && abs(vo)<2)
            {
                //車輪の停止(念のため5回)
                for(int _ = 0; _ < 5; _++)
                {
                    writeSomeData(Arduino_Address, TARGET_X, 0, 4);
                    wait_ms(1);
                    writeSomeData(Arduino_Address, TARGET_Y, 0, 4);
                    wait_ms(1);
                    writeSomeData(Arduino_Address, TARGET_R, 0, 4);
                    wait_ms(1);
                }
                awayFlag = 2;
                path_size = makePath(Gcode[0], Gcode[1], Gcode[2], x, y, angleZ);
                path = 0;
                
                //waitがあるのでジャイロのリセット
                jy901.reset();
                //一応pidもリセットしとく
                pid_x.reset();
                pid_y.reset();
                pid_yaw.reset();
            }
            else
            {
                writeSomeData(Arduino_Address, TARGET_X, vx, 4);
                writeSomeData(Arduino_Address, TARGET_Y, vy, 4);
                writeSomeData(Arduino_Address, TARGET_R, vo, 4);
            }
        }
        else if(awayFlag == 4)
        {
            if(abs(awayCode[0]-x)<5 && abs(awayCode[1]-y)<5 && abs(awayCode[2]-angleZ)<2 && abs(vo)<2)
            {
                //車輪の停止(念のため5回)
                motorStop();
                awayFlag = 0;
                path_size = makePath(Gcode[0], Gcode[1], Gcode[2], x, y, angleZ);
                path = 0;
                //waitがあるのでジャイロのリセット
                jy901.reset();
                //一応pidもリセットしとく
                pid_x.reset();
                pid_y.reset();
                pid_yaw.reset();
            }
            else
            {
                writeSomeData(Arduino_Address, TARGET_X, vx, 4);
                writeSomeData(Arduino_Address, TARGET_Y, vy, 4);
                writeSomeData(Arduino_Address, TARGET_R, vo, 4);
            }
        }
        
        else if(abs(Gcode[0]-x)<5 && abs(Gcode[1]-y)<5 && abs(Gcode[2]-angleZ)<2 && abs(vo)<2)
        {
            //車輪の停止(念のため5回)
            for(int _ = 0; _ < 5; _++)
            {
                writeSomeData(Arduino_Address, TARGET_X, 0, 4);
                wait_ms(1);
                writeSomeData(Arduino_Address, TARGET_Y, 0, 4);
                wait_ms(1);
                writeSomeData(Arduino_Address, TARGET_R, 0, 4);
                wait_ms(1);
            }
            
            //シーケンスを進める
            seq++;
            //Gコード取得
            code.getGcode(seq, Gcode_size, Gcode);
            //次の地点までのパスを作成
            path_size = makePath(Gcode[0], Gcode[1], Gcode[2], x, y, angleZ);
            //パスのリセット
            path = 0;
            
            //waitがあるのでジャイロのリセット
            jy901.reset();
            //一応pidもリセットしとく
            pid_x.reset();
            pid_y.reset();
            pid_yaw.reset();
        }
        else    //目標地点に到達していないとき
        {
            writeSomeData(Arduino_Address, TARGET_X, vx, 4);
            writeSomeData(Arduino_Address, TARGET_Y, vy, 4);
            writeSomeData(Arduino_Address, TARGET_R, vo, 4);
        }
        LED = seq;
    }
    LED = 7;
    motorStop();
    wait_ms(500);
}
void followMe()
{
    writeSomeData(Arduino_Address, TARGET_Z, 120, 4);
    writeSomeData(Arduino_Address, SERVO_ENABLE, 1, 4);
    wait_ms(1000);
    pid_x.setParameter(1.0, 0, 0);//(6.0, 0.57851);
    pid_y.setParameter(0.7, 0, 0);//(2.0, 0.7155);
    pid_yaw.setParameter(7, 0.6579);
    
    int path = 0;
    int path_size = 1;
    
    int modeAngle = 0;
    
    //
    int guideX = 0, guideY = 150;
    int targetX = 0;
    int targetY = 0;
    float angleZ = 0;
    float targetR = 0;
    float x = 0, y = 0;
    float vx = 0, vy = 0, vo = 0;
    
    int followMode = 0;
    
    pid_x.reset();
    pid_y.reset();
    pid_yaw.reset();
    while(1)
    {
        //自己位置推定
        angleZ = jy901.calculateAngleOnlyGyro();
        float dx = RE[0].getDisAngle() * DEG_TO_RAD * wheel_r;
        float dy = RE[1].getDisAngle() * DEG_TO_RAD * wheel_r;
        x += dx * cos(angleZ * DEG_TO_RAD) + dy * sin(-angleZ * DEG_TO_RAD);
        y += dy * cos(angleZ * DEG_TO_RAD) + dx * sin(angleZ * DEG_TO_RAD);
        
        //ガイドロボット相対位置取得
        guideX = Register[FRONT_OBJ_POSITION];
        guideY = Register[FRONT_OBJ_DISTANCE];
        
        if(y > 900 && followMode == 0)
        {
            followMode = 1;
        }
        if(followMode == 1)
        {
            pid_yaw.setParameter(1.5, 0, 0);
            targetR = atan2(double(-guideX), double(guideY))*RAD_TO_DEG;
            vx = 0;
            vy = pid_y.controlPID(guideY, 150);
            //vy = 0;
            vo = pid_yaw.controlPID(targetR, 0);
            if(angleZ > 40)
            {
                followMode = 2;
                modeAngle = 90;
            }
            else if(angleZ < -40)
            {
                followMode = 2;
                modeAngle = -90;
            }
        }
        if(followMode == 2)
        {
            path_size = makePath(x, 1300, modeAngle, x, y, angleZ);
            followMode = 3;
            pid_yaw.reset();
        }
        if(followMode == 3)
        {
            pid_yaw.setParameter(7, 0.6579);
            //経路更新
            path++;
            if(path >= path_size)path = path_size-1;
            targetX = PATH[path][0];
            targetY = PATH[path][1];
            targetR = PATH[path][2];
            vx = pid_x.controlPID(targetX, x);
            vy = pid_y.controlPID(targetY, y);
            vo = pid_yaw.controlPID(targetR, angleZ);
            if(y > 1280)
            {
                vx = 0;
                vy = 0;
                vo = 0;
                followMode = 4;
            }
        }
        if(followMode == 4 && x < -1200)
        {
            //followMode = 5;
        }
        if(followMode == 5)
        {
            pid_yaw.setParameter(1.5, 0, 0);
            targetR = atan2(double(-guideX), double(guideY))*RAD_TO_DEG;
            vx = 0;
            //vy = pid_y.controlPID(targetY, 150);
            vy = 0;
            vo = pid_yaw.controlPID(targetR, 0);
            if(angleZ > 130)
            {
                path_size = makePath(-1500, y, 180, x, y, angleZ);
                path = 0;
                followMode = 6;
                pid_yaw.reset();
            }
        }
        if(followMode == 6)
        {
            pid_yaw.setParameter(7, 0.6579);
            //経路更新
            path++;
            if(path >= path_size)path = path_size-1;
            targetX = PATH[path][0];
            targetY = PATH[path][1];
            targetR = PATH[path][2];
            vx = pid_x.controlPID(targetX, x);
            vy = pid_y.controlPID(targetY, y);
            vo = pid_yaw.controlPID(targetR, angleZ);
            if(x < -1450)
            {
                vx = 0;
                vy = 0;
                vo = 0;
                followMode = 7;
            }
        }
        if(guideY < 1)
        {
            vx = 0;
            vy = 0;
        }
        else if(followMode == 0 || followMode == 4 || followMode == 7)
        {
            //目標速度
            vx = pid_x.controlPID(guideX, 0);
            vy = pid_y.controlPID(guideY, 150);
            vo = pid_yaw.controlPID(targetR, angleZ);
        }
        
        writeSomeData(Arduino_Address, TARGET_X, vx, 4);
        writeSomeData(Arduino_Address, TARGET_Y, vy, 4);
        writeSomeData(Arduino_Address, TARGET_R, vo, 4);
        //wait_ms(30);
    }
}

void pickAndPlace(FILE *fp)
{  
    MakeSequencer code(fp);
    const int seq_size = code.getGcodeSize();
    int Gcode[Gcode_size] = {};
    code.getGcode(0, Gcode_size, Gcode);
    for(int i = 0; i < Gcode_size; i++)
        printf("%d, ", Gcode[i]);
    printf("\r\n");
    
    pid_x.setParameter(1.5, 0.57851);//(6.0, 0.57851);
    pid_y.setParameter(2.0, 0.58);//(2.0, 0.7155);
    pid_yaw.setParameter(7, 0.6579);
                               
    float angleZ = 0;
    float x = 0, y = 0;
    
    int linePos = line.getPosition();
    int last_linePos = linePos;
    int d_linePos = 0;
    
    int seq = 0;
    int path = 0;
    
    int targetZ = 0;
    int hand = 10;
    int last_targetZ = 0;
    int last_hand = 10;
    
    int controlFlag = 1;
    
    int path_size = makePath(Gcode[seq], Gcode[seq], Gcode[seq], x, y, angleZ);
    
    jy901.reset();
    pid_x.reset();
    pid_y.reset();
    pid_yaw.reset();
    
    float last_t_lineRead = 0;
    
    while(seq < seq_size)
    {
        //自己位置推定
        angleZ = jy901.calculateAngleOnlyGyro();
        float dx = RE[0].getDisAngle() * DEG_TO_RAD * wheel_r;
        float dy = RE[1].getDisAngle() * DEG_TO_RAD * wheel_r;
        x += dx * cos(angleZ * DEG_TO_RAD) + dy * sin(-angleZ * DEG_TO_RAD);
        y += dy * cos(angleZ * DEG_TO_RAD) + dx * sin(angleZ * DEG_TO_RAD);
        
        //printf("%f, %f\r\n", x, y);
        
        if(timer2.read() - last_t_lineRead > 0.100)
        {
            last_linePos = linePos;
            linePos = line.getPosition();
            d_linePos = linePos - last_linePos;
            last_t_lineRead = timer2.read();
        }
        
        //目標位置取得
        int targetX = PATH[path][0];
        int targetY = PATH[path][1];
        int targetR = PATH[path][2];
        //経路更新
        path++;
        if(path >= path_size)path = path_size-1;
        
        //目標速度ベクトル計算
        float xd = targetX - x;
        float yd = targetY - y;
        float r = sqrt(xd*xd + yd*yd);
        float fai = atan2(yd, xd) - angleZ*DEG_TO_RAD;
        float target_dx = r*cos(fai);
        float target_dy = r*sin(fai);
        float vx = pid_x.controlPID(target_dx, 0);
        float vy = pid_y.controlPID(target_dy, 0);
        float vo = pid_yaw.controlPID(targetR, angleZ);
        
        //printf("%f, %f, %f\r\n", x, y, angleZ);
        //printf("%f:%d, %f:%d, %f:%d\r\n", x, targetX, y, targetY, angleZ, targetR);
        //printf("%d, %d, %d\r\n", targetX, targetY, targetR);
        //printf("%f, %f, %f\r\n", vx, vy, vo);
        
        //目標地点に到達したときの処理
        //if(abs(Gcode[seq][0]-x)<5 && abs(Gcode[seq][1]-y)<5 && abs(Gcode[seq][2]-angleZ)<3)
        if(abs(Gcode[0]-x)<5 && abs(Gcode[1]-y)<5 && abs(Gcode[2]-angleZ)<10)
        {
            //車輪の停止(念のため5回)
            for(int _ = 0; _ < 1; _++)
            {
                writeSomeData(Arduino_Address, TARGET_X, 0, 4);
                wait_ms(1);
                writeSomeData(Arduino_Address, TARGET_Y, 0, 4);
                wait_ms(1);
                writeSomeData(Arduino_Address, TARGET_R, 0, 4);
                wait_ms(1);
            }
            
            last_targetZ = targetZ;
            last_hand = hand;
            targetZ = Gcode[3];
            hand = Gcode[4];
            
            if(Gcode[5] == 1)
            {
                alarm(3);
            }
            if(targetZ != last_targetZ)
            {
                printf("%d\r\n", targetZ);
                writeSomeData(Arduino_Address, TARGET_Z, targetZ, 4);
                writeSomeData(Arduino_Address, SERVO_ENABLE, 1, 4);
                controlFlag = 0;
                wait_ms(abs(targetZ-last_targetZ)*20);
            }
            if(hand != last_hand)
            {
                writeSomeData(Arduino_Address, TARGET_H, Gcode[4], 4);
                controlFlag = 0;
                wait_ms(1000);
            }
            
            //シーケンスを進める
            seq++;
            //Gコード取得
            code.getGcode(seq, Gcode_size, Gcode);
            for(int i = 0; i < Gcode_size; i++)
                printf("%d, ", Gcode[i]);
            printf("\r\n");
            //次の地点までのパスを作成
            path_size = makePath(Gcode[0], Gcode[1], Gcode[2], x, y, angleZ);
            //パスのリセット
            path = 0;
            
            //waitがあるのでジャイロのリセット
            jy901.reset();
            //一応pidもリセットしとく
            pid_x.reset();
            pid_y.reset();
            pid_yaw.reset(); 
        }
        else    //目標地点に到達していないとき
        {
            writeSomeData(Arduino_Address, TARGET_X, vx, 4);
            writeSomeData(Arduino_Address, TARGET_Y, vy, 4);
            writeSomeData(Arduino_Address, TARGET_R, vo, 4);
        }
    }
}

void xbeeControll()
{
    PacketSerial xbee(USBTX, USBRX, Register, 115200);
    
    while(1)
    {
    }
}

enum TASK
{
    ROBOT_GUIDE     = 6,    //110
    FOLLOW_ME       = 5,    //101
    PICK_AND_PLACE  = 3,    //011
    CONTROLL        = 7    //111
};

int main()
{
    for(int _ = 0; _ < 5; _++)
    {
        writeSomeData(Arduino_Address, TARGET_X, 0, 4);
        writeSomeData(Arduino_Address, TARGET_Y, 0, 4);
        writeSomeData(Arduino_Address, TARGET_R, 0, 4);
    }
    LED = 0;
    buzzer = 0;
    
    line.setBarStrobe();
    line.clearInvertBits();
    uint8_t returnStatus = line.begin();
    jy901.calibrateAll(5000);
    
    bool buttonFlag = 0;
    int buttonTime = 0;
    int mode = 1;
    int task = 0;
    alarm();
    while(1)
    {
        LED = mode;
        task = modeChange.read();
        //押してないとき
        if(button == 1)
        {
            if(timer.read()-buttonTime < 1.0 && buttonFlag == 0)
            {
                mode++;
                if(mode >= 5)mode = 0;
                wait_ms(300);
            }
            buttonFlag = 1;
            
        }
        //押したとき
        else
        {
            if(buttonFlag == 1)
            {
                buttonTime = timer.read();
            }
            if(timer.read()-buttonTime > 1.5)
            {
                //実行処理
                LED = 0;
                switch(task)
                {
                    case CONTROLL:
                        FILE *demofp = fopen( "/local/demo.txt", "r");
                        pickAndPlace(demofp);
                        fclose(demofp);
                        break;
                    case ROBOT_GUIDE:
                        FILE *robotfp;
                        switch(mode)
                        {
                            case 1:
                                robotfp = fopen( "/local/robot1.txt", "r");
                                break;
                            case 2:
                                robotfp = fopen( "/local/robot2.txt", "r");
                                break;
                            case 3:
                                robotfp = fopen( "/local/robot3.txt", "r");
                                break;
                            case 4:
                                robotfp = fopen( "/local/robot4.txt", "r");
                                break;
                        }
                        robotGuide(robotfp);
                        break;
                    case FOLLOW_ME:
                        followMe();
                        break;
                    case PICK_AND_PLACE:
                        
                        FILE *fp;
                        switch(mode)
                        {
                            case 1:
                                fp = fopen( "/local/guide1.txt", "r");
                                break;
                            case 2:
                                fp = fopen( "/local/guide2.txt", "r");
                                break;
                            case 3:
                                fp = fopen( "/local/guide3.txt", "r");
                                break;
                            case 4:
                                fp = fopen( "/local/guide4.txt", "r");
                                break;
                                
                            default:
                                fp = fopen( "/local/guide1.txt", "r");
                                break;
                        }
                        pickAndPlace(fp);
                        break;
                        
                    default:
                        alarm(2);
                        break;
                }
            }
            buttonFlag = 0;
        }
    }
}

bool writeSomeData(char addr, char reg, int32_t data ,int size)
{
    char tmp[2+size];
    tmp[0] = reg;
    tmp[1] = size;
    for(int i = 0; i < size; i++)
    {
        tmp[i+2] = (data >> (i*8)) & 0xFF;
    }
    //char DATA[2] = {reg,size};
    bool N = i2c.write(addr, tmp, 2+size);
    //N|= i2c.write(addr, tmp, size);
    return N;
}

int makePath(int targetX, int targetY, int targetR, int x, int y, int angleZ)
{
    int num = float( sqrt( double( abs(targetX-x)*abs(targetX-x) + abs(targetY-y)*abs(targetY-y) ) )+ abs(targetR-angleZ) ) / 1.0;   //1mm間隔
    //printf("num = %d\r\n", num);
    for(int i = 1; i <= num; i++)
    {
        float a = float(i) / num;
        PATH[i-1][0] = x + (float(targetX - x) * a);// * cos( last_angleZ*DEG_TO_RAD);
        PATH[i-1][1] = y + (float(targetY - y)* a);// * sin(-last_angleZ*DEG_TO_RAD);
        PATH[i-1][2] = angleZ + float(targetR - angleZ) * a;
    }
    if(num > 0)
    {
        PATH[num-1][0] = targetX;
        PATH[num-1][1] = targetY;
        PATH[num-1][2] = targetR;
    }
    else
    {
        PATH[0][0] = targetX;
        PATH[0][1] = targetY;
        PATH[0][2] = targetR;
        num = 1;
    }
    return num;
}

void alarm(int n)
{
    int frequency[] = {NOTE_G5, NOTE_C5, NOTE_E5, NOTE_AS5, NOTE_DS5};//, 1, NOTE_GS5, NOTE_CS5, NOTE_F5, NOTE_B5, NOTE_E5, 1};
    int beat[] = {16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
    for (int i = 0; i < n; i++)
    {
        buzzer.period(1.0 / frequency[i]);
        buzzer.write(0.5);
        wait(1.0 / beat[i]);
        buzzer.write(0);
        wait(0.05);
    }
    buzzer = 0;
}
void motorStop()
{
    for(int _ = 0; _ < 5; _++)
    {
        writeSomeData(Arduino_Address, TARGET_X, 0, 4);
        wait_ms(1);
        writeSomeData(Arduino_Address, TARGET_Y, 0, 4);
        wait_ms(1);
        writeSomeData(Arduino_Address, TARGET_R, 0, 4);
        wait_ms(1);
    }
}

float sign(float val)
{
    if(val > 0)
    {
        return 1.0;
    }
    else if(val < 0)
    {
        return -1.0;
    }
    else
    {
        return 0;
    }
}