Forum: Mikrocontroller und Digitale Elektronik Modulo Addition


von Frank M. (frankm)


Lesenswert?

Hallo Kollegen,

ich hänge an einem Problem fest, welches sich so darstellt:
Ich muß zu einem laufenden Winkel (Sägezahn 0...2PI) einen Offset hinzu 
addieren. Das Ergebniss muß dann wieder auf 0...2PI begrenzt sein 
(Winkelüberlauf).
Bis jetzt habe ich die "Begrenzung" so gelöst:

if (winkel > PI2) winkel = winkel - PI2
if (winkel < 0.0) winkel = winkel + PI2

was rein mathematisch funktioniert.

Jedoch:
Wenn der Ursprungs-Sägezahn auf Null springt, dann bekomme ich für einen 
Zyklus eine umgekehrte Spitze in mein Ergebniss.


Ich habe schon viel versucht, jedoch kommt hier das klassische Brett 
vorm Kopf zum Tragen & ich brauche Unterstützung...

Vielen Dank für Eure Ideen!


Gruss & frohe Ostern!

Frank

von Simon K. (simon) Benutzerseite


Lesenswert?

Ich verstehe noch nicht so ganz, was der Winkeloffset mit einem Sägezahn 
zu tun haben soll.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Welche Programmiersprache?
Welche Datentypen?
Welcher Prozessor?

Und evtl. wäre eine Skizze/Foto/Bild nicht schlecht...

von Frank M. (frankm)


Lesenswert?

Hallo Kollegen,

ich verwende einen TriCore 1796, programmiere in C und verwende Float 
als Datentyp.

@Simon:

Wenn Du Dir einen Sägezahn mit einer Phasenlage vorstellst und Du aber 
zum weiteren rechnen soll dieser Sägezahn aber eine andere Phasenlage 
besitzen. Dazu addiert man einen Offset und man erhält eine neuen 
Sägezahn jedoch mit einer Phasenverschiebung.


Gruss


Frank

von noname (Gast)


Lesenswert?

Hallo,

Offset addieren. Wenn Ergebnis größer als 2PI, dann 2PI abziehen.

von HolgerT (Gast)


Lesenswert?

Hallo Frank,

Frank Mayer schrieb:
> if (winkel > PI2) winkel = winkel - PI2
> if (winkel < 0.0) winkel = winkel + PI2

Ich nehme an, vorher machst Du die Addition von Winkel und Offset. Dann 
verstehe ich die zweite Zeile nicht - der Winkel (Sägezahn), kann nicht 
negativ werden. Aber vielleicht habe ich das Problem noch nicht richtig 
verstanden.

Ich würde es so machen (Pseudocode):
1
winkel := winkel + Offset
2
wenn (winkel > PI2) dann winkel = winkel - PI2

oder, falls Offset > PI2 sein kann:
1
winkel := winkel + Offset
2
solange (winkel > PI2) mache
3
  winkel = winkel - PI2

Gruß
HolgerT

von Helmut -. (dc3yc)


Lesenswert?

Für solche Fragestellungen gibts in C den Modulo-Operator. Als 
Wertebereich des Ergebnisses würde dann z.b. 0<=winkel<PI2 herauskommen.

von Frank M. (frankm)


Lesenswert?

Hallo Kollegen,

wenn ich die Modulo Funktion verwende, die Helmut angesprochen hat:

(als Pseudo-Code)

winkel = winkel + Offset;

winkel = modulo(winkel,PI2);

Wie sieht das den in C aus?


Danke!


Gruss


Frank

von Flo (Gast)


Lesenswert?

kann es sein dass PI2  0,5 Pi entspricht?

Sieht ähnlich in der cmath Lib aus (glaub ich):
PI_2 ist da Pi halbe

Schreib mal 2*PI hin, damit die Schreibweise eindeutig ist.

von Georg (Gast)


Lesenswert?

