Python,Webiopi和Raspberry Pi

时间:2014-07-28 19:37:45

标签: python raspberry-pi robot webiopi

我试图通过无线和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)

2 个答案:

答案 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的内置名称,如strintfile

因此,如果您遗漏了global语句,那么Python将搜索名称motor_stop(以及其他函数名称),如下所示:

  1. 本地:此功能中是否定义了motor_stop?不,继续前进。
  2. 附上:此功能是否在另一个功能中定义?不,所以“封闭”规则不适用。继续前进。
  3. 全球:是否在该计划的最高级定义了motor_stop?是。找到了。
  4. (Builtin):根本不会检查此规则,因为该名称是由“全局”规则找到的。
  5. 您的所有功能都在程序的顶层定义,因此“全局”规则将找到它们而不需要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的保留字之一,如breakif)。因此,让我们为您的函数提供一个更有意义的参数名称,这将进一步简化它:

    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()