RobotC VEX / Lego编程:如何使机器人并行运行多个反应?

时间:2014-03-21 00:11:29

标签: java robot nxt mindstorms

我需要让我的机器人能够使用碰撞开关,这样任何一个都可以按下,并且只要按下碰撞开关,与碰撞开关对应的电机就会运行。我遇到的问题是让LED正常点亮。当碰撞开关代码块运行时,每当光传感器值高于400时,我需要LED点亮并熄灭七次,持续一秒钟。我该怎么办?请帮忙! 我的代码发布在下面:

#pragma config(Sensor, in2,    lightSensor,    sensorReflection)
#pragma config(Sensor, dgtl3,  bumpSwitch,     sensorTouch)
#pragma config(Sensor, dgtl4,  bumpSwitch2,    sensorTouch)
#pragma config(Sensor, dgtl10, ledGreen,       sensorLEDtoVCC)
#pragma config(Sensor, dgtl11, ledRed,         sensorLEDtoVCC)
#pragma config(Motor,  port1,           leftMotor,     tmotorVex269, openLoop)
#pragma config(Motor,  port10,          rightMotor,    tmotorVex269, openLoop)

task main() {

while(true) {

    if (SensorValue(lightSensor) > 400) {
        int count = 0;
        while (count < 7) {
            turnLEDOn(ledGreen);
            turnLEDOn(ledRed);
            wait(1);
            turnLEDOff(ledGreen);
            turnLEDOff(ledRed);
            count++;
        }
    }

    while (SensorValue(bumpSwitch) == 0 && SensorValue(bumpSwitch2) == 0) {
        stopMotor(rightMotor);
        stopMotor(leftMotor);
    }

    while (SensorValue(bumpSwitch2) == 1) {
        startMotor(rightMotor, 55);
        startMotor(leftMotor, 55);
    }

    while (SensorValue(bumpSwitch) == 1){
        startMotor(rightMotor, -55);
        startMotor(leftMotor, -55);
    }
}
}

2 个答案:

答案 0 :(得分:0)

机器人编程的经验(虽然我没有使用机器人C)表明,为了使机器人并行运行两个或更多传感器反应,你必须以非常不同的方式构建程序,而不仅仅是一个反应。 Robot C教程没有涵盖这一点,甚至还介绍了执行此操作所需的语言和库功能。

在这种情况下,您希望光线传感器触发持续1秒的LED开/关序列,而撞击传感器触发电机动作,直到这些传感器不再撞击为止。

这里的问题是你的电机控制器的内部while循环阻塞了线程,主要是防止它绕过运行LED控制回路。 LED控制回路同样会阻塞螺纹7秒钟,从而延迟运行电机控制回路。

通常,机器人控制循环的每次迭代都应该读取传感器,发送输出命令,记住以后需要处理的任何状态,然后再循环,这样控制循环的所有部分都可以在每个循环中运行(如同可能的或以受控的速度)。不要通过保持内部while循环来阻止控制流,直到传感器发生变化。

第一步是取消阻止电机控制回路:

while (true) {

  // Light sensor LED control code ...

  // Bumper/motor control
  if (SensorValue(bumpSwitch) == 1) {
    startMotor(rightMotor, -55);
    startMotor(leftMotor, -55);
  } else if (SensorValue(bumpSwitch2) == 1){
    startMotor(rightMotor, 55);
    startMotor(leftMotor, 55);
  } else {
    stopMotor(rightMotor);
    stopMotor(leftMotor);
  }
}

现在您当前的LED控制代码仍然会调用wait(1) 7次。根据{{​​3}} wait(1)等待1.0秒,所以这部分代码目前需要7秒才能运行。检查碰撞开关之间的时间很长。

此外,您的代码在关闭和重新打开LED之间没有明显延迟,因此您不会注意到LED会在该序列结束前关闭。

