#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入門)