ロボット プログラミングの経験 (私は Robot C を使用したことはありませんが) から、ロボットに 2 つ以上のセンサー反応を並行して実行させるには、1 つの反応だけを行う場合とは非常に異なる方法でプログラムを構成する必要があることがわかります。Robot C のチュートリアルでは、これについては説明していません。また、そのために必要な言語やライブラリ機能についても紹介していません。
この場合、光センサーが 1 秒間持続する LED のオン/オフ シーケンスをトリガーするようにし、バンプ センサーがモーター アクションをトリガーし、それらのセンサーが衝突しなくなるまで継続するようにします。
ここでの問題は、モーター制御の内部while
ループがスレッドをブロックしていることであり、ほとんどの場合、LED 制御ループの実行が妨げられています。同様に、LED 制御ループはスレッドを 7 秒間ブロックし、モーター制御ループの実行を遅らせます。
一般に、ロボット制御ループの各反復は、センサーを読み取り、出力コマンドを送信し、後で処理する必要がある状態を記憶してから、制御ループのすべての部分が各サイクルで実行されるように再度ループする必要があります (できるだけ頻繁に、または制御された速度)。while
センサーが変化するまで内部ループにとどまって制御フローをブロックしないでください。
最初のステップは、モーター制御ループのブロックを解除することです。
while (true) {
// Light sensor LED control code ...
// Bumper/motor control
if (SensorValue(bumpSwitch) == 1) {
startMotor(rightMotor, -55);
startMotor(leftMotor, -55);
} else if (SensorValue(bumpSwitch2) == 1){
startMotor(rightMotor, 55);
startMotor(leftMotor, 55);
} else {
stopMotor(rightMotor);
stopMotor(leftMotor);
}
}
これで、現在の LED 制御コードはまだwait(1)
7 回呼び出します。http://www.robotc.net/support/nxt/ROBOTC-for-Beginners/ によるとwait(1)
、1.0 秒待機するため、コードのこの部分の実行には現在 7 秒かかります。バンプスイッチをチェックするまでに長い時間がかかります。
さらに、コードでは LED をオフにしてから再びオンにするまでの間に大幅な遅延がないため、そのシーケンスが終了するまで LED がオフになっていることに実際には気付かないでしょう。
したがって、2 番目のステップは、LED 制御コードが制御ループをブロックしないように修正することです。基本的には 2 つのアプローチがあります (ロボット C が最初の選択肢をサポートしているかどうかはわかりませんが、より単純です):
- 光センサーがしきい値を超えていて、前の繰り返しでしきい値を下回っていた場合、つまり遷移したばかりの場合、スレッド (またはタスク) を開始 [または「フォーク」] して、LED オン/オフ ループを実行します。そのスレッドは 7 回ループする必要があります: {LED をオンにして
wait(1.0/14.0)
数秒、LED をオフにしてからwait(1.0/14.0)
数秒}。そうすれば、ループを 7 周するのに 7 * (1/14 + 1/14) = 1.0 秒かかります。これは、多くのプログラミング言語が整数演算で計算し、 を生成し、一方で浮動小数点演算を使用するため1.0/14.0
ではなく、そう書いたのです。ロボット C についてはわかりません。または、約 1/14 秒である 71 ミリ秒を待機するために使用できます。1/14
1/14
0
1.0/14.0
wait1Msec(71)
- 変数を使用して、フラッシュ LED ループのシーケンスを追跡します。メインループを一巡するたびに、
if
これらの変数をチェックするステートメントを使用して、フラッシュ LED サイクルの次のステップを実行し、それらの変数を更新します。手順は次のとおりです。初期状態で光センサーがしきい値を超えたときに LED をオンにし、1/14 秒後に LED をオフにし、1/14 秒になったときに LED をオンにします。後で ... これらの 14 のステップの後、追跡変数をオフにして初期状態に戻します。最も単純な追跡変数は、0 (初期状態) から 14 (最後の LED の「オフ」フェーズを実行する) までのカウンターと、最後の変更からのシステム クロックの値であり、クロックが 71 ミリ秒遅れていることを検出できます。それ。ステップ 14 が終了したら、0 に戻ります。追跡変数には、現在点滅しているかどうかを示す 3 つの個別の変数など、代替手段があります。
アプローチ #2 は、2 つのことを同時に行うのが難しいため、よりトリッキーです。(運転中にテキスト メッセージを送信することでマルチタスクができると考える人は、危険なほど間違っています。)
LED の点滅中にロボットがバンパー/モーター制御ループを実行する必要がない場合、つまり、LED の 1 秒間の点滅中にバンパーに反応しなくてもかまわない場合は、はるかに単純なアプローチが機能します。これらのバンパー センサーが、ロボットがテーブルの端から飛び出さないようにしている場合、1 秒間応答しないことは悪いニュースです。しかし、ロボットがライトを点滅させている間にバンパーを 1 秒間押しても問題ない場合、コードのライト センサー LED 部分は次のようになります。
while (true) {
// Light sensor LED control code
if (SensorValue(lightSensor) > 400) {
for (int i = 0; i < 7; ++i) {
turnLEDOn(ledGreen);
turnLEDOn(ledRed);
wait1Msec(71); // 1/14 second
turnLEDOff(ledGreen);
turnLEDOff(ledRed);
wait1Msec(71);
}
}
// Bumper/motor control code ...
}
これは、もう 1 つの簡単な仮定になります。1 秒間の LED 点滅ループが終了した後も光センサーがまだ明るい場合は、メイン制御ループで次の 1 秒間の点滅ループを実行しても問題ないということです。これはすぐに発生します。光センサーが明るい限り、LED は点滅し続け、モーターは 1 秒に 1 回だけバンパーをチェックします。これを修正するには、変数を使用して、光センサーがいつ暗から明に変わるかを把握します。