Thread|ing für Roboter?

  • Hallo,

    Habe es soweit geschafft meinen roboter über pygame und tkinter zu steuern, wobei mir pygame symphatischer ist.
    Das Teil fährt jetzt sauber, würde aber gerne eine funktion für einen Wischer (mit Servo.....später Kamera tilt welcher sich auch während der Fahr steuern lässt) hinzufügen welche man an und abschalten kann.

    Nun ist mein Problem dass Programme ja step by step abgearbeitet werden. Habe etwas von Threads bzw threading gelesen.

    Kann mir jemand erklären was das genau ist bzw wie ich es anwenden könnte?


    mfg
    saixo

  • Wenn du ein Script startest läuft es als ein Prozess bzw Thread und wird der Reihe nach abgearbeitet. Jede Zeile wird quasi nacheinander behandelt und die nachfolgende kann erst ausgeführt werden wenn die vorherige beendet bzw fertig ist.
    Am besten mit dem Finger jede einzelne Zeile von oben nach unten abfahren und überlegen was er dort macht...
    Beispiel:

    [code=php]while True:
    print "schleife.."
    time.sleep(1)
    print "fertig"[/php]

    Die print Zeile wird solange nicht ausgeben wie die Schleife beschäftigt ist. Erst wenn die Schleife unterbrochen wird, also die Bedingung "True" geändert wird, erfolgt die Ausgabe von "fertig".


    Für Dein Anliegen gäbe es nun mehrere verschiedene Möglichkeit - wie eigentlich immer. Es muss nämlich nicht unbedingt 'threading' sein.

    • Die Aufgabe auf zB. einen microController auslagern.
    • Ein Script oder Befehl im Hintergrund ausführen lassen.

      • Es kann auch permanent im Hintergrund laufen und wartet auf "Befehle"
    • Eine Funktion mithilfe 'threading' vom Hauptscript abkoppeln


    Zu 1.:
    So mache ich das bei mir: Ein Arduino dient als Schnittstelle zwischen Motoren, Sensoren usw und schickt kontinuierlich alle Informationen zum Raspberry welcher wiederum Entscheidungen trifft oder allg. Befehle umsetzt. Ein Arduino kann aber kein Threading, kann also auch nur eins gleichzeitig machen.

    Zu 2.:
    Scripte oder Befehle im Hintergrund ausführen ist relativ einfach. Hier unterscheide ich jetzt aber 2 Zustände:
    Entweder es wird einfach nur stumpf in den Hintergrund geschickt um zB irgendwas zu kopieren und es beendet sich dann selbst (bzw man kann es auch killen)...
    Oder (und das betrifft den Unterpunkt) es läuft unabhängig vom Hauptscript ebenfalls die ganze Zeit und wird vom Hauptscript dazu aufgefordert etwas zu 'machen'. Dabei könnte dieses Script zum Beispiel einen Socket laufen haben wohin sich das Hauptscript verbindet und ein Command absetzt. Oder es überwacht eine sog. FIFO Datei wohin das Hauptscript ein Command rein schreibt.

    Zu 3.:
    Auch das nutze ich mit meinem RoPi Projekt um gleichzeitig in nur einem Script mehrere Socket-Verbindungen handhaben zu können.. Dazu erstellst du eine Funktion die dann bei Bedarf in einem weiteren Thread ausgeführt wird.


    Zum einzelnen mehr wenn du dich für einer der Möglichkeiten entschieden hast ;)

  • Hallo, erstaml ein Dankeschön für diese ausführliche Antwort :)

    Nummer 2 scheint mir am angenehmsten, habe es auch schon versucht, leider komme ich nicht drauf wie ich ein pythonscript killen kann ohne alle python scripte zu killen. Hab was gelesen dass die alle ne Nummer bekommen und man sie mit dieser nummer killen kann. Habe aber die Befürchtung dass diese Nummern nicht immer gleich sein werden je nach Reihenfolge.

    mfG
    saixo

  • Also die Sache bei 2. ist folgendes: Einmal gestartet lässt es sich nur unsanft beenden - oder es beendet sich nach Programmablauf selbst.
    Auf den ersten Blick ist es eher untypisch ein Python-Script durch ein anderes auszuführen. Da du aber kein gegenseitiges blocken haben möchtest, bleibt dir eben nur übrig es im Hintergrund auszuführen oder in einem separaten Thread...

    Jeder Prozess (also auch jedes Script) erhält eine eindeutige Kennung: Die sog. Process-ID. Also eine Process-Identifikations-Nummer, kurz: PID
    Über diese PID kann der Prozess beeinflusst werden.

    Ein Prozess einfach so gewaltsam zu killen ist aber ebenfalls unschön. Besser wäre es in das Script eine gewisse Funktion einzubauen um es sauber zu beenden, es reagiert dann also auf ein Signal woraufhin es sich augenblicklich beendet und ggf sogar auch noch die verwendeten GPIO's zurück setzen kann - würde man es gewaltsam killen geht letzteres nicht (nur wenn man auch darauf reagieren würde, aber das wäre jetzt zu kompliziert :))
    Siehe dazu auch > hier <
    Problem hierbei is allerdings das Python nicht ohne zusätzliches die PID anderer Prozesse ermitteln kann - ich bevorzuge dafür das Module psutil

    Aus einem Python Script heraus ein anderes Script oder Prozess zu starten und dann auch wieder zu killen ist allerdings nichts was ich jemandem Raten würde :fies: Es nur zu starten und nicht weiter zu beachten ist nicht wirklich tragisch (& ans Ende einfügen sodass es im Hintergrund ausgeführt wird), aber naja 2 Python Scripts... Da würde ich dann doch lieber Threading bevorzugen ;)

    Threading Beispiel:
    [code=php]
    from __future__ import print_function
    import threading, time, sys
    # thread docu: http://www.tutorialspoint.com/python/python_multithreading.htm
    # Dictionary docu: http://www.tutorialspoint.com/python/python_dictionary.htm
    dictionary = {}

    def worker():
    while dictionary['running']:
    print("worker: ..Im super heavy busy..")
    time.sleep(2)
    print("worker: ..puh..")
    time.sleep(2)

    try:
    print('Starting "worker" Thread')
    dictionary['running'] = True
    worker_thread = threading.Thread(target=worker)
    worker_thread.start()
    while True:
    time.sleep(4.5)
    print('main: keep going!')
    except (KeyboardInterrupt, SystemExit):
    print("\nStopping 'worker' Thread")
    dictionary['running'] = False
    print("\nQuit\n")
    [/php]Beenden durch drücken von STRG+C

  • Vielen lieben Dank für die Umfassende Hilfestellung. Werde es gleich mal ausprobieren :)

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!