Frage zu einer Polynominterpolation

drfunfrock

Level-1
Beiträge
934
Reaktionspunkte
72
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich will eine recht komplizierte Funktion durch ein Polynom 2. Grades ersetzen. Dazu setze ich Numpy ein, wie z.B.

polynom=np.polyfit(x,y,2)
funktion = np.poly1d(polynom)

werte = funktion(x)

wobei x = [0,1,2,3,4....]

Das klappt auch gut. Der max. Fehler ist kleiner als 2% und das reicht für mich. Nun habe ich aber ein paar Parameter, die vom Benutzer geändert werden können und da es sich um eine SPS handelt, kann ich da nicht polyfit laufen lassem. Daher ich müsste die Form des Polynoms

a+bx+cx^2

nach

a'( parameter) + b'(parameter) x + c'(parameter) x^2

anpassen. Nun hab ich gleich 4 Parameter. Wie kann man da vorgehen? a, b und c sind dann funktionen von meinen Parametern.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja, aber die ist nicht stetig und hat nur das Aussehen einer Art Wurzelfunktion. Ich beziehe mich auf den Thread mit der Winch. Die ist voll und wird abgerollt. Gesucht die Funktion die mir die Länge in Abhängigkeit vom Enkoder gibt. Per Iteration habe ich dann die abgespulte Länge in Abhängigkeit von dem
Enkoderzähler herausbekommen.

Dabei kommen dann 2 Listen heraus, die X-Achse mit den Enkoderwerten [0,1,2,3,4,5....] und die Y-Achse mit den Längen [0,0.223 ....]Man hat also immer das komplette Ergebnis im Speicher.

Analytisch hab ich das nicht fertiggebracht, weil der das Behandeln einer Startlage, die nicht voll ist, Probleme bereitet. Egal, das Ganze scheint mit einem Polynom 2. Grades hervorragend angenähert werden zu können, weil bei höheren Graden, die Koeffizienten sehr klein sind. Wenn du auf die Gleichung im vorherigen Thread schaust, die die Anzahl der Lagen in Abhängigkeit von der Kabellange herausbekommt, dann wird meine Vermutung bestätigt. Da kommen max. Wurzeln vor.

Ich habe mir überlegt, einfach 2 verschiedene Polynome für jeweils einen Parameter zu generieren, dh. ich ändere den um den Faktor 2 oder 10. Damit sollte alles zu machen sein. Ich bekomme dann 8 Gleichungen für 4 bekannte Parameter. Sollte einer unter einer Wurzel sehen, bekomme ich Wurzel(2) oder 1/Wurzel(2) im Verhältnis, der Polynomkoeffizienten dabei heraus usw.

Ich mach das zum ersten Mal. Das ist richtig spannend, weil das Ergebnis dann so richtig einfach wird. Die ganze Komplexität in unserer Progammierung löst sich in Nichts auf.

Was mich faziniert, wie einfach es mit Numpy war eine Polynominterpolation für ein vorhandenes Funktionsergebnis zu finden.

Parameter a' ist leicht zu finden, weil es einfach der Offset ist und der ist 0, weil das Kabel bei 0 startet.
Parameter b' ist einfach, weil es grösster-umfang*pi*encoder/encoder_pulse_per_rev. Dh. es ist die Tangente (Änderung der Länge per Enkoderpuls). Es ist die grösstmögliche Änderung, weil mit jeder Lage, die abgerollt ist, der Umfang kleiner wird.
Fehlt noch c'
 
Zuletzt bearbeitet:
Nach ein paar Problemen, hab ich die Polynomkoeffizienten gefunden. Zuerst beschränkte sich die Genauigkeit auf einen Fehler von 3%. Erst als ich anfing, die Konstanten meines Koeffizienten b, leicht zu varieren, kam ich auf einen max. Fehler von 0.1%. Damit lässt sich eine Trommel mit Draht, Seil etc. mathematisch ausreichend genau beschreiben, ohne auf eine Iteration zugreifen zu müssen. :cool: Ich kann Polynominterpolation nur weiterempfehlen. Wer feste Trommelparameter hat, der braucht nur eine Näherung per nummerischen Verfahren.
 
