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

发布于 2024-09-05 08:51:51 字数 3653 浏览 2 评论 0原文

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

我将机器人以 30-45 度的角度朝向桌子上的黑色胶带,它会自行对齐并开始沿着黑色胶带移动。它有点抽搐,可能是由于我下面的编程逻辑,它正在运行一个 while 循环并不断检查 if 语句,因此它最终会尝试每隔几毫秒左右转动一次,这解释了抽搐部分。但没关系,它可以工作,虽然不像我希望的那么顺利,但它可以工作!问题是我无法让我的机器人进入黑色胶带的矩形路径。一旦到达黑色胶带的角落,它就会继续直行,而不是左转或右转。

我的 2 个传感器位于机器人正下方,靠近前轮,几乎与地板齐平。它的“索引”值范围为 0 到 8。8 是最亮的对比度,0 是最暗的对比度。因此,当机器人进入黑带区域时,索引值会下降,基于此,我有一个 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.

I am working on a robot, it's part of the summer robotics workshop in our college. We are using C-STAMP micro controllers by A-WIT. I was able to make it move, turn left, turn right, move backward. I have even managed to make it go along the black tape using a contrast sensor.

I send the robot at 30-45 degrees toward the black tape on the table and it aligns itself and starts to move along the black tape. It jerks a little, probably due to my programming logic below, it's running a while-loop and constantly checking if-statements, so it ends up trying to turn left and right every few milliseconds, which explains the jerking part. But it's okay, it works, not as smooth as I want it to work but it works! Problem is that I can't make my robot go into a rectangular path of the black tape. As soon as it reaches the corner of the black tape it just keeps going straight instead of making left or right turn.

My 2 sensors are located right underneath the robot, next to the front wheel, almost at the floor level. It has "index" value ranging from 0 to 8. Eight being the brightest contrast and zero being the darkest contrast. So when the robot moves into the black-tape-zone, the index value drops, and based on that, I have an if-statement telling my robot to either turn left or right.

Here's my attempt. To avoid confusion I didn't post the entire source code, but only the logical part responsible for the movement of my robot along the black tape.

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

I've spent the entire day trying to figure it out. I've pretty much exhausted all avenues. Asking for the solution on stackoverflow is my very last option now.

Thanks in advance!
If you have any questions about the code, let me know, but comments should be self-explanatory.

This is my goForward function in case anyone wonders:

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

UPDATE: Here's what I've come up with so far. I've erased all my if-statements that I've posted earlier and decided to write the logic from scratch:

// 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

念三年u 2024-09-12 08:51:51

你需要捕获突然发生的情况:[循环n]“我看到磁带”-> [循环n+1] 当你遇到拐角时会发生“我看不到胶带”。

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

给定您的示例,流程可能类似于:

: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

增加扫描速率可能似乎有所帮助......但是机器人移动的速度越快,您的扫描速率就越快......即您可能仍然从磁带上跳转 -> 。在这种情况下,您当前的代码会陷入困境。

You need to trap the sudden occurrence: [cycle n] "I see the tape" -> [cycle n+1] "I don't see the tape" that happens when you encounter a corner.

A state machine is a good way of handling this type of problem. With a state machine the code for a specific state is isolated, it only runs when the state is true. This isolation prevents "cross-talk" and gives you one known code block for each state.

Given your example the flow might be something like:

: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

Increasing the scan rate might seem to help....but the faster the robot moves the faster your scan rate....i.e. You might still jump from on tape -> off tape in which case your current code flounders.

木有鱼丸 2024-09-12 08:51:51

我的猜测是,左转/右转后立即“取消”转弯?
但这取决于车削的实施方式

My guess is that the goForward immediately after the turnLeft/TurnRight "cancels" the turning?
It depends on how turning is implemented though

弄潮 2024-09-12 08:51:51

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

首先用手移动机器人,并观察传感器何时经过黑色和白色区域。尝试想出一种行为,并用手模拟它。如果这没有达到您想要的效果,那么您需要修改该行为。

建议:您可能希望添加更多循环,以确保如果出现问题,机器人会在恢复正常行为之前自行纠正。 (例如,不要右转/左转 100 毫秒,而是只要传感器看到正确的东西就执行该行为。)

Make sure your "plan" makes sense before worrying about the code.

Start by moving the robot around by hand and observing when the sensors pass over black and white areas. Try to come up with a behaviour, and simulate it by hand. If this doesn't work as you want, then you need to revise the behaviour.

A suggestion: You may wish to add some more loops to ensure that if something seems wrong, the robot corrects itself before resuming normal behaviour. (E.g. rather than turning right/left for 100ms, do that behaviour as long as it takes for the sensors to see the right thing.)

终遇你 2024-09-12 08:51:51

您的 while 循环运行速度是否足够快以捕获角点?如果两个传感器都报告它们在磁带上,并且在下一个周期中两个传感器都脱离磁带,那么您无法检测到这一点,对吗?传感器在磁带上和磁带外报告相同的值 (8)?

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

看来您的 goforward 实现阻塞了循环太长时间。 1 并不意味着永远运行,它会执行一次 for 循环,然后暂停 17(毫秒?)。暂停是为了什么?将其删除。这可能会导致抖动,并阻止下一组传感器值的输入。

Does your while loop run fast enough to catch a corner? If both sensors report that they are on the tape, and in the next cycle both sensors are off the tape, you can't detect that, right? The sensor reports the same values (8) for being on the tape and off the tape?

Try making your code faster. Without seeing the entire code, it's hard to make a recommendation, but it seems that you might be evaluating if statements that are not necessary. Add an ELSE after the first IF, once you know that you are going straight.

It seems that your goforward implementation is blocking the loop for too long. 1 does not mean run forever, it does one pass of the for-loop, and then you PAUSE 17 (msec?). What's the PAUSE for? Remove it. This probably causes the jerking, and it prevents the next set of sensor values from coming in.

樱娆 2024-09-12 08:51:51

现在,从代码的外观来看,每当机器人看到黑色时,它就会永远前进。我不太确定未来如何实施。

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

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

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

Right now, by the looks of your code, every time the robot sees black, it goes forward forever. I'm not really sure how going forward is implemented.

In pseudocode, your code says:

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

Do you see how your robot would go forward forever with that kind of logic? Again, I have no idea how going forward is implemented so I could be wrong.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文