首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python,Webiopi和Raspberry Pi

Python,Webiopi和Raspberry Pi
EN

Stack Overflow用户
提问于 2014-07-28 19:37:44
回答 2查看 2.3K关注 0票数 0

我试图通过无线和无线控制我的覆盆子皮卡。基本功能工作良好-有接口,我点击fwd和汽车将前进,当我释放按钮,它将停止。

我现在想集成超声波距离传感器,这样当我向前行驶时,汽车应该在前面有什么东西的时候停下来。当我点击fwd按钮的时候,车就会停下来,但是它只会在范围内停下来,而不是当我释放按钮的时候。我的while循环不知何故是循环(卡住),而不是从webiopi读取发布按钮功能。

有谁能帮上忙吗?我已经干了好几天了,不知道我哪里出了问题。

下面是我的python脚本中的循环:

代码语言:javascript
复制
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函数调用的代码:

代码语言:javascript
复制
 function go_forward() {
              var args = "fwd"
              webiopi().callMacro("go_forward", args);
      }
 function stop1() {
              var args = "stop"
              webiopi().callMacro("go_forward", args);
              webiopi().callMacro("stop");
    }

这就是我现在的情况,但仍然不起作用(我是个十足的菜鸟:-):

代码语言:javascript
复制
 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通道不是输出“错误:-(。

“守则”现在看起来如下:

代码语言:javascript
复制
 def go_forward(direction):
   motor_forward()

 def loop():
   if get_range() < 30 and GPIO.digitalRead(M1) == GPIO.HIGH:
     stop()
     print "stop"
   sleep(1)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-07-29 02:41:10

我马上回答您的主要问题,但首先我想提到您作为Python初学者正在做的事情,这使您的生活变得比需要的更复杂。

函数开始时没有必要使用global语句。在Python中,只需要在想要写入全局变量时使用global语句。如果只需要读取变量或调用函数,那么就不需要使用global语句。函数中使用的任何名称,无论是变量名称还是函数名称,都将按照以下顺序进行搜索:本地的、包围的、全局的、内置的。“本地”是指在函数中定义的名称,如direction变量。“封装”是在另一个函数中定义函数时使用的规则。在许多情况下,这是有用的,但这是一个高级的主题,您现在不需要担心它。“全局”是指在程序的顶层定义的(变量、函数或类)的名称--例如motor_stop函数等。最后,“内置”是指Python的内置名称,如strintfile

因此,如果省略了global语句,那么Python将搜索名称motor_stop (和其他函数名)如下:

  1. 本地:在这个函数中定义了motor_stop吗?不是的。下一步。
  2. 封装:是在另一个函数中定义的函数吗?不,所以“包围”规则不适用。下一步。
  3. Global:是否在程序的顶层定义了一个motor_stop?是。找到了。
  4. (Builtin):根本不检查这个规则,因为名称是由“全局”规则找到的。

您的所有函数都是在程序的顶层定义的,所以“全局”规则可以在不需要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语句:

代码语言:javascript
复制
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变量,那么为什么不使用该变量呢?

代码语言:javascript
复制
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是不必要的,您的函数可以变成:

代码语言:javascript
复制
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";它们可以任意调用(除了breakif之类的保留词)。因此,让我们给您的函数一个更有意义的参数名称,这将进一步简化它:

代码语言:javascript
复制
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代码:

代码语言:javascript
复制
 def motor_forward():
     GPIO.output(M1, GPIO.HIGH)
     GPIO.output(M2, GPIO.LOW)
     string = "echo 0=130 > /dev/servoblaster"
     os.system(string)
票数 1
EN

Stack Overflow用户

发布于 2014-07-28 19:50:12

试试看--你总是在距离上停下来,但你可能想在方向上停下来。

代码语言:javascript
复制
  if get_range() < 30:
      motor_stop()
  elif direction == "fwd":
      motor_forward()
  else:
      motor_stop()

顺便说一下,当你引用( arg )时,你不需要(Arg)只使用arg

打印arg

调用签名中的父函数在那里显示其对函数的parm。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25002980

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档