[Vorstellung] Heron-Verfahren in NXC f

Mindstorms im Unterricht. Ideen, Vorstellungen

Moderator: Moderatoren

Der Marc
Mindstormsfreund
Mindstormsfreund
Beiträge: 8
Registriert: 10. Sep 2008 18:33
Kontaktdaten:

[Vorstellung] Heron-Verfahren in NXC für den NXT

Beitragvon Der Marc » 22. Sep 2008 15:06

Hi Community!

Mein Name ist Marc (wer hätte es gedacht) und wir haben an unserer Schule eine schöne, kleine und feine RoboLab AG :D ! Nun zu unserem Problem (wer hat hier keins?):

Wir setzen zur Zeit das Heronverfahren (Mathematik Kl. 9, wir sind aber in der Zehnten) in NXC um. Der Roboter soll das Heronverfahren durchrechnen und das mit Hilfe eines Rechteckes zu einem Quadrat werden lassen (?). Einen Quellcode dazu werde ich noch posten. Ich wollt nur schon mal was beginnen.



Wir haben es nun geschaftt! Wir sind damit auch auf den Fuldaer Medientagen aufgetreten und uns kam einiges an Interesse entgegen. Unten seht ihr nun den Quellcode. Bildmaterial über den endgültigen Roboter folgt noch. Dieses ist noch nicht fertig, da wir während des Entwicklungsprozesses mehrmals das Ding umgebaut haben.


LG
Marc
Zuletzt geändert von Der Marc am 6. Dez 2008 12:58, insgesamt 2-mal geändert.

Der Marc
Mindstormsfreund
Mindstormsfreund
Beiträge: 8
Registriert: 10. Sep 2008 18:33
Kontaktdaten:

Heron-Verfahren!

Beitragvon Der Marc » 6. Dez 2008 12:53

Liebe Community!

Hier nun der komplette Quellcode mit Kommentaren. Wenn Ihr fragen habt, so wendet Euch doch einfach an mich :wink:

Code: Alles auswählen

/*
Wernher-von-Braun-Schule Neuhof, RoboLab AG
August bis November 2008

~*~ Visualisierung des Heron-Verfahrens durch einen NXT ~*~


Das Heron-Verfahren ist ein Näherungsverfahren um die Qudratwurzel einer Zahl
zu bestimmen.

Nähere Informationen hierzu unter http://de.wikipedia.org/wiki/Heron-Verfahren
wobei wir das ganze Grafisch, das bedeutet geometrisch, dargestellt haben.

© 2008 by
Benjamin Hosenfeld
Patrick Kimpel
Marc Leinweber
Marius Ruppel
& Stefanie Jungk

*/
#define ausgleich 40
#define TEMPO 100
#define DREHEN 280

// Quadratzahl: Aus dieser Zahl soll die Wurzel gezogen werden.
unsigned long quadratzahl = 6;

// Startwert: 2,5 (entsprechend vergrößert, siehe unten)
unsigned long startwert = 1800;
int epsilon = 5;
unsigned long m1;
unsigned long m2 = 0;
unsigned long gegenwert;
unsigned long differenz;
unsigned long halt;
unsigned long g_halt;


task main ()

