我试图通过无线和webiopi控制我的Raspberry Pi车。基本功能工作正常 - 有我点击前进的界面,汽车将前进,当我释放按钮时,它将停止。
我现在想要整合超声波距离传感器,这样当我向前行驶时,汽车应该停在前面的东西。当我点击前进按钮时,我将它移动到哪里,当某些物品在范围内时,汽车将会开车并停止,但只有当物品在范围内而不是在我释放按钮时它才会停止。我的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使用自己的&#39;循环&#39;然后我添加了循环代码来检查电机GPIO的状态以及距离和电机是否正在运行以及距离是否过短然后停止。当我按下前进按钮时汽车现在移动,当我释放它时停止,当向前移动并且距离小于30cm时它会停止。唯一的问题是,当距离太短而且我多次按下前进按钮时,我现在得到一个&#34; GPIO.output(Echo,1) _webiopi.GPIO.InvalidDirectionException:GPIO通道不是OUTPUT&#34;错误:-(。
守则现在看起来像这样:
def go_forward(direction):
motor_forward()
def loop():
if get_range() < 30 and GPIO.digitalRead(M1) == GPIO.HIGH:
stop()
print "stop"
sleep(1)
答案 0 :(得分:1)
试试这个 - 你总是停在射程上,但可能想要停在方向上
if get_range() < 30:
motor_stop()
elif direction == "fwd":
motor_forward()
else:
motor_stop()
顺便说一句,你引用它时不需要(arg)arg
print arg
呼叫签名中的parens用于向函数显示其参数
答案 1 :(得分:1)
我会在一分钟内回答你的主要问题,但首先我想提一下你作为Python初学者所做的事情,这会让你的生活变得更加复杂。
您无需在功能开始时使用global
语句。在Python中,如果要将写入全局变量,则只需使用global
语句。如果你需要做的只是读取变量,或者调用函数,那么就不需要global
语句。函数中使用的任何名称,无论它们是变量名称还是函数名称,都将按以下顺序搜索:local,enclosing,global,builtin。 “Local”表示在函数内定义的名称,例如direction
变量。 “Enclosing”是在另一个函数中定义函数时使用的规则。这在许多情况下都很有用,但它是一个高级主题,您现在不需要担心它。 “全局”表示在程序顶层定义的名称(变量,函数或类) - 例如motor_stop
函数等。最后,“builtin”表示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”;它们可以被称为任何你喜欢的东西(除了Python的保留字之一,如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
循环不会退出。
(我可以看到一个可能的问题,即虽然你发布了“前进”按钮,但是在汽车向前行驶时,while循环可能不会退出 - 但我必须看到你的{{ 1}}代码知道如何解决这个问题。它可能就像在motor_forward()
之后放一个break
语句一样简单,在这种情况下真的不需要motor_forward()
循环完全 - 但我必须知道你的while
代码如何与webiopi交互以及webiopi的事件处理代码是如何工作的。我现在都不知道,所以我将回答我可以解决的问题现在回答即使我的答案不完整,也不要让你完全没有回答。)
按标记编辑:以下是motor_forward代码:
motor_forward()