- 追加された行はこの色です。
- 削除された行はこの色です。
#nomenubar
#navi(NQC入門)
未完成です
このページは作成中です
* task について [#u2b9500e]
* モータをコントロールするのはどのtask? [#nfe8d16c]
複数のタスク(task)を扱うプログラムはすでにこれまでにも登場してきました
(例えば [[NQC入門/6. サウンド機能を使う]])。
タスクは、サブルーチンや関数と違って、そのタスクを開始した親のタスクとは独立に処理が実行されます (並列処理)。
ここで問題になるのが、複数のタスクが同時にモータやサウンド出力に命令を出した場合、いったいどちらのタスクが優先されるのか、ということです。
そのことをあまり考えずにプログラムを作成した場合、ロボットは不可解な動きをします。したがって、思い通りにロボットを動かすためには、モータへの命令が同時になされた場合にはどちらを優先すべきか、あらかじめプログラムに記述しておかなければなりません。以下では、そのための方法を説明します。
例として、ライントレースをしながら障害物に接触したら2秒間停止するロボットのプログラムを作成してみましょう。
以下の例では、センサ1とセンサ3に光センサ、センサ2にタッチセンサを取り付けて、2つの光センサが黒い線を跨いで走行するロボットを考えてみます。
** 優先順位の高い task から優先順位の低いタスクを一旦止める方法 [#c2c77e10]
* 優先順位の低いタスクを一旦止める [#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); PlaySound(0);
stop follow_line; // 一旦 follow_line のタスクを停止
Off(OUT_A+OUT_C); Wait(200); // 2秒停止
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);
}
}
** task の優先順位 (priority) を指定する方法 [#l5eec6d4]
* タスクの優先順位を指定する [#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); PlaySound(0);
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入門)