Lieber Besucher, herzlich willkommen bei: RCLine Forum. Falls dies Ihr erster Besuch auf dieser Seite ist, lesen Sie sich bitte die Hilfe durch. Dort wird Ihnen die Bedienung dieser Seite näher erläutert. Darüber hinaus sollten Sie sich registrieren, um alle Funktionen dieser Seite nutzen zu können. Benutzen Sie das Registrierungsformular, um sich zu registrieren oder informieren Sie sich ausführlich über den Registrierungsvorgang. Falls Sie sich bereits zu einem früheren Zeitpunkt registriert haben, können Sie sich hier anmelden.

1

Donnerstag, 15. Oktober 2009, 17:30

Mehrpunkt Gaskurve in C

Ich bin gerade am Rätseln, wie ich am platzschonendsten/genialsten eine Gaskurve in meinem Koax-Mischer unterbringe.
Device ist ein ATTINY84 mit C-Code WinAVR/AVRStudio.
Für eine echte Expo-Funktion fehlt leider der Platz.
Mir schwebt eine Throttle Kurve mit abgeflachter Steigung im Schwebebereich vor.
Die Berechnung sollte im 16-Bit Bereich stattfinden (2000 steps/ms).
Vielleicht hat ja jemand eine Idee...

2

Donnerstag, 15. Oktober 2009, 17:53

RE: Mehrpunkt Gaskurve in C

Der Weg wird sein eine eingabe Ausgabe Kurve in mehrere Segmente aufzuteilen.

Also rein Zeichnerisch mal die gewünschten Ausgabewerte, zu den Eingabewerten aufzeichnen.

Dabei wird es dann zu übergabepunkten kommen.

Für die Linien zwischen den Übergabepunkten wird dann dir Steilheit berechnet also.

(maximaler Übergabewert - minimaler übergabewert)/ (eingabewert bei maximalem übergabewert.- eingabewert bei minimalem übergabewert)

Das Spielchen machst Du so oft, wie Du Segmente haben willst.
Die Errechenten Steigungswerte kommen dann in eine Tabelle und werden dann je nach gewünschtem Eingabewert herausgeholt.

Ein Eingabewert von 1522µs würde in das Segment 3 passen ( z.B. 1500...1600).
Der minimale ausgabewert von Segment 3 wäre 32000, die Steilheit wäre 5.

Der Controller müsste also jetzt folgende Berechnung ausführen:
(1522-1500)*5+32000 =32110

Die Berechnung wäre für alle Segmente gleich, lediglich die Werte würden sich ändern.
Es wäre also eine Fallentscheidung - Welches Segment wird verwendet,
Sowie ein Subtraktion, eine Addition und eine Multiplikation notwedig um die benötigten Werte zu kriegen.

Um möglichst wenig Rechenzeit zu vergeuden, würde ich hier nur INT bzw Long INT Variablen verwenden.
Um auch krumme Werte für den Steilheitsfaktor zuzulassen, kann man diesen z.B. *128 verwenden und dann das Ergebnis wieder durch 128 teilen.

Wenn man für die Multiplikationsfaktoren Potenzen von 2 verwendet, kann die Teilung hinterher durch Schiebebefehle erfolgen, die schneller abgearbeitet werden als Divisionen.

Ich lass mir solche Tabellen von EXCEL berechnen und geb die Werte dan in ein ARRAY in den Controller ein.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »wkrug« (15. Oktober 2009, 17:54)


3

Donnerstag, 15. Oktober 2009, 19:32

RE: Mehrpunkt Gaskurve in C

Hi Wilhelm,
vielen Dank erstmal für Deine Ausführungen.
Ich werde mir das mal in Ruhe angucken und evtl. in Excel durchspielen.
Eine Tabelle im Ram wäre mir aber zu groß, da ich ja 4KB für 2000 Werte bräuchte, die ich nicht mehr habe...

4

Donnerstag, 15. Oktober 2009, 20:18

Lies Dir den Text von Wilhelm noch mal sorgfältig durch!

Du brauchst pro Gaskurvenpunkt *) lediglich ein paar Bytes Speicher plus ein paar dutzend für den Code.

Grüße
Malte

*) drei bis fünf Gaskurvenpunkte sollten langen.

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »DrM« (15. Oktober 2009, 20:20)


5

Donnerstag, 15. Oktober 2009, 20:26

RE: Mehrpunkt Gaskurve in C

Hallo Achim,

