Domanda

Sto cercando di controllare la mia auto Raspberry Pi tramite wireless e webiopi.La funzione di base funziona bene-avere l'interfaccia in cui faccio clic su fwd e l'auto andrà avanti e quando rilascio il pulsante si fermerà.

Ora voglio integrare il sensore di distanza ad ultrasuoni in modo che quando guido in avanti, l'auto dovrebbe fermarsi quando qualcosa è di fronte ad essa.Lo faccio andare dove quando faccio clic sul pulsante fwd, l'auto guiderà e si fermerà quando qualcosa è nel raggio d'azione, ma si fermerà solo quando qualcosa è nel raggio d'azione e non quando rilascio il pulsante.Il mio ciclo while è in qualche modo in loop (bloccato) e non legge la funzione del pulsante di rilascio da webiopi.

Qualcuno può per favore aiutare-ci sono stato per giorni e non sono sicuro di dove sto andando male: - (

Ecco il loop dal mio script 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()

Ed ecco il codice dalla mia chiamata alla funzione wei-pii:

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

Questo è come l'ho ora ma ancora non funziona (sono un noob totale :-) ) :

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

Forse un piccolo passo avanti.Vedi che webipi usa il proprio 'loop' e ho aggiunto il codice del loop per verificare quale sia lo stato del motore GPIO e la distanza e se il motore è in funzione e se la distanza è troppo breve, quindi fermarsi.Auto si muove ora quando premo il pulsante avanti e si ferma quando lo rilascio e quando si sposta in avanti e la distanza è inferiore a 30 cm si fermerà.L'unico problema è che quando la distanza è troppo breve e premo il pulsante avanti troppo velocemente più volte, ora ottengo un " GPIO.uscita(Eco,1) _webiopi.GPIO.InvalidDirectionException:Il canale GPIO non è un OUTPUT" errore: - (.

Il codice ora assomiglia a questo:

 def go_forward(direction):
   motor_forward()

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

Soluzione

Risponderò al tuo problema principale in un minuto, ma prima voglio menzionare qualcosa che stai facendo come principiante di Python, che sta rendendo la tua vita più complicata di quanto debba essere.

Non c'è bisogno di global dichiarazione che hai all'inizio della tua funzione.In Python, devi solo usare il global dichiarazione se si desidera scrivere ad una variabile globale.Se tutto quello che devi fare è Leggete la variabile, o chiamare la funzione, allora non c'è bisogno per il global dichiarazione.Tutti i nomi utilizzati nella funzione, siano essi nomi di variabili o nomi di funzioni, verranno cercati nel seguente ordine:locale, racchiudente, globale, incorporato."Locale" significa nomi definiti all'interno della tua funzione, come il tuo direction variabile."Racchiudere" è una regola utilizzata quando si definisce una funzione all'interno di un'altra funzione.Questo è utile in molte situazioni, ma è un argomento un po ' avanzato e non devi preoccuparti per ora."Globale" indica i nomi (di variabili, funzioni o classi) definiti al livello superiore del programma, ad esempio motor_stop funzione tra gli altri.E infine, "incorporato" significa i nomi incorporati di Python, come str o int o file.

Quindi se hai lasciato fuori il global dichiarazione, quindi Python cercherebbe il nome motor_stop (e gli altri nomi di funzione) come segue:

  1. Locale: C'è un motor_stop definito in questa funzione?No.Andiamo avanti.
  2. Racchiudere: Questa funzione è definita all'interno di un'altra funzione?No, quindi la regola "allegare" non si applica.Andiamo avanti.
  3. Globale: C'è un motor_stop definito al livello superiore del programma?Sì.Trovato.
  4. (Incorporato):Questa regola non viene mai verificata, perché il nome è stato trovato dalla regola "globale".

Tutte le tue funzioni sono definite al livello superiore del tuo programma, quindi la regola "globale" le troverà senza bisogno di global dichiarazione.Questo dovrebbe rendere la tua vita un po ' più semplice.

Ora per la tua domanda principale:perché il tuo codice è in loop per sempre.Questo perché la condizione di prova tua while loop non diventerà mai falso.Voi siete impazziti while direction == "fwd", e il codice dentro il while loop non cambia mai il direction variabile.Quindi ogni volta che raggiunge la fine del ciclo, torna a testare di nuovo la condizione.Il direction la variabile contiene ancora la stringa "fwd", e così il ciclo while corre una seconda volta.Poi il direction la variabile contiene ancora la stringa "fwd", e così corre una terza volta.E così via, e così via.

Un modo per uscire dal while loop quando si desidera che esca sarebbe quello di impostare il direction variabile a qualcos'altro, come "stop", quando vuole fermarsi.(Ad esempio, dopo aver chiamato motor_stop()).Un altro modo sarebbe quello di utilizzare il return dichiarazione per uscire dalla funzione in quel punto.Ma il mio suggerimento sarebbe di usare il break dichiarazione invece, che significa " A questo punto, esci immediatamente dal ciclo in cui mi trovo."Funziona su entrambi while loop e for loop, ed è una dichiarazione molto utile da conoscere.Sembra che tu voglia il tuo while loop per uscire ogni volta che si chiama motor_stop(), così ci sono due posti Lei metterebbe un break dichiarazione:

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

Ci sono alcune altre modifiche che suggerirei di fare.Per prima cosa, chiami get_range() tre volte nel tuo ciclo, ma hai davvero solo bisogno di chiamarlo una volta.Hai già assegnato il suo risultato a dist variabile, quindi perché non usare quella variabile?

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

E in secondo luogo, non c'è modo all'interno del while loop per direction non essere "fwd" , quindi il finale else non è necessario e la tua funzione può diventare:

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

Infine, hai un parametro di funzione chiamato arg, che è un nome che non ti dice nulla su ciò per cui è usato.Lo si assegna immediatamente a una variabile chiamata direction, che è un nome molto migliore.Quindi perché non usarlo come nome del parametro in primo luogo?Non esiste una regola che dice i parametri di una funzione dovere essere chiamato"arg";possono essere chiamati qualsiasi cosa tu voglia (tranne una delle parole riservate di Python come break o if).Quindi diamo alla tua funzione un nome di parametro più significativo e questo lo semplificherà ulteriormente:

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

C'.Questo è molto più facile da leggere e capire, e dovrebbe risolvere il problema che stavi vedendo del tuo while loop non esce quando l'auto si avvicina troppo a un oggetto.

(C'è ancora un possibile problema che posso vedere, che è che il ciclo while potrebbe non uscire mentre l'auto sta guidando in avanti, anche se hai rilasciato il pulsante "avanti" but ma dovrei vedere il tuo motor_forward() codice per sapere come risolvere quello.Potrebbe essere semplice come mettere un break dichiarazione dopo motor_forward(), nel qual caso non ci sarebbe davvero bisogno di un while ma dovrei sapere come il tuo motor_forward() il codice interagisce con webiopi e come funziona il codice di gestione degli eventi di webiopi.Nessuno dei quali so in questo momento, quindi ho intenzione di rispondere a quali problemi posso rispondere ora anche se la mia risposta è incompleta, piuttosto che lasciarti senza alcuna risposta.)

Modifica di Mark: Ecco il codice motor_forward:

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

Altri suggerimenti

Prova questo - si fermano sempre sulla gamma ma potrebbe voler fermare in direzione

  if get_range() < 30:
      motor_stop()
  elif direction == "fwd":
      motor_forward()
  else:
      motor_stop()
.

btw non è necessario (ARG) solo ARG quando lo fai riferimento

Stampa arg

I parenti nella firma della chiamata sono lì per mostrare il suo parm a una funzione

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top