Und falls der Quellcode von MegaPi als Vorbild genommen wird, ist auch keine Besserung zu erwarten. Bei der Beseitigung von global ist auch zu beachten, dass die Funktion 'sensorCallback' in einem anderen Thread läuft als 'work'.__deets__ hat geschrieben:Den globalen Zustand kann man natuerlich auch noch beseitigen, dazu habe ich gerade keine Lust. Ich denke mal es wird eh gefrickelt wie es nur geht... wie immer beim Pi.. *seufz*
threading Probleme
@__deets__: ob es eine gute Idee ist, ständig neue Reads abzusetzen, obwohl der vorherige möglicherweise noch gar nicht fertig ist, bezweifle ich mal. Normalerweise würde ein Callback den nächsten anstoßen.
Code: Alles auswählen
import time
from megapi import MegaPi
class UltrasonicSensor(object):
def __init__(self, bot, port):
self.bot = bot
self.port = port
self._request_callback()
self.value = 0
def _request_callback():
self.bot.ultrasonicSensorRead(self.port, self._callback)
def _callback(self, value):
self.value = value
self._request_callback()
def main():
bot = MegaPi()
bot.start()
sensor = UltrasonicSensor(bot, 7)
while True:
if sensor.value < 50:
stop()
else:
forward()
time.sleep(0.1)
if __name__ == '__main__':
main()
Hallo Sirus2,
ich habe noch mal eine Verständnisfrage. In der SPS Programmierung kann ich einen Funktionsbaustein Programmieren der Ein und Ausgangsvariablen hat.
Wenn die Logik zum auslesen des Sensors dieselbe ist kann ich diese für Ultraschall und Kompasse nutzen. Ich übergebe dann an die Funktion den Port und den Befehl und erhalte die jeweilige Variable zurück.
Ich habe mal das Programm so abgeändert weiß aber nicht ob das so richtig ist?
ich habe noch mal eine Verständnisfrage. In der SPS Programmierung kann ich einen Funktionsbaustein Programmieren der Ein und Ausgangsvariablen hat.
Wenn die Logik zum auslesen des Sensors dieselbe ist kann ich diese für Ultraschall und Kompasse nutzen. Ich übergebe dann an die Funktion den Port und den Befehl und erhalte die jeweilige Variable zurück.
Ich habe mal das Programm so abgeändert weiß aber nicht ob das so richtig ist?
Code: Alles auswählen
import time
from megapi import MegaPi
class ReadSensor(object):
def __init__(self, bot, port, funktion):
self.bot = bot
self.port = port
self.funktion = funktion
self._request_callback()
self.value = 0
def _request_callback():
self.bot.self.funktion(self.port, self._callback)
def _callback(self, value):
self.value = value
self._request_callback()
def main():
bot = MegaPi()
bot.start()
Ultrasonic = ReadSensor(bot, 7, ultrasonicSensorRead)
Compass = ReadSensor(bot, 8, compassRead)
while True:
if Ultrasonic.value < 50:
stop()
else:
forward()
if Compass.value < 50:
stop()
else:
forward()
time.sleep(0.1)
if __name__ == '__main__':
main()
@Sirius3 wo du recht hast... allerdings ist auch dein Ansatz nur ein erster Schritt IMHO. Denn so ballert man die serielle Verbindung zu, und ggf. kommen Motordaten oder andere nicht verzoegert zum Zuge. Da waere wahrscheinlich noch ein Throttling obendrauf nett.
@emilio20 Programmieren ist nicht raten. self.bot.self.funktion funktioniert nicht (und das es das nicht tut kannst du auch alleine ausprobieren).
Was du brauchst ist
als Parameter. Den bot als Argument kann man dann gleich eliminieren, weil er eh an der "bound method" die du uebergeben hast "dranhaengt".
Und zum Aufruf in _request_callback sollte
ausreichen.
@emilio20 Programmieren ist nicht raten. self.bot.self.funktion funktioniert nicht (und das es das nicht tut kannst du auch alleine ausprobieren).
Was du brauchst ist
Code: Alles auswählen
Ultrasonic = ReadSensor(7, self.ultrasonicSensorRead)
Und zum Aufruf in _request_callback sollte
Code: Alles auswählen
self._funktion(self.port, self._callback)
Hallo
das Script von Sirus2 funktioniert leider nicht. Fehler erhalte ich keinen wenn ich es Starte.
das geht
das Script von Sirus2 funktioniert leider nicht. Fehler erhalte ich keinen wenn ich es Starte.
Code: Alles auswählen
import time
from megapi import MegaPi
class UltrasonicSensor(object):
def __init__(self, bot, port):
self.bot = bot
self.port = port
self._request_callback()
self.value = 0
def _request_callback():
self.bot.ultrasonicSensorRead(self.port, self._callback)
def _callback(self, value):
self.value = value
self._request_callback()
def main():
bot = MegaPi()
bot.start()
sleep(1)
sensor = UltrasonicSensor(bot, 7)
while True:
try:
if sensor.value < 50:
print "Stop"
else:
print "Forword"
print "distance:"+str(sensor.value)+" cm"
time.sleep(0.1)
except Exception,ex:
print str(ex)
if __name__ == '__main__':
main()
das geht
Code: Alles auswählen
from megapi import *
def onDistance(dist):
print "distance:",dist
if dist<50 :
#bot.encoderMotorRun(1,0);
#bot.encoderMotorRun(2,0);
print"Stop"
else:
#bot.encoderMotorRun(1,-100);
#bot.encoderMotorRun(2,100);
print "FWD"
def main():
bot = MegaPi()
bot.start()
while(1):
try:
sleep(0.2)
bot.ultrasonicSensorRead(7,onDistance);
except Exception,ex:
print str(ex)
if __name__ == '__main__':
main()
Hallo
Das Script arbeitet nicht erhalte keinen rückgabewert
testUS2.py von Sirus2
testUS3 das andere das geht.
Das Script arbeitet nicht erhalte keinen rückgabewert
testUS2.py von Sirus2
Code: Alles auswählen
pi@raspberrypi:~ $ cd robot
pi@raspberrypi:~/robot $ python testUS2.py
init MegaPi
<megapi.mSerial instance at 0x7674de90>
Code: Alles auswählen
pi@raspberrypi:~ $ cd robot
pi@raspberrypi:~/robot $ python testUS3.py
init MegaPi
<megapi.mSerial instance at 0x76796d28>
distance: 155.379302979
FWD
distance: 155.810348511
FWD
distance: 155.810348511
FWD
distance: 155.39654541
FWD
distance: 155.810348511
FWD
distance: 155.379302979
FWD
distance: 155.379302979
FWD
distance: 155.913787842
FWD
distance: 155.5
FWD
^Cpi@raspberrypi:~/robot $
Woher weisst du denn, das es nicht geht? Es sind keine print-anweisungen enthalten, die das laufen dokumentieren. Und damit sind wir auch schon beim pro-tipp: bau doch mal prints ein, um zu sehen, wo das programm ist....
Hm, da hab ich mich mit dem scrollen selbst verwirrt & die nicht gesehen.
Aber das es nicht klappt wird bei genauerem hinschauen klar... und dem waelzen des Sourcecodes vom MegaPi: tatsaechlich ist es ok, so wie ich es gemacht habe, permanent neu eine Anfrage zu schedulen. Denn die Callbacks werden ueber eine eindeutige ID abgelegt.
Was Sirius macht geht hingegen nicht, weil der Callback in einem Hintergrund-Thread aufgerufen wird, und das re-schudulen in demselbigen verhindert, dass das Programm weiter laeuft. Das nehem ich zumindest an.
Statt also selbst in UltrasonicSensor _request_callback aufzurufen, benenn das um in "read_sensor", und ruf es auf sensor in deiner Hauptschleife auf.
Aber das es nicht klappt wird bei genauerem hinschauen klar... und dem waelzen des Sourcecodes vom MegaPi: tatsaechlich ist es ok, so wie ich es gemacht habe, permanent neu eine Anfrage zu schedulen. Denn die Callbacks werden ueber eine eindeutige ID abgelegt.
Was Sirius macht geht hingegen nicht, weil der Callback in einem Hintergrund-Thread aufgerufen wird, und das re-schudulen in demselbigen verhindert, dass das Programm weiter laeuft. Das nehem ich zumindest an.
Statt also selbst in UltrasonicSensor _request_callback aufzurufen, benenn das um in "read_sensor", und ruf es auf sensor in deiner Hauptschleife auf.
@emilio20: zu den ersten beiden Zeilen der Ausgabe finde ich aber kein print. Wenn Du das Programm wirklich so ausgeführte wurde, sollte Python in Zeile 21 mit einem NameError ausssteigen.
@__deets__: es wird bei ultrasonicSensorRead nicht nur ein Callback gesetzt, sondern auch jedesmal etwas über die serielle Schnittstelle geschickt. Was Du da zu weiterlaufen, etc. annimmst, finde ich nicht im Quellcode.
@__deets__: es wird bei ultrasonicSensorRead nicht nur ein Callback gesetzt, sondern auch jedesmal etwas über die serielle Schnittstelle geschickt. Was Du da zu weiterlaufen, etc. annimmst, finde ich nicht im Quellcode.
@Sirius: das mit der Kommunikation ist richtig, aber danach kommen ja ggf. Motorsteuerbefehle - und ggf. blockiert das senden, wenn der buffer voll ist.
Zum Rest:
https://github.com/Makeblock-official/P ... api.py#L85
https://github.com/Makeblock-official/P ... pi.py#L307 (im Thread)
https://github.com/Makeblock-official/P ... pi.py#L331 (dann auch im Thread)
Damit wird also im Lesethread geschrieben, *warum* sich das verklemmt kann ich ohne Debugger auch nicht nachvollziehen, halte es aber schon fuer ziemlich wahrscheinlich - denn sonst haette emilio ja seine prints in der Konsole.
Zum Rest:
https://github.com/Makeblock-official/P ... api.py#L85
https://github.com/Makeblock-official/P ... pi.py#L307 (im Thread)
https://github.com/Makeblock-official/P ... pi.py#L331 (dann auch im Thread)
Damit wird also im Lesethread geschrieben, *warum* sich das verklemmt kann ich ohne Debugger auch nicht nachvollziehen, halte es aber schon fuer ziemlich wahrscheinlich - denn sonst haette emilio ja seine prints in der Konsole.
@Sirius3 die Zeilen belegen, dass dein re-scheduling im event-callback dazu fuehrt, dass der eigentlich nur fuer das lesen der seriellen Schnittstelle zustaendige Thread ploetzlich auch schreibt. Ich bezweifele, dass das so gewollt ist.
@emilio: Sirius3 hat einen Fehler in dem von dir geposteten Skript aufgezeigt, solange du den nicht behebst, oder das Skript postest, das du *wirklich* laufen laesst, kann man da wenig machen.
Und ich habe dir auch schon Hinweise gegeben, wie du dem Problem selbst auf die Spur kommen kannst - durch print-debugging, und du kannst zB die UltrasonicSensor so modifizieren, dass sie *kein* callback request macht, um zu schauen, ob dann deine Hauptschleife weiterlaeuft. Debuggen gehoert zum programmieren. Sonst hiesse es Eintippen.
@emilio: Sirius3 hat einen Fehler in dem von dir geposteten Skript aufgezeigt, solange du den nicht behebst, oder das Skript postest, das du *wirklich* laufen laesst, kann man da wenig machen.
Und ich habe dir auch schon Hinweise gegeben, wie du dem Problem selbst auf die Spur kommen kannst - durch print-debugging, und du kannst zB die UltrasonicSensor so modifizieren, dass sie *kein* callback request macht, um zu schauen, ob dann deine Hauptschleife weiterlaeuft. Debuggen gehoert zum programmieren. Sonst hiesse es Eintippen.