我试图通过无线和无线控制我的覆盆子皮卡。基本功能工作良好-有接口,我点击fwd和汽车将前进,当我释放按钮,它将停止。
我现在想集成超声波距离传感器,这样当我向前行驶时,汽车应该在前面有什么东西的时候停下来。当我点击fwd按钮的时候,车就会停下来,但是它只会在范围内停下来,而不是当我释放按钮的时候。我的while循环不知何故是循环(卡住),而不是从webiopi读取发布按钮功能。
有谁能帮上忙吗?我已经干了好几天了,不知道我哪里出了问题。
下面是我的python脚本中的循环:
def go_forward(arg):
global motor_stop, motor_forward, motor_backward, get_range
print "Testing"
print mousefwd()
while (arg) == "fwd":
print (arg)
direction = (arg)
dist = get_range()
print "Distance %.1f " % get_range()
if direction == "fwd" and get_range() < 30:
motor_stop()
return
else:
motor_forward()这是我的webiopi函数调用的代码:
function go_forward() {
var args = "fwd"
webiopi().callMacro("go_forward", args);
}
function stop1() {
var args = "stop"
webiopi().callMacro("go_forward", args);
webiopi().callMacro("stop");
}这就是我现在的情况,但仍然不起作用(我是个十足的菜鸟:-):
def go_forward(arg):
global motor_stop, motor_forward, motor_backward, get_range
print "Testing"
direction = arg
while direction == "fwd":
print arg
dist = get_range()
print "Distance %.1f " % get_range()
if get_range() < 30:
motor_stop()
elif direction == "fwd":
motor_forward()
else:
motor_stop()也许能向前迈一小步。请注意,webipi使用自己的“循环”,我添加了循环代码来检查电机GPIO的状态和距离,以及电机是否运行,如果距离太短,则停止。汽车现在移动时,我按前进按钮,停止,当我释放它,当前进和距离小于30厘米,它将停止。唯一的问题是,当距离太短,而且我多次按前向按钮时,我现在得到一个"GPIO.output(Echo,1) _webiopi.GPIO.InvalidDirectionException: GPIO通道不是输出“错误:-(。
“守则”现在看起来如下:
def go_forward(direction):
motor_forward()
def loop():
if get_range() < 30 and GPIO.digitalRead(M1) == GPIO.HIGH:
stop()
print "stop"
sleep(1)发布于 2014-07-29 02:41:10
我马上回答您的主要问题,但首先我想提到您作为Python初学者正在做的事情,这使您的生活变得比需要的更复杂。
函数开始时没有必要使用global语句。在Python中,只需要在想要写入全局变量时使用global语句。如果只需要读取变量或调用函数,那么就不需要使用global语句。函数中使用的任何名称,无论是变量名称还是函数名称,都将按照以下顺序进行搜索:本地的、包围的、全局的、内置的。“本地”是指在函数中定义的名称,如direction变量。“封装”是在另一个函数中定义函数时使用的规则。在许多情况下,这是有用的,但这是一个高级的主题,您现在不需要担心它。“全局”是指在程序的顶层定义的(变量、函数或类)的名称--例如motor_stop函数等。最后,“内置”是指Python的内置名称,如str、int或file。
因此,如果省略了global语句,那么Python将搜索名称motor_stop (和其他函数名)如下:
motor_stop吗?不是的。下一步。motor_stop?是。找到了。您的所有函数都是在程序的顶层定义的,所以“全局”规则可以在不需要global语句的情况下找到它们。这会让你的生活简单一点。
下面是您的主要问题:为什么您的代码会永远循环。这是因为您的while循环的测试条件永远不会变成假的。您正在while direction == "fwd"上循环,而while循环中的代码从不更改direction变量。因此,每当它到达循环的末尾,它就会返回到测试条件。direction变量仍然包含字符串"fwd",所以while循环第二次运行。然后direction变量仍然包含字符串"fwd",因此它第三次运行。以此类推等等。
当您希望while循环退出时,退出它的一种方法是当您想要停止时,将direction变量设置为其他东西,比如"stop"。(例如,打电话给motor_stop()之后)。另一种方法是在此时使用return语句退出函数。但我的建议是使用break语句,这意味着“此时,立即退出我所处的循环”。它同时适用于while循环和for循环,并且是一个非常有用的语句。看起来,您希望您的while循环在调用motor_stop()时随时退出,因此有两个地方可以放置break语句:
def go_forward(arg):
print "Testing"
direction = arg
while direction == "fwd":
print arg
dist = get_range()
print "Distance %.1f " % get_range()
if get_range() < 30:
motor_stop()
break
elif direction == "fwd":
motor_forward()
# No break statement here, so the while loop continues
else:
motor_stop()
break我建议做一些其他的改变。首先,在循环中调用get_range()三次,但实际上只需要调用一次。您已经将其结果分配给了一个dist变量,那么为什么不使用该变量呢?
def go_forward(arg):
print "Testing"
direction = arg
while direction == "fwd":
print arg
dist = get_range()
print "Distance %.1f " % dist
if dist < 30:
motor_stop()
break
elif direction == "fwd":
motor_forward()
# No break statement here, so the while loop continues
else:
motor_stop()
break其次,在while循环中,direction 而不是不能成为"fwd",所以最终的else是不必要的,您的函数可以变成:
def go_forward(arg):
print "Testing"
direction = arg
while direction == "fwd":
print arg
dist = get_range()
print "Distance %.1f " % dist
if dist < 30:
motor_stop()
break
else:
motor_forward()最后,您有一个名为arg的函数参数,它是一个没有告诉您它用于什么的名称。立即将其赋值给一个名为direction的变量,这是一个更好的名称。那么,为什么不首先使用它作为参数名呢?没有任何规则规定函数的参数必须被称为"arg";它们可以任意调用(除了break或if之类的保留词)。因此,让我们给您的函数一个更有意义的参数名称,这将进一步简化它:
def go_forward(direction):
print "Testing"
while direction == "fwd":
print direction
dist = get_range()
print "Distance %.1f " % dist
if dist < 30:
motor_stop()
break
else:
motor_forward()那里。这更容易阅读和理解,它应该解决了您看到的while循环的问题,当汽车离对象太近时不会退出。
(我仍然可以看到一个可能的问题,那就是尽管您发布了“前进”按钮,但是我必须查看您的motor_forward()代码才能知道如何解决这个问题。这可能就像把break语句放在motor_forward()之后一样简单,在这种情况下,根本不需要while循环--但是我必须知道您的motor_forward()代码是如何与webiopi交互的,以及webiopi的事件处理代码是如何工作的。这些我现在都不知道,所以我要回答我现在能回答的问题,即使我的答案是不完整的,而不是让你完全没有答案。)
马克的编辑:这里是motor_forward代码:
def motor_forward():
GPIO.output(M1, GPIO.HIGH)
GPIO.output(M2, GPIO.LOW)
string = "echo 0=130 > /dev/servoblaster"
os.system(string)发布于 2014-07-28 19:50:12
试试看--你总是在距离上停下来,但你可能想在方向上停下来。
if get_range() < 30:
motor_stop()
elif direction == "fwd":
motor_forward()
else:
motor_stop()顺便说一下,当你引用( arg )时,你不需要(Arg)只使用arg
打印arg
调用签名中的父函数在那里显示其对函数的parm。
https://stackoverflow.com/questions/25002980
复制相似问题