auto tracking car

Dependencies:   mbed-rtos mbed

main.cpp

Committer:
kosakaLab
Date:
2016-06-14
Revision:
0:2af3980d8cc8

File content as of revision 0:2af3980d8cc8:

//  Auto tracking car
//      ver. 160610 by Kosaka lab.
//
//  main.cpp: 優先度の異なるつぎのタイマー処理を生成。
//  優先度|    コールされる関数名|  サンプル時間[s]| 割込み方法| 用途
//  ---------------------------------------------------------
//  最高  |   timerTS0()| TS0| ハードウェアタイマー | 電流制御
//  2位  |   timerTS1()| TS1| RTOSタイマー   | 位置制御または速度制御
//  3位  |   timerTS2()| TS2| RTOSスレッド   | 不使用 (main()と同じ優先度)
//  4位  |   timerTS3()| TS3| RTOSスレッド   | データセーブ
//  最低  |   timerTS4()| TS4| RTOSスレッド   | PCモニタ表示
#include "mbed.h"   // mbedマイコンではstdio.hに相当
#include "rtos.h"   // リアルタイムOS用

#include "controller.h" // ブラシ付DCモータの位置制御器と電流制御器用


Serial pc2(USBTX, USBRX);               // PCのモニタ上のtera termに文字を表示する宣言
LocalFileSystem local("mbedUSBdrive");  // PCのmbed USB ディスク上にデータをセーブする宣言
Ticker TickerTimerTS0;          // タイマー割込みを宣言。1ms以下もOK。RTOSよりも優先度が高い
unsigned char   fTimerTS2ON=0, fTimerTS3ON=0, fTimerTS4ON=0;  // timerTS2, TS3, TS4のスタート・ストップ指定フラグ

void CallTimerTS2(void const *argument) {   // タイマーtimerTS2()をTS2ごとにコール make sampling time TS3 timer (priority 3: precision 4ms)
    int ms;             // [ms], 処理時間
    unsigned long c;    // カウンタ
    while (true) {      // 永遠に繰り返す
        c = _countTS0;          // timerTS0()によるカウント数cを記憶
        if( fTimerTS2ON ){  // タイマースタートフラグがオンのとき
            timerTS2();         // timerTS2()をTS2[s]ごとにコールする is called every TS2[s].
        }
        if( (ms=(int)(TS2*1000-(_countTS0-c)*TS0*1000))<=0 ){    ms=1;} // c記憶時点から今まで時間を計算してTS2から引く。それが負なら1msに設定
        Thread::wait(ms);   // while()内の処理がTS2[s]ごとに実行されるようにms[ms]待つ
    }
}
void CallTimerTS3(void const *argument) {   // タイマーtimerTS3()をTS3ごとにコール make sampling time TS3 timer (priority 3: precision 4ms)
    int ms;             // [ms], 処理時間
    unsigned long c;    // カウンタ
    while (true) {      // 永遠に繰り返す
        c = _countTS0;          // timerTS0()によるカウント数cを記憶
        if( fTimerTS3ON ){  // タイマースタートフラグがオンのとき
            timerTS3();         // timerTS3()をTS3[s]ごとにコールする is called every TS3[s].
        }
        if( (ms=(int)(TS3*1000-(_countTS0-c)*TS0*1000))<=0 ){    ms=1;} // c記憶時点から今まで時間を計算してTS3から引く。それが負なら1msに設定
        Thread::wait(ms);   // while()内の処理がTS3[s]ごとに実行されるようにms[ms]待つ
    }
}

void CallTimerTS4(void const *argument) {   // タイマーtimerTS4()をTS4ごとにコール make sampling time TS4 timer (priority 4: precision 4ms)
    int ms;             // [ms], 処理時間
    unsigned long c;    // カウンタ
    while (true) {      // 永遠に繰り返す
        c = _countTS0;          // timerTS0()によるカウント数cを記憶
        if( fTimerTS4ON ){  // タイマースタートフラグがオンのとき
            timerTS4();         // timerTS4()をTS4[s]ごとにコールする is called every TS4[s].
        }
        if( (ms=(int)(TS4*1000-(_countTS0-c)*TS0*1000))<=0 ){    ms=1;} // c記憶時点から今まで時間を計算してTS4から引く。それが負なら1msに設定
        Thread::wait(ms);   // while()内の処理がTS4[s]ごとに実行されるようにms[ms]待つ
    }
}

int main(){ // モータ制御プログラム本体:マイコン起動時に最初にコールされる
    unsigned short  i;
    FILE *fp = fopen("/mbedUSBdrive/data.csv", "w");    // PC上のmbed USB ディスクにデータをセーブするためにディスクをオープン
    RtosTimer RtosTimerTS1(timerTS1);                                 // timerTS1のためのRTOSタイマーを宣言
    Thread ThreadTimerTS3(CallTimerTS3, NULL, osPriorityBelowNormal); // timerTS3のためのRTOSスレッドを宣言
    Thread ThreadTimerTS4(CallTimerTS4, NULL, osPriorityLow);         // timerTS4のためのRTOSスレッドを宣言
// Priority of Thread (RtosTimer is osPriorityAboveNormal)
//  osPriorityIdle          = -3,          ///< priority: idle (lowest)--> then, mbed ERROR!!
//  osPriorityLow           = -2,          ///< priority: low
//  osPriorityBelowNormal   = -1,          ///< priority: below normal
//  osPriorityNormal        =  0,          ///< priority: normal (default)
//  osPriorityAboveNormal   = +1,          ///< priority: above normal
//  osPriorityHigh          = +2,          ///< priority: high 
//  osPriorityRealtime      = +3,          ///< priority: realtime (highest)
//  osPriorityError         =  0x84        ///< system cannot determine priority or thread has illegal priority

    init_parameters();  // モータの機器定数等の設定, 制御器の初期化

    // シミュレーション開始
    pc2.printf("Simulation start!!\r\n");   // PCのモニタ上のtera termに文字を表示
    // PWMとすべてのタイマーをスタートする
    TickerTimerTS0.attach(&timerTS0, TS0 );         // timerTS0スタート
    RtosTimerTS1.start((unsigned int)(TS1*1000.));  // timerTS1スタート
    fTimerTS3ON = 1;                                // timerTS3スタート
    fTimerTS4ON = 1;                                // timerTS4スタート

    while( (_countTS0*TS0) < TMAX ){    // 現在の時間tを見て、目標速度等を設定し、TMAX[s]に終了
        Thread::wait(1);    // 1ms待つ(待つ間にtimerTS3とtimerTS4が実行される)
    }
    // PWMとすべてのタイマーをストップする
//  stop_pwm();             // PWMストップ
    TickerTimerTS0.detach();// timerTS0ストップ
    RtosTimerTS1.stop();    // timerTS1ストップ
    fTimerTS3ON=0;          // timerTS3ストップ
    fTimerTS4ON=0;          // timerTS4ストップ

    // PC上のmbed USB ディスクにデータをセーブする
    for(i=0;i<N_DATA;i++){
        fprintf( fp, "%f, %f, %f, %f, %f\r\n", 
        data[i][0],data[i][1],data[i][2],data[i][3],data[i][4]);    // PCのmbed USB ディスク上にデータをセーブする
    }
    fclose( fp );       // PC上のmbed USB ディスクをリリース
    Thread::wait(100);  // セーブ完了まで待つ

    pc2.printf("Control completed!!\r\n\r\n");  // 制御実験終了をPCモニタ上に表示
}