Hallo, weiß jemand eine Möglichkeit wie man den Satz des Pythagoras effektiv auf einem Mikrocontroller berechnen kann? Ich muss ihn 8000 mal in der Sekunde berechnen und die Wurzel braucht einfach zu lange. Zur Erinnerung Satz des Pythagoras: c = sqrt(a*a + b*b) Gruß Peter
Vermeiden. Wie lautet denn die Aufgabenstellung, die du meinst mit einem Phytagoras berechnen zu müssen. Ev. kann man auf dieser Ebene schon etwas anderes finden.
Oder ein iteratives Verfahren für die Wurzel verwenden. 8000 mal pro Sekunde heisst, wenn du die ganze Rechenpower ausnutzen darfst: bis zu 2000 Takte Zeit, das sollte eigentlich reichen, wenn du nicht noch float oder "langbittige" Variablen benutzen musst... Kannst du ein paar Infos mehr liefern? Wie immer führen viele Wege nach Rom, aber du musst uns schon sagen zu welchem Rom du gelangen möchtest.
Ich muss bei einer feldorientierten Regelung die Ständerspannung einer Synchronmaschine berechnen. Dabei wird der Betrag des Spannungsvektors aus den einzelnen Spannungskomponenten gebildet. Die Formel lautet Us = sqrt(Usd*Usd + Usq*Usq)
Berechnest du die Wurzel in Gleitkomm? Es gibt auch Ganzzahl- bzw. Festkommaimplementationen, die schneller sind. Sind a und b völlig vonvorhersagbar, oder gibt es einen Zusammenhang zwischen den a- und b-Werten in aufeinanderfolgenden Schleifndurchläufen? Dann kann man evtl. das neue Ergebnis aus dem vorangegangenen ableiten. Was mit mit dem Ergebnis c gemacht? Vielleicht brauchst c gar nicht, sondern c² oder ein anderer von c abhängiger Ausdruck wäre ebenso ausreichend, so dass du auf die Wurzelberechnung ganz verzichten oder sie zumindest durch eine einfachere Operation ersetzen kannst. Wie sieht die Gesamtanwendung aus? Ein Beispiel: Die Berechnung der Punkte auf einem Kreis zur grafischen Darstellung kann ebenfalls mit dieser Formel erfolgen, es gibt aber sehr viel effizientere Algorithmen dafür.
Ein iteratives Verfahren benutze ich schon Das Problem ist, dass der Rechner noch einiges mehr rechnen muss und die Wurzel zu viel Zeit braucht. Ich habe überlegt ob man die Formel nicht irgendwie umstellen kann so dass die Zahlen kleiner werden und es mit einer Tabelle lösen kann
Elm Chan hat da eine ASM Funktion für den den gcc, die das mit ~600 cycles berechnen kann: http://elm-chan.org/docs/avrlib/sqrt32.S Allerdings für 16bit Integer Werte.
Peter schrieb: > Ich muss bei einer feldorientierten Regelung > die Ständerspannung einer Synchronmaschine berechnen. Die Spannung geht als IstWert in die Regelung zurück? Könntest du zb den Sollwert quadrieren und die Regelung quasi 'auf den Quadraten laufen lassen' ? Wenn der Istwert größer als der Sollwert ist, dann ist auch das QUadrat des Istwertes größer als das Quadrat des Sollwertes und umgekehrt. Aber: Ein Quadrat im Sollwert rechnet sich leichter als die Wurzel im Istwert (und der Sollwert ändert sich wahrscheinlich auch nicht so oft)
Ja Us geht in die Regelung ein. Hab ich auch schon überlegt. Beim PI regler würde es gehen müsste aber anschließend doch die Wurzel ziehen da sonst der Wert nicht passt. >Die Spannung geht als IstWert in die Regelung zurück? >Könntest du zb den Sollwert quadrieren und die Regelung quasi 'auf den >Quadraten laufen lassen' ?
Peter schrieb: > Ja Us geht in die Regelung ein. > > Hab ich auch schon überlegt. > Beim PI regler würde es gehen müsste > aber anschließend doch die Wurzel ziehen > da sonst der Wert nicht passt. Ich glaube nicht, dass du am Ausgang noch die Wurzel ziehen musst. Der Regler stellt ja eigentlich nur die Stellgröße solange nach, bis Istwert und Sollwert übereinstimmen. Der weiß nichts von irgendwelchen 'Einheiten'. Die Sensitivität des Reglers (keine Ahnung ob man das so nennen kann) wird eine andere sein aber das sollte eigentlich mit den Regelparametern ausgleichbar sein.
Da die Regelabweichung normalerweise klein ist (sonst taugt der Regler nichts), ist Istwert - Sollwert ≈ (Istwert² - Sollwert²) / (2·Sollwert) Damit ist die Wurzel weg, und etwas anderes brauchst du doch auch nicht, oder?
Vielleicht hilft dir dieser Artikel weiter: http://www.flipcode.com/archives/Fast_Approximate_Distance_Functions.shtml
Wenns Zeitkritisch ist und nicht auf 2Mio nachkommastellen genau sein muss, und du noch Platz im speicher hast, dann rechne das doch auf deinem PC vor und speicher das agnze in einem 2Dim Feld aub, dann musst du dir die DAten nur daraus hohlen und damit weiterrechnen. So un vorher gesehen sind Ständerspannungen ja nun auch nicht.
>>Us = sqrt(Usd*Usd + Usq*Usq)
Der Wert von (Usd*Usd + Usq*Usq) wird sich bei 8000 Abtastwerten/s nur
langsam ändern. Man kann dann das iterative Heron Verfahren heranziehen,
als Näherung das alte Ergebnis nehmen und mit dem neuen Wert einmal ein
update durchführen. Ich wette, das funzt. Hatte yalu auch schon oben
vorgeschlagen.
Cheers
Detlef
Edit:
Oder das Wurzelziehproblem in den Regler mit einbauen: Ein Integrierer,
der mit seinem quadrierten Ausgangswert rückgekoppelt ist bildet die
Wurzel on the fly.
Fuer int: http://www.convict.lu/Jeunes/Math/square_root_CORDIC.htm Fuer float: http://www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/archv014.cgi?read=51193
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.