Ich finde die mathematische Problembeschreibung / Lösung sehr interessant.
Was mir jetzt fehlt, ist der Bezug zur konkreten Aufgabe. Vielleicht könntest du hierzu ein paar Sätze schreiben.
Wir haben auch schon einige Wickler und ähnliches gemacht und dabei nie so tief in die Mathematik einsteigen müssen.
Auch wenn sich 0,1% im ersten Moment gut anhört, wirst du - meiner Meinung nach - trotzdem um die üblichen "Randthemen" wie Tänzer, Schlaufenregelung, Drehzahl-Drehmomentregelung nicht herumkommen.

Gruß
Dieter
 
Der bezug ist der Thread http://www.sps-forum.de/programmier...kabelwicklung-auf-kabeltrommel-berechnen.html

Wenn du eine Trommel abwickelst, dann ergibts das eine nicht stetige Funktion der Länge des Kabels, die auch noch iteriert werden muss. Jede Lage produziert eine Gerade, die mit den inneren Lagen flacher wird. An den Übergängen von Lage zu Lage, ist die Funktion nicht differenzierbar. Ich brauche nämlich, die Länge in Abhängigkeit vom Enkoderzähler, der auch als Winkel interpretiert werden kann und dann die Länge des Kabels und dessen Geschwindigkeit in m/s und das für eine Trommel, die abgewickelt werden soll.

Länge(Enkoder)

Damit könnte man vor und zurückrechnen, wenn die Funktion differenzierbar wäre. Das ist wichtig, um z.B. die Geschwindigkeit des Kabels zu ermitteln. Eine nichtstetige Funktion führt zu Jitter. Da wurde die Idee geboren, eine Aproximation zu nehmen. Die Entscheidung für ein Polynom fiel, weil der Thread für die Anzahl der Lagen in Abhängigkeit von der Kabellänge ergab, dass dort max. quadratische Funktionen zu finden sind.

Aproximation:

Code:
Länge(x) = a + bx + cx^2  

X entspricht dem Enkoderzähler

Bisher hatte ich nur eine Lösung für die Anzahl der Lagen. Also habe ich eine Python-Funktion geschrieben, die mir die Iteration macht, denn eine analytische Lösung hab ich nicht gefunden. Python zusammen mit Numpy ist Matlab-ähnlich. Dh. alles wird in Listen verwaltet. Beispiel:

Code:
x = [0 1 2 3 ]          # X Werte 
y = [t*t for t in x]    # entspricht dem quadrat von x [0 1 4 9]
plot(x,y)

In meinem Falle habe ich dann die Funktion des Aufrollens eines Kabels iteriert. Abrollen ist nicht so einfach. Das gibt dann 2 Listen mit x und y-Achse

x=[0 1 2 3 4 .... Enkoderendwert]
y = [0 3.14 6.28 .... usw.]

Die Y-Wert sind noch vom aufrollen, müssen also umgedreht (gespiegelt) werden und dann in Relation zum Kabelende gesetzt werden. Daher das Kabelende vom Aufrollen soll 0 beim Abrollen sein.

y = [Kabellänge - t for t in y[::-1]]

Mit y[::1] bekomme ich die gespiegelte Liste.

Das ganze geplottet mit plot(x,y) ergibt dann eine Kurve aus vielen Geraden, die an die Wurzelfunktion erinnert. Damit hatte ich x und y für die Polyfit-Funktion von Numpy, die mir eine Liste (was sonst?) mit Polynomkoeffizenten numerisch errechnet

Code:
koeffizienten = polyfit(x,y,2) # 2. Ordnung. 

Z.B. 
[-1, 2, 0] was [c, b, a] entspricht für das Polynom a+bx+cx^2
Du kannst auch eine höhere Ordnung probieren, aber die Koeffizienten sind dann wesentlich kleiner als 1E-3. Das Polynom kann man dann gleich ausprobieren mit

Code:
y2 = poly1d(x,koeffizienten)
plot(x,y2)

Die Fehlerfunktion wird einfach mit

