如何使我的机器人沿黑色胶带沿矩形路径移动?

时间:2010-06-11 00:57:33

标签: c logic robotics

我正在研究机器人,它是我们学院夏季机器人研讨会的一部分。我们正在使用A-WIT的C-STAMP微控制器。我能够让它移动,向左转,向右转,向后移动。我甚至设法使用对比度传感器沿着黑色磁带。

我将机器人以30-45度的角度送到桌子上的黑色胶带上,然后它自动对齐并开始沿黑色胶带移动。它有点急促,可能是由于我的编程逻辑,它正在运行一个while循环并不断检查if语句,所以它最终试图每隔几毫秒左右转动,这解释了抽搐部分。但它没关系,它的工作原理,并不像我希望的那样顺畅,但它有效!问题是我不能让我的机器人进入黑色磁带的矩形路径。一旦它到达黑色磁带的角落,它就会一直向前而不是左转或右转。

我的2个传感器位于机器人正下方,靠近前轮,几乎位于地板上。它的“索引”值范围从0到8.八是最亮的对比度,零是最暗的对比度。因此,当机器人移动到黑带区域时,索引值会下降,并且基于此,我有一个if语句告诉我的机器人向左或向右转。

这是我的尝试。为了避免混淆,我没有发布整个源代码,只发布了负责机器人沿着黑带移动的逻辑部分。

while(1) {

    // don't worry about these.
    // 10 and 9 represent Sensor's PIN location on the motherboard
    V = ANALOGIN(10, 1, 0, 0, 0);
    V2 = ANALOGIN(9, 1, 0, 0, 0);

    // i got this "formula" from the example in my Manual. 
    // V stands for voltage of the sensor.
    // it gives me the index value of the sensor. 0 = darkest, 8 = lightest.
    index = ((-(V - 5) / 5) * 8 + 0.5);
    index2 = ((-(V2 - 5) / 5) * 8 + 0.5);

    // i've tweaked the position of the sensors so index > 7 is just right number.
    // the robot will move anywhere on the table just fine with index > 7. 
    // as soon as it drops to or below 7 (i.e. finds black tape), the robot will 
    // either turn left or right and then go forward.

    // lp & rp represent left-wheel pin and right-wheel pin, 1 means run forever.
    // if i change it from 1 to 100, it will go forward for 100ms.
    if (index > 7 && index2 > 7)
        goForward(lp, rp, 1);

    if (index <= 7) {
        turnLeft(lp, rp, 1);
        goForward(lp, rp, 1);
        // this is the tricky part. i've added this code last minute
            // trying to make my robot turn, but i didn't work.
        if (index > 4) {
            turnLeft(lp, rp, 1);
            goForward(lp, rp, 1);
        }
    }

    else if (index2 <= 7) {
        turnRight(lp, rp, 1);
        goForward(lp, rp, 1);
            // this is also the last minute addition. it's same code as above
            // but it's for the 2nd sensor.
        if (index2 > 4) {
            turnRight(lp, rp, 1);
            goForward(lp, rp, 1);
        }
    }
}

我花了一整天时间试图解决这个问题。我已经筋疲力尽了所有的途径。在stackoverflow上请求解决方案是我现在的最后一个选择。

提前致谢! 如果您对代码有任何疑问,请告诉我,但评论应该是不言自明的。

这是我的goForward功能,万一有人想知道:

void goForward(BYTE lp, BYTE rp, WORD t)
{
    WORD i;

    for(i = 0; i < t; i = i + 1){
        PULSOUT(lp, 400, 1, 1);
        PULSOUT(rp, 800, 1, 1);
        PAUSE(17);
    }
}

更新:这是我到目前为止所提出的。我已经删除了我之前发布的所有if语句,并决定从头开始编写逻辑:

// if there's enough bright light in both sensors at the same time
    // robot will move forward forever.
    if (index > 7 && index2 > 7)
        goForward(lp, rp, 1);

    // but if there's not enough bright light anymore (i.e. reached black tape)
    // proceed to the else-statement.
    else {
        // if left sensor detects the black tape then turn right
        // if doesn't detect the black tape then keep going forward
        if (index2 <= 7)
            turnRight(lp, rp, 1);
        else
            goForward(lp, rp, 1);

        // if right sensor detects the black tape then turn left
        // if it doesn't detect the black tape then keep going forward
        if (index <= 7) 
            turnLeft(lp, rp, 1);
        else 
            goForward(lp, rp, 1);
    }

    // The reason for turnLeft and turnRight is to keep robot re-alligning
    // to the black tape. It will happen so fast (every 1ms) that the jerking
    // shouldn't even be noticeable.

5 个答案:

答案 0 :(得分:3)

你需要捕捉突发事件:[周期n]“我看到了磁带” - &gt; [周期n + 1]“我看不到你遇到角落时发生的磁带。”

state machine是处理此类问题的好方法。使用state machine隔离特定状态的代码,它仅在状态为true时运行。这种隔离可以防止“串扰”,并为每个状态提供一个已知的代码块。

根据您的示例,流程可能类似于:

:Loop

State == Moving forward and on tape.
  read sensors
  delta = abs(valueLastCycle - valueThisCycle);
  if (delta >= bigChangeValue){
    // the tape was just gone. 
    // change state and handle this situation.
    CurrentState = suddenValueChange;
  }else
    if (index <= 7) {
        turnLeft(lp, rp, 1);
        goForward(lp, rp, 1);
    else if (index2 <= 7) {
        turnRight(lp, rp, 1);
        goForward(lp, rp, 1);
    }
   ...
State == suddenValueChange
 ...
 code that handles sudden value change event
 maybe:
 Stop Robot;
 Move backwards slowly until on tape or distance x
 etc...

Goto Loop

提高扫描速度似乎有所帮助......但机器人移动得越快,扫描速度就越快。你可能仍然会从磁带上跳过 - &gt;关闭磁带,在这种情况下,您当前的代码会崩溃。

答案 1 :(得分:2)

我的猜测是,在转弯左转/转弯“转弯”之后,goForward“取消”转弯? 这取决于如何实现转弯

答案 2 :(得分:2)

你的while循环运行速度是否足以赶上角落?如果两个传感器都报告它们在磁带上,并且在下一个循环中两个传感器都没有磁带,那么你无法检测到它,对吧?传感器报告相同的值(8)是否在磁带上和磁带上?

尝试更快地制作代码。在没有看到整个代码的情况下,很难提出建议,但似乎您可能正在评估那些不必要的语句。一旦你知道自己正在直行,就在第一个IF之后添加一个ELSE。

似乎你的goforward实现阻止循环太长时间了。 1并不意味着永远运行,它执行for循环的一次传递,然后你暂停17(毫秒?)。什么是PAUSE?去掉它。这可能会导致抖动,并阻止下一组传感器值进入。

答案 3 :(得分:2)

在担心代码之前,请确保您的“计划”有意义。

首先用手动移动机器人并观察传感器何时经过黑白区域。尝试提出一个行为,并手动模拟它。如果这不能按你的意愿工作,那么你需要修改行为。

建议:您可能希望添加更多循环以确保如果出现错误,机器人会在恢复正常行为之前自行更正。 (例如,不要向右/向左转100ms,只要传感器看到正确的东西,就要做这种行为。)

答案 4 :(得分:1)

现在,根据代码的外观,每当机器人看到黑色时,它就会永远向前发展。我不确定如何实施。

在伪代码中,您的代码说:

if you see black
 go forward forever
if you don't see black
 turn left or right

你是否看到你的机器人将如何以这种逻辑永远前进?再一次,我不知道如何实施,所以我可能是错的。