首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RobotC VEX /乐高编程:如何让机器人并行运行多个反应?

RobotC VEX /乐高编程:如何让机器人并行运行多个反应?
EN

Stack Overflow用户
提问于 2014-03-21 08:11:29
回答 2查看 2.5K关注 0票数 0

我需要让我的机器人能够使用凹凸开关,以便任何一个都可以被按下,并且只要凹凸开关被按下,与该凹凸开关相对应的电机就会运行。我遇到的问题是如何让LED正确地亮起来。当凹凸开关代码块运行时,我需要LED在每次光传感器值高于400时亮起并熄灭七次,持续一秒。我该怎么做呢?请帮帮我!我的代码发布在下面:

代码语言:javascript
复制
#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);
    }
}
}
EN

回答 2

Stack Overflow用户

发布于 2014-03-21 10:44:13

机器人编程的经验(尽管我还没有使用robot C)表明,要使机器人并行运行两个或多个传感器反应,您必须以完全不同的方式构建程序,而不是只针对一个反应。Robot C教程没有涵盖这一点,甚至没有介绍实现这一点所需的语言和库功能。

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

这里的问题是你的电机控制的内部while循环阻塞了线程,主要是阻止它运行控制循环。LED控制环路同样阻塞线程7秒,延迟其运行电机控制环路。

一般来说,机器人控制循环的每次迭代都应该读取传感器,发送输出命令,记住以后需要处理的任何状态,然后再次循环,以便控制循环的所有部分都能在每个循环中运行(尽可能频繁地或以受控的速率运行)。在传感器发生变化之前,不要通过停留在内部while循环中来阻止控制流。

第一步是解除电机控制回路的阻塞:

代码语言:javascript
复制
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);
  }
}

现在,您当前的发光二极管控制代码仍然调用wait(1) 7次。根据http://www.robotc.net/support/nxt/ROBOTC-for-Beginners/的说法,wait(1)等待了1.0秒,所以这部分代码目前需要7秒才能运行。检查凹凸开关之间的间隔时间很长。

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

因此,第二步是修复LED控制代码,使其不会阻塞控制回路。基本上有两种方法(我不知道Robot C是否支持第一种选择,但它更简单):

  1. 当光传感器高于阈值并且在上一次迭代中低于阈值时,即它刚刚转换,然后启动或“分支”线程(或任务)以运行发光二极管开/关循环。该线程应该循环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使用浮点数学。我不知道Robot。或者,你可以使用wait1Msec(71)等待71毫秒,大约是1/14秒。
  2. 使用变量来跟踪闪光发光二极管循环的顺序。在主循环周围的每个循环中,使用if语句检查这些变量,如果时间到了,执行闪光发光二极管周期的下一步,并更新这些变量。步骤是:当LED处于初始状态且光传感器高于阈值时打开LED,1/14秒后关闭LED,1/14秒后打开LED,...禁用这些步骤中的14个步骤后,将跟踪变量设置回初始状态。最简单的跟踪变量是从0(初始状态)到14 (执行最后一次LED“关闭”阶段)的计数器和上次更改后的系统时钟值,以检测时钟何时比该值晚71毫秒。一旦它完成了步骤14,返回到0。跟踪变量有其他选择,例如3个独立的变量,分别表示它当前是否闪烁,它当前正在执行的7个闪存周期中的哪一个,它是否处于该周期的开或关阶段,以及时钟读数。

方法#2比较棘手,因为同时做两件事很棘手。(那些认为开车时发短信就能同时处理多项任务的人大错特错了。)

如果机器人在闪烁LED时不需要运行保险杠/马达控制回路,也就是说,如果它不介意在LED闪烁1秒时对保险杠无反应,那么一种简单得多的方法就行得通。如果这些保险杠传感器阻止机器人跑出桌子的尽头,那么1秒没有反应是个坏消息。但如果机器人在闪光灯的同时按下保险杠1秒是可以的,那么代码的光传感器LED部分可能是这样的:

代码语言:javascript
复制
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就会持续闪烁,马达每秒只会检查一次保险杠。要解决这个问题,可以使用一个变量来计算光线传感器何时由暗变亮。

票数 0
EN

Stack Overflow用户

发布于 2014-12-23 05:18:25

你应该放入一个子程序。

代码语言:javascript
复制
//*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);
            }
        }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22547738

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档