Added one task

Dependencies:   mbed

Revision:
0:fb4269aa5fb4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri May 26 03:51:19 2017 +0000
@@ -0,0 +1,855 @@
+#include "mbed.h"
+
+#include "gpio.h"
+
+#include "robot.h"
+#include "GP2Y0E03.h"
+#include "MCP3208.h"
+#include "L3GD20.h"
+
+#define ERROR   (-1)
+#define SUCCESS 0
+
+//#define L3GD20_TEST
+//#define GP2Y0E03_TEST
+//#define MCP3208_TEST
+//#define LBR127_TEST
+
+/*---------RCサーボ制御用--------*/
+float servo_pulse = 0.001f;     //RCサーボパルス幅[s]
+uint32_t servo_state = 0;       //サーボピン状態
+/*-----------------------------*/
+
+/*-----------------ラインセンサ--------------------*/
+float line_pos[2] = {0.0f, 0.0f};
+uint32_t intersection = 0;          //交差点検知
+/*------------------------------------------------*/
+
+/*---------状態変数----------*/
+float v_tr = 0.0f;      //並進方向電圧, unit: V
+float theta = 0.0f;     //姿勢角, unit: degree
+
+float omega_d = 0.0f;   //目標角速度, unit: degree/s
+/*--------------------------*/
+
+/*-----------------------------*/
+float ts = 0.001f;                  //制御周期
+
+uint32_t sequence       = 0;       //タスク管理変数
+uint32_t error_seq      = 0xFF;        //エラーを起こしているタスク番号
+int32_t (*Task_Fptr[10])(void);     //タスク管理用関数ポインタ
+/*-----------------------------*/
+
+/*-----制御器-----*/
+PID_Struct trace_pid;   //ライントレース用
+PID_Struct gyro_pid;   //ジャイロによるオドメトリ用
+
+PID_Struct manual_control; //手動モータ制御用
+
+PID_Struct *current_pid_ptr;   //現在接続されている制御器
+/*----------------*/
+
+/*---------各タスク関数--------*/
+//ロボットの動作をシーケンシャルに記述する
+//各タスク関数内ではフィードバック制御則へのアクセス原則禁止
+int32_t Task0(void);   
+int32_t Task1(void);
+int32_t Task2(void);
+int32_t Task3(void);
+int32_t Task4(void);
+int32_t Task5(void);   
+int32_t Task6(void);
+int32_t Task7(void);
+int32_t Task8(void);
+int32_t Task9(void);
+/*---------------------------*/
+
+void Turn_90deg(int32_t);
+void Turn_180deg(int32_t);
+
+void Accelerate(float);
+void Decelerate();
+void Stop();
+
+int main() 
+{
+    uint32_t i;
+    
+    /*Peripheral initialization*/
+    //GPIO_Init();
+    
+    SPI_Init();
+    
+    /*-----各種デバイス初期化----*/
+    L3GD20_Init();
+    MCP3208_Init();
+    /*-------------------------*/
+    
+    /*------フィードバックコントローラ-------*/
+    PID_Struct_Init(&trace_pid, 1.1, 20.0, 0.0);
+    //PID_Struct_Init(&gyro_pid, 0.015, 0.0, 0.0);
+    PID_Struct_Init(&gyro_pid, 0.02, 0.0, 0.0);
+    current_pid_ptr = &manual_control;
+    /*-----------------------------------*/
+    
+    TIM_Init();     //タイマスタート
+    /*-------------------------*/
+    
+    /*-----関数ポインタ設定------*/
+    Task_Fptr[0] = Task0;
+    Task_Fptr[1] = Task1;
+    Task_Fptr[2] = Task2;
+    Task_Fptr[3] = Task3;
+    Task_Fptr[4] = Task4;
+    Task_Fptr[5] = Task5;
+    Task_Fptr[6] = Task6;
+    Task_Fptr[7] = Task7;
+    Task_Fptr[8] = Task8;
+    Task_Fptr[9] = Task9;
+    /*-------------------------*/
+    
+    
+    
+    
+    while(1)
+    {
+        if(Task_Fptr[sequence]() == ERROR)  //タスク呼び出し, エラーチェック
+        {
+            error_seq = sequence;       //エラーを起こしているタスク番号を取得
+        }
+    
+        sequence ++;
+        /*
+        if(sequence == 1)
+        {
+            sequence = 3;
+        }
+        */
+    }
+}
+
+int32_t Task0(void)
+{
+    /*
+    if()
+    {
+        return ERROR;   
+    }
+    */
+    
+    servo_pulse = 0.0021f;  //アームを折りたたむ
+    wait(0.5f);
+    
+    /*-----最下点までリフトを移動-----*/
+    Put_Vm_Lift(-0.8f);      //リフト下降
+    wait(2.0f);
+    Put_Vm_Lift(0.0f);      //リフト停止
+    /*-----------------------------*/
+    /*----リフトのリポジショニング----*/
+    Put_Vm_Lift(1.0f);      //リフト上昇(どん兵衛用)
+    wait(0.8f);
+    Put_Vm_Lift(0.0f);      //リフト停止
+    /*-----------------------------*/
+    
+    /*--------------------スタート待機-----------------------*/
+    while(ain_cup > 0.5f) //カップ検出センサが反応するまで待機
+    {
+        printf("cup = %f\n", (float)ain_cup);
+    }
+    
+    servo_pulse = 0.001f;  //アームを展開
+    wait(0.3f);
+    /*-----------------------------------------------------*/
+    /*
+    while(1)
+    {
+        HAL_Delay(10);
+        printf("pos = %f\n", line_pos[0]);
+    }
+    */
+    return 0;
+}
+
+int32_t Task1(void)
+{
+    uint32_t i;
+    float v = 0.0f;
+    
+    /*
+    if()
+    {
+        return ERROR;   
+    }
+    */
+    
+    /*-------------------ライントレース--------------------*/
+    current_pid_ptr = &trace_pid;   //制御器変更
+    Accelerate(2.0f);       //加速
+    
+    for(i = 0; i < 2; i ++)     //1-2回目の交差点はスキップ
+    {
+        while(!intersection)    //一回目の交差点検出はスキップ
+        {
+            printf("running...\n");   
+        }
+        while(intersection)    //一回目の交差点通過を待つ
+        {
+            printf("running...\n");   
+        }
+    }
+    /*-----------------------------------------------------*/
+    
+    return 0;
+}
+
+int32_t Task2(void)     //3本目の交差点を左折
+{
+    /*
+    if()
+    {
+        return ERROR;   
+    }
+    */
+    
+    while(!intersection)    //3回目の交差点検出まで直進
+    {
+        printf("running...\n");   
+    }
+    while(intersection)    //3回目の交差点通過を待つ
+    {
+        printf("running...\n");   
+    }
+    
+    wait(0.4f);
+    
+    Stop();         //停止
+    Turn_90deg(1);  //左90度旋回
+    
+    return 0;
+}
+
+int32_t Task3(void)     //横道を直進し、どん兵衛を回収、180度回転
+{
+    uint32_t i;
+    float v = 0.0f;
+    
+    /*
+    if()
+    {
+        return ERROR;   
+    }
+    */
+    
+    /*-------------------ライントレース--------------------*/
+    current_pid_ptr = &trace_pid;   //制御器変更
+    Accelerate(1.0f);       //加速
+    /*-----------------------------------------------------*/
+    
+    #if 0
+    //本来はここでカップを検出するまで前進する
+    wait(1.3f);
+    #endif
+    
+    #if 1
+    while(ain_cup > 0.6f) //カップ検出まで前進
+    {
+        printf("waiting...\n");
+    }
+    
+    wait(0.05f);
+    Stop();                 //停止
+    
+    servo_pulse = 0.0021f;  //カップ把持
+    wait(1.0f);
+    
+    Put_Vm_Lift(1.5f);      //リフト上昇
+    wait(0.8f);
+    Put_Vm_Lift(0.0f);      //リフト停止
+    #endif
+    
+    current_pid_ptr = &trace_pid;   //制御器変更
+    Accelerate(1.5f);       //加速
+    wait(0.5f);
+    Stop();                 //停止
+    
+    Turn_180deg(1); //左180度旋回
+    
+    return 0;
+}
+
+int32_t Task4(void) //カップ回収後、メインストリートに戻る
+{
+    uint32_t i;
+    float v = 0.0f;
+    
+    /*
+    if()
+    {
+        return ERROR;   
+    }
+    */
+    
+    /*-------------------ライントレース--------------------*/
+    current_pid_ptr = &trace_pid;   //制御器変更
+    Accelerate(1.5f);       //加速
+    /*-----------------------------------------------------*/
+    
+    while(!intersection)    //交差点検出まで直進
+    {
+        printf("running...\n");   
+    }
+    while(intersection)    //交差点通過を待つ
+    {
+        printf("running...\n");   
+    }
+    
+    wait(0.6f);
+    
+    Stop();
+    
+    Turn_90deg(1);  //左90度旋回
+
+    return 0;
+}
+
+int32_t Task5(void) //カップ回収後のメインストリート走行+カップ棚置き
+{
+    uint32_t i;
+    float v = 0.0f;
+    
+    /*
+    if()
+    {
+        return ERROR;   
+    }
+    */
+    /*-------------------ライントレース--------------------*/
+    current_pid_ptr = &trace_pid;   //制御器変更
+    Accelerate(2.0f);       //加速
+    /*-----------------------------------------------------*/
+    
+    while(ain_cup > 0.7f) //棚検出まで前進
+    {
+        printf("waiting...\n");
+    }
+    
+    Stop();
+    
+    servo_pulse = 0.001f;  //カップ解放
+    wait(0.5f);
+    
+    /*----------ジャイロを使って後退--------------*/
+    current_pid_ptr = &gyro_pid;   //制御器変更
+    Accelerate(-1.5f);       //加速
+    
+    wait(0.6f);
+    
+    Stop();
+    /*------------------------------------------*/
+    
+    Turn_180deg(1);  //左180度旋回
+    
+    /*-----最下点までリフトを移動-----*/
+    Put_Vm_Lift(-0.8f);      //リフト下降
+    wait(2.5f);
+    Put_Vm_Lift(0.0f);      //リフト停止
+    /*-----------------------------*/
+    /*----リフトのリポジショニング----*/
+    Put_Vm_Lift(1.0f);      //リフト上昇(UFO用)
+    wait(0.35f);
+    Put_Vm_Lift(0.0f);      //リフト停止
+    /*-----------------------------*/
+    
+    return 0;
+}
+
+int32_t Task6(void)     //4本目の交差点を棚側から左折
+{
+    
+    uint32_t i;
+    float v = 0;
+    /*
+    if()
+    {
+        return ERROR;   
+    }
+    */
+    
+    /*-------------------ライントレース--------------------*/
+    current_pid_ptr = &trace_pid;   //制御器変更
+    Accelerate(1.5f);       //加速
+    /*-----------------------------------------------------*/
+    
+    while(!intersection)    //交差点検出まで直進
+    {
+        printf("running...\n");   
+    }
+    while(intersection)    //交差点通過を待つ
+    {
+        printf("running...\n");   
+    }
+    
+    wait(0.6f);
+    
+    Stop();         //停止
+    Turn_90deg(1);  //左90度旋回
+    
+    return 0;
+}
+
+int32_t Task7(void)     //横道を直進し、UFOを回収、180度回転
+{
+    /*-------------------ライントレース--------------------*/
+    current_pid_ptr = &trace_pid;   //制御器変更
+    Accelerate(1.0f);       //加速
+    /*-----------------------------------------------------*/
+   
+    
+    while(ain_cup > 0.6f) //カップ検出まで前進
+    {
+        printf("waiting...\n");
+    }
+    
+    wait(0.05f);
+    Stop();                 //停止
+    
+    servo_pulse = 0.0021f;  //カップ把持
+    wait(1.0f);
+    
+    Put_Vm_Lift(1.5f);      //リフト上昇
+    wait(0.8f);
+    Put_Vm_Lift(0.0f);      //リフト停止
+    
+    
+    current_pid_ptr = &trace_pid;   //制御器変更
+    Accelerate(1.5f);       //加速
+    wait(0.5f);
+    Stop();                 //停止
+    
+    Turn_180deg(1); //左180度旋回
+}
+
+
+int32_t Task8(void)     //棚左側にUFOを置くために、位置合わせ
+{
+    uint32_t i;
+    float v = 0;
+    /*
+    if()
+    {
+        return ERROR;   
+    }
+    */
+    
+    /*-------------------ライントレース--------------------*/
+    current_pid_ptr = &trace_pid;   //制御器変更
+    Accelerate(1.5f);       //加速
+    /*-----------------------------------------------------*/
+    
+    /*---------------1回目の交差点-----------------*/
+    while(!intersection)    //交差点検出まで直進
+    {
+        printf("running...\n");   
+    }
+    while(intersection)    //交差点通過を待つ
+    {
+        printf("running...\n");   
+    }
+    
+    wait(2.5f); //棚左側とカップの位置を合わせるためのパラメータ
+    /*--------------------------------------------*/
+    
+    Stop();
+    Turn_90deg(-1); //右90度旋回
+    
+    return 0;
+}
+
+int32_t Task9(void)     //ジャイロを使って棚まで接近、UFOを置く
+{
+    uint32_t i;
+    float v = 0;
+    /*
+    if()
+    {
+        return ERROR;   
+    }
+    */
+    
+    /*----------ジャイロを使って前進--------------*/
+    current_pid_ptr = &gyro_pid;   //制御器変更
+    Accelerate(1.5f);       //加速
+    /*------------------------------------------*/
+    
+    while(ain_cup > 0.7f) //棚検出まで前進
+    {
+        printf("waiting...\n");
+    }
+    
+    Stop();
+    
+    servo_pulse = 0.001f;  //カップ解放
+    wait(0.5f);
+    
+    while(1)
+    {
+        printf("Tasks completed\n");
+    }
+    
+    
+    return 0;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#if 0
+
+int32_t Task8(void)     //棚左側にUFOを置くために、位置合わせ
+{
+    uint32_t i;
+    float v = 0;
+    /*
+    if()
+    {
+        return ERROR;   
+    }
+    */
+    
+    /*-------------------ライントレース--------------------*/
+    current_pid_ptr = &trace_pid;   //制御器変更
+    Accelerate(2.0f);       //加速
+    
+    for(i = 0; i < 3; i ++)     //1-3回目の交差点はスキップ
+    {
+        while(!intersection)    //一回目の交差点検出はスキップ
+        {
+            printf("running...\n");   
+        }
+        while(intersection)    //一回目の交差点通過を待つ
+        {
+            printf("running...\n");   
+        }
+    }
+    /*-----------------------------------------------------*/
+    
+    /*---------------4回目の交差点-----------------*/
+    while(!intersection)    //交差点検出まで直進
+    {
+        printf("running...\n");   
+    }
+    while(intersection)    //交差点通過を待つ
+    {
+        printf("running...\n");   
+    }
+    
+    wait(1.5f);
+    /*--------------------------------------------*/
+    
+    Stop();
+    
+    return 0;
+}
+
+int32_t Task9(void)
+{
+    uint32_t i;
+    float v = 0;
+    /*
+    if()
+    {
+        return ERROR;   
+    }
+    */
+    
+    while(1)
+    {
+        printf("Tasks completed\n");
+    }
+    
+    
+    return 0;
+}
+
+#endif
+
+void Turn_90deg(int32_t dir)
+{
+    uint32_t i;
+    float v = 0.0f;
+    float sign = 1.0f;
+    
+    if(dir == 1)    //回転方向
+    {
+        sign = 1.0f;
+    }
+    else if(dir == -1)
+    {
+        sign = -1.0f;
+    }
+    
+    theta = 0.0f;   //角度初期化
+    
+    /*--------台形加速(角度)---------*/
+    for(i = 0; i < 10; i ++)
+    {
+        v += 0.15f;
+        Put_Vm_L(-sign * v); //回転
+        Put_Vm_R(sign * v);
+        wait(0.05f);
+    }
+    /*-----------------------------*/
+
+    if(dir == 1)
+    { 
+        while(theta < 80.0f)
+        {
+            printf("Turning...\n");   
+        }
+    }
+    else if(dir == -1)
+    {
+        while(theta > -80.0f)
+        {
+            printf("Turning...\n");   
+        }
+    }
+    
+    Put_Vm_L(0.0f); //停止
+    Put_Vm_R(0.0f);
+    wait(0.5f);
+}
+
+void Turn_180deg(int32_t dir)
+{
+    uint32_t i;
+    float v = 0.0f;
+    float sign = 1.0f;
+    
+    if(dir == 1)    //回転方向
+    {
+        sign = 1.0f;
+    }
+    else if(dir == -1)
+    {
+        sign = -1.0f;
+    }
+    
+    theta = 0.0f;   //角度初期化
+    
+    /*--------台形加速(角度)---------*/
+    for(i = 0; i < 10; i ++)
+    {
+        v += 0.15f;
+        Put_Vm_L(-sign * v); //回転
+        Put_Vm_R(sign * v);
+        wait(0.05f);
+    }
+    /*-----------------------------*/
+
+    while(theta < 170.0f)
+    {
+        printf("Turning...\n");   
+    }
+    Put_Vm_L(0.0f); //停止
+    Put_Vm_R(0.0f);
+    wait(0.5f);
+}
+
+void Accelerate(float v_desired)    //v_desired[V]まで緩やかに加速
+{
+    uint32_t i;
+    float v = 0.0f;
+    float v_step = v_desired / 10.0f;   //単位速度
+
+    for(i = 0; i < 10; i ++)
+    {
+        v += v_step;
+        v_tr = v;
+        wait(0.05f);
+    }
+}
+
+void Decelerate()           //緩やかに減速、停止
+{
+    uint32_t i;
+    float v = 0.0f;
+    float v_step = -v_tr / 10.0f;
+
+    for(i = 0; i < 10; i ++)
+    {
+        v += v_step;
+        v_tr = v;
+        wait(0.05f);
+    }
+
+    v_tr = 0.0f;    //確実に停止
+    wait(0.1f);
+}
+
+void Stop()         //急激に減速、停止
+{
+    current_pid_ptr = &manual_control;  //制御OFF
+        Put_Vm_L(0.0f); 
+        Put_Vm_R(0.0f);
+        wait(0.5f);
+}
+
+void Flip1_Callback()       //RCサーボ制御用割り込み関数
+{
+    switch(servo_state)
+    {
+        case 0:
+            flipper1.attach(&Flip1_Callback, servo_pulse);
+            servo = 1;
+            servo_state ++;
+            break;
+        case 1:
+            flipper1.attach(&Flip1_Callback, 0.01f - servo_pulse);
+            servo = 0;
+            servo_state ++;
+            break;
+        default:
+            servo_state = 0;
+            break;
+    }
+}
+
+void Flip2_Callback()       //フィードバック制御用割り込み関数
+{
+    int32_t i;
+    uint32_t adres_max = 0;
+    uint32_t adres_min = 65535;  
+    uint32_t adres_mid = 0;
+    int32_t pos_int = 0;
+    
+    float omega = 0.0f;    //unit: deg/s
+    float vm_L, vm_R;       //unit: V
+    
+    /*-----------------センサ読み取り-----------------*/
+    //MCP3208_Read(0);
+    MCP3208_Read(1);
+    MCP3208_Read(2);
+    MCP3208_Read(3);
+    MCP3208_Read(4);
+    MCP3208_Read(5);
+    
+    L3GD20_Read();
+    /*-----------------------------------------------*/
+    
+    /*---------------最大最小値を求める----------------*/
+    for(i = 0; i < 5; i ++)
+    {
+        mcp3208.adres[i+1] = 4095 - mcp3208.adres[i+1];     //ADCの出力とラインの色に合わせて反転/非反転
+        
+        if(adres_min > mcp3208.adres[i+1])
+            adres_min = mcp3208.adres[i+1];
+        if(adres_max < mcp3208.adres[i+1])
+            adres_max = mcp3208.adres[i+1];
+    }        
+    
+    adres_mid = (adres_max + adres_min) / 2;
+    /*-----------------------------------------------*/
+    if(adres_max - adres_min > 200)
+    {
+        line_pos[0] = 0.0f;
+        for(i = 0; i < 5; i ++)
+        {
+            pos_int += (i+1)*(mcp3208.adres[i+1] - adres_min);
+        }
+        line_pos[0] = ((float)pos_int);
+        line_pos[0] = line_pos[0] / (mcp3208.adres[1]+mcp3208.adres[2]+mcp3208.adres[3]+mcp3208.adres[4]+mcp3208.adres[5]-5*adres_min) - 3.0f;
+    }   
+    else
+    {
+        line_pos[0] = 0.0f;
+    }
+    
+    /*-------------------交差点検出-------------------*/
+    if((mcp3208.adres[1] > adres_mid) && (mcp3208.adres[5] > adres_mid))
+    {
+        intersection = 1;
+    }
+    else if((mcp3208.adres[1] < adres_mid) && (mcp3208.adres[5] < adres_mid))
+    {
+        intersection = 0;
+    }
+    /*-----------------------------------------------*/
+    
+    /*---------------フィルタ----------------*/
+    
+    /*--------------------------------------*/
+    
+    /*-----------ジャイロ角速度取得-----------*/
+    omega = (float)l3gd20.z * 0.07f;
+    theta += omega * ts;
+    /*--------------------------------------*/
+    
+    /*------------------制御則-----------------*/
+    if(current_pid_ptr == &trace_pid)   //ライントレース
+    {
+        //vm_R = PD_Control(current_pid_ptr, omega, 10.0f * line_pos[0]);
+        vm_R = PD_Control(current_pid_ptr, -line_pos[0], 0.0f);
+        vm_L = -vm_R;
+        
+        vm_L += v_tr;
+        vm_R += v_tr;
+    }
+    else if(current_pid_ptr == &gyro_pid)
+    {
+        vm_R = PD_Control(current_pid_ptr, omega, omega_d);
+        vm_L = -vm_R;
+        
+        vm_L += v_tr;
+        vm_R += v_tr;
+    }
+    else
+    {
+        vm_L = 0.0f;
+        vm_R = 0.0f;
+    }
+    
+    if(current_pid_ptr == &manual_control)
+    {
+        //手動でモータ電圧を管理している場合
+    }
+    else
+    {
+        Put_Vm_L(vm_L); //モータへ電圧印加
+        Put_Vm_R(vm_R);
+    }
+    
+    /*----------------------------------------*/
+}
+
+void Flip3_Callback()       
+{
+    
+    
+    
+}
+
+void PinIntrrpt1_Callback()
+{
+    
+}
+
+void PinIntrrpt2_Callback()
+{
+    
+}
\ No newline at end of file