{
  // NXC kennt keine Gleitkommadarstellung, entsprechende "Vergrößerung" der Zahlen
  quadratzahl *= 1000000;

  gegenwert = quadratzahl / startwert;

  ClearScreen ();
  TextOut (0, LCD_LINE1, "Wir ziehen die");
  TextOut (0, LCD_LINE2, "Wurzel aus");
  NumOut (15, LCD_LINE3, quadratzahl);
  TextOut (0, LCD_LINE4, "mittels Heron-");
  TextOut (0, LCD_LINE5, "verfahren mit");
  TextOut (0, LCD_LINE6, "dem Startwert");
  NumOut (15, LCD_LINE7, startwert);
  Wait (3000);
  ClearScreen ();
  Wait (500);
  TextOut (0, LCD_LINE1, "Zuerst fahre ich");
  TextOut (0, LCD_LINE2, "das Rechteck mit");
  TextOut (0, LCD_LINE3, "den Startwerten");
  TextOut (0, LCD_LINE5, "a:");
  NumOut (16, LCD_LINE5, startwert);
  TextOut (0, LCD_LINE6, "und b:");
  NumOut (40, LCD_LINE6, gegenwert);
  Wait (3000);

// Der Roboter fährt das Ausgangsrechteck mit den Werten a=Startwert & b=Gegenwert.
  repeat (2)

  {
    ResetRotationCount (OUT_B);
    ResetRotationCount (OUT_C);
    Wait (1000);

    // Länge der Strecke wird über die interne Prozessorzeit (CurrentTick) in
    // Millisekunden gezählt.

    // Die Seitenlänge wird durch die Variable 'halt' beestimmt. Diese enthält
    // den Startwert mal 2 (zur Vergrößerung des Maßstabs) und die aktuelle Zeit.
    halt = CurrentTick () + (startwert *2);

    // Der Roboter soll solange geradeausfahren, bis die aktuelle Zeit die Va-
    // riable 'halt' überschreitet.


    while (CurrentTick () <= halt)

    // Durch eine Ungegnauigkeit der Lego-Motoren, muss die Geradeausfahrt des
    // Roboters optimiert werden. Hierbei werden die Umdrehungen der beiden Mo-
    // toren verglichen und durch ein Stoppen des schnelleren Motors ausge-
    // glichen.
    {
      OnFwd (OUT_BC, TEMPO);

      while (MotorRotationCount (OUT_B)< MotorRotationCount (OUT_C))

      {
       Off (OUT_C);
       OnFwd (OUT_B, TEMPO);
      }

      while (MotorRotationCount (OUT_B)> MotorRotationCount (OUT_C))

      {
       Off (OUT_B);
       OnFwd (OUT_C, TEMPO);
      }

      while (MotorRotationCount (OUT_B) == MotorRotationCount (OUT_C))

      {
       OnFwd (OUT_BC, TEMPO);
      }
    }

    Off (OUT_BC);

    // Vor der 90-Grad-Drehung am Ende einer Rechtecksseite werden die Umdreh-
    // ungszähler ein weiteres Mal verglichen. Der zurückliegende Motor gleicht
    // noch einmal aus, um die folgende Drehung zu optimieren.
    do

    {
     OnFwd (OUT_B, ausgleich);
    }

    while (MotorRotationCount (OUT_B)< MotorRotationCount (OUT_C));

    Off (OUT_B);

    do

    {
     OnFwd (OUT_C, ausgleich);
    }

    while (MotorRotationCount (OUT_B)> MotorRotationCount (OUT_C)) ;

    // 90-Grad-Drehung durch den Befehl 'RotateMotorEx' und Rücksetzung der Um-
    // drehungszähler der Motoren (ResetRotationCount).

    Off (OUT_BC);
    Wait (1000);
    RotateMotorEx(OUT_BC, 30, DREHEN, 100, true, true);

    ResetRotationCount (OUT_B);
    ResetRotationCount (OUT_C);
    Wait (1000);

    // Errechung der 'halt'-Variable für die Gegenseite (g_halt). Hierbei wird
    // wieder mit dem Faktor '2' multipliziert, um den Maßstab zu vergrößern.
    g_halt = CurrentTick () + (gegenwert*2);


    while(CurrentTick () <= g_halt)

    {
     OnFwd (OUT_BC, TEMPO);

     while (MotorRotationCount (OUT_B) < MotorRotationCount (OUT_C))

     {
      Off (OUT_C);
      OnFwd (OUT_B, TEMPO);
     }

     while (MotorRotationCount (OUT_B) > MotorRotationCount (OUT_C))

     {
      Off (OUT_B);
      OnFwd (OUT_C, TEMPO);
     }

     while (MotorRotationCount (OUT_B) == MotorRotationCount (OUT_C))

     {
      OnFwd (OUT_BC, TEMPO);
     }
    }

    Off (OUT_BC);

    do

    {
     OnFwd (OUT_B, ausgleich);
    }

    while (MotorRotationCount (OUT_B) < MotorRotationCount (OUT_C));

    Off (OUT_B);

    do

    {
     OnFwd (OUT_C, ausgleich);
    }

    while (MotorRotationCount (OUT_B) > MotorRotationCount (OUT_C));

    Off (OUT_BC);
    Wait (1000);
    RotateMotorEx(OUT_BC, 30, DREHEN, 100, true, true);
    Wait (500);

    ResetRotationCount (OUT_B);
    ResetRotationCount (OUT_C);
    Wait (500);
  }

  ClearScreen ();
  Wait (500);
  TextOut (0, LCD_LINE3, "Nun beginne");
  TextOut (0, LCD_LINE4, "ich zu rechnen");

  // Beginn des 'Heron'-Algorithmus.

   m1 = (gegenwert + startwert) / 2;
   differenz = m1 - m2;

   while (differenz>epsilon)

   {
    gegenwert = quadratzahl / m1;
    m2 = (m1 + gegenwert) / 2;
    differenz = abs (m1 - m2);
    ClearScreen ();
    Wait (500);
    TextOut (0, LCD_LINE1, "Jetzt fahre ich");
    TextOut (0, LCD_LINE2, "das Rechteck mit");
    TextOut (0, LCD_LINE3, "den Werten");
    TextOut (0, LCD_LINE5, "a:");
    NumOut (16, LCD_LINE5, m1);
    TextOut (0, LCD_LINE6, "und b:");
    NumOut (40, LCD_LINE6, gegenwert);
    Wait (3000);

    repeat (2)

    {
    Wait (500);

    ResetRotationCount (OUT_B);
    ResetRotationCount (OUT_C);
    Wait (1000);
    halt = CurrentTick() + (m1*2);

    while (CurrentTick () <= halt)

     {
      OnFwd (OUT_BC, TEMPO);

      while (MotorRotationCount (OUT_B) < MotorRotationCount (OUT_C))

      {
       Off (OUT_C);
       OnFwd (OUT_B, TEMPO);
      }

      while (MotorRotationCount (OUT_B) > MotorRotationCount (OUT_C))

      {
       Off (OUT_B);
       OnFwd (OUT_C, TEMPO);
      }

      while (MotorRotationCount (OUT_B) == MotorRotationCount (OUT_C))

      {
       OnFwd (OUT_BC, TEMPO);
      }
     }

     Off (OUT_BC);

     do

     {
      OnFwd (OUT_B, ausgleich);
     }

     while (MotorRotationCount (OUT_B)< MotorRotationCount (OUT_C));

     Off (OUT_B);

     do

     {
      OnFwd (OUT_C, ausgleich);
     }

     while (MotorRotationCount (OUT_B)> MotorRotationCount (OUT_C));

     Off (OUT_BC);
     Wait (1000);
     RotateMotorEx(OUT_BC, 30, DREHEN, 100, true, true);
     Wait (500);

     ResetRotationCount (OUT_B);
     ResetRotationCount (OUT_C);
     Wait (1000);
     g_halt = CurrentTick () + (gegenwert*2);

     while(CurrentTick () <= g_halt)

     {
      OnFwd (OUT_BC, TEMPO);

      while (MotorRotationCount (OUT_B)< MotorRotationCount (OUT_C))

      {
       Off (OUT_C);
       OnFwd (OUT_B, TEMPO);
      }

      while (MotorRotationCount (OUT_B)> MotorRotationCount (OUT_C))

      {
       Off (OUT_B);
       OnFwd (OUT_C, TEMPO);
      }

      while (MotorRotationCount (OUT_B) == MotorRotationCount (OUT_C))

      {
       OnFwd (OUT_BC, TEMPO);
      }
     }

     Off (OUT_BC);

     do

     {
      OnFwd (OUT_B, ausgleich);
     }

     while (MotorRotationCount (OUT_B)< MotorRotationCount (OUT_C));

     Off (OUT_B);

     do

     {
      OnFwd (OUT_C, ausgleich);
     }

     while (MotorRotationCount (OUT_B)> MotorRotationCount (OUT_C));

     Off (OUT_BC);
     Wait (1000);
     RotateMotorEx(OUT_BC, 30, DREHEN, 100, true, true);
     Wait (500);

     ResetRotationCount (OUT_B);
     ResetRotationCount (OUT_C);
     Wait (500);

    }

    m1 = m2;

   }

   // Bildschirmausgabe der Quadratwurzel.

   ClearScreen ();
   Wait (500);
   TextOut (0, LCD_LINE1, "Die Wurzel aus");
   NumOut (15, LCD_LINE2, quadratzahl);
   TextOut (0, LCD_LINE3, "ist rund");
   NumOut (15, LCD_LINE4, m1);
   Wait (5000);
   ClearScreen ();
   Wait (500);
   TextOut (10, LCD_LINE2, "(c)");
   NumOut (30, LCD_LINE2, 2008);
   TextOut (60, LCD_LINE2, "by");
   TextOut (0, LCD_LINE3, "team7.goerkie.de");
   TextOut (10, LCD_LINE4, "B. Hosenfeld");
   TextOut (10, LCD_LINE5, "P. Kimpel");
   TextOut (10, LCD_LINE6, "M. Leinweber");
   TextOut (10, LCD_LINE7, "M. Ruppel");
   TextOut (10, LCD_LINE8, "& S. Jungk");
   Wait (8000);

}

Der Marc
Mindstormsfreund
Mindstormsfreund
Beiträge: 8
Registriert: 10. Sep 2008 18:33
Kontaktdaten:

Beitragvon Der Marc » 12. Jan 2009 14:43

Schade. Es scheint niemanden zu interessieren... :(

Benutzeravatar
Bertolego
Moderator
Moderator
Beiträge: 773
Registriert: 16. Mai 2006 18:27
Wohnort: NRW

Beitragvon Bertolego » 12. Jan 2009 19:16

Hallo Marc,

dein /Euer Projekt finde ich klasse, zeigt es doch eine gute Alternative zum einfachen Sqrt(x) :D

Gibt es ein Video davon zu sehen?
Ich denke, das ist viel anschaulicher zu verstehen was der Mathe-Robi macht!

Der Marc
Mindstormsfreund
Mindstormsfreund
Beiträge: 8
Registriert: 10. Sep 2008 18:33
Kontaktdaten:

Beitragvon Der Marc » 19. Jan 2009 14:18

Gute Idee...

Ich denke da lässt sich wohl mal was machen. Melde mich, sobald ich Marius mal angezapft habe :D :wink:

Edit:

YouTube-Video

Ist allerdings nur die erstellte Animation unseres Lehrers und diese Animation entspricht auch nicht der richtigen Konstruktion. Wir haben auf der "Turtle"-Konstruktion aufgebaut und sie für uns verändert.

Aber mal 'ne andere Frage: Du hast doch sicherlich von der Geradeausfahrschwierigkeit gelesen (s. Quelltextkommentare). Was hast du für Lösungsansätze?

while (CurrentTick () <= halt)

// Durch eine Ungegnauigkeit der Lego-Motoren, muss die Geradeausfahrt des
// Roboters optimiert werden. Hierbei werden die Umdrehungen der beiden Mo-
// toren verglichen und durch ein Stoppen des schnelleren Motors ausge-
// glichen.
{
OnFwd (OUT_BC, TEMPO);

while (MotorRotationCount (OUT_B)< MotorRotationCount (OUT_C))

{
Off (OUT_C);
OnFwd (OUT_B, TEMPO);
}

while (MotorRotationCount (OUT_B)> MotorRotationCount (OUT_C))

{
Off (OUT_B);
OnFwd (OUT_C, TEMPO);
}

while (MotorRotationCount (OUT_B) == MotorRotationCount (OUT_C))

{
OnFwd (OUT_BC, TEMPO);
}
}

Off (OUT_BC);

// Vor der 90-Grad-Drehung am Ende einer Rechtecksseite werden die Umdreh-
// ungszähler ein weiteres Mal verglichen. Der zurückliegende Motor gleicht
// noch einmal aus, um die folgende Drehung zu optimieren.
do

{
OnFwd (OUT_B, ausgleich);
}

while (MotorRotationCount (OUT_B)< MotorRotationCount (OUT_C));

Off (OUT_B);

do

{
OnFwd (OUT_C, ausgleich);
}

while (MotorRotationCount (OUT_B)> MotorRotationCount (OUT_C)) ;

// 90-Grad-Drehung durch den Befehl 'RotateMotorEx' und Rücksetzung der Um-
// drehungszähler der Motoren (ResetRotationCount).

Off (OUT_BC);
Wait (1000);
RotateMotorEx(OUT_BC, 30, DREHEN, 100, true, true);

ResetRotationCount (OUT_B);
ResetRotationCount (OUT_C);
Wait (1000);



Und das Problem mit den großen Zahlen? Findest du unseren Lösunsvorschlage angemessen? Übrigens: Wir bekommen bald eine eigene Website wo auch ein NXT-Wiki laufen soll. Bin mal gespannt was da rauskommt. Vielleicht könnte man ja mit eurem Board eine Partnerschaft gründen.

Website der Wernher-von-Braunschule, Neuhof, LK Fulda, Hessen
AG-Unterseite


Und eben stelle ich fest, dass wir euch leider nur Bildmaterial liefern können. Wir sind zur Zeit an einem Plotterprojekt (Geheimnis :D) und haben dafür komplett abgerissen... :oops:
Aber natürlich stellen wir unser neues Projekt auch vor. Und unser Ziel ist es, wer hätte es gedacht, komplexe mathematische Funktionen in ein KOS einzutragen. Vielleicht sogar mit Benutzereingabe. Das ist allerdings das Maximalziel...

(Zum Projekt)

LG
Marc

Benutzeravatar
sirs
Schreibt viel
Schreibt viel
Beiträge: 274
Registriert: 17. Mär 2008 16:45
Wohnort: Bayern!

Beitragvon sirs » 19. Jan 2009 17:10

wie lange habt ihr dazu gebraucht?
Es grüßt euch sirs! hier klicken :)
Das KÄSEPARADOX: Je mehr Käse, desto mehr Löcher. Je mehr Löcher, desto weniger Käse. -> Mehr = Weniger

Der Marc
Mindstormsfreund
Mindstormsfreund
Beiträge: 8
Registriert: 10. Sep 2008 18:33
Kontaktdaten:

Beitragvon Der Marc » 20. Jan 2009 09:21

mhhh.... Also wir haben die verschiedensten Modelle getestet, um das optimale Modell zu finden. Alles in allem haben wir für das Projekt bis es mit Programmierung und Modell stand vier Monate gebraucht. Es tauchen halt immer wieder Fehler auf, die es zu beseitigen gilt. Ich nehme an ihr kennt das. Irgendwelche Faktoren sind immer wieder negativ aufgefallen. Am schnellsten stand bei dieser Sache definitiv das Programm. Das haben wir in ca. 50 Minuten so auf die Beine gestellt, wie es ungefähr da steht. Zwischendurch haben wir nur noch ganz kleine Kleinigkeiten beseitigt.

Helson
Neuer Schreiber
Neuer Schreiber
Beiträge: 1
Registriert: 13. Jul 2012 22:11

Re:

Beitragvon Helson » 18. Jul 2012 14:12

Bertolego hat geschrieben:Hallo Marc,

dein /Euer Projekt finde ich klasse, zeigt es doch eine gute Alternative zum einfachen Sqrt(x) :D

Gibt es ein Video davon zu sehen?
Ich denke, das ist viel anschaulicher zu verstehen was der Mathe-Robi macht!

Das würde mich auch brennend interessieren. Die Unterseite der AG ist leider nicht mehr vorhanden.

LG
Take it easy


Zurück zu „Unterricht & AG“

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot] und 8 Gäste

Lego Mindstorms EV3, NXT und RCX Forum : Haftungsauschluss