Jawaban singkat; tidak, Anda benar-benar perlu melakukan sesuatu yang sedikit berbeda.
jawaban panjang yang tidak lengkap; Biarkan saya memberi Anda beberapa kode psuedo yang sesuai untuk robotC, yang menempatkan Anda di jalur yang lebih baik. Pertama, jangan gunakan tugas - ini BUKAN tugas robotC. Mereka dapat dibuat bekerja, mungkin, mungkin tidak (dan Anda perlu beberapa perubahan untuk mencoba).
// 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();
}
}
ada beberapa hal di sini; prioritas menjadi tidak relevan. Sebagus tampaknya memiliki tugas dalam robotC dengan prioritas, mereka bukan pilihan yang baik untuk implementasi subsumption dalam pengalaman saya. Untuk alasan seperti, prioritas tidak selalu dihormati, tugas tidak dapat terganggu (kadang-kadang) sehingga ketika acara prioritas yang lebih tinggi terjadi, itu tidak akan bereaksi seperti yang Anda harapkan, robotC hanya baru-baru ini menjadi peserta kembali, sehingga hal-hal seperti mengakses sensor dari lebih dari 1 tugas mungkin berisiko (masalah waktu I2C), dan dalam beberapa kasus tidak (sensor yang disurvei secara otomatis).
Anda dapat menambahkan implementasi prioritas Anda sendiri ke loop di atas saat Anda menyelesaikan pekerjaan, tetapi itu benar-benar tidak diperlukan untuk memulai.
Komentar Anda "// kotak penghalang" menggambarkan perilaku balistik. Itu agak sulit untuk diterapkan menggunakan multi-tasking. Loop sederhana yang saya gunakan membuatnya jauh lebih mudah, dan lebih baik untuk pemula / belajar.
Hal lain yang akan saya tinggalkan untuk Anda, adalah bahwa pelunasan sementara rapi dan sesuai untuk banyak hal, bukanlah cara yang baik untuk menerapkan apa yang lebih baik dilakukan secara tradisional. Memang bagian 'hindari' mungkin merupakan kandidat yang baik untuk disubsidi, tetapi sejujurnya tugas Anda yang lain harus disebut 'GoOnAboutYourBusiness'. Saya mengatakan ini karena Anda mungkin tidak ingin mengubah dari pencarian ke mengikuti dengan subsumption. Tangani mereka dengan loop pemrograman tradisional. Dengan sensor tunggal, - apakah cahaya yang dirasakan lebih gelap atau lebih terang dari pada putaran terakhir? jika semakin gelap (dengan asumsi garis hitam) terus berputar ke arah yang sama, jika semakin terang berbelok ke arah lain, jika tetap sama, lurus. Anda mungkin perlu menambahkan beberapa PID dan menggunakan kurva kemudi alih-alih hanya belok kiri dan kanan agar lebih halus.
Dan ya, banyak sensor membantu. http://www.mindsensors.com/ - yeah, itu saya dalam film saat ini (11/10/2012)
Perbarui: kode aktual
Saya akan mencoba ini sebentar lagi, tetapi ini mengkompilasi dan menggambarkan apa yang saya tulis di atas:
#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
, apakah itu prioritas tugas? Apakah 9 akan menjadi prioritas tertinggi? Dalam hal itu, bukankah seharusnyafind
memiliki prioritas lebih daritrack
? Padahal, kondisifind
danelse
kondisinyatrack
sama. Jadi, sebagai manusia, jika nilai sensor lebih besar dari ambang, apa yang akan Anda lakukan? Terus spiral atau putar untuk menyesuaikan garis?