Frank Mayer schrieb:
> Wie sieht das den in C aus?

Zwei Varianten:

1.
winkel = winkel + Offset;
winkel = (winkel < PI2) : winkel ? winkel - PI2;

2.
winkel = winkel + Offset;
if(winkel > PI2)
  winkel -= PI2;

von Frank M. (frankm)


Lesenswert?

Hi Flo,

ich kann auch 6.28 oder die Zahl X einführen, was ja dem Rechengang 
nichts abnimmt.


Gruss,


Frank

von Georg (Gast)


Lesenswert?

Sry, bei der ersten Variante gehoeren ':' und '?' vertauscht

von stokes (Gast)


Lesenswert?

Geht das nicht einfacher mit dem Modulo Operator welcher in C 
normalerweise Verwendung findet?

so in etwa dann: winkel = winkel % (2*pi);
oder kurz winkel %= (2*pi);

Dann braucht man sich auch nicht drum kümmern wenn der Winkel ein 
Vielfaches von 2Pi größer ist.

Mfg

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Modulo Operator
Der ist in C nur für Integertypen definiert, nicht aber für 
Fliesskommazahlen.

von Karl H. (kbuchegg)


Lesenswert?

> Jedoch:
> Wenn der Ursprungs-Sägezahn auf Null springt, dann bekomme ich für einen
> Zyklus eine umgekehrte Spitze in mein Ergebniss.

Jede Wette:
Dein Sägezahn mag zwar auf 0 springen, in deinem float steht aber keine 
0, sondern irgendwas in der Form -1E-12. Also eine sehr kleine negative 
Zahl. Und die ist nun mal kleiner als 0.

Willkommen in der realen Welt, in der naive Anwendung von float oder 
double sofort mit 'seltsamen Verhalten' bestraft wird. Natürlicht nicht 
sofort, sondern erst dann wenn der Kunde das erste mal zusieht.

Bei Fliesskommarechnungen immer ein Epsilon einplanen! Wer float so 
vergleicht

   if( irgendwas == wasanderes )

sollte sofort eine mit dem nassen Fetzen übergezogen bekommen

   if( fabs( irgendwas - wasanderes ) < epsilon )

ist die Art und Weise wie man Fliesskommazahlen miteinander auf 
Gleichheit vergleicht.
Ähnliches gilt auch für < und > Vergleiche.

Für Epsilon muss man sich überlegen, wie gross der Rechenfehler an der 
betreffenden Stelle sein kann und dementsprechend ein Epsilon auswählen.

von stokes (Gast)


Lesenswert?

Okay, sorry das wusste ich nicht.
Somit würde ich mich dan bzgl. der Lösung am 2ten Vorschlag von Georg 
anhalten und es um ne Schleife ergänzen, um sicherzustellen, dass der 
resultierende Winkel immer zwischen 0 und 2pi liegt.
Das könnte dann etwa so aussehen:

winkel = winkel + Offset;
while(winkel > 2*PI)  winkel -= 2*PI;

mfg

von Frank M. (frankm)


Lesenswert?

Hallo Kollegen,

um nun die erste Runde zusammenzufassen:

- modulo Operator gibt ist hierfür nicht (nur für int)
- man muß beide Richtungen abfragen(abfangen)

liege ich mit meinem:

if (winkel > 2*PI) winkel = winkel - 2*PI
if (winkel < 0.0)  winkel = winkel + 2*PI

so weit neben drann?

Zugegeben muß diese Schreibweise einen Fehler beinhalten. Jedenfalls für 
den Fall, daß der Referenz-Sägezahn gegen Null springt, sonst hätte ich 
diesen Rücksprung für diesen Zyklus nicht.

Ist es etwa die zweite Zeile?

Ich versuche es mit dem Vorschlag von stokes..


Vielen Dank für die vielfältige Hilfe!

Gruss,


Frank

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
Noch kein Account? Hier anmelden.