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!
10.08.2009, 16:25 (Dieser Beitrag wurde zuletzt bearbeitet: 10.08.2009 16:25 von oenk.)
' schrieb:Stell Dir vor Du hast einen komplexen Messstand und Du kannst oder möchtest nicht immer davor sitzen, um an dem Programm für den Messstand zu arbeiten. Also baust Du ein virtuelles Instrument statt der realen Datenerfassung und an jeder stelle, wo der Messstand konfiguriert, Daten erfasst werden, Daten gespeichert werden kann ein Case hin, der je nach einem Wert in der Konfigurationsdatei das eine oder das andere Instrument benutzt. Etwas aufwändig.
Nun wird eine Variante des Messstandes gesbaut (andere Geräte gleich Funktionalität) und es kommen neue Anforderung an das was getan werden muss hinzu. Jetzt wird es schon ziemlich aufwändig die Ganzen Cases zu aktualisieren.
Nimm ein Klasse für jeden Messstand und das virtuelle Gerät, die von einer Basisklasse abgeleitet werden. Dann gibt nur noch eine Case-Struktur in der die Klasse nach Lesen der Konfiguration eingestellt wird. Das ganze Programm enthält keine Cases mehr sondern nur noch die VIs (Methoden) der Basisklasse. LV übernimmt die Entscheidung, welches VI jeweils benutzt wird.
Natürlich musst Du immer die VI (Methoden) aller Klassen programmieren. Das kann Dir niemand abnehmen egal ob Du nun Cases oder Klassen verwendest. Mit Klassen behälst Du in jedem Falle den Überblick was noch fehlt.
Genau so meinte ich es, nur viel viel schöner ausgeführt ;-)
' schrieb:Bin mal gespannt, wann der LabVIEW-Advanced II - Lehrgang endlich mal kommt. Dort soll es nämlich genau um LVOOP gehen. Vielleicht kann ich dann auch von LVOOP überzeugt werden (wenn ich verstehe, was das Ganze soll und wie es funktioniert).
Gruß Markus
wenn dir der Weg nach Zürich nicht zu weit ist, kann ich folgenden Kurs empfehlen: link
Danach war ich in der Lage den Treiber in GOOP umzusetzten.
In theory, there is no difference between theory and practice; In practice, there is.
Chuck Reid
10.08.2009, 17:08 (Dieser Beitrag wurde zuletzt bearbeitet: 10.08.2009 17:08 von Y-P.)
Developer Suite Core -> LabVIEW 2015 Prof.
2006
EN
71083
Deutschland
Objektorientiertes Programmieren mit LV
@oenk: Danke für die Info.
Gruß Markus
-------------------------------------------------------------------------- Bitte stellt mir keine Fragen über PM, dafür ist das Forum da - andere haben vielleicht auch Interesse an der Antwort !!
--------------------------------------------------------------------------
' schrieb:Kann man denn mit der üblichen "OO-Denkweise" in LVOOP wirklich gut programmieren? Kann ich mir das LVOOP wirklich so vorstellen wie in C# oder Java? (Objekte übergeben an andere Objekte usw?)
nein, der Name Objekt ist für LVOOP IMHO unglücklich gewählt. Er weckt Erwartungen, die das Konzept nicht erfüllen kann/will, weil es anders gedacht ist ... (siehe weiter unten)
' schrieb:Das Problem der Abstrahierung betrifft aber nicht nur LVOOP, oder OOP, sondern ist allgemeines Problem. Auch wenn man ohne OOP programmiert, besteht dieses Problem der Wiederverwendung. Nur bei OOP gibt es solche Tools wie Ableitung, Überladung und ähnliches, die zur Lösung genau dieses Problems gerichtet sind. Ansonsten klar, bleibt fast nur das Kopieren und Einfügen + Bibliotheken und Templates.
... die Ableitung ist IMHO die größte Stärke von LVOOP. Ich verstehe das Konzept eigentlich als "Angebot" für fortgeschrittene, langjährige Entwickler, die früher oder später damit beginnen sich eine eigene Bibliothek zu erstellen. Ich hab z.B. für all meine Projekte mehr oder weniger das gleiche Grundgerüst, mit VIs die aus LIBs kommen, etc pp. Hier wäre LVOOP ein sehr guter Ansatz um solche LIBs weiter zu verallgemeinern, leider ist das Konzept - aus meiner Sicht - noch nicht ganz fertig: z.B. versagt es bei der Type Propagation von Queue Refnums, die man als Dynamic Dispatch Terminal anlegt, es funktioniert nicht unter LV RT ... usw.
Wenn man LVOOP nur für ein Projekt verwendet und die Klassen & Methoden (= SubVIs ...) immer wieder neu programmiert, ist es eigentlich Zeitverschwendung das in OO zu realisieren. Einen wirklichen Vorteil bei der Entwicklung hat man erst, wenn man "seine" generalisierten Objekte für bestimmte Zwecke entwickelt hat und nur noch Abgeleitete Objekte daraus erstellt, die per Ableitung auf den auf den jeweiligen Zweck abgestimmten Datentyp "reagieren". Das kann man so ähnlich auffassen wie XControls: die erstellt man auch nicht nur für eine Anwendung. Wenn man sich die Arbeit macht, dann möchte man die auch gerne mehrfach einsetzen ...
' schrieb:Aus diesem Grund nutze ich sie nicht. Ich versuche so zu programmieren, wie es vom Jeff Kodosky ursprünglich gedacht war. Also keine unsichtbaren Leitungen und uninitialisierten Schieberegister.
Sorry, Eugen, das ist Quatsch. Da könnt ich jedes mal wieder heulen wenn ich das von dir lese. Jede Menge Daten durch die Gegen zu kopieren und armdicke Kabelstränge durchs Block-Diagramm zu legen* ist auch kein guter Stil. Mit einer FVG bist du auf jeden Fall näher am Objekt im Sinne von C++, als mit LVOOP ... Vor 20 Jahren hat auch keiner gedacht dass Teenies mit dem Handy Fotos machen, Musik hören, Spiele spielen und per MMS kommunizieren. Trotzdem hat in der Richtung eine Entwicklung stattgefunden, die sich mittlerweile zum Standard etabliert hat, Carl Benz hat auch nicht im Traum daran gedacht dass man 100 Jahre später mit 250 km/h über die Autobahn bügelt ...
' schrieb:Wer sagt denn das die Schieberegister in FGV's uninitialisiert sind? Es gibt das Zustandsautomaten und ein Zustand ist "Initialisiere" Diese Art der Programmierung wird einem im Intermediate Kurs sogar beigebracht.
lass dich von Eugen da nich beirren, er mag sie halt nicht (ich mag z.B. keinen Pressack ... da könnt isch kotzen ey!) die FGVs - ich versuch seit Jahren ihn zu überzeugen, aber es gelingt mir einfach nicht- FGVs sind SUUUUUPA! ** aber für Eugen muss halt aussen noch nen Konstante dran klemmen, sonst wird er nich glücklich
Ich persönlich denke: LVOOP ist im Prinzip eine tolle Sache. Bei jedem neuen LV Release schaue ich wie weit es nun ist und wenn es tatsächlich irgendwann den Funktionsumfang bietet den ich brauche um meine LIBs & Templates damit aufzubauen werd ich es definitiv auch einsetzen.
*und komm mir nu nicht mit der Ausrede: "ich pack das ja alles in Cluster" - im LV Style-Guide steht ganz deutlich: "avoid deeply nested structures"!
** ironischerweise wär hier LVOOP eigentlich das Killer-Feature schlechthin, wenn man per LVOOP erzeugte FGVs (<strike>kleiner</strike> großer Seitenhieb an Eugen: AQ hat extra mal eine LVOOP-Style FGV vorgestellt... damit sich ein Objekt seine Member-Variablen "merkt" ) tatsächlich als Objekt mehrfach instantiieren könnte und by Reference aufrufen könnte ... geht zwar im Prinzip jetzt schon, aber man müsste halt mehrere gleiche Objekte erstellen, Reentrant LVObjects gibts AFAIK noch nicht ...
' schrieb:Kann ich auch von folgendem ausgehen: Daten, die in einer Klasse liegen - ob als private oder public - werden nicht mehr (so oft) kopiert?
Nein, leider nicht (ich bin mir gerade zwar nicht 100%ig sicher). In diesem Fall ist das Klassenobjekt eben doch nur ein Cluster, der von VI (Methode) zu VI (Methode) weitergereicht wird.
' schrieb:Wenn ich also ein größerer 2D-Array habe, das bearbeitet werden muss, dann wird das ja mit normalem DF ständig (naja sagen wir sehr oft) kopiert. Was viel Arbeit macht. Ich könnte mir durchaus vorstellen, dass, liege dieses Array als private in einer Instanz, erheblich Kopierarbeit gespart werden könnte.
Die Zahl war 3. Die Daten werden dreifach kopiert, wenn Sie an ein SubVI übergeben werden und wieder zurückgegeben werden.
Sie müssen auf dem Frontpanel angezeigt werden, dann wird mit ihnen gearbeitet und dann ist da noch das Anzeigeelement mit dem das Ergebnis zurückgegeben wird. Das klingt nach Verschwendung. Dafür kann ich ein SubVI zum Testen immer wieder starten, nachdem es einmal aufgerufen wurde, da auf dem Frontpanel die ganzen Startdaten gespeichert sind.
Vielleicht hilft hier die "In Place Element Structure". Das müsste ich erst einmal nachlesen und probieren. Den Speicherverbrauch der VIs kann man sich mit dem Menüpunkt Tools > Profile > Performance and Memory... anzeigen lassen. Und Tools > Profile > Show Buffer Allocations... zeigt an, an welcher Stelle Kopien der Daten erstellt werden.
Aber auch mit einem FPV bekomme ich meine Daten aus meinem Beispiel nicht auf einmal hinein, weil LV eben wieder mehrere Kopien anlegt. Ich kann also meine Bilder nur einzeln nacheinander hineinschreiben.
Warum benutze ich nun nicht immer ein FPV anstelle von einer Klasse. Damit die Daten abgelegt werden können, wird ein Anschluss für das Bild zum Schreiben und ein Anschluss für das Bild zum Lesen benötigt. Außerdem muss ich angeben welche Nummer das Bild hat, das ich lesen will, bzw. an welcher Position das Bild eingefügt worden. Damit sind zwei weitere Anschlüsse verbraucht. Dann gibt es noch den Error-Cluster rein und raus sowie wie das Enum mit dem ich die Funktionalität wähle. Jetzt will ich meine Bilddaten noch in eine Datei schreiben und brauche einen Pfad Eingang. Sind zusammen schon 8 Anschlüsse. 28 hat man maximal zur Vewrfügung. Damit wird klar, dass man FPV nicht für recht komplexe "Klassen" einsetzen kann, obwohl es die Grundanforderung der Objektorientierung "Kapselung der Daten" erfüllt.
Für mein angeführtes Beispiel habe ich LVOOP und FPV kombiniert. Für das Hauptprogramm, welches im wesentlichen ein GUI bildet habe ich ein FPV, das eine Klasse enthält, damit ich in der Hauptschleife nicht meine Klasse durch alle Fälle der Ereignisstruktur hindurchführen muss. Das automatische Verbinden gibt es schließlich erst seit, während die Anfänge des Programms weiter zurückreichen. Eigentlich reicht hier auch eine lokale Variable. Das FPV ist mehr historisch. In der Klasse selbst habe ich aber auch nicht die eigentlichen Bilddaten untergebracht, sondern nur eine Vielzahl von Funktionen vereinigt, die die Bilddaten in einem FPV organisieren und bearbeiten.
Es gibt also nicht die dogmatische Lösung. Vielmehr muss die günstigste Lösung für die jeweilige Aufgabe herausgesucht werden z. B. im Rahmen einer Diskussion hier im Forum.
10.08.2009, 20:58 (Dieser Beitrag wurde zuletzt bearbeitet: 10.08.2009 21:01 von eg.)
@unicorn, dies hier könnte zwar unvollständige Antwort, aber eine interessante sein.
Ich denke (vermute) - solange man das FP eines SubVIs nicht aufmacht (graphische Darstellung) werden die Daten auch nicht doppelt abgespeichert. Das kann man, denke ich, leicht feststellen in dem man den Profiler benutzt.
Und wo kommen dann die Daten her, wenn Du das SubVI erst laufen lässt und dann das FP öffnest?
Hokus Pokus Fidibus?
Nein, aus diesem Grund werden sie eben mehrfach abgelegt.
10.08.2009, 21:55 (Dieser Beitrag wurde zuletzt bearbeitet: 10.08.2009 22:00 von eg.)
Hmm, also wenn ich ein SubVI erstelle und dieses mit geschlossenem FP in einem anderen VI einsetze, dann das VI starte und nach dem Start und Durchlauf das SubVI öffne, dann sehe ich da nur den Defaulwert auf dem FP des SubVIs.
' schrieb:Hmm, also wenn ich ein SubVI erstelle und dieses mit geschlossenem FP in einem anderen VI einsetze, dann das VI starte und nach dem Start und Durchlauf das SubVI öffne, dann sehe ich da nur den Defaulwert auf dem FP des SubVIs.
Aber nur wenn du Debugging für das Sub-VI ausgeschaltet hast, was in diesem Beispiel aber nicht der Fall ist...
' schrieb:Hi Christian, geile Antwort. Darauf habe ich gewartet
P.S. ich habe zwar hier ein mal zugegeben, dass LVOOP zusammen mit FGVs eventuell gut zu gebrauchen sind, aber das meine ich nicht wirklich.
das tröstet mich... wenn man LVOOP irgendwann vernünftig einsetzen kann wirst du sicher auch Klassen programmieren wollen, die ihre Member-Variablen speichern können. Entweder kann das dann LVOOP selber - und IMHO müsste es das eigentlich bieten, damit man von OOP sprechen kann - oder man muss es sich eben programmieren und FGVs sind dann genau das Mittel der Wahl.
' schrieb:Nein, leider nicht (ich bin mir gerade zwar nicht 100%ig sicher). In diesem Fall ist das Klassenobjekt eben doch nur ein Cluster, der von VI (Methode) zu VI (Methode) weitergereicht wird.
Jupp. Mehr ist es nicht, wenn man die Ableitung nicht / die Objekte nur in einem Projekt nutzt: protected Clusters, man kommt nur über einen zusätzlichen Schritt (SubVI) wieder an die Daten ran, die man reingeschoben hat. Für "normale" Programmierung bietet das keinen Vorteil, sondern eher den Nachteil dass man sich deutlich mehr Arbeit macht als man braucht. Dass die rein gesteckte Arbeit natürlich wieder einen Vorteil haben kann, wenn man die Objekte in mehreren Projekten einsetzen kann hab ich ja oben schon beschrieben.