我正在研究机器人,它是我们学院夏季机器人研讨会的一部分。我们正在使用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.
答案 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
你是否看到你的机器人将如何以这种逻辑永远前进?再一次,我不知道如何实施,所以我可能是错的。