Frage

Ich versuche, mein Himbeer-Pi-Auto über WLAN und Webiopi zu steuern.Die Grundfunktion funktioniert einwandfrei - haben Sie die Schnittstelle, wo ich auf fwd klicke und das Auto vorwärts fährt und wenn ich den Knopf loslasse, stoppt es.

Ich möchte jetzt den Ultraschall-Abstandssensor integrieren, damit das Auto beim Vorwärtsfahren anhalten soll, wenn etwas davor ist.Ich habe es dort, wo das Auto fährt und anhält, wenn ich auf die Vorwärtsfahrtaste klicke, wenn sich etwas in Reichweite befindet, aber es stoppt nur, wenn sich etwas in Reichweite befindet und nicht, wenn ich die Taste loslasse.Meine while-Schleife schleift sich irgendwie (steckt fest) und liest die Freigabetastenfunktion nicht von webiopi.

Kann mir bitte jemand helfen - ich bin jetzt schon seit Tagen dabei und weiß nicht, wo ich falsch liege :-(

Hier ist die Schleife aus meinem Python-Skript:

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

Und hier ist der Code aus meinem webiopi-Funktionsaufruf:

 function go_forward() {
              var args = "fwd"
              webiopi().callMacro("go_forward", args);
      }
 function stop1() {
              var args = "stop"
              webiopi().callMacro("go_forward", args);
              webiopi().callMacro("stop");
    }

So habe ich es jetzt, aber es funktioniert immer noch nicht (ich bin ein totaler Neuling :-)) :

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

Vielleicht ein kleiner Schritt nach vorne.Sehen Sie, dass Webipi eine eigene 'Schleife' verwendet und ich den Schleifencode hinzugefügt habe, um den Status der Motor-GPIOs und die Entfernung zu überprüfen und ob der Motor läuft und ob die Entfernung zu kurz ist, dann stoppen Sie.Das Auto bewegt sich jetzt, wenn ich den Vorwärtsknopf drücke und stoppt, wenn ich ihn loslasse und wenn es vorwärts fährt und die Entfernung weniger als 30 cm beträgt, stoppt es.Das einzige Problem ist, dass wenn die Entfernung zu kurz ist und ich die Vorwärts-Taste mehrmals zu schnell drücke, ich jetzt ein "GPIO" bekomme.ausgabe (Echo, 1) _webiopi.GPIO.InvalidDirectionException:Der GPIO-Kanal ist kein AUSGANGS-" Fehler :-( .

Der Code sieht jetzt so aus:

 def go_forward(direction):
   motor_forward()

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

Lösung

Ich werde Ihr Hauptproblem gleich beantworten, aber zuerst möchte ich etwas erwähnen, das Sie als Python-Anfänger tun, was Ihr Leben komplizierter macht, als es sein muss.

Es gibt keine Notwendigkeit für die global aussage, die Sie zu Beginn Ihrer Funktion haben.In Python müssen Sie nur das verwenden global erklärung, wenn Sie möchten schreiben zu einer globalen Variablen.Wenn alles, was Sie tun müssen, ist lesen die Variable, oder rufen Sie die Funktion, dann gibt es keine Notwendigkeit für die global Anweisung.Alle in Ihrer Funktion verwendeten Namen, unabhängig davon, ob es sich um Namen von Variablen oder Namen von Funktionen handelt, werden in der folgenden Reihenfolge gesucht:lokal, umschließend, global, eingebaut."Lokal" bedeutet Namen, die in Ihrer Funktion definiert sind, wie Ihre direction variabel."Einschließen" ist eine Regel, die verwendet wird, wenn Sie eine Funktion in einer anderen Funktion definieren.Dies ist in vielen Situationen nützlich, aber es ist ein etwas fortgeschrittenes Thema und Sie müssen sich vorerst keine Gedanken darüber machen."Global" bedeutet Namen (von Variablen, Funktionen oder Klassen), die auf der obersten Ebene Ihres Programms definiert sind - z. B. Ihre motor_stop funktion unter anderem.Und schließlich bedeutet "eingebaut" Pythons eingebaute Namen, wie str oder int oder file.

Also wenn du das ausgelassen hast global anweisung, dann würde Python nach dem Namen suchen motor_stop (und die anderen Funktionsnamen) wie folgt:

  1. Lokal: Gibt es eine motor_stop in dieser Funktion definiert?Nein.Mach weiter.
  2. Einschließenden: Ist diese Funktion in einer anderen Funktion definiert?Nein, also gilt die Regel "Einschließen" nicht.Mach weiter.
  3. Global: Gibt es eine motor_stop auf der obersten Ebene des Programms definiert?Ja.Hab es gefunden.
  4. (Vordefiniert):Diese Regel wird überhaupt nicht überprüft, da der Name von der "globalen" Regel gefunden wurde.

