câu trả lời ngắn; không, bạn thực sự cần phải làm mọi thứ khá khác một chút.
câu trả lời dài không đầy đủ; Hãy để tôi cung cấp cho bạn một số mã psuedo thích hợp cho robotC, điều đó đưa bạn đến một con đường tốt hơn. Đầu tiên, không sử dụng các tác vụ - đây KHÔNG phải là nhiệm vụ của robotC dành cho. Chúng có thể được tạo ra để hoạt động, có thể, có thể không (và bạn cần khá nhiều thay đổi để thậm chí thử).
// 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();
}
}
Có một vài điều ở đây; ưu tiên trở nên không liên quan. Mặc dù có vẻ như có các nhiệm vụ trong robotC với các ưu tiên, nhưng chúng không phải là một lựa chọn tốt để thực hiện trợ cấp theo kinh nghiệm của tôi. Vì những lý do như, các ưu tiên không phải lúc nào cũng được tôn trọng, các nhiệm vụ không thể bị gián đoạn (đôi khi) vì vậy khi xảy ra sự kiện ưu tiên cao hơn, nó sẽ không phản ứng như bạn mong đợi, robotC chỉ mới được đăng ký lại, vì vậy những thứ như truy cập vào cảm biến từ hơn 1 nhiệm vụ có thể có rủi ro (vấn đề thời gian I2C) và trong một số trường hợp không phải là (cảm biến được thăm dò tự động).
Bạn có thể thêm triển khai ưu tiên của riêng mình vào vòng lặp ở trên khi bạn làm mọi thứ hoạt động, nhưng nó thực sự không cần thiết để bắt đầu.
Nhận xét của bạn "// hộp vật cản" mô tả hành vi đạn đạo. Đó là một chút khó khăn để thực hiện bằng cách sử dụng đa tác vụ. Vòng lặp đơn giản mà tôi đã sử dụng làm cho nó dễ dàng hơn nhiều và tốt hơn cho người mới bắt đầu / học tập.
Một điều khác tôi sẽ để lại cho bạn, đó là sự phụ thuộc trong khi gọn gàng và phù hợp với nhiều thứ, không phải là một cách tốt để thực hiện những gì được thực hiện tốt hơn theo truyền thống. Thật vậy, phần 'trốn tránh' có thể là một ứng cử viên tốt cho việc trợ cấp, nhưng thành thật mà nói, nhiệm vụ khác của bạn nên được gọi là 'GoOnTheYourBusiness'. Tôi nói điều này bởi vì có lẽ bạn không muốn thay đổi từ tìm kiếm sang theo dõi với sự sụt giảm. Xử lý những người có vòng lặp lập trình truyền thống. Với một cảm biến duy nhất, - ánh sáng được cảm nhận tối hơn hoặc sáng hơn so với vòng lặp trước? nếu trời tối hơn (giả sử đường màu đen) tiếp tục quay cùng hướng, nếu trời sáng hơn thì rẽ theo hướng khác, nếu nó giữ nguyên, hãy đi thẳng. Bạn có thể cần phải thêm một số PID và sử dụng đường cong lái thay vì chỉ rẽ trái và phải để mượt mà hơn.
Và có, nhiều cảm biến giúp. http://www.mindsensors.com/ - vâng, đó là tôi trong phim hiện tại (11/10/2012)
Cập nhật: mã thực tế
Tôi sẽ thử điều này trong một thời gian ngắn, nhưng nó biên dịch và minh họa những gì tôi đã viết ở trên:
#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
, chúng có phải là ưu tiên của nhiệm vụ? Là 9 sẽ là ưu tiên cao nhất? Trong trường hợp đó, không nênfind
có nhiều ưu tiên hơntrack
? Trong thực tế, điều kiệnfind
vàelse
điều kiệntrack
là như nhau. Vì vậy, là một con người, nếu giá trị cảm biến lớn hơn ngưỡng, bạn sẽ làm gì? Đi trên xoắn ốc hoặc biến để điều chỉnh dòng?