简短的回答;不,您真的需要做很多不同的事情。
长期不完整的答案;让我给您一些适合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只是最近才重新进入,因此诸如访问传感器之类的事情多于一项任务可能会有风险(I2C时序问题),在某些情况下则没有风险(自动轮询传感器)。
您可以在工作正常时将自己的优先级实现添加到上述循环中,但实际上并不需要启动它。
您的注释“ //阻止障碍物”描述了弹道行为。使用多任务来实现这些功能有些棘手。我使用的简单循环使它变得更容易,并且对于初学者/学习来说更好。
我会留给您的另一件事是,在保持整洁并适用于许多事物的同时进行包容并不是实现传统上更好的方法的好方法。确实,“逃避”部分可能是一个不错的选择,但老实说,您的其他任务应称为“ 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
相同。因此,作为一个人,如果传感器值大于阈值,您会怎么做?继续旋转或旋转以调整线?