warum fehlt der Platz?

Ich kenn mich da ja nicht aus, aber ich würde vermuten dass es einen Grund dafür gibt exp zu nehmen. Ich kann mir als Grund dafür nur vorstellen weil es leicht/effizient zu programmieren ist => ich würde mal suchen wie exp gut zu proggen ist...

Was mir dazu einfällt:
Ich denke du hast eh schon eine Multiplikation drinnen, dann kann das eigentlich nicht wahnsinnig viel mehr Platz brauchen. Reicht nicht eine Näherung der Exp-Funktion völlig:

exp(x) = 1 + x + 1/2 x^2 + 1/6 x^3 + .... = 1 + x*( 1 + 1/2 x* ( 1 + 1/3 x*(....) ) )

Es muss ja wohl nicht wirklich mathematisch exakt eine exp-Funktion sein, sodern nur so ähnlich sein um das gewünschte Resultat zu erzielen. Vielleicht reicht daher schon das erste Glied, also bis x^2, aber ich würde meinen mehr als bis x^3 muss man wirklich nicht gehen. Für bis x^2 wird's einfach:

xmax soll, von der Mitte gerechnet (das Vorzeichen musst du dann mit ner if abfangen) der maximale Wert sein (bei dir 1000).
=>
y = a * x + (1-a)/xmax * x*x

x hat maximal 10 bits, 16 bit Rechnung => für a nehmen wir maximal 6 bits, also ersetzen wir a durch a/64.
=>
y = a * x/64 + (1- a/64 )/xmax * x*x
=>
y = a * x/64 + (64- a )/xmax * x*x / 64

um nun x^2 auszurechnen haben wir ein Problem mit 16 bit, also teilen wir x zunächst durch 16 und multiplizieren dann
=>
y = a * x / 64 + (64- a )/xmax * (x/16)*(x/16) * 256/ 64

und da xmax=1024
=>
y = a * x / 64 + (64- a ) * (x/16)*(x/16) /256

also:
x/16 bilden
x/16 mit sich multiplizieren
das Ergebnis /64 nehmen
das Ergebnis mit (64-a) multiplizieren
das Ergebnis /4 nehmen
a mit x multiplizieren
das Ergebnis /64 nehmen
das vorherige Ergebnis dazu addieren

=> 3 Multiplikationen

In dieser Rechnung könnte es vielleicht sein dass im letzten Schritt ein Überlauf stattfindet, vielleicht muss man dann zwischen drinnen geschickt /2 teilen, habe ich jetzt auf die Schnelle nicht rausgefunden. Vielleicht ist auch noch ein Fehler drinnen. Überlasse ich alles dir, aber das Prinzip an das ich denke ist klar. Message ist, mit ein paar wenigen Multiplikationen sollte das gut und kompakt zu machen sein.

Hoffe dass das nicht nur Quatsch ist :)

Olli

Edit: aber für jede gewünschte verschiedene Exp-Kurve müssen diese Gaspunkte abgelegt werden, gut wenn die fix ist, wohl weniger wenn es einstellbar sein soll

aber vielleicht kann man die 5 Gaspunkte wie oben vorher berechnen....

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »OlliW« (15. Oktober 2009, 20:28)


6

Donnerstag, 15. Oktober 2009, 20:32

Was ich nicht so recht verstehe ist, wozu ich überhaupt eine Tabelle brauche.
Ich würde gerne einen eher steilen Teil bis zum ersten Übergabepunkt, dann einen flachen Teil bis zum zweiten Übergabepunkt, anschließen wieder einen steilen Teil bis Vollgas haben.
Das ganze würde ich gern flexibel und einstellbar halten. Am liebsten mit drei Parametern
1. Mittelpunkt des flachen Teils in % vom Vollgas (Geberweg)
2. Breite des Bereiches in % vom Vollgas (Geberweg)
3. Steilheit des flachen Bereiches in sagen wir 1/1...1/100
(bei Steilheit 100 wäre dann alles eine Gerade)

Daraus soll dann in der Firmware alles andere berechnet werden.

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »amm« (15. Oktober 2009, 20:35)


7

Donnerstag, 15. Oktober 2009, 20:50

stückweise Geraden:

y = (ymax-ymin)/(xmax-xmin) * (x-xmin) + ymin

8

Donnerstag, 15. Oktober 2009, 21:01

Danke Olli, und auch den anderen, jetzt hab ich erstmal zum Nachdenken. :ok:

