Коротка відповідь; ні, вам дійсно не потрібно робити речі зовсім інакше.
довга неповна відповідь; Дозвольте дати вам код psuedo, відповідний 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 з пріоритетами, вони не є хорошим вибором для реалізації субсидії на моєму досвіді. З таких причин, як пріоритети не завжди виконуються, завдання не можна переривати (іноді), тому, коли трапляється подія з більш високим пріоритетом, вона не реагуватиме так, як ви очікували, роботC тільки нещодавно став повторним учасником, тому такі речі, як доступ до датчика з більш ніж 1 завдання може бути ризикованим (проблеми з I2C від часу), а в деяких випадках - немає (автоматично опитувані датчики).
Ви можете додати свою власну пріоритетну реалізацію до вищевказаного циклу, коли ви працюєте, але це дійсно не потрібно для запуску.
Ваш коментар "// поле перешкод" описує балістичну поведінку. Це трохи складно реалізувати, використовуючи багатозадачні завдання. Простий цикл, який я використовував, робить його набагато легшим та кращим для початківців / навчання.
Інша річ, з якою я вас залишу, - це те, що передбачення, будучи охайним і підходящим для багатьох речей, не є гарним способом реалізації того, що краще робити традиційно. Дійсно, частина «ухилення» може бути хорошим кандидатом на отримання субсидії, але, чесно кажучи, ваше інше завдання слід назвати «GoOn AboutYourBusiness». Я говорю це тому, що ви, мабуть, не хочете переходити від пошуку до наступного з підрахунком. Обробляйте з тими традиційними петлями програмування. З одним датчиком, - чи відчуття світла темніше чи світліше, ніж у останньому циклі? якщо він темніший (припускаючи чорну лінію), продовжуйте повертати той самий напрямок, якщо світліше повернути в інший бік, якщо він залишився колишнім, ідіть прямо. Вам, мабуть, потрібно додати деякий 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
однакові. Отже, як людина, якщо б значення датчика було більшим за поріг, що б ви зробили? Піти по спіралі чи повернути, щоб відрегулювати лінію?