Alle Ihre Funktionen sind auf der obersten Ebene Ihres Programms definiert, sodass die "globale" Regel sie findet, ohne dass die global Anweisung.Dies sollte Ihr Leben ein wenig einfacher machen.

Nun zu Ihrer Hauptfrage:warum Ihr Code für immer wiederholt wird.Das liegt daran, dass die Testbedingung Ihre while schleife wird niemals falsch werden.Du bist aufgesprungen while direction == "fwd", und der Code in der while schleife ändert nie die direction variabel.Jedes Mal, wenn es das Ende der Schleife erreicht, kehrt es zurück, um den Zustand erneut zu testen.Der direction variable enthält noch die Zeichenfolge "fwd", und so läuft die while-Schleife ein zweites Mal.Dann die direction variable enthält noch die Zeichenfolge "fwd", und so läuft es ein drittes Mal.Und so weiter und so weiter.

Eine Möglichkeit, das zu verlassen while schleife, wenn Sie möchten, dass es beendet wird, wäre das Setzen der direction variabel zu etwas anderem, wie "stop", wenn du aufhören willst.(ZB nachdem Sie angerufen haben motor_stop()).Eine andere Möglichkeit wäre die Verwendung des return anweisung, um die Funktion an diesem Punkt zu beenden.Aber mein Vorschlag wäre, das zu verwenden break anweisung stattdessen, was bedeutet "Verlasse an diesem Punkt sofort die Schleife, in der ich mich befinde." Es funktioniert auf beiden while schleifen und for schleifen, und ist eine sehr nützliche Aussage, über die man Bescheid wissen sollte.Es sieht so aus, als ob du deine willst while schleife zum Beenden bei jedem Anruf motor_stop(), also gibt es zwei Orte, an die Sie einen setzen würden break Anweisung:

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

Es gibt ein paar andere Änderungen, die ich vorschlagen würde.Zuerst rufst du an get_range() dreimal in Ihrer Schleife, aber Sie müssen es wirklich nur einmal aufrufen.Sie haben das Ergebnis bereits einem zugewiesen dist variable, warum also nicht diese Variable verwenden?

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

Und zweitens gibt es keinen Weg in die while schleife für direction nicht "fwd" zu sein, also das Finale else ist unnötig, und Ihre Funktion kann werden:

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

Schließlich haben Sie einen Funktionsparameter mit dem Namen arg, was ein Name ist, der nichts darüber aussagt, wofür er verwendet wird.Sie weisen es sofort einer Variablen namens zu direction, was ein viel besserer Name ist.Warum also nicht das an erster Stelle als Parameternamen verwenden?Es gibt keine Regel, die die Parameter einer Funktion angibt müssen werde "arg" genannt;sie können beliebig genannt werden (außer einem der reservierten Wörter von Python wie break oder if).Geben wir Ihrer Funktion also einen aussagekräftigeren Parameternamen, der sie noch weiter vereinfacht:

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

Dort.Das ist viel einfacher zu lesen und zu verstehen, und es sollte das Problem lösen, das Sie von Ihrem gesehen haben while schleife wird nicht verlassen, wenn das Auto einem Objekt zu nahe kommt.

(Es gibt immer noch ein mögliches Problem, das ich sehen kann, nämlich dass die while-Schleife möglicherweise nicht beendet wird, während das Auto vorwärts fährt, obwohl Sie die "Vorwärts" -Taste losgelassen haben - aber ich müsste sehen Ihre motor_forward() code, um zu wissen, wie man das löst.Es könnte so einfach sein wie das Setzen eines break erklärung nach motor_forward(), in welchem Fall es wirklich keine Notwendigkeit für eine geben würde while schleife überhaupt - aber ich müsste wissen, wie deine motor_forward() code interagiert mit webiopi und wie der Ereignisbehandlungscode von webiopi funktioniert.Nichts davon weiß ich im Moment, also werde ich beantworten, welche Probleme ich jetzt beantworten kann, auch wenn meine Antwort unvollständig ist, anstatt Sie ohne Antwort zu lassen.)

Bearbeiten von Mark: Hier ist der motor_forward-Code:

 def motor_forward():
     GPIO.output(M1, GPIO.HIGH)
     GPIO.output(M2, GPIO.LOW)
     string = "echo 0=130 > /dev/servoblaster"
     os.system(string)

Andere Tipps

Versuchen Sie das - Sie stoppen immer auf dem Reichweite, möchten jedoch in Richtung Anhalten

generasacodicetagpre.

btw Sie benötigen nicht nur das (ARG), wenn Sie es aufweisen

drucken Sie arg

Die PARENS in der Anrufsignatur gibt es, um ihr ein PARM in eine Funktion zu zeigen

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top