9

Donnerstag, 15. Oktober 2009, 21:21

Zitat

Original von waldmann
stückweise Geraden:

y = (ymax-ymin)/(xmax-xmin) * (x-xmin) + ymin



Das wäre dann in Excel sowas. Ich müsste das mal probieren, die Frage ist, ob das in der Praxis zu grobe Übergänge gibt...
»4712« hat folgendes Bild angehängt:
  • Bild2.jpg

10

Donnerstag, 15. Oktober 2009, 22:32

was mich daran ja prinzipiel stören würde ist dass man so 2 Werte angeben muss um den Kurvenverlauf festzulegen, wo es doch einer auch tun würde... (das scheint mir der grosse Vorteil bei EXPO zu sein)

11

Donnerstag, 15. Oktober 2009, 22:56

Ok Olli,
was mach ich nun mit "y = a * x + (1-a)/xmax * x*x"
Was ist da "a"?

32Bit Rechnung ist übrigens kein Problem, ist eh für andere Sachen nötig und braucht nicht sooo viel Platz...
Für pow() müsste ich aber die math bibliothek mitnehmen, das haut rein.

12

Donnerstag, 15. Oktober 2009, 23:31

ähm, ich wollte damit nicht andeuten das ich der Meinung bin dass der obige Vorschlag die ultimative Lösung sei... :)

a gibt dir die Steigung um die Nullage, also das was du die Steilheit des flachen Bereiches nanntest. In der Formel die du zitierst wäre z.B. a = 0...1. Wenn du das in Excel einsetzt müsstest du das schön sehen. Für a = 1 ergibt sich eine einfache Gerade, für a = 0 ergibt sich eine Parabel.

In dem Vorschlag oben würde a = 0...64 sein.

x wäre der Wert des Ausschlags von der Mittellage, x = 0...1024.

Du kannst also die Mittellage, dein Wunsch 1., problemlos einstellen, weil du ja eh die Mittellage von deinem Wert abziehen musst um auf den Bereich 0...1024 zu kommen, also x = PPM_Wert - x0 machen musst.

Das Vorzeichen, also die Richtung des Ausschlags von der Mittellage, müsstest du mit einem if abfangen.

Für ein 10bit Wert mit 32bit zu rechnen ist IMHO ziemliche Vergeudung von Resourcen :) Und pow ist doch floating point, oder? Das wäre dann IMHO erst recht Vergeudung von Resourcen...

13

Freitag, 16. Oktober 2009, 00:44

So langsam wirds, danke Olli!
Ja "pow()" ist float und das brauch ich wirklich nicht.
»4712« hat folgendes Bild angehängt:
  • Bild2.jpg

14

Freitag, 16. Oktober 2009, 00:56

es wäre ja mal interessant das noch mit der echten exp zu vergleichen, um zu sehen wie wichtig die höheren Terme (x^3 etc) sind, denn der flache Bereich schaut doch ein bischen eng um die Nullage herum aus, wenn man auch noch bedenkt dass das nur bis 200 geht... also, ich meine, deine Kurve sieht auf den ersten Blick für mich "schöner" aus... oder wird das mit grösserem a "besser"? Vielleicht ist es ja doch gut 2 Parameter zu haben...

15

Freitag, 16. Oktober 2009, 01:14

Eben war a=1 hier 16
»4712« hat folgendes Bild angehängt:
  • Bild2.jpg

16

Freitag, 16. Oktober 2009, 06:55

aha... hmm... wie gefällt dir das? Beim Schlafen ist mir noch der Gedanke/die Befürchtung gekommen: vielleicht sind die höheren Terme hier ja das entscheidende an der exp Funktion, und meine ganze Argumentation oben ist falsch? (täte mir ja leid wenn ich dich auf eine falsche Fährte gesetzt hätte...)

Ähm, a = 16, du beziehst dich auf die Formel mit a/64?

Ist das absichtlich nur von 1...200 statt 1...2000, oder soll das den Vollausschlag repräsentieren?

17

Freitag, 16. Oktober 2009, 08:39

Habe "y = a * x/64 + (1- a/64 )/xmax * x*x" genommen und der Einfachheit halber bis 200 - in der Praxis sind es 2400.

18

Freitag, 16. Oktober 2009, 08:56

Zitat

