Für kleine FSMs mit wenig States und Übergängen bzw. Übergangsbedingungen sehe ich auch vorteile bei der graphischen Beschreibung. Auch zu Dokumentationszwecken wo Leute einen Überblick über das System erhalten sollen.
Wird eine FSM größer so herrscht dort schnell die Unübersichtlichkeit. Da ist es für mich (!) deutlich übersichtlicher das textuell/tabellarisch zu sehen.
Ich komme aus der programmierbaren Logik-Ecke und da sind FSMs sehr wohl getaktet und reagieren nicht unmittelbar auf Events. Ein "immer" ist in einigen Branchen demnach nicht korrekt. Aus System-Sicht ist das was du schreibt aber schon in Ordnung, da geht man weniger auf diese Details von Zeitabläufen und Synchronität ein.
Breakpoints ließen sich wohl realisieren wenn bei der Berechnung eines Zustands, was bei Änderungen an den Eingängen, im periodischen Raster (getaktete FSM) oder nach einem Wechsel eines Zustands geschieht die Abarbeitung anhält. Auch ließe sich auf bestimmte Eingangs-Kombination oder Werten von Ausgängen triggern.
Ein Einfrieren ließe sich ja auch über Breakpoint bzw. die Anhaltefunktion realisieren. Das sollte dann natürlich nur die eine FSM anhalten und nicht die ganze Logic Engine. Auch ein Trace/History wäre hilfreich um zu sehen wieso man in einem Zustand gelandet ist oder woher man kam. Eine Live-Anzeige wird schwierig wenn man häufige Zustandsübergänge hat.
Noch eine Ergänzung: vieleicht sollte man FSMs und LUTs, so wie ichs oben im vorherigen Post beschrieben habe, auch auseinanderhalten. Mit LUTs kann man FSMs realisieren, aber es ist nicht deren Kernaufgabe. Eigentlich sinds ja auch nicht mal LUTs sondern eine Art if-elsif-Zweige
Hinzugefügt nach 20 Minuten 12 Sekunden:
Beispiel: Wir schalten um 3 Uhr ein und und um 5 aus. Wenn eine Bewegung erkannt wird schalten wir unmittelbar aus.
Zwischen einschalten der Ventile 1 und 2 vergehen 5 Minuten. Alles sollte man sich als Tabelle vorstellen, links die Eingänge, rechts die Ausgänge.
Dann pro Zeile ein Fall der bei der Ausführung analysiert wird. Zeilen weiter oben haben höhrere Priorität.
Eingänge:
- R (Reset, bool) -> Neustart
- B (Bewegungsmelder, bool) -> Abschalten
- T (Timer, Event, Jede Minute)
- U (Aktuelle Uhrzeit)
Lokal genutzte Variablen oder Realisiert über externen Feedback (Ein- und Ausgänge)
- ST (State, string, Default: "off")
Ausgänge:
- V1 (Ventil 1, bool)
- V2 (Ventil 1, bool)
Legende:
X = don't care
- = keine Zuweisung
E = Event
Tabelle:
Zeile 1 (Reset-Fall, Abschalten):
Eingangsfilter: ST = X, R = true, B = X, T = X, U = X
Ausgangszuweisung: ST = "off", V1 = false, V2 = false
Zeile 2 (Bewegungsmelder):
Eingangsfilter: ST = "on" OR "on_delay",R = false, B = true, T = X, U = X
Ausgangszuweisung: ST = "off", V1 = false, V2 = false
Zeile 3 (einschalten):
Eingangsfilter: ST = "off", R = 0, B = true, T = E, U = 3uhr
Ausgangszuweisung: ST = "on_delay", V1 = true, V2 = false
Zeile 4 (einschaltverzögerung):
Eingangsfilter: ST = "on_delay", R = false, B = false, T = E, U = 3uhr 5 minuten
Ausgangszuweisung: ST = "on", V1 = true, V2 = true
Zeile 5 (abschalten, Fängt die Fälle der inaktiven Zeit):
Eingangsfilter: ST = "on", R = false, B = false, T = E, (U > 5uhr) OR (U < 3uhr)
Ausgangszuweisung: ST = "off", V1 = false, V2 = false
Ich hoffe man verstehts einigermaßen. So spät am Abend ist das schon eine Meisterleistung