Wenn dein Problem oder deine Frage geklärt worden ist, markiere den Beitrag als "Lösung",
indem du auf den "Lösung" Button rechts unter dem entsprechenden Beitrag klickst. Vielen Dank!
Ich habe folgendes Problem mit Labview 2011:
Mein Programm zur Anlagensteuerung arbeitet mit parallelen Schleifen (Timed Loops) die ich mittels Notifier über eine Masterloop steuere.
Zudem gibt es Loops die immer laufen und nicht mit Notifiern gesteuert werden.
Das System funktioniert an sich gut, jedoch treten in meinem Programm zwei Fehler auf.
1. Schleifen bleiben zufällig irgendwann stehen. Egal ob gesteuerte oder ungesteuerte Loops. Dies scheint jedoch ein Bug in zu sein, da Ich das Programm in einem solchen Fall auch nicht mehr beenden kann (Resetting VI - Fenster). Dort hilft es dann nur Labview bzw. die Executable mittels Taskmanager abzuschießen.
2. Hin und wieder resetten sich Subvi's im laufenden Betrieb. Das ist besonders dann ärgerlich, wenn ein Regler einfach auf Null springt und dann wieder hoch regelt.
Es scheint als würden Shiftregister ihren vorherigen Wert verlieren.
Um zu verdeutlichen wie mein Programm Looptechnisch aufgebaut ist, habe aus diesem ein Beispiel erstellt in dem schlicht die eigentlichen Prozesse fehlen (Das wäre zu viel um es hochzuladen). Die Schleifen haben die gleichen Timings wie im organalen Programm.
Ich wäre Dankbar, wenn jemand Erfahrungen, Ideen oder Lösungsansätze mit mir teilen kann.
MFG: Sepp
Anzeige
12.12.2018, 10:18 (Dieser Beitrag wurde zuletzt bearbeitet: 12.12.2018 10:20 von Achim.)
Wofür genau brauchst du Timed Loops? Ich hab mit denen keine so guten Erfahrungen gemacht, aber ich würde gerne wissen, was du dir von der Verwendung so vieler Timed Loops erhoffst!
Und warum müssen ständig zyklisch Notifier gesendet werden? Das Konzept hab ich nicht verstanden.
Notifier werden doch genau 1x gesendet, um ein "Ereignis" zu mitzuteilen. Dann ist erst mal wieder Ruhe, bis zum nächsten "sporadischen" Ereignis.
Kannst du das mal erläutern?
"An sich" läuft das System somit ja nicht so gut...
A.
"Is there some mightier sage, of whom we have yet to learn?"
"Opportunity is missed by most people because it is dressed in overalls and looks like work." (Thomas Edison)
Timed Loops waren bereits ein Versuch das Problem zu beheben. Da Ich gehofft habe mit ihrem Offset und Prioritäteneinstellungen ein exaktes aufeinander fallen von Loopstarts zu verhindern.
Zu den vielen Loops ist zu sagen. Ich erwarte nicht das mein Programm in 9 Threads ausgeführt wird. Durch die vielen Loops werden Totzeiten verhindert. Wenn ich beispielsweise auf die Antwort eines Messgerätes warte, kann ich andere Geräte bereits ansprechen. Ich hatte früher das Programm in einem einzigen Zustandsautomaten laufen, was zu Durchlaufszeiten von einigen Sekunden geführt hat. Dadurch geht die Regelung vor die Hunde, die Messdaten sind nicht aktuell und die Bedienung wird zu einer Geduldsprobe.
Zu den Notifiern muss ich sagen, ja ich weis dass ich sie nicht so benutze wie vom Erfinder vorgesehen. Dies ist meine Lösung um Schleifen schlicht zu pausieren. Ich wollte so verhindern, dass ich Schleifen habe die einfach mit einer internen Case-Bedingung ausgeblendet werden. Somit erhoffe ich mir einen direkteren Start einer Schleife (da kein Wait ablaufen muss) und weniger Rechnerauslastung. Denn die Schieberegister müssen nicht ständig durch den leeren Case weitergegeben werden (Teils entstehen pro Durchlauf 48000 Datenpunkte (DBL) mit Zeitwert (DBL)).
Ich weis nicht wie Labview solche Vorgänge von der Performance handelt (große Datenmengen durchschleifen). Ich bin für Vorschläge offen, die Problematik mit "Schleifen pausieren" besser zu lösen.
Also 9 parallele Timed-Loops, das wäre wahrscheinlich sogar unter einem RT-System der Tod des Programms. Das Windows nicht mehr mit kommt, wundert mich da nicht.
Timed Loops bedeuten einen tiefen Eingriff in den Task-Scheduler. Da werden gnadenlos andere Tasks rausgehauen oder pausiert, wenn die entsprechende Timed-Loop daran ist, was abzuarbeiten. Sachen, bei denen du das Zeitverhalten nicht vorhersagen kannst, wie serielle Kommunikation u.ä., haben in einer Timed-Loop auch nichts verloren.
Gruß, Jens
Wer die erhabene Weisheit der Mathematik tadelt, nährt sich von Verwirrung. (Leonardo da Vinci)
!! BITTE !! stellt mir keine Fragen über PM, dafür ist das Forum da - andere haben vielleicht auch Interesse an der Antwort!
Danke für den Einblick in das Programmverhalten von Timed Loops, Jens.
Ich werde nächste Woche das Ganze mal "ohne" Timed Loops testen (die Schleifen für die Zeitberechnung müssen wegen anderer Programmteile so bleiben.) und Schauen ob das Absturzverhalten sich verbessert. Die reine Anzahl an Loops lässt sich vermutlich nur sehr schlecht reduzieren.
Frage noch am Rande: Haben die "Wait(ms)" und die "Wait Until Next ms Multiple" Funktion nur unterschiedliche Startverhalten oder gibt es auch hier Performanceunterschiede auf die betroffene While Loop? (im Sinne, startet die "Wait(ms)" Funktion an einer ganzzahligen ms oder auch an bsp. 0,46 ms und macht das einen Unterschied).
Mit freundlichen Grüßen und schon mal Dank für die bisherigen Antworten:
Sepp
Ich hab immer noch nicht so richtig kapiert, wie dein Schleifenkonzept zu deinen verschiedenen Aufgaben passt.
Warum müssen Schleifen pausiert werden? Soll nach einer "Pause" ein schnelles Loslaufen möglich sein?
Dazu könntest du in jeder dieser Schleifen eine "Queue driven state machine" packen. Und diese wartet dann am "Dequeue" solange, bis ein neues Kommando kommt. Das Kommando schickst du dann "von außen", wenn es weitergehen soll. Ansonsten könnte sich diese SM auch selber antreiben, je nach dem was in einem State "entschieden" wird.
Diese einzelnen SM würde ich in je ein "Prozess-VI" (SeriellProzess.vi, DAQProzess.vi, RegelungProzess.vi) packen, dann kannst du in jedem VI auch ne Eventstruktur verwenden und dort ggf. auch User Events konfigurieren (z.B. Input direkt von einer HW-Komponente). Alle Prozesse laufen parallel und erst mal asynchron. Die Synchronisierung (wo notwendig!) könntest du ergänzend mit Notifiern ("neuer Sollwert", "neuer Istwert") oder Occurences oder...hinkriegen.
Der Stopp aller parallel laufenden Prozesse kommt per Queue Message aus einer Zentralen SM, die auch das GUI verwaltet bzw. von dort manuelle Events empfängt.
Genauso tauschen die ProzessVIs untereinander Daten aus, d.h. auch durch Queues, oder durch FGVs
Meiner Ansicht nach brauchst du genau NULL Timed Loops
Festzuhalten: Es ist hier definitv kein LabVIEW (2011)-Bug zu beobachten!
"Is there some mightier sage, of whom we have yet to learn?"
"Opportunity is missed by most people because it is dressed in overalls and looks like work." (Thomas Edison)
(13.12.2018 13:03 )Achim schrieb: Ich hab immer noch nicht so richtig kapiert, wie dein Schleifenkonzept zu deinen verschiedenen Aufgaben passt.
Warum müssen Schleifen pausiert werden? Soll nach einer "Pause" ein schnelles Loslaufen möglich sein?
Dazu könntest du in jeder dieser Schleifen eine "Queue driven state machine" packen. Und diese wartet dann am "Dequeue" solange, bis ein neues Kommando kommt. Das Kommando schickst du dann "von außen", wenn es weitergehen soll. Ansonsten könnte sich diese SM auch selber antreiben, je nach dem was in einem State "entschieden" wird.
Diese einzelnen SM würde ich in je ein "Prozess-VI" (SeriellProzess.vi, DAQProzess.vi, RegelungProzess.vi) packen, dann kannst du in jedem VI auch ne Eventstruktur verwenden und dort ggf. auch User Events konfigurieren (z.B. Input direkt von einer HW-Komponente). Alle Prozesse laufen parallel und erst mal asynchron. Die Synchronisierung (wo notwendig!) könntest du ergänzend mit Notifiern ("neuer Sollwert", "neuer Istwert") oder Occurences oder...hinkriegen.
Der Stopp aller parallel laufenden Prozesse kommt per Queue Message aus einer Zentralen SM, die auch das GUI verwaltet bzw. von dort manuelle Events empfängt.
Genauso tauschen die ProzessVIs untereinander Daten aus, d.h. auch durch Queues, oder durch FGVs
Die Sache mit dem Pausieren liegt daran, dass die Gerätesteuerung nicht vollkommen in einer Statemachine bearbeitet wird. Die Initialisierung findet zunächst in der Hauptloop statt und der eigentliche zeitkritische Part geschieht in den parallelen Schleifen (Das ist eine Systementscheidung die bereits etwas länger zurückliegt und nicht geändert werden kann ohne das Programm defakto neu aufzubauen). Daher würde die Schleife Nachlaufen, käme es zu Fehlern in meinem Programm. Warum ich mich mit meinem Halbwissen nicht für einfache Caseabfragen entschieden hab die über local variables gesteuert werden, hab ich in einem vorigen Post erklärt.
Soviel erst mal zu meinen Ausreden
Die Queue driven state machine kannte ich noch nicht, aber das Verhalten entspricht dem was ich ursprünglich gesucht habe um Schleifen zu steuern. Damit kann ich mir die "Masterloop" sparen.
(13.12.2018 13:03 )Achim schrieb: Festzuhalten: Es ist hier definitv kein LabVIEW (2011)-Bug zu beobachten!
Auch wenn ich mich damit nicht beliebt machen sollte: Aber wenn die Runtime und die Entwicklungsumgebung durch ein Programm in einen Zustand laufen, aus dem der einzige Ausweg ein terminieren der Labview.exe ist. Dann ist das ein Bug in LabVIEW, da dieser Zustand nicht korrekt behandelt wird. Ich weis nicht ob ich das korrekt rüber gebracht habe. Das Fenster "Resetting VI" geht nicht mehr weg und LabVIEW ist bis zu seinem Neustart nicht bedienbar.
Aber allem zum trotz natürlich herzlichen Dank Achim für die Anregung bezüglich der Queue driven state machine. Das hat mir sehr weitergeholfen.
(12.12.2018 14:28 )jg schrieb: Also 9 parallele Timed-Loops, das wäre wahrscheinlich sogar unter einem RT-System der Tod des Programms. Das Windows nicht mehr mit kommt, wundert mich da nicht.
Timed Loops bedeuten einen tiefen Eingriff in den Task-Scheduler. Da werden gnadenlos andere Tasks rausgehauen oder pausiert, wenn die entsprechende Timed-Loop daran ist, was abzuarbeiten. Sachen, bei denen du das Zeitverhalten nicht vorhersagen kannst, wie serielle Kommunikation u.ä., haben in einer Timed-Loop auch nichts verloren.
Gruß, Jens
Ich habe die Timed-Loops durch normale While-Loops ersetzt. Die ersten Langzeittests sehen vielversprechend aus. Ich denke Ich kann dieses Problem als gelöst taggen. Für die Probleme mit den spontanen resets in meinem Regler habe ich Workarounds eingebaut, die diese spezifischen Fälle erkennen und Redundanzen aktivieren. (Ich habe schon lange gesucht, aber ich will nicht abstreiten, dass ich vielleicht doch mal in bestimmten Fällen irgendwo durch null teile (bzw. auch 0/0))
Vielen Dank an alle die mir hier geholfen haben.
MfG: Sepp