1. Mittelpunkt des flachen Teils in % vom Vollgas (Geberweg)
2. Breite des Bereiches in % vom Vollgas (Geberweg)
3. Steilheit des flachen Bereiches in sagen wir 1/1...1/100
(bei Steilheit 100 wäre dann alles eine Gerade)

Du musst ja die Gaskurven ohnehin als fest eingestellte Parameter in den Controller reinkriegen.
Sonnst müsstest Du ja zusätzlich einen Programmieradapter mit Display und Tasten verbauen.

Die Steilheit der einzelnen Segmente kann nach der von mir vorgeschlagenen Methode frei eingestellt werden.

Die verwendung von 32Bit Variablen ist temporär notwendig, um auch Dezimalbrüche vor der Berechnung Multiplizieren und das Ergebnis hinterher wieder runterzuteilen können.
Wenn Du einen ziemlich vollen 16Bit Wert z.B. 60000 mit 5 Multiplizierst bist Du schon ausserhalb des Wertebereiches einer 16Bit int Zahl. Das führt dann zu Rechenfehlern!
Die 32Bit Int kannst Du ja auch temporär in einer Funktion anlegen, der Speicherplatz wird somit nur lokal in dieser Funktion belegt - Mit "C" ist sowas möglich.
Für die Ein- und Ausgabewerte dürften normale 16Bit INT ausreichend sein.

Bei der Methode die Du vorschlägst sind die Übergabepunkte das Problem.
Sie müssen nämlich für jede Einstellung neu berechnet werden.
Das dürfte von der Berechnung her sehr viel aufwändiger sein.

Bei der von mir vorgeschlagenen Methode sind diese Übergabepunkte fixe Werte und sollten somit keine Übergangsprobleme machen.

Guck Dir mal so eine 5Punkt Gaskurve bei einem Helikopter Mischer an. Auch da werden im Prinzip die Übergabepunkte verschoben und nicht die Punkte in der Mitte der Segmente.

Letztlich muß der Startpunkt eines Segments, sowie die Steilheit des Segments im Controller abgelegt werden, weil sich der Endepunkt des Segments ja wieder als Startpunkt des nächsten zeigt.
Da Du für die Berechnung der Übergabepunkte auch die entsprechenden Eingabewerte brauchst müssten für so einen Datensatz 3Werte im Controller abgelegt werden.

Wenn Du das so machst, kannst Du auch die Breite der Segmente für jedes Segment einzeln einstellen.

Wenn Du für die Eingabewerte feste Inkremente verwendest, z.B. 200µs, kriegst Du sonst halt immer gleich breite Segmente.

19

Freitag, 16. Oktober 2009, 09:15

Wilhelm,

Achim will das in seinen Koax-Mischer einbauen, und er hat da bereits eine sehr ausgefeilte Menüführung (ähnlich wie bei ESCs) um alle möglichen Parameter einstellen zu können (und nicht jedesmal neu proggen zu müssen). Ich vermute daher dass er keine fixen Settings haben will, d.h., irgendwann sollen/müssen die nötigen "Konstanten" irgendwo berechnet werden. Ich würde deswegen auch meinen, dass es sehr umständlich wäre wenn man "nur" um die Abflachung um die Null herum hinzubekommen X Parameter eingeben müsste. 1,2,3 Parameter OK, aber wenn man 10 Parameter um eine EXPO mit 5 Punkten zu approximieren eingeben müsste, würde man schon mal die Krise bekommen können, schätze ich.

Olli

PS: auch bei der Methode der Übergabepunkte sind doch "Konstanten" vorzuberechnen, oder?

20

Freitag, 16. Oktober 2009, 12:17

Zitat


[img]http://www.rclineforum.de/forum/attachment.php?attachmentid=146358&sid=[/img]

Das wäre dann in Excel sowas. Ich müsste das mal probieren, die Frage ist, ob das in
der Praxis zu grobe Übergänge gibt...


Das wäre die Lösung. Die "Übergänge" wirst Du vermutlich nicht spüren, denn es ist ja keine Achterbahn, auf der Du sitzt.

Zitat

was mich daran ja prinzipiel stören würde ist dass man so 2 Werte angeben muss um den Kurvenverlauf festzulegen, wo es doch einer auch tun würde... (das scheint mir der grosse Vorteil bei EXPO zu sein)


Nein, wenn Du nur einen Wert angibst, kannst Du lediglich z.B. die "Weichheit" einstellen, aber weder die X- Postion, noch die Y-Position.

Grüße
Malte

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »DrM« (16. Oktober 2009, 12:18)