Taktung von Threads (Ampelsteuerung)

  • ... agieren sie selbstständig bzw verbinden sich ggf zu anderen Ampeln ...

    Nette Idee, dass die Ampeln dann untereinander kommunizieren. Das wird dann aber ziemlich kompliziert, da jede Ampel über die AmpelTopology Wissen haben müssen.
    ... möchte mal Wissen wie ein Dirigent reagiert wenn plötzlich im Konzert ein Bratscher einer ersten Geige zuruft was sie zu tun hat :lol:

    :no_sad: ... Kein raspiBackup - kein Mitleid ... :no_sad:

    Mein Raspberry Zoo

    3 * RPi1B, 2 * RPi3B, 2 * RPI4, 1 * CM4, 1 * RPi5

  • Viel müssen die nicht voneinander wissen, nur ggf welche Richtung die schalten und was deren aktueller Schaltzustand is - vorallem aber hast du an einer Kreuzung meistens nur 2 Fahrtrichtungen, also 2 Doppelschaltungen, also musst du nicht von 3 anderen den Schaltzustand wissen sondern nur von einer ;)

  • Interessant wie man doch aus so eine Standardanfängeraufgabe bei der Pi mit Python - der Ampel mit seinen 3 LEDs - ein anspruchsvolles Projekt generieren kann. Vor allen Dingen kann man da sehr schnell in die Tiefen von Kommunikations- und Synchronisationsthemen eintauchen.

    Ich werde erst mal den Weg des Conductors mit seinem Taktschlag weiterverfolgen (events). Das sollte relativ schnell hinzubekommen sein. Danach denke ich über die Anforderung (1) nach wie man das hinbekommen kann und dann Anforderung (2). Ich poste dann den Code hier und hoffe er ist noch recht einfach zu lesen. Es sollten für (1) nur noch 2-3 kleinere Klassen dazukommen.

    :no_sad: ... Kein raspiBackup - kein Mitleid ... :no_sad:

    Mein Raspberry Zoo

    3 * RPi1B, 2 * RPi3B, 2 * RPI4, 1 * CM4, 1 * RPi5

  • Jedem der mal mit Threads spielen will und sie kennenlernen will empfehle ich mal eine einfache Ampelsteuerung mit autarken Ampeln zu implementieren . Man bekommt da eine Menge Threading Insights ...

    :no_sad: ... Kein raspiBackup - kein Mitleid ... :no_sad:

    Mein Raspberry Zoo

    3 * RPi1B, 2 * RPi3B, 2 * RPI4, 1 * CM4, 1 * RPi5

  • Jetzt läuft die Ampel taktgesteuert :)

    Erst ein Testpattern dass alle 2^3 LED Kombinationen einmal durchgeht, dann blinken die gelben LEDs und dann beginnt die normale Ampelsteuerung - und das in einer Endlosschleife.

    Code dazu findet sich hier. Wer sich die blinkenden LEDs ansehen will - die blinken hier (Testpattern, blinkendes Gelb und normale Ampelphasen).

    War schon etwas Zeit notwendig um diese Threadkommunikation hinzubekommen :-/

    Drei Dinge habe ich festgestellt:

    1) Wenn ich Event benutzt habe um den Takt vorzugeben, kam es immer wieder vor dass eine Ampel den Takt verpasste und alles ausser Triit kam. Nachdem ich dann Condition mit notifyAll benutzt habe funktioniert es perfekt. Warum - das verstehe ich aber ehrlich gesagt nicht so ganz :(

    2) Die Endlosschleife wird mit CTRL-C beendet. Da hatte ich immer ein Hänger weil die Ampelthreads nicht beendet wurden und musste sie hart per kill beenden. Ursache: Da sie im wait auf den Takt hingen bekamen sie nie mit wenn sie sich beenden sollten. Lösung: Vor dem stop Call wird einmal ein notifyAll losgeschickt, dass die Ampeln aus ihrem Wartezustand rauskommen.

    3) Ein Ampelsteuerungsszenario ist gut geeignet um sich mal mit Threads und Python zu befassen und einzuarbeiten :shy:

    :no_sad: ... Kein raspiBackup - kein Mitleid ... :no_sad:

    Mein Raspberry Zoo

    3 * RPi1B, 2 * RPi3B, 2 * RPI4, 1 * CM4, 1 * RPi5

    Edited 2 times, last by framp (July 10, 2018 at 9:42 PM).

  • Hi,
    sauber :thumbs1:

    aber wie ist das in der Realität: ist da nicht eine Pause drin - wenn die eine Ampel auf rot springt ... wird die andere Ampel doch erst nach einer kurzen Verzögerung rot/gelb

    Ja, wie gesagt: mit Sicherheit ein lehrreiches Beispiel ;) ...

    cu,
    -ds-


  • (Testpattern, blinkendes Gelb und normale Ampelphasen).

    Rot-gelb auf der einen und gelb auf der anderen Ampel?
    Damit würde ich binnen kürzester Zeit mein Auto zermanschen.
    Ich kenne nämlich an so einigen Kreuzungen die Ampelphasen ganz genau und fahre mit 70 genau beim Wechsel von Rot nach rot-gelb rüber. Wenn dann der liebe Taximann bei gelb noch durchfährt, dann sind unsere beiden Autos etwas onduliert.

  • Ihr habt ja Recht :blush: Mir war die Logik der Steuerung mit Threads erst mal wichtig. Da die Steuerungsinfrastruktur nun funktioniert war es ein Leichtes eben noch zwei realitätsnähere Ampelprogramme zu erstellen. Den Code und das Video habe ich updated und es sind da dann die drei Versionen zu sehen. Aber Vorsicht: Das Video ist jetzt etwas größer geworden und ich war zu faul das zu verkleinern. Also nicht mit einer ISDN Verbindung ansehen :shy:

    Wer Lust hat kann ja weitere Ampelsteuerungen erstellen und hier vorstellen. Sind nur 6 LEDs am GPIO nötig ;)

    Das Format ist recht einfach. Anbei die drei Ampelprogramme, die im Video zu sehen sind:

    :no_sad: ... Kein raspiBackup - kein Mitleid ... :no_sad:

    Mein Raspberry Zoo

    3 * RPi1B, 2 * RPi3B, 2 * RPI4, 1 * CM4, 1 * RPi5

    Edited once, last by framp (February 2, 2015 at 10:16 PM).

  • Ein paar Tips für deine zukünftigen Python Codes: :fies:

    - Einheitliche Einrückungen. TABs und Leerzeichen zu vermischen mag Python i.d.R. überhaupt nicht.. "def signal_handler" verwendet 8 Leerzeichen, die Anweisungen danach aber TABs und noch weiter unten wird in "class StoppableThread" wieder Leerzeichen genutzt, aber in der darauffolgenden Classe wieder TABs :-/
    - Benutzer definierte Variablen die man verstellen könnte, am Anfang des Scripts platzieren, damit man sowas wie DEBUG oder die SLEEP_*'s nicht irgendwo mitten im Script findet..
    - In Python können zwischen Variable, = und dem Wert ruhig Leerzeichen sein - das macht es wie ich finde übersichtlicher. Das gilt auch für " , " Sachen, da kann man nach dem Komma auch ein Leerzeichen einfügen um es besser lesbar zu machen ;)
    - GPIO.setmode finde ich in Form von BCM angenehmer da dann die tatsächliche GPIO Nummerierung verwendet wird, nicht die pin# vom PCB.
    - Geht das nicht mit was eleganterem als mit time.sleep ?
    - Threads lassen sich also doch beenden? Hatte hier schon unzählige Diskussionen das es in python nicht möglich/vorgesehen wäre Threads zu beenden... :s

    Ansonsten aber sehr geil umgesetzt :thumbs1:

  • Danke für die Kommentare.

    - Einheitliche Einrückungen. TABs und Leerzeichen zu vermischen mag Python i.d.R. überhaupt nicht.. "def signal_handler" verwendet 8 Leerzeichen, die Anweisungen danach aber TABs und noch weiter unten wird in "class StoppableThread" wieder Leerzeichen genutzt, aber in der darauffolgenden Classe wieder TABs :-/

    Mein Editor benutzt tabs für Einrückungen. Die von Dir zitierten Stellen sind genau diejenigen, wo ich Codesnippets per Copy/Paste aus dem Browser kopiert habe (Der signal_handler stammt aus einem Thread von Dir hier im Forum :) . Ich benutze keine UnderscoreVariablennamen)

    Quote

    - Benutzer definierte Variablen die man verstellen könnte, am Anfang des Scripts platzieren, damit man sowas wie DEBUG oder die SLEEP_*'s nicht irgendwo mitten im Script findet..

    Jein - ich habe gerne soweit wie möglich die Konstanten zusammen mit ihren Elementen, wo die Konstanten benutzt werden. Aber da es ja auch als Beispiel genutzt werden können soll, habe ich ein paar globale Konstanten wie vorgeschlagen nach vorne gezogen.

    Quote

    - In Python können zwischen Variable, = und dem Wert ruhig Leerzeichen sein - das macht es wie ich finde übersichtlicher. Das gilt auch für " , " Sachen, da kann man nach dem Komma auch ein Leerzeichen einfügen um es besser lesbar zu machen ;)

    Das ist Geschmackssache. Wenn ich nicht irre steht das auch in den PIPs.

    Quote

    - GPIO.setmode finde ich in Form von BCM angenehmer da dann die tatsächliche GPIO Nummerierung verwendet wird, nicht die pin# vom PCB.

    Auch Geschmackssache

    Quote

    - Geht das nicht mit was eleganterem als mit time.sleep ?

    Was meinst Du damit?

    Quote

    - Threads lassen sich also doch beenden? Hatte hier schon unzählige Diskussionen das es in python nicht möglich/vorgesehen wäre Threads zu beenden... :s

    Als ich das Problem erkannt hatte fand ich bei der netzsuche nur Hinweise, dass es nicht geht und habe es dann über Subclassing erschlagen. Dass das Thema hier im Forum schon durchgekaut wurde ist mir nicht bei meiner Intenetsuche (Nicht Forumssuche) untergekommen. Die Forenbeiträge dazu tauchen in der Hitlist wohl erst weiter später auf.

    Quote

    Ansonsten aber sehr geil umgesetzt :thumbs1:

    Merci

    :no_sad: ... Kein raspiBackup - kein Mitleid ... :no_sad:

    Mein Raspberry Zoo

    3 * RPi1B, 2 * RPi3B, 2 * RPI4, 1 * CM4, 1 * RPi5

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!