TIA Hüllkurven auswertung programmieren

TP-Inc

Level-3
Beiträge
1.035
Reaktionspunkte
224
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

durchs mitlesem bei diesem Thread https://www.sps-forum.de/simatic/103046-tia-portal-analogwert-ueber-zeit-weg-aufzeichnen-2.html hab ich beschlossen mal zu versuchen eine Hüllkurvenauswertung zu programmieren. Hab zwar im Moment nicht wirklich einen Anwendungsfall, aber man weiß ja nie.

Das Aufzeichnen der Kurve ist noch relativ easy, beim Vergleich der Ist zur Soll Kurve stehe ich im Moment am Schlauch. Ich habe die "Kurve" als Array[1..X,0..1] of REAL hinterlegt.

Jetzt zum Problem: Wenn ich die Kurve auswerten möchte, müsste ich das komplette Array nach dem passenden X-Bereich durchsuchen, um den dazugehören Y-Wert zu finden. Das ist halt nicht gerade ressourcenschonend. Gibts da ne Abkürzung?
 
Was Du vor hast, ist ja eine nachträgliche Auswertung. Die gehört meiner Meinung nach nicht ins Echtzeitsystem, sprich SPS, sondern kann zeitlich versetzt durch einen nachfolgenden Prozess übernommen werden. Und da spielen Ressourcen meist keine Rolle --> siehe KI.

Wenn Du es aber im Echtzeitsystem machen möchtest, um beispielsweise sofort reagieren zu können, reicht eine einfache Toleranzüberwachung zwischen Soll und Ist aus.

Code:
InToleranz := ABS(Soll - Ist) < Toleranz;
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Du müsstest zunächst die Thematik eingrenzen, in dem du definierst, um was für eine Funktionsart es sich handelt. Eine stetig steigende Funktion mit eindeutigen Funktionswerten wäre natürlich das einfachste. Vielleicht mal damit anfangen?
 
Wenn die x-Achse stetig steigend ist, kannst Du das passende Intervall durch binäre Suche finden.
Das sind bei 1000 Stützstellen 10 Vergleiche, das ist auch im Zyklus durchaus machbar.
Gruß
Erich
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Also ich hatte den Fall tatsächlich mal gehabt - deshalb in dem Thread auch mein Beitrag dazu. In meinem Fall hatte es sich bei der aufgezeichneten Kurve um ein Gebilde gehandelt, das man nicht mit einber Funktionsgleichung darstellen konnte.
Meine aufgezeichnete Kurve hatte dabei zunächst 100 Stützstellen für die X- bzw. die Y-Achse. Durch entsprechende Glättung und Nachbearbeitung konnte ich das Gebilde dann auf ca. 30 Stützstellen reduzieren.
Die nun zu vergleichende Kurve hatte dann natürlich wieder 100 und mehr Stützstellen - das war aber gar nicht das Problem. Die Auswertung ob IO oder NIO hatte ich dann sogar im Zyklus der SPS gemacht - die Zykluszeit stieg hierbei dann zwar an - das war aber noch vertretbar.
Die Auswertung selbst lief so, dass ich mit für jeden Wert der aufgezeichneten Kurve einen virtuellen (also errechneten) Wert aus der Vorgabekurve gebastelt habe. Das ging darüber, dass ich mir für den aufgezeichneten Wert dann den Wert davor und den dahinter aus der Vorgabekurve gesucht habe. Von den Werten dann die Steigung errechnet und diese Steigung dann zum Errechnen des Hilfswertes benutzt. Dadurch lies sich dann sagen (wie in Beitrag #2 dargestellt) ob die Kurve an der Stelle noch im Range ist oder nicht. Ich habe daraus dann sogar noch etwas anderes gebildet - nämlich eine Abweichungskurve - also vom aufgezeichneten Wert den errechneten Wert abgezogen und das in einem neuen Array dann wieder abgelegt. So konnte man das dann auch noch schön visualisieren.

Viel einfacher geht es allerdings - und dann ist die Anzahl der Stützstellen schon fast nicht mehr relevant - wenn die Vorgabekurve und die aufgezeichnete Kurve immer den gleichen Bereich darstellen - also auch gleich viele Werte beinhalten. Ich habe dann einfach geringfügig unterschiedliche x-Werte ignoriert und die y-Werte direkt gegeneinander verrechnet.Der Unterschied zu dem vorher dargestellten ist dabei eher marginal was man durch die Anbweichungskurve dann sogar sehen kann ...

Vielleicht als Anregung ...

Gruß
Larry
 
.. also X-Achse stetig steigend
Dann werden dich Suchbegriffe wie "interpolieren" zunächst auf den richtigen Weg geleiten.

Die Suche auf der X-Achse kannst du verkürzen, in dem du vom vorherigem Wert ausgehst. Also gucken, ob größer oder kleiner und dann in der entsprechenden Richtung genau das Wertepaar suchen, zwischen denen dein aktueller Wert liegt. Zwischen diesen interpolieren und anschließen auf die Y-Achse übertragen. Mit Hilfe des genannten Suchbegriffes findest du bestimmt auch Beispiele.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
"Polyline" ist ein weiterer, ganz heißer Suchbegriff. Diesen Hebel kann man natürlich auch im TIA-Portal unter "Anweisungen" oder in der Onlinehilfe ansetzen ;) .
Ich denke aber, du wirst das selber programmieren wollen, mit flexiblen Arraygrößen vielleicht?
 
