0

I need to get my robot to be able to use the bump switches so that either one can be pressed and the motor corresponding to that bumpswitch will run for as long as the bump switch is pressed. The problem I'm having is getting the LEDs to light up correctly. While the bump switch code block is running, I need the LEDs to light up and go off seven times for one second every time the Light sensor value gets higher than 400. How do I do it? Please Help! My Code is posted below:

#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);
    }
}
}
4

2 回答 2

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);
            }
        }
    }
于 2014-12-22T21:18:25.477 回答
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 次。根据http://www.robotc.net/support/nxt/ROBOTC-for-Beginners/ wait(1)等待1.0秒,所以这部分代码目前需要7秒才能运行。检查碰撞开关之间的时间很长。

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

所以第二步是修复LED控制代码阻塞控制回路。基本上有两种方法(不知道Robot 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. 使用变量通过 flash-LED 循环跟踪排序。围绕主循环的每个循环,使用if检查这些变量的语句,如果时间到了,请在闪烁 LED 循环中执行下一步,并更新这些变量。步骤为:在初始状态且光传感器高于阈值时打开LED,1/14秒后关闭LED,1/14秒后打开LED稍后,... 在 14 个这些步骤之后,关闭并将跟踪变量设置回初始状态。最简单的跟踪变量将是一个从 0(初始状态)到 14(执行最后一个 LED“关闭”阶段)的计数器和最后一次更改的系统时钟值,让您检测时钟何时晚于 71 毫秒那。完成第 14 步后,返回 0。跟踪变量有其他选择,例如 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 就会一直闪烁,电机每秒只会检查一次保险杠。要解决此问题,请使用变量来确定光传感器何时从暗变为亮。

于 2014-03-21T02:44:12.910 回答