#nomenubar
#navi(NQC入門)

このページは作成中です

* task について [#u2b9500e]

複数のタスク(task)を扱うプログラムはすでにこれまでにも登場してきました
(例えば [[NQC入門/6. サウンド機能を使う]])。
タスクは、サブルーチンや関数と違って、そのタスクを開始した親のタスクとは独立に処理が実行されます (並列処理)。
ここで問題になるのが、複数のタスクが同時にモータやサウンド出力に命令を出した場合、いったいどちらのタスクが優先されるのか、ということです。
そのことをあまり考えずにプログラムを作成した場合、ロボットは不可解な動きをします。したがって、思い通りにロボットを動かすためには、モータへの命令が同時になされた場合にはどちらを優先すべきか、あらかじめプログラムに記述しておかなければなりません。以下では、そのための方法を説明します。

例として、ライントレースをしながら障害物に接触したら2秒間停止するロボットのプログラムを作成してみましょう。

以下の例では、センサ1とセンサ3に光センサ、センサ2にタッチセンサを取り付けて、2つの光センサが黒い線を跨いで走行するロボットを考えてみます。

* 優先順位の低いタスクを一旦止める [#r254fc8a]

 #define EYE_L SENSOR_1
 #define EYE_R SENSOR_3
 #define BUMPER SENSOR_2
 #define THRESHOLD 50
 
 task main() {
 
     SetSensor(EYE_L,SENSOR_LIGHT);
     SetSensor(EYE_R,SENSOR_LIGHT);
     SetSensor(BUMPER,SENSOR_TOUCH);
 
     while( true ) {
         start follow_line;     // ライントレースを開始
 
         until (BUMPER == 1);
         stop follow_line;      // 一旦 follow_line のタスクを停止
         Off(OUT_A+OUT_C); Wait(200);   // 2秒間停止
     }
 }
 
 task follow_line(){
     while (true) {
         if ((EYE_L >= THRESHOLD)&&(EYE_R >= THRESHOLD)) {
             OnFwd(OUT_A+OUT_C);
         } else if ((EYE_L >= THRESHOLD)&&(EYE_R <= THRESHOLD)) {
             OnFwd(OUT_A); OnRev(OUT_C);
         } else if ((EYE_L <= THRESHOLD)&&(EYE_R >= THRESHOLD)) {
             OnRev(OUT_A); OnFwd(OUT_C);
         } else {
             Off(OUT_A+OUT_C); Wait(100);
             OnFwd(OUT_A+OUT_C); Wait(20);
         }
         Wait(1);
     }
 }


* タスクの優先順位を指定する [#td75a235]

 #define EYE_L SENSOR_1
 #define EYE_R SENSOR_3
 #define BUMPER SENSOR_2
 #define THRESHOLD 50
 
 task main() {
 
     SetPriority(1);   // タスクの優先順位を0〜255で指定 (最大は0 最低は255)
 
     SetSensor(EYE_L,SENSOR_LIGHT);
     SetSensor(EYE_R,SENSOR_LIGHT);
     SetSensor(BUMPER,SENSOR_TOUCH);
 
     start follow_line;
 
     while( true ) {
         until (BUMPER == 1);
 
         // モータAとモータCのアクセス権を獲得する
 
         acquire(ACQUIRE_OUT_A+ACQUIRE_OUT_C){
             Off(OUT_A+OUT_C);
             Wait(200);
         }
     }
 }
 
 task follow_line(){
     SetPriority(2);   // タスクの優先順位を main より下げておく
 
     while (true) {
         acquire(ACQUIRE_OUT_A+ACQUIRE_OUT_C) {  //
 
             if ((EYE_L >= THRESHOLD)&&(EYE_R >= THRESHOLD)) {
                 OnFwd(OUT_A+OUT_C);
             } else if ((EYE_L >= THRESHOLD)&&(EYE_R <= THRESHOLD)) {
                 OnFwd(OUT_A); OnRev(OUT_C);
             } else if ((EYE_L <= THRESHOLD)&&(EYE_R >= THRESHOLD)) {
                 OnRev(OUT_A); OnFwd(OUT_C);
             } else {
                 Off(OUT_A+OUT_C); Wait(100);
                 OnFwd(OUT_A+OUT_C); Wait(20);
             }
             Wait(1);
         }
     }
 }

#navi(NQC入門)

トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS