Go Down

Topic: YAW Korrektur (Read 243 times) previous topic - next topic

KUCKY

Oct 13, 2017, 08:48 am Last Edit: Oct 13, 2017, 10:20 am by KUCKY
Hallo zusammen,
ich versuche seit einigen Tagen für meinen Quadrocopter eine YAW "Korrektur" zu schreiben. Der Code selber funktioniert. Die Werte verstehe ich aber nicht. Folgender Versuch:

Der Quadrocopter hängt an einem Faden und dreht sich um die eigene Achse. Zuerst gegen und dann mit dem Uhrzeiger. Die Geschwindigkeit ist annähernd gleich. Ich hätte jetzt eine "Sinuskurve" erwartet. Die Zacken kann ich mir nicht erklären. Was mir auffällt ist, das sich die Zeiten zwischen case0 und case1 sowie case 1 zu case2 ca. 50 millis bewegen. Mit der Zeile „if(millis() - lastYAW >= 100)" sind es sogar 150mS. Die gesamte LoopZeit liegt zwischen 2 und 20mS. Kleiner Zacken könnte ich mir noch erklären.


Code: [Select]

void IMUClass::UpdateIMU() {

static uint32_t lastYAW = millis();
static uint8_t state = 0;
static double yaw1 = 0;
static double yaw2 = 0;
static double diff1 = 0;
static double yawCorrection = 0;

 if(mpu9150.read()) {

 mpu9150.printAngles(mpu9150.m_fusedEulerPose);

 imuData->imuOutput[AXIS_02_X] = -(mpu9150.m_fusedEulerPose[VEC3_X] * RAD_TO_DEGREE);
 imuData->imuOutput[AXIS_13_Y] = (mpu9150.m_fusedEulerPose[VEC3_Y] * RAD_TO_DEGREE);
 imuData->imuOutput[AXIS_YAW] = map((mpu9150.m_fusedEulerPose[VEC3_Z] * RAD_TO_DEGREE), 180, -180, 0, 360); /// 180, -180 ???

 switch(state) {
 case 0:
         yaw1 = (imuData->imuOutput[AXIS_YAW]);
         Serial3.print(yaw1);Serial3.print(" ; ");
         state++;
         break;

 case 1:
         if(millis() - lastYAW >= 100){    /// <--
               yaw2 = (imuData->imuOutput[AXIS_YAW]);
               Serial3.print(yaw2);Serial3.print(" ; ");Serial3.print(millis());Serial3.print(" ; ");
               state++;
          }
 break;

 case 2:
           diff1 = (yaw2 - yaw1);
           yawCorrection = diff1;
           Serial3.print(diff1);Serial3.print(" ; ");
              if(diff1 <= 180){
                   Serial3.print("<=180 ; ");
                   diff1 += 360;
                            if((yawCorrection >= 180) || (yawCorrection <= -180))
                            yawCorrection = diff1;

           Serial3.print(yawCorrection);Serial3.print(" ; ");
          }
           else {
                 Serial3.print(">180 ;");
                 diff1 -= 360;
                      if(yawCorrection < 180)
                          yawCorrection = diff1;

          Serial3.print(yawCorrection);Serial3.print(" ; ");
          }

          lastYAW = millis();
          state = 0;
          break;
          Serial3.println();
 } /// end of switch
 }
}//--------------------------- end of UpdateIMU -----------------------------------------------------------------------


Hat jemand eine Idee, oder mache ich einen Denkfehler.

Gruß Willi

gregorss

Hat jemand eine Idee, oder mache ich einen Denkfehler.
Ich habe den Code nicht gelesen, weil er sehr schlecht zu lesen ist. Es gibt keine Formatierung, die die Struktur des Codes deutlich macht.

Was mir aufgefallen ist: Es ist nicht nur keine Sinuskurve - wenn man die Kurve sehr grob nachzeichnen würde, käme etwas dabei heraus, das einer Rechteckschwingung ähnelt.

Gruß

Gregor
DU MUSST DEIN ÄNDERN LEBEN!

KUCKY

Stimmt, die Formatierung hatte ich nicht kontrolliert. So besser?
Lt. Excel wäre es ein Polynom. Aber Du hast Recht, es ist eher ein Rechteck.

gregorss

Stimmt, die Formatierung hatte ich nicht kontrolliert. So besser?
Sehr viel besser. Ich habe es ausgedruckt und lese das in wenigen Minuten, wenn ich zum Rauchen in die Sonne gehe. Raucher sehen einfach besser aus, wenn sie sich zum Qualmen auf den richtigen Balkon begeben. Ich werde dauernd gefragt, ob ich Urlaub hatte ...

Gruß

Gregor
DU MUSST DEIN ÄNDERN LEBEN!

gregorss

Dein Code ist schwer durchschaubar. Er kann an einigen Stellen deutlich kürzer formuliert werden (womit ich jetzt nicht Sachen wie ein „Fragezeichen-if()" meine). Letzten Endes scheinst Du die ganze switch()-Struktur zu verwenden, um eine Berechnung durchzuführen, die sich sehr gut ohne switch() erledigen lässt.

Was das eigentliche Problem angeht, kann ich Dir nicht helfen. Dazu stecke ich zu wenig im Thema. Und was Du zeigst, scheint mir auch nicht die Ursache für die Zacken zu sein.

Gruß

Gregor
DU MUSST DEIN ÄNDERN LEBEN!

KUCKY

#5
Oct 13, 2017, 12:52 pm Last Edit: Oct 13, 2017, 01:17 pm by KUCKY
Danke für die Antwort.  Dann muss ich mal weiter suchen. Das mit dem "if" werde ich mal versuchen.

P.S. Ich darf nicht mehr rauchen. Frau sagt: "Entweder auf die alten Tage ein Motorad kaufen oder rauchen". Habe mich durchgesetzt, und das rauchen eingestellt. :)

Gruß und schönes Wochenende
Willi

gregorss

#6
Oct 13, 2017, 04:22 pm Last Edit: Oct 13, 2017, 04:25 pm by gregorss
P.S. Ich darf nicht mehr rauchen. Frau sagt: "Entweder auf die alten Tage ein Motorad kaufen oder rauchen". Habe mich durchgesetzt, und das rauchen eingestellt. :)
Wenn Du Dich durchgesetzt hättest, hättest Du ein Motorrad UND würdest rauchen. Vielleicht wärst Du dann halt unbeweibt :-)

Gruß

Gregor

PS: Was ich mit dem Fragezeichen-if() meinte, war sowas:

... a>1?b=2:b=3

Wenn a größer als 1 ist, ergibt dieser Ausdruck b=2, sonst b=3. Das ist knackich kurz aber man muss diese Syntax kennen und für jemanden, der nicht programmieren kann, ist das vollkommen unverständlich
DU MUSST DEIN ÄNDERN LEBEN!

Tommy56

... a>1?b=2:b=3
Oder um die Verwirrung zu komplettieren:
Code: [Select]

b = (a>1) ? 2 : 3;


Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

gregorss

#8
Oct 13, 2017, 04:38 pm Last Edit: Oct 13, 2017, 04:38 pm by gregorss
Oder um die Verwirrung zu komplettieren:
Code: [Select]

b = (a>1) ? 2 : 3;

b=a>3.14?cos(NUMBER):digitalRead(abs(NUMBER-1));

Wow, oder?

Gruß

Gregor
DU MUSST DEIN ÄNDERN LEBEN!

KUCKY

Danke für Eure Hilfe. Der Tipp mit dem "Rechteck" hat mich auf den Fehler aufmerksam gemacht. Ich hatte die Ausgabe in "case2" gemacht. Dann ist der Wert nicht pro Loop sondern u.U. alle 100mS. Nun sind die Werte besser.
b = (a>1) ? 2 : 3; kenne ich. Werde das probieren.

Gruß Willi

gregorss

b = (a>1) ? 2 : 3; kenne ich. Werde das probieren.
Belasse es beim Probieren. Ein „richtiges" if() ist für Neulinge wesentlich verständlicher. Ich versuche, immer so zu programmieren, dass es auch von Nichtprogrammierern schnell verstanden wird. Außerdem formatiere ich meinen Code quasi immer so, dass die Struktur schnell erfasst werden kann. Bei der Fehlersuche kann das Gold wert sein.

Gruß

Gregor
DU MUSST DEIN ÄNDERN LEBEN!

combie

#11
Oct 13, 2017, 10:52 pm Last Edit: Oct 13, 2017, 10:56 pm by combie
Ich kann mich dieser Ansicht eher nicht anschließen.

Ich halte den ternären Operator für sehr sinnvoll.
Der passende Hammer, für so manchen Nagel.
Eins der vielen Werkzeuge eines Programmierers.
Dadurch, dass man selber lernt ihn anzuwenden, kann man andere Programme leichter lesen.
(denn andere agieren nicht mit dieser "Rücksicht")

Nee, ich glaube nicht, dass man diesem Lernschritt auslassen sollte.
Und Neulinge vorm lernen beschützen/weghalten, ist nicht mein Weg.
"Freiheit, Gleichheit, Brüderlichkeit!"
Aber wie gelangen wir zu den Tätigkeitswörtern?
Quelle: Stanislaw Jerzy Lec

gregorss

Und Neulinge vorm lernen beschützen/weghalten, ist nicht mein Weg.
Du bist mehr für's Lesen, gell ;-)

Gruß

Gregor

PS: Schönes WE!
DU MUSST DEIN ÄNDERN LEBEN!

combie

#13
Oct 15, 2017, 11:05 am Last Edit: Oct 15, 2017, 11:14 am by combie
Quote
Du bist mehr für's Lesen, gell ;-)
Wenn es "schön" macht, was ist dagegen zu sagen?


In meiner Wühlkiste ist mir eben ein Erkenner für positive Flanken unter die Finger gekommen.....
Da musste ich an dich denken!

Ein einfacher endlicher Automat, in quasi einer Zeile!
Code: [Select]


bool flankenMerker = true; // default, wg. Pullup

bool erkenneFlanke(const bool value, bool & merker)
{
  return merker==value?false:merker=value;
}


void setup()
{
 Serial.begin(9600);
 Serial.println("");
 pinMode(5,INPUT_PULLUP);
}

void loop()
{
  if(erkenneFlanke(digitalRead(5),flankenMerker)) Serial.println("positive Flanke erkannt.");
}
"Freiheit, Gleichheit, Brüderlichkeit!"
Aber wie gelangen wir zu den Tätigkeitswörtern?
Quelle: Stanislaw Jerzy Lec

Go Up