So die binäre Suche hab ich jetzt mal, wirklich ein praktisches Konzept. Eine Frage zu dem hätte ich noch. Den Baustein für die Binäre Suche habe ich für ein Array[*] if REAL geschrieben, da die Funktion ja mehrfach einsetzbar sein soll. Die Kurvenpunkte hab ich als zweidimensionales Array abgelegt. Kann ich irgendwie nur die erste Dimension an Schnittstelle übergebenen?

Und irgendwie kann man mit Variant doch sicher auch noch den fixen Datentyp REAL aus dem ganzen rausbringen oder?
 
Eine Frage hätte ich auch noch: was hat dieser Thread mit Hüllkurven zu tun?

Es geht anscheinend allgemein um das Thema Interpolation, nicht nur von Hüllkurven.

Und jetzt speziell "nur noch" um das Suchen, also in einer sortierten Liste genau einen vorgegeben Wert zu finden oder, falls er nicht vorhanden ist, den nächst kleineren und den nächst grösseren.
Das wäre also eine Funktion mit 1 Ergebnis, dem Index, der auf den exakten oder z.B. nächst kleineren Wert zeigt.
Im aufrufenden Programm muss man noch prüfen, ob eine exakte Übereinstimmung gefunden wurde und "ungegebenenfalls" den unter dem gelieferten Index+1 vorhandenen Wert lesen.
Oder man bräuchte eine "Funktion", die immer beiden Indizes für die Interpolation liefert, also ggfs zweimal denselben Index.
Bei so viel "Drumherum" würde ich nicht lange zögern, die binäre Suche nicht in eine "UniversalFunktion" auszulagern. Sooo aufwändig ist sie doch nicht. Die erforderlichen Vergleiche geschehen immer zwischen identischen DatenTypen, die nur von Anwendung zu Anwendung wechseln können. Bei SCL (oder AWL) also kein Thema und in FUP oder KOP würde man's eher nicht programmieren wollen.

Was macht die zweite Dimension? Ist dies quasi ein zweites Array? Ein Array für die X-Werte und ein zweites (gleich langes) für die Y-Werte?
Was würde man bei einem Array of Struct machen?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

mit Hüllkürven an sich hats nicht mehr viel zu tun, ist ein bisschen abgeschweift, das stimmt. Ich hab erlich gesagt nicht mehr viel weiter gemacht, da ich wieder "echte" Arbeit machen musste.
Ich denke du hast Recht, eine komplett universal einsetzbare Funktion für eine Binäre Suche ist wahrscheinlich nicht notwendig. Man muss ja tatsächlich nur die Datentypen in der Deklaration austauschen.

Die zweite Dimension sind die Y-Werte der Kurve. Ich verstehe deine Frage auf die Frage dazu allerdings nicht ganz?
 
Ich verstehe deine Frage auf die Frage dazu allerdings nicht ganz?
Wenn man die 2. Dimension ("nur") benötigt, um zusätzlich zu den X-Werten auch die (zugehörigen) Y-Werte zu speichern, könnte man in Erwägung ziehen, ein Array für die X-Werte zu spendieren und ein weiteres Array für die Y-Werte ... dann müsstest Du nicht unnötigerweise die Y-Werte mit an die Funktion übergeben, sondern nur das 1-dimensionale der X-Werte.
Bei der Übergabe eines mehrdimensionalen Arrays (by Reference) müsste/könnte man an die Funktion einen zusätzlichen Parameter übergeben, der besagt, welche "Spalte" der Tabelle abgesucht werden soll.

Ich könnte mir aber auch ein Array of Struct vorstellen, insbesondere, wenn nicht alle Daten im Array denselben DatenTyp haben. Da wird es aber noch aufwändiger/schwieriger, die SuchSpalte zu spezifizieren.
 
Zurück
Oben