Code:
error =  sqrt(((y2-y))/y)**2)*100.
plot(x,error)

geplottet.

Jetzt hatte ich den Fehler und die numerische Lösung, die mit einem max Fehler am Ende <0.1% sehr genau ist.

Wenn man jetzt die Winchparameter einzeln modifiziert, hat dass Konsequenzen für die Koeffizienten. a ist 0, weil Länge(0) = 0 ist.

Wenn ich die Breite der Trommel um den Faktor 2 modifiziere, dann wird c um den Faktor 1 / 4 kleiner. Beipiel:

Code:
faktoren = koeffizienten_vor_modifikation / koeffizienten_nach_modifikation

Daher

c ~1 / b^2

Das mache ich so mit allen Parametern und multipliziere die dann nur noch.

Beim Koeffizienten b hab ich das einfacher gemacht, weil ich dort, den

Code:
b = max_Durchmesser*pi*enkoder/enkoderauflöung

als Geschwindigkeit interpretiert habe. Dieser Koeffizient, war leider mal zu hoch, mal zu niedrig, so dass der Fehler bis auf 3% stieg. Es gab in der Gleichung für b eine Subtraktion, die ich dann leicht modifiziert habe.

Als Resultat bin ich nun in der Lage mit m/s zu rechnen, ohne dass ich Jitter zusätzlich einbringe. Ich kann vom Enkoderzähler auf die Länge schliesse und umgekehrt.
 
Zuletzt bearbeitet:
Ok soweit verstanden. Du brauchst die Restlänge abhängig von der Geberpos.

Wir "umgehen" das Problem ganz einfach dadurch, dass wir die Länge mit einem Geber direkt an den Abwickelrollen messen.
Die 0,1%-Genauigkeit würden bei uns nicht reichen.

Gruß
Dieter
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Demnach ist die Aufgabenstellung in dem anderen Thread aber eigentlich folgende:

Wie kann ich die Länge bei gegebener Umdrehungs-/ bzw. Windungszahl bestimmen?

Und nicht:
Wie kann ich die Anzahl an Lagen bei gegebener Länge bestimmen?
 
Ok soweit verstanden. Du brauchst die Restlänge abhängig von der Geberpos.

Wir "umgehen" das Problem ganz einfach dadurch, dass wir die Länge mit einem Geber direkt an den Abwickelrollen messen.
Die 0,1%-Genauigkeit würden bei uns nicht reichen.

Gruß
Dieter

Wir haben bewusst auf jeglichen Sensor diesbezüglich erzichtet. Was ich erreichen will, ist eine halbwegs stabile Lageregelung, weil zur Zeit die Position jittert.
 
Demnach ist die Aufgabenstellung in dem anderen Thread aber eigentlich folgende:

Wie kann ich die Länge bei gegebener Umdrehungs-/ bzw. Windungszahl bestimmen?

Und nicht:
Wie kann ich die Anzahl an Lagen bei gegebener Länge bestimmen?

Die Zahl der Lagen brauch ich trotzedem. Danke dafür. Ursprünglich dachte ich, es reicht hier nur die Lagen zu kennen. Das war mein Irrtum.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wir haben bewusst auf jeglichen Sensor diesbezüglich erzichtet. Was ich erreichen will, ist eine halbwegs stabile Lageregelung, weil zur Zeit die Position jittert.

Bin mal gespannt, ob das klappt :p
Hast du schon mal eine Toleranzbetrachtung gemacht?

Gruß
Dieter
 
Bin mal gespannt, ob das klappt :p
Hast du schon mal eine Toleranzbetrachtung gemacht?

Gruß
Dieter