所以第二步是修复LED控制代码阻止控制回路。基本上有两种方法(我不知道机器人C是否支持第一种选择,但它更简单):

  1. 当光传感器高于阈值时,它在前一次迭代中低于阈值,即刚刚过渡,然后启动[或“fork”]一个线程(或任务)运行LED开/关循环。该线程应该循环7次:{打开LED,wait(1.0/14.0)秒,关闭LED,然后wait(1.0/14.0)秒}。这样,循环周围的7个循环将花费7 *(1/14 + 1/14)= 1.0秒。我将其写为1.0/14.0而不是1/14,因为许多编程语言在整数数学中计算1/14,产生0,而1.0/14.0使用浮点数学。我不知道机器人C.或者,你可以使用wait1Msec(71)等待71毫秒,大约是1/14秒。
  2. 使用变量通过闪光LED循环跟踪排序。围绕主循环的每个循环,使用if语句检查这些变量,如果是时间,则执行flash-LED循环中的下一步,并更新这些变量。步骤是:当LED处于初始状态时打开LED并且光传感器高于阈值,在1/14秒后关闭LED,在1/14秒时打开LED稍后,...在这些步骤中的14个之后关闭并将跟踪变量设置回初始状态。最简单的跟踪变量是从0(初始状态)到14(执行最后一个LED“关闭”阶段)的计数器和从最后一次更改的系统时钟值,以便您检测时钟是否晚于71毫秒那。一旦完成步骤14,返回0.跟踪变量有其他选择,例如3个单独的变量,它是否正在闪烁,它正在进行的7个闪存周期中的哪一个,无论是在ON还是OFF阶段。循环和时钟读数。
  3. 方法#2比较棘手,因为一次做两件事很棘手。 (那些认为自己可以在开车时通过短信进行多项任务的人是危险的错误。)

    如果机器人在闪烁LED时不需要运行保险杠/电机控制回路,也就是说,如果它不介意在闪烁LED 1秒钟时对保险杠没有反应,则可以采用更简单的方法。如果那些保险杠传感器让机器人不能在桌子的末端运行,那么1秒钟没有响应就是坏消息。但是,如果机器人在闪烁灯光的同时按下保险杠1秒钟就可以了,那么代码的光传感器LED部分可能是这样的:

    while (true) {
      // Light sensor LED control code
      if (SensorValue(lightSensor) > 400) {
        for (int i = 0; i < 7; ++i) {
          turnLEDOn(ledGreen);
          turnLEDOn(ledRed);
          wait1Msec(71); // 1/14 second
          turnLEDOff(ledGreen);
          turnLEDOff(ledRed);
          wait1Msec(71);
        }
      }
    
      // Bumper/motor control code ...
    }
    

    这使得另一个简化的假设是:如果在完成1秒LED闪烁循环后光传感器仍然亮,则可以在主控制循环周围再次进行另一次1秒闪烁循环,这很快就会发生。因此,只要光传感器很亮,LED就会一直闪烁,电机每秒只检查一次保险杠。要解决这个问题,请使用变量来确定光传感器何时从暗到亮。

答案 1 :(得分:0)

你应该放入一个子程序。

//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

task blink()
{
// Light sensor LED control code
if (SensorValue(lightSensor) > 400) 
    {
    for (int i = 0; i < 7; ++i) {
        turnLEDOn(ledGreen);
        turnLEDOn(ledRed);
        wait1Msec(71); // 1/14 second
        turnLEDOff(ledGreen);
        turnLEDOff(ledRed);
        wait1Msec(71);
    }

}


    task main()
    {
        startTask(blink);
        while (true)
            {

            // Light sensor LED control code ...

            // Bumper/motor control
            if (SensorValue(bumpSwitch) == 1) {
                startMotor(rightMotor, -55);
                startMotor(leftMotor, -55);
                } else if (SensorValue(bumpSwitch2) == 1){
                startMotor(rightMotor, 55);
                startMotor(leftMotor, 55);
                } else {
                stopMotor(rightMotor);
                stopMotor(leftMotor);
            }
        }
    }