Hallo zusammen,
hoffe die Frage wird nicht nerven.
Habe natürlich davor schon gegoogelt, keine Antwort gefunden.
Ich habe ein Beispielbild eingefugt.
Es gibt 3 bekannte Eingangsgrößen, daraus soll ein Wert ermittelt
werden.
Sowas wird immer in den Motorsteuergeräten als verschiedene Kennfelder
benutzt.
Wie verarbeitet man sowas mit dem uC?
Mir ist bekannt, dass hier interpoliert wird. Bei 2D Matrix ist das
schon mit einem nicht unerheblichen Rechenaufwand verbunden. Kommt noch
eine Eingangsgröße dazu, dann wird es ganz schön bunt.
Kann leider keine genaueren Angaben machen, weil es noch nichts
feststeht.
Danke für die Hilfe
Wenn sich die Werte durch eine Funktion hinreichend annähern lassen,
dann halt mit dieser Funktion.
Wenn nicht, dann mit einem 3D-Feld und linearer Interpolation.
Wenn man die Stützstellen äquidistant macht, sind richtigen Punkte im
Feld leicht zu finden.
(Es sind auch andere Interpolationen denkbar, aber unterm Strich wird
das bei den paar Stützstellen nicht viel bringen. Aber man könnte mit
weniger Stützstellen auskommen.)
Ein Controller für eine Motorsteuerung sollte eigentlich genug Speicher
für sowas haben...
Maxe schrieb:> Dein angehängtes Kennfeld hat doch nur zwei Unabhängige> (=Eingangsgrößen).
Vielleicht ist die Anzahl der Dimensionen noch geheim:
Tobias schrieb:> Kann leider keine genaueren Angaben machen, weil es noch nichts> feststeht.
:-)
>Ein Controller für eine Motorsteuerung sollte eigentlich genug Speicher>für sowas haben...
Es hat nichts mit Motorsteuerung zu tun. Ich weiß nur, dass dort sehr
viel mit solchen Kennfeldern gearbeitet wird.
>Vielleicht ist die Anzahl der Dimensionen noch geheim
Es ist an sich Nichts geheim, aber das Konzept steht noch nicht fest.
Ich versuche das aktuell in meinem Kopf zu sortieren.
>Dein angehängtes Kennfeld hat doch nur zwei Unabhängige>(=Eingangsgrößen)
Ja, tut mir leid. Habe das Beispielbild nicht genau angeschaut, gleich
das erste genommen. Es werden aber 3 Eingangsgrößen sein.
Da das Ganze bei mir in keine Richtung linear ist, kann ich keine Formel
programmieren. Muss schon eine Art lookup Tabelle benutzen und die
Zwischenwerte rechnen.
Werde versuchen die Stützstellen äquidistant zu machen. Je nach
Möglichkeit.
Ich frage mal so frech, gibt es ein Programmierbeispiel dafür?
Will das Rad nicht neu erfinden, konnte aber mit eigener Kraft Nichts
Brauchbares finden.
Vielleicht falsch gesucht.
Mir ist noch nicht so recht klar, wo dein Problem liegt. Wenn du alle
Werte (oder wenigistens einige Werte) innerhalb eines Gebietes haben
willst, die dir eine Funktion mit drei unabhängigen Variablen liefert,
bleibt dir eigentlich nur eine dreifach verschachtelte Schleife.
Und da wäre erstmal die Frage, in welcher Programmiersprache du das
aufzuziehen gedenkst.
Tobias schrieb:> Da das Ganze bei mir in keine Richtung linear ist, kann ich keine Formel> programmieren.
Nichtlineare Formeln wurden schon erfunden. Das ist also kein Grund.
Und sonst interpolierst du zwischen deine Stützstellen per
Spline-Interpolation. Das erspart Unstetigkeiten in der Ableitung.
>bleibt dir eigentlich nur eine dreifach verschachtelte Schleife.
Das wäre zu einfach. Die Stützwerte werden natürlich so gut wie nie
getroffen.
>in welcher Programmiersprache
In C wäre gut
>Und sonst interpolierst du zwischen deine Stützstellen per>Spline-Interpolation.
Klingt einfacher als es ist.
Danke euch, werde weiter denken und googeln.
Falls jemand ein Beispiel reinwerfen möchte, wäre ich sehr dankbar. Soll
bitte nicht etwa auf meine Faulheit hindeuten.
Geht eigentlich recht einfach, sehr effizient und superschnell (ohne
echte Division), dann, wenn die Stützstellen auf 2hochN liegen, also
2,4,8,16 oder 32.. usw.
Pseudo-Code in C:
1
#define DIV (8) // Abstand zwischen 2 Stützstellen
Tobias schrieb:> Wie verarbeitet man sowas mit dem uC?
Wie mir jedem anderen Computer auch.
> Mir ist bekannt, dass hier interpoliert wird. Bei 2D Matrix ist das> schon mit einem nicht unerheblichen Rechenaufwand verbunden. Kommt noch> eine Eingangsgröße dazu, dann wird es ganz schön bunt.
Wie schnell muß es denn sein?
Oliver
pseudo schrieb:> Geht eigentlich recht einfach, sehr effizient und superschnell (ohne> echte Division), dann, wenn die Stützstellen auf 2hochN liegen, also> 2,4,8,16 oder 32.. usw.
Man verwendet besser 2^n Intervalle, also 2^n+1 Stützstellen (3, 5, 9,
...).
Bei der Interpolation fällt eine Division mit 2^n an, was sich dann
durch ein >>n ersetzen lässt.
Das lässt sich recht einfach umsetzen wenn du ein Grid an Werten hast.
Also für die Dimensionen hast du Stützstellen der Form x_1..x_l,
y_1..y_m, z_1..z_n und für alle Kombinationen (x_i, y_j, z_k) hast du
entsprechend Werte hinterlegt.
Dann kannst du für die Koordinaten (x, y, z) von deinem Eingabewert
jeweils den Index in deinem Grid per Bisektion ermitteln was jeweils in
O(log(n)) liegt und damit recht flott geht.
Damit bekommst du die Indizies (i, j, k) und eine Info ob dein x z.B.
zwischen i-1 und i oder i und i+1 lag.
Damit kannst du dann die 2^n Stützpunkte aus dem Grid auslesen und
interpolieren.
Hannes schrieb:> pseudo schrieb:>> Geht eigentlich recht einfach, sehr effizient und superschnell (ohne>> echte Division), dann, wenn die Stützstellen auf 2hochN liegen, also>> 2,4,8,16 oder 32.. usw.>> Man verwendet besser 2^n Intervalle, also 2^n+1 Stützstellen (3, 5, 9,> ...).> Bei der Interpolation fällt eine Division mit 2^n an, was sich dann> durch ein >>n ersetzen lässt.
Hannes, genau so war es von pseudo gedacht. Er hätte es aber etwas
klarer zum Ausdruck bringen können. Hast Du ja aber jetzt nachgeholt.
Mehrdimensionale nicht lineare Kennfelder lassen sich idr. auch ganz gut
mit einem Neuronalen Netz interpolieren. Multi-Layer Perceptron sollte
ganz brauchbar sein.
Tobias schrieb:> Falls jemand ein Beispiel reinwerfen möchte, wäre ich sehr dankbar.
Mal geradlinig runtergeschrieben, ohne Anspruch auf Fehlerfreiheit...
(Auf jeden Fall sollte man vor dem Weiternutzen die ganzzahligen
Rundungen anschauen, die sind sicher nich timmer optimal, und je nach
Anwendung bei allen Zwischenergebnissen die Wertebereiche hinterfragen.)
3dgen.cpp erzeugt für eine ausgedachte Funktion die Stützstellen gleich
in einem Format, das zur Initialisierung eines int[][][]-Feldes geeignet
ist.
Die Ausgabe kann man beim Aufruf in eine 3dvalues.inc umleiten.
Das wiederum wird mit #include in 3d.c verwurstet.
Weil man in einem Controller nicht unbedingt gerne mit Gleitkommazahlen
rechnet, ist innerhalb 3d.c alles gleich mit einem Faktor 100 skaliert,
als int gespeichert und alles findet in Ganzzahlen statt (außer ein paar
Testausgaben).
Die Skalierung wäre getrennt für x, y, z, und die Funktionswerte
getrennt änderbar.
In den Beispieldaten fangen alle Unabhängigen bei 0 an, der Quelltext
ist aber für andere Bereiche vorbereitet.
Davon abgesehen ist es eher für Verständlichkeit ohne Tricks
geschrieben. Optimierung überlasse ich dem Compiler.
Zur Interpolation:
Ich habe hier den einfachen Weg genommen und gehe bei einem Punkt
(x,y,z) von den umgebenden Stützstellen aus: x_links und x_rechts
schließen x ein, die anderen Dimensionen entsprechend.
Ausgehend von f(x_links,y_links,z_links) interpoliere ich in jede der
drei Richtungen und bekomme eine Näherung für f(x,y,z).
Das ist nur sinnvoll, wenn die Funktion zwischen den benachbarten
Stützstellen nicht stark gekrümmt ist.
Zum Verständnis auf 2 Dimensionen reduziert:
Zur Interpolation an der Stelle (x,y) geht man davon aus, daß die
Funktion in der viereckigen Fläche zwischen f(x_links,y_links),
f(x_rechts,y_links), f(x_links,y_rechts) und f(x_rechts,y_rechts) etwa
eben ist.
Dann geht man von f(x_links,y_links) entlang der x-Achse nach
f(x_rechts,y_links) und interpoliert auf dieser Linie, sowie von
f(x_links,y_links) entlang der y-Achse nach f(x_links,y_rechts) nochmal.
Man spannt also von (x_links,y_links) aus in Richtung x und y eine Ebene
auf und geht davon aus, daß der gesuchte Punkt etwa auf der Ebene liegt.
Liegt der Funktionswert des vierten, ungenutzten Punkts
f(x_rechts,y_rechts) aber deutlich über oder unter der gedachten Ebene,
ist die Funktion gekrümmt.
Dann könnte man die Näherung deutlich verbessern, wenn man
1. entlang f(x_links,y_links)--f(x_rechts,y_links) eine Näherung für
f(x,y_links) berechnet
2. entlang f(x_links,y_rechts)--f(x_rechts,y_rechts) eine Näherung für
f(x,y_rechts) berechnet
3. aus f(x,y_links)--f(x,y_rechts) dann f(x,y) interpoliert in
x-Richtung.
Durch die Verwendung der vierten Ecke würde man sich dann nicht so stark
von einer Krümmung veräppeln lassen.
Ein weiterer Vorteil wäre, daß die interpolierten Werte im ganzen
Bereich stetig verlaufen. In der einfachen Version hat man durch die
Krümmung jeweils eine Unstetigkeit, wenn man über eine ungenutzte Ecke
hinauskommt.
Analog hier im Fall mit f(x,y,z) nicht zwischen 4 statt 3 Stützstellen,
sondern zwischen 8 umgebenden Stützstellen.
Das habe ich im Beispiel oben nicht gemacht.
Erstens ist es natürlich mehr Rechnerei, die sich nur lohnt, wenn die
Stützstellen so weit liegen, daß die Funktion eine nennenswerte Krümmung
dazwischen hat. Muß man im jeweiligen Fall sehen, was man will.
Zweitens hatte ich gestern abend zu dem Zeitpunkt schon 2 Weizen.
Kevin M. schrieb:> Multi-Layer Perceptron sollte> ganz brauchbar sein.
Da braucht es aber schon einen anständigen Rechenknecht. Und das
Training ist auf einem PC erfolgt! Neben der reinen Rechenleistung ist
auch das Aufsetzen des NN nicht trivial. Kann natürlich sein, dass das
heute üblich ist. Ein Kumpel von mir hat als Student bei so einem
Motor-Spezialisten gejobbt und da wird eben mit solchen
Kennlinienfeldern gearbeitet. Aber da wird oder wurde nichts in Echtzeit
interpoliert. Die Kennlinien wurden akribisch von Hiwis ausgemessen und
je nach erforderlicher Genauigkeit als Datenfeld im Eprom oder direkt im
Controller hinterlegt. Ich weiß aber nicht, ob das heute immer noch so
ist.
Gruß Rainer
Rainer V. schrieb:> Da braucht es aber schon einen anständigen Rechenknecht.
Nicht wirklich.
Rainer V. schrieb:> Und das> Training ist auf einem PC erfolgt!
Und weiter?
In zehn Jahren wird hier im Forum nicht mehr C vs Assembler diskutieren,
sondern NN vs Kennfelder :-)
Vielleicht könnte man auf die Daten auch ein 3D Polynom fitten (Matlab
"polyfit") oder eine andere empirische Näherungsgleichung. Das wäre auf
dem Controller schlank. 3d Kennfelder werden sehr schnell sehr
speicherintensiv und machen
Hallo,
weil wir erst vor kurzem sowas ähnliches im Arduino Forum hatten. Man
kann die Tabelle in Excel o.a. erstellen und sich dann daraus die
polynomische Formel berechnen und anzeigen lassen. Der µC muss dann nur
leider viel Rechnen und viel mit Fließkomma. Deswegen kann man das auch
in Excel komplett vorberechnen und wirft die Tabelle ins Flash. Je
nachdem was notwendig oder praktischer ist.
Andreas R. schrieb:> In zehn Jahren wird hier im Forum nicht mehr C vs Assembler diskutieren,> sondern NN vs Kennfelder :-)
Ich würde sagen, in 5 Jahren haben wir KI auf den Controllern...aber das
gehört nicht ganz hierher...
Gruß Rainer
Anti-Blender schrieb:> Siemens hatte schon 1994 den ersten neurocomputer am Start, da hiess es> auch 'in 5 Jahren .:.'
Das ist fast 20 Jahre her und heute macht eine KI (Google z. B.) schon
gehörige Sachen und der Kühlschrank mit Web gehört ganz sicher auch
schon dazu.
Anti-Blender schrieb:> KI wird ein Nischenprodukt für den Überwachungsstaat bleiben.
Bis auf Nischenprodukt stimme ich da zu und würde formulieren: KI wird
auch für den Überwachungsstaat gut sein! Ist natürlich
Definitionssache...
Gruß Rainer
"KI" ist das alles nicht. Neuronale Netze können sehr gut Statistik und
Klassifikation, das sind auch die Bereiche in denen sie heute eingesetzt
werden.
Zur Frage mit dem MLP, ja das funktioniert heute noch genau so. Netz
wird offline trainiert und dann könnte man es auf den µC spielen. (Die
Grundlagen dazu sind seit den 70ern "erfunden".)
Das funktioniert daher so gut weil hinter vielen sehr großen Tabellen
halt doch sehr einfache Funktionen stehen. Ein NN kann diese einfachen
Funktionen sehr gut isolieren und abbilden, genügend Rechenpower beim
Training vorausgesetzt.
Für den µC kann man das Netz auch in INT8 oder INT16 mit Fixpoint
rechnen.
Ein kontinuierliches Kennlinienfeld ist eine eher einfache Sache. Etwas
Mathematik vorausgesetzt. Und dann sollte man als Integer rechnen, nicht
als float.
Ich wuerd allenfalls mit 10x10 - 202x20 Stuetzwerten rechnen, wenn ein
Polynom nicht passt. Erst mal sollte man die Genauigkeit der
verschiedenen Methoden vergleichen. Wie genau soll es sein ?
Pandur S. schrieb:> Ein kontinuierliches Kennlinienfeld ist eine eher einfache Sache.
Nur geht es ja offensichtlich eben gerade nicht um ein solches, sondern
um ein von vorherein nur durch experimentell ermittelte Stützpunkte
beschriebenes. Was bezüglich der Zielanwendung übrigens recht normal
wäre.
> Ich wuerd allenfalls mit 10x10 - 202x20 Stuetzwerten rechnen
Das dürfte im Wesentlichen eine Frage des vorhandenen Speichers sein.
Höhere Stützpunktauflösung haut halt beim Speicherbedarf entsprechend
der Zahl der Dimensionen exponentiell rein. Da kommt man auch bei
größeren µC recht schnell an die Grenzen der verfügbaren Flashgrößen.
> Polynom nicht passt. Erst mal sollte man die Genauigkeit der> verschiedenen Methoden vergleichen.
Wie soll das gehen, wenn über die "richtigen" Werte zwischen den
diskreten Stützpunkten überhaupt keine Informationen vorliegen? Womit
willst du dann Berechnungsergebnisse verschiedener
Interpolationsmethoden vergleichen?
Nö, da hilft dann wohl nur die schöne alte Methode des trial and error.
Einfach Ausprobieren, womit die Sache besser läuft.
c-hater schrieb:> Wie soll das gehen, wenn über die "richtigen" Werte zwischen den> diskreten Stützpunkten überhaupt keine Informationen vorliegen? Womit> willst du dann Berechnungsergebnisse verschiedener> Interpolationsmethoden vergleichen?
Ein Weg in solchen Fällen ist, mit einem reduzierten Satz von
Stützstellen zu arbeiten und zu prüfen, wie gut sich die Werte der
weggelassenen Stützstellen reproduzieren lassen. Das gibt einem auch
gleich ein Gefühlt dafür, wieviel Redundanz der Stützstellensatz
enthält.
Wolfgang schrieb:> Ein Weg in solchen Fällen ist, mit einem reduzierten Satz von> Stützstellen zu arbeiten und zu prüfen, wie gut sich die Werte der> weggelassenen Stützstellen reproduzieren lassen. Das gibt einem auch> gleich ein Gefühlt dafür, wieviel Redundanz der Stützstellensatz> enthält.
Ja, das ist eine absolut sinnvolle Vorgehensweise.
c-hater schrieb:> Nö, da hilft dann wohl nur die schöne alte Methode des trial and error.> Einfach Ausprobieren, womit die Sache besser läuft.
Ja, "früher" wurde das so gemacht...
Gruß Rainer
Einganswerte 25 und 1500
Ist schon ne Weile her, Code habe ich auch nicht mehr dazu.
Erst die Werte der benachbarten Stützstellen nehmen und sich mal mit dem
Dreisatz in der Tabelle bewegen
1
(90+180)/1000*500=135
2
(50+90)/1000*500=70
3
135-70=65
4
65/10*5=32,5
5
70+32,5=102,5
man zieht also gedanklich eine Linie vom Wert 70, vertikal zum Wert 135,
diese Strecke hat ne Länge von 65, diese 65 durch die Differenz aus den
Skalenpunkten 30 und 20 (bleibt ja immer 10) mal die Differenz aus dem
Eingangswert und dem unteren Skalenpunkt 25-20, also mal 5, das gibt man
dann dem unterem Ergebnis (Linienbeginn) dazu.
Ich hatte das bezüglich der Stützstellen so optimiert das diese z.B. 512
oder 1024 waren, weil sich das durch Schieben schneller
Teilen/Multiplizieren lässt als durch 500 oder durch 1000 rechnen zu
müssen.
PS. Das im Eingangspost hätte ich schon als 3D-Kennfeld bezeichnet,
stell dir ein Blatt Papier vor (Länge x Breite) mit der Skala 0-100 und
0-8000 außen, die Zahlen an den Schnittpunkten gehen ja in die Höhe(3te
Dimension) und das ist das Ergebnis, kein Eingangswert.
Beim 3D Kennlinienfeld kann man mit Approximation, wie auch mit
Interpolationen arbeiten. Der Unterschied : Bei Interpolationen geht die
Kurve durch die Stuetzstellen, bei Approximationen nur in der Naehe
durch. Beides kann Sinn machen.
Bei Polynom-Interpolationen durch N punkte benoetigt man ein Polynom mit
N-1 tem Grad, was schnell mal keinen Sinn mehr macht, da es instabil
wird. Dann gibt es die Moeglichkeit der Stueckweise Interpolation, dh
einer Geraden durch die Stuetzwerte, resp eine Parabel durch jeweils 3
Punkte. Oder falls die Ableitung stetig sein muss, kan man Beziers
verwenden.
Falls die Werte eh verrauscht, resp mit einer Unsicherheit behaftet
sind, kann man eine Approximation machen, optimalerweise mit der
Funktion, welche der Theorie entspricht.
Rainer V. schrieb:> Ich weiß aber nicht, ob das heute immer noch so> ist.
Offensichtlich nicht...dabei scheint mir die Methode z.B. bei
Motorsteuerung doch absolut perfekt. Ich kenne die Werte, die meine
Sensoren bringen können und fahr das im Labor durch. Das gibt mehrere
Kennlinienfelder, je nach dem, welcher Parameter optimiert werden soll
und fertig! Da wird nichts Interpoliert...warum auch. Anders wäre es
nur, wenn extrem viele Werte mit vielen Dimensionen benötigt würden oder
die Funktion so gutmütig ist, dass man das zeitaufwändige Ausmessen
sparen kann.
Gruß Rainer
ich vermute das heutzutage eh mehr z.b. 32 statt 8 oder 16 Stützstellen
verwendet werden und dann kann man das interpolieren etwas ungenauer
durchführen, also erst runden um dann schnelle rechnen zu können oder
die Rechenpower ist eh groß genug.
Rainer V. schrieb:> Ich kenne die Werte, die meine> Sensoren bringen können und fahr das im Labor durch. Das gibt mehrere> Kennlinienfelder, je nach dem, welcher Parameter optimiert werden soll> und fertig!
Das ist doch Unsinn. Wenn die Zielgröße nunmal dynamisch von drei
Parametern abhängt, dann nützt es dir garnix, wenn du mehrere
2D-Kennlinienfelder (oder auch ganz viele 1D-Kennlinienfelder) hast.
Damit kannst du dann im praktischen Betrieb der Sache rein garnix
anfangen.
Sowas ist nur als Vorversuch brauchbar, um dann bei der eigentlichen
Aufnahme des Kennlinienfelds schonmal grob zu wissen, welche Bereiche
des Datenraums man erst garnicht exakter untersuchen muss, wofür man
sich also den Meßaufwand sparen kann. Sie können auch Hinweise geben
über die nötige Auflösung im relevanten Teil des Datenraums, also
ebenfalls hilfreich sein, um Messaufwand zu sparen. UND sie können
Hinweise dazu geben, ob man wirklich eine vollständige Abbildungstabelle
benötigt, oder ob eventuell auch was mit Intepolation reicht.
> dass man das zeitaufwändige Ausmessen> sparen kann.
Das kann man praktisch nie. Man kann nur den Zeitaufwand optimieren,
wenn man vorab abschätzen kann, wo und wie dicht die Messpunkte für das
3D-Feld liegen müssen.