Na ja, es gibt schon eine uralte Software, die kaum zu warten ist, aber zur Zeit funktioniert. Was ist versuche ist 1. zu kapieren, was der Programmierer da gemacht hat und 2. etwas besser zu machen, damit ich später mich entspannen kann. Die Lageregelung funktioniert insgesamt zufriedenstellend, hauptsache die Anzeige von Geschwindigkeit und Kabellänge ist wiederholbar :cool: Eine absolute "Genauigkeit" von 10% stört hier niemanden. In diesem Falle konnte ich nicht stoppen, weil ich einfach Ing bin und mich die Herausforderung reizt. Man kann das mit der Approximation schliesslich überall da gebrauchen, wo man Lookup-Tabellen ersetzen will oder wie hier eine unbekannte Funktion vorliegen hat. Und eine stetige Funktion immer besser, als eine die nicht differenzierbar ist, wenn der Wert in einen Regler eingeht.

Die praktischen Probleme fangen da an, wo 25 Tonnen am Kabel hängen, weil dann das Kabel oval ist. Sensoren, die den Umfang messen oder gar die abgespulte Länge, sind nicht denkbar, weil viel zu wartungsintensiv. Ich bin hier neu in der Firma und als erstes bekam ich dann so ein Projekt um eine Software an E-Motoren anzupassen. Mein Vorgänger hatte das nur halbfertig und ich keine Ahnung.

Ich bekam dann einen Hassanfall auf Omron, weil deren Can-Bus-Initialisierung lief, aber nur im Free-Run-Mode. Die Initialisierung kann auch nur mit Ladder geschrieben werden. Aua. Bei uns liefen deshalb alle SPS im Free-Run-Mode :ROFLMAO: Das mit dem Free-Run wollte ich dann ändern und brauchte dafür 3 Tage. Dann benutzten diese CAN-BUS FB von Omron implizit virtuelle Kanäle, die sie sich mit RS232 teilen. Davon gibt es 8. Und weil Can-Bus einen virtuellen Kanal nutzte, ohne das dieses dokumentiert war, hatte ich grausige Fehler auf RS232. Was Omron da mit seinem Tool CX-Programmer abliefert ist unterste Schublade.
 
Zuletzt bearbeitet:
Hallo,
schön, dass der Fehler mit der RS232 gefunden wurde.
Ich empfehle sehr, sich eingehender mit dem Omron Kontaktplan zu beschäftigen.
Es gibt bei anderen SPS keine vergleichbaren Möglichkeiten.
Schon mal den APR-Befehl angeguckt?
Es gibt für die Kontaktplan-Befehle einen eigenen Prozessor in der SPS.
Benutzt man ST, so werden die meisten ST-Befehle intern in die Kontaktplan-Befehle übersetzt.
Dadurch benötigt ein gleiches ST-Programm bis zu 3 Mal mehr Speicher und die Abarbeitung kann auch bis zu 3 Mal länger dauern.
Bei der CJ-Serie gibt es keine synchronen Abarbeitungsmöglichkeiten, aber alles ist konsistent, nur MC-Baugruppen mit Mechatrolink ist synchron. Man kann nur die Zykluszeit auf eine höhere Zeit festsetzen, dann wartet sie, bis die Zeit abgelaufen ist.
Für vollständige Synchronfunktionen würde man eine NJ benötigen, bei der alles synchron läuft (EtherCAT und Motion und SPS-Zyklus/aber auch nicht CAN-Bus)
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja ist mir alles klar, nur ich hasse Ladder und was damit verbrochen wurde. Man kann sich dann auch gleich eine Kugel in den Kopf geben. Für jedes Zwischenresultat braucht es eine Variable und dann wird das Ladderdiagramm derart lang, dass es keiner mehr durchschaut, nicht einmal der Experte vor mir, der an dem Projekt 5 Jahre mit Ladder gearbeitet hatte.

Ich habe dank ST 50% des Codes streichen können. Zudem ist jetzt alles schön übersichtlich und der Code wartbar. Und wenn ST dreimal mehr Speicher benötigt und ich dann gehindert sein sollte ein Projekt zu beenden, wäre das genau der richtige Grund meinen Chef zu überzeugen umzusteigen. Die ST-Implementation ist crap und hat dazu geführt, dass ich aus einem FB heraus, direkt auf Adressen zugreifen musste, weil es Referenzen auf Arrays nicht gibt, die ich für RS232 benötigte (NMEA-Checksumme).

Omron hat mich nicht überzeugt.
 
Zurück
Oben