短い答え; 実際には、まったく異なることをする必要はありません。
長い不完全な答え。robotCに適した擬似コードをいくつか紹介します。これにより、より良い方法に進むことができます。まず、タスクを使用しないでください-これはrobotCタスクの目的ではありません。それらはおそらく動作するように作られているかもしれませんし、そうでないかもしれません(試してみるためにもかなりの数の変更が必要です)。
// global variables
int distance;
int light;
main() {
while (true) {
distance = read_distance;
light = read_light;
if (task1_wantsToRun())
task1_run();
if (task2_wantsToRun())
task2_run();
}
}
ここにはいくつかの事柄があります。優先度は無関係になります。robotCに優先度のあるタスクがあるように見えるので、私の経験では、包摂の実装には適していません。優先度が常に守られるとは限らない、タスクを中断できない(時々)などの理由により、優先度の高いイベントが発生した場合、期待どおりに反応しない、robotCが最近再入可能になったため、センサーへのアクセスなど2つ以上のタスクからは危険な場合があり(I2Cタイミングの問題)、場合によっては危険ではありません(自動的にポーリングされるセンサー)。
物事が機能するように、独自の優先度実装を上記のループに追加できますが、実際には開始に必要ありません。
あなたのコメント「// box the obstruction」は弾道の振る舞いを説明しています。これらは、マルチタスクを使用して実装するのが少し難しいです。私が使用した単純なループは、それをはるかに簡単にし、初心者/学習にとってより良いものにします。
私があなたに残しているもう1つのことは、包摂は多くのことに対してきちんとしていて適切である一方で、伝統的に行われている方法を実装するための良い方法ではないということです。実際、「回避」の部分は包摂の良い候補かもしれませんが、正直なところ、他のタスクは「GoOnAboutYourBusiness」と呼ばれるべきです。これは、おそらく検索から包摂を伴うフォローに変更したくないためです。従来のプログラミングループでそれらを処理します。単一のセンサーを使用した場合-感知された光は、最後のループよりも暗いですか、それとも明るいですか?暗くなった場合(黒い線を想定)、同じ方向に回転し続けます。明るくなった場合は、反対方向に回転します。同じままの場合は、直進します。スムーズにするために、左右に曲がるのではなく、PIDを追加してステアリングカーブを使用する必要があります。
そして、はい、複数のセンサーが役立ちます。http://www.mindsensors.com/- ええ、それは現在映画の中で私です(11/10/2012)
更新:実際のコード
私はしばらくしてこれを試しますが、コンパイルして上で書いたものを示しています:
#pragma config(Sensor, S1, S_LIGHT, sensorLightActive)
#pragma config(Sensor, S2, S_DISTANCE, sensorSONAR)
#pragma config(Motor, motorB, LEFT, tmotorNXT, PIDControl, encoder)
#pragma config(Motor, motorC, RIGHT, tmotorNXT, PIDControl, encoder)
//*!!Code automatically generated by 'ROBOTC' configuration wizard !!*//
int distance_value, light_value;
bool evade_wantsToRun()
{
return distance_value < 30;
}
void evade_task()
{
// full stop
motor[LEFT] = 0;
// evade the object ballistically (ie in full control)
// turn left, drive
nSyncedTurnRatio = 0;
motor[LEFT] = -20;
Sleep(500);
nSyncedTurnRatio = 100;
Sleep(1000);
// turn right, drive
nSyncedTurnRatio = 0;
motor[LEFT] = 20;
Sleep(500);
nSyncedTurnRatio = 100;
Sleep(1000);
// turn right, drive
nSyncedTurnRatio = 0;
motor[LEFT] = 20;
Sleep(500);
nSyncedTurnRatio = 100;
Sleep(1000);
// turn left, resume
nSyncedTurnRatio = 0;
motor[LEFT] = 20;
Sleep(500);
motor[LEFT] = 0;
}
///////////////////////////////
void TurnBySteer(int d)
{
// normalize -100 100 to 0 200
nSyncedTurnRatio = d + 100;
}
///////////////////////////////
typedef enum programPhase { starting, searching, following, finished };
programPhase phase = starting;
// these 'tasks' are called from a loop, thus do not need to loop themselves
void initialize()
{
nSyncedTurnRatio = 50;
nSyncedMotors = synchBC;
motor[LEFT] = 30; // start a spiral drive
phase = searching;
}
void search()
{
if (light_value < 24)
{
nSyncedTurnRatio = 100;
phase = following;
}
}
int lastLight = -1;
int currentSteer = 0;
void follow()
{
// if it is solid white we have lost the line and must stop
// if lightSensors detects dark, we are on line
// if it got lighter, we are going more off line
// if it got darker we are headed in a good direction, slow down turn in anticipation
// +++PID will be even smoother
if (light_value > 64)
{
motor[LEFT] = 0;
phase = finished;
return;
}
if (light_value < 24)
currentSteer = 0;
else if (light_value > lastLight)
currentSteer += sgn(currentSteer) * 1;
else // implied (light_value < lastLight)
currentSteer -= sgn(currentSteer) * 1;
TurnBySteer(currentSteer);
}
bool regularProcessing_wantsToRun()
{
return phase != finished;
}
void regularProcessing_task()
{
switch (phase)
{
case starting:
initialize();
break;
case searching:
search();
break;
case following:
follow();
}
}
task main()
{
// subsumption tasks in priority oder
while (true)
{
// read sensors once per loop
distance_value = SensorValue[S_DISTANCE];
light_value = SensorValue[S_LIGHT];
if (evade_wantsToRun())
evade_task();
if (regularProcessing_wantsToRun())
regularProcessing_task();
else
StopAllTasks();
EndTimeSlice(); // give others a chance, but make it as short as possible
}
}
StartTask
は、タスクの優先順位ですか?9が最優先されますか?その場合、find
よりも優先すべきではありませんtrack
か?実際、の状態find
とのelse
状態はtrack
同じです。それで、人間として、センサー値がしきい値よりも大きい場合、どうしますか?スパイラルに行くか、ラインを調整するために回転しますか?