如何让我的机器人沿着黑色胶带沿矩形路径移动?
Posted
技术标签:
【中文标题】如何让我的机器人沿着黑色胶带沿矩形路径移动?【英文标题】:How to make my robot move in a rectangular path along the black tape? 【发布时间】:2011-03-02 11:07:16 【问题描述】:我正在研究一个机器人,它是我们学院暑期机器人研讨会的一部分。我们正在使用 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);
我花了一整天的时间试图弄清楚。我几乎用尽了所有途径。在 *** 上寻求解决方案是我现在最后的选择。
提前致谢! 如果您对代码有任何疑问,请告诉我,但 cmets 应该是不言自明的。
这是我的 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.
【问题讨论】:
你试过chiphacker.com吗? 【参考方案1】:你需要捕获突然发生的事件:[cycle n] “I see the tape” -> [cycle n+1] “I don't see the tape”当你遇到拐角时发生的。
state machine 是处理此类问题的好方法。使用state machine,特定状态的代码是隔离的,它仅在状态为真时运行。这种隔离可以防止“串扰”,并为每个状态提供一个已知的代码块。
根据您的示例,流程可能类似于:
: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
提高扫描速度可能会有所帮助....但是机器人移动得越快,您的扫描速度就越快....即您可能仍会从磁带上跳到磁带上 -> 在这种情况下,您当前的代码会陷入困境。
【讨论】:
有趣。感谢您花时间写下所有这些。我现在会尝试将此伪代码转换为实际代码,然后在星期一进行测试。 做一点研究..我的伪代码很不完整。即它很烂:) 它看起来很复杂但很整洁。我什至没有想过要获得机器人经过黑色胶带然后向后移动并转弯的距离增量。我现在将用我到目前为止提出的内容更新我的问题。我还没有实现你的伪代码,我只是简化了我的代码,我认为现在它会更有意义。【参考方案2】:我的猜测是在 turnLeft/TurnRight 之后的 goForward 立即“取消”了转弯? 这取决于如何实现转向
【讨论】:
它工作正常。这就是让这个机器人与黑色胶带对齐的原因。但是 goForward 可能会取消它应该在到达拐角时进行的 90 度转弯。 你可能是对的,在 goForward 之前加上 if 语句可能会解决这个问题。【参考方案3】:在担心代码之前确保你的“计划”有意义。
首先用手移动机器人并观察传感器何时通过黑白区域。尝试提出一种行为,并手动模拟它。如果这不能如您所愿,那么您需要修改行为。
一个建议:您可能希望添加更多循环以确保如果出现问题,机器人会在恢复正常行为之前自行纠正。 (例如,与其向右/向左转动 100 毫秒,不如在传感器看到正确的东西时执行该行为。)
【讨论】:
【参考方案4】:您的 while 循环是否运行得足够快以捕捉角落?如果两个传感器都报告它们在磁带上,并且在下一个循环中两个传感器都在磁带上,那么您就无法检测到,对吧?传感器报告磁带上和磁带外的相同值 (8)?
尝试让您的代码更快。如果没有看到整个代码,很难提出建议,但似乎您可能正在评估不必要的 if 语句。在第一个 IF 之后添加一个 ELSE,一旦你知道你要直走。
您的 goforward 实现似乎阻塞循环的时间过长。 1 并不意味着永远运行,它执行一次 for 循环,然后你 PAUSE 17(毫秒?)。 PAUSE 是为了什么?去掉它。这可能会导致抖动,并阻止下一组传感器值进入。
【讨论】:
处理器速度为 40Mhz。我确实测试了机器人,所以它在离开黑色胶带后停止了。它走了几英寸然后停下来,这还不错。在第一个 If 之后添加 else 语句会实现什么? 我不知道 PAUSE 是为了什么,我只是按照手册中的示例进行操作。当它向前移动时,我没有注意到任何抽搐。它抽搐的原因是因为它一到达黑色胶带就会左,右,左,右,左,右对齐。不过我会在星期一尝试将其移除,我现在没有机器人。 如果你知道两个索引都>7,它们都不可能 这只是黑暗与光明。我对板载 LED 进行了简单的测试。当您通过将手指靠近它来降低光强度时。 LED 从 LED1 变为 LED8。还是相反。无论如何,它只是检测暗与亮。【参考方案5】:现在,从您的代码来看,每次机器人看到黑色,它就会永远前进。我不太确定下一步是如何实现的。
在伪代码中,您的代码说:
if you see black
go forward forever
if you don't see black
turn left or right
您是否看到您的机器人会以这种逻辑永远前进?同样,我不知道如何实现前进,所以我可能是错的。
【讨论】:
这正是我想做的。想象一个大方桌,其中包含一条中等大小的矩形黑色胶带。它沿着黑色胶带很好,但是一旦它到达黑色胶带的末端,(它不再看到黑色,它现在在木头上)它应该转弯,但它没有继续前进并从桌子上掉下来。以上是关于如何让我的机器人沿着黑色胶带沿矩形路径移动?的主要内容,如果未能解决你的问题,请参考以下文章