- 3D-Druck Einstieg und Tipps         
Seite 1 von 4 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 31

Thema: Neuling: Odometrie

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    23.12.2007
    Ort
    AC
    Beiträge
    23

    Neuling: Odometrie

    Anzeige

    Praxistest und DIY Projekte
    Hallo Robotikfreunde!

    Endlich hab ich es auch mal geschafft meinen ASURO zusammenzulöten.
    Es klappt auch alles so weit - außer meinem Programm...
    Weil meine Kumpels, mit denen ich normalerweise baue, im moment Skifahren sind, dachte ich mir, ich poste einfach mal hier rein und wende mich mit meinen Problemen an Euch !

    Ich habe ein Odometrieprogramm geschrieben und dachte es würde auch gut laufen, tut es aber nicht. Asuro hat immer noch einen rechtsdrall und die Drehzahlen der Räder beeinflussen sich trotz Programm nicht!

    Hier einfach mal der Code:

    Code:
    /* Geradeausfahren */
    
    void GeradeAus()
    {
       unsigned int i=0;
       unsigned int OdoDataInit[2];
       unsigned int OdoData[2];
       unsigned int n0=0;
       unsigned int n1=0;
       OdometrieData(OdoDataInit);
       float comp;
       unsigned int old0=OdoDataInit[0];
       unsigned int old1=OdoDataInit[1];
       unsigned int spd0=175;
       unsigned int spd1=175;
       OdometrieData(OdoData);
    
       MotorDir(FWD,FWD);
       MotorSpeed(spd0,spd1);
    
       for(i=0; i<=50; i++)  // 50 mal Messen für exakteren Wert
       {
          /* Berechnung der Drehzahl des 0. Odosensors */
    
          if(old0==0){old0=1;} // sonst teilt man nacher durch 0 wenns dunkel ist!
    
          if(OdoData[0]/old0 > 2 || OdoData[0]/old0 < 0.5) // Wenn Übergang n erhöht
          {
             n0++;
          }
    
          old0=OdoData[0];
    
          /* Berechnung der Drehzahl des 1. Odosensors */
    
          if(old1==0){old1=1;} // sonst teilt man nacher durch 0 wenns dunkel ist!
    
          if(OdoData[1]/old1 > 2 || OdoData[1]/old1 < 0.5)
          {
             n1++;
          }
    
          old1=OdoData[1];
       }
    
       /* Drehzahlen ins Verhältnis setzen und dann Geschw. ev. Erhöhen */
    
       comp=n0/n1;
    
       if(comp > 1)
       {
          if(spd0<255)
          {
             spd0++;
          }
          else
          {
             spd1--;
          }
       }
       else if(comp < 1)
       {
          if(spd1<255)
          {
             spd1++;
          }
          else
          {
             spd0--;
          }
       }
    }
    Ich hoffe ist nicht zuuu laufzeitlastig Ist mein erstes Programm!

    Vielen Dank im Vorraus[/code]

  2. #2
    Benutzer Stammmitglied
    Registriert seit
    12.09.2007
    Alter
    30
    Beiträge
    98
    willkommen im forum

    als ich sehe das problem darin, das bei jedem aufruf der funktionen alle variablen auf die anfangswerte gesetzt werden.

    mfg liggi
    Lieber am Asuro rumschrauben als alles andere.
    Meine Homepage

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    23.12.2007
    Ort
    AC
    Beiträge
    23
    So, habe jetzt mal eingebaut dass er mir anzeigt ob er auch tatsächlich was macht oder nicht. Dies ist der Fall
    Doch nach Testläufen fährt er exakt so wie ohne Odometrie Programm. Ich gucke mir jetzt mal deinen Vorschlag an, danke schonmal!

    // Edit
    Hmm irgendwie muss ich doch aber die Variablen initialisieren. Wie mach ich das denn ohne dass die jedes mal zurückgesetzt werden? Das scheint auch das Problem zu sein.

  4. #4
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo teHIngo,

    du solltest mal dein gesamtes Programm posten, dann könnte man dir vielleicht zeigen, wo man wie welche Variablen initialisieren könnte..

    Ein Problem scheint mir schon beim Setzen der Motorpower zu bestehen: Du hast nur ein MotorSpeed(spd0,spd1); direkt nach der Initialisierung der Variablen (da haben spd0/1 den Wert 175). Nach der Auswertung der ODO-Sensoren und nach der anschliesenden Änderung von spd0/1 wird die Funktion verlassen und alles ist vergessen.

    Noch ein paar Anmerkungen (vielleicht etwas schludrig wegen Spongebob):

    - In deiner Schleife, die wegen <=50, genau 51 mal ausgeführt wird, werden mit OdometrieData() keine neuen Daten für OdoData eingelesen.

    - Die Werte der Odometriesensoren sind in der Praxis nie 0

    - Die Befehle comp=n0/n1; if(comp > 1) bzw. if(comp < 1) könnte man auch durch if (n0 > n1) bzw. if (n0 < n1) ersetzen. Das für einen AVR ungünstge float comp; könnte dann entfallen.

    Zu "if(OdoData[0]/old0 > 2 || OdoData[0]/old0 < 0.5)"

    Der Übergang zwischen den Hell-/Dunkelfeldern ergibt keine Wertesprünge, der Verlauf ist annähernd sinusförmig.

    Mehr gibt's erst nach Shrek..

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    23.12.2007
    Ort
    AC
    Beiträge
    23
    Hey Danke! Ich hab jetzt noch nichts korrigiert, werde mich aber gleich mal dran setzen. Erstmal hier alles festlich herrichten, ist ja auch Weihnachten ...

    Trotzdem hier schonmal das gesamte Programm!

    Code:
    #include "asuro.h"		// Konfigurationsdateien laden	
    #include <string.h>
    #define ENDLOS while(1)
    
    /* Funktionen definieren */
    
    void schlafen(unsigned int t)
    {
       unsigned int i;
       for(i=0; i<t; i++)
          {
             Sleep(72);
          }
    }
    
    /* Geradeausfahren */
    
    void GeradeAus()
    {
       unsigned int i=0;
       unsigned int OdoDataInit[2];
       unsigned int OdoData[2];
       unsigned int n0=0;
       unsigned int n1=0;
       OdometrieData(OdoDataInit);
       float comp;
       unsigned int old0=OdoDataInit[0];
       unsigned int old1=OdoDataInit[1];
       unsigned int spd0=190;
       unsigned int spd1=190;
    
       
    
       OdometrieData(OdoData);
    
       MotorDir(FWD,FWD);
       MotorSpeed(spd0,spd1);
    
       for(i=0; i<=100; i++)  // 50 mal Messen für exakteren Wert
       {
          /* Berechnung der Drehzahl des 0. Odosensors */
    
          if(old0==0){old0=1;} // sonst teilt man nacher durch 0 wenns dunkel ist!
    
          if(OdoData[0]/old0 > 1.4 || OdoData[0]/old0 < 0.6) // Wenn Übergang n erhöht
          {
             n0++;
             StatusLED(YELLOW);
          }
    
          old0=OdoData[0];
    
          /* Berechnung der Drehzahl des 1. Odosensors */
    
          if(old1==0){old1=1;} // sonst teilt man nacher durch 0 wenns dunkel ist!
    
          if(OdoData[1]/old1 > 1.4 || OdoData[1]/old1 < 0.6)
          {
             n1++;
             StatusLED(RED);
          }
    
          old1=OdoData[1];
       }
       StatusLED(GREEN);
    
       /* Drehzahlen ins Verhältnis setzen und dann Geschw. ev. Erhöhen */
    
       comp=n0/n1;
    
       if(comp > 1)
       {
          if(spd0<255)
          {
             spd0++;
             BackLED(ON,OFF);
          }
          else
          {
             spd1--;
          }
       }
       else if(comp < 1)
       {
          if(spd1<255)
          {
             spd1++;
             BackLED(OFF,ON);
          }
          else
          {
             spd0--;
          }
       }
    }
    
    
    /* Beginn des Hauptprogramms */
    
    int main (void){
    Init();				//Prozessor initialisieren
    
    ENDLOS				// Endlosschleife
    {
    
      GeradeAus();
    
    }
    
    /* Schluss ! */
    
    return 0;
    }
    Heute Nachmittag werde ich vielleicht mal ein Programm schreiben dass mir die Odometerdaten zusendet, aber mit sowas hatte ich bisher immer Probleme weil nur kryptische Daten ankamen, mal schauen!

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    22.12.2007
    Beiträge
    9
    Wenn du die Variablen nur beim Ersten Aufruf der Funktion initialisieren willst schreib einfach ein static davor. Also zb. static unsigned int spd0=190;

    HTH
    Reini

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    30.10.2007
    Ort
    Meensen
    Alter
    35
    Beiträge
    77
    kann man nicht die variablen global deklarieren wie z.B. in Java?
    dann würden nach #define ENDLOS while(1) alle variablen kommen anstatt in den Funktionen zu stehen.

    Ich Vermute das aber nur!

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    23.12.2007
    Ort
    AC
    Beiträge
    23
    Sehr interessant! Ich habe mir eure Anregungen zu Herzen genommen und umgesetzt.
    Code:
    #include "asuro.h"		// Konfigurationsdateien laden	
    #include <string.h>
    #define ENDLOS while(1)
    
    /* Funktionen definieren */
    
    void schlafen(unsigned int t)
    {
       unsigned int i;
       for(i=0; i<t; i++)
          {
             Sleep(72);
          }
    }
    
    /* Geradeausfahren */
    
    void GeradeAus()
    {
       static unsigned int i=0;
       unsigned int OdoDataInit[2];
       unsigned int OdoData[2];
       static unsigned int n0=0;
       static unsigned int n1=0;
       OdometrieData(OdoDataInit);
       unsigned int old0;
       unsigned int old1;
       static unsigned int spd0=190;
       static unsigned int spd1=190;
       MotorDir(FWD,FWD);
       MotorSpeed(spd0,spd1);
    
       for(i=0; i<50; i++)  // 50 mal Messen für exakteren Wert
       {
          OdometrieData(OdoData);
          /* Berechnung der Drehzahl des 0. Odosensors */
    
          if(old0==0){old0=1;} // sonst teilt man nacher durch 0 wenns dunkel ist!
    
          if(OdoData[0]/old0 > 1.4 || OdoData[0]/old0 < 0.6) // Wenn Übergang n erhöht
          {
             n0++;
          }
    
          old0=OdoData[0];
    
          /* Berechnung der Drehzahl des 1. Odosensors */
    
          if(old1==0){old1=1;} // sonst teilt man nacher durch 0 wenns dunkel ist!
    
          if(OdoData[1]/old1 > 1.4 || OdoData[1]/old1 < 0.6)
          {
             n1++;
          }
    
          old1=OdoData[1];
       }
       StatusLED(GREEN);
    
       /* Drehzahlen ins Verhältnis setzen und dann Geschw. ev. Erhöhen */
    
       if(n0<n1)
       {
          if(spd0<255)
          {
             spd0++;
    	 StatusLED(GREEN);
          }
          else
          {
             spd1--;
    	 StatusLED(RED);
          }
       }
       else if(n0>n1)
       {
          if(spd1<255)
          {
             spd1++;
    	 StatusLED(GREEN);
          }
          else
          {
             spd0--;
    	 StatusLED(RED);
          }
       }
    }
    
    
    /* Beginn des Hauptprogramms */
    
    int main (void){
    Init();				//Prozessor initialisieren
    
    ENDLOS				// Endlosschleife
    {
    
      GeradeAus();
    
    }
    
    /* Schluss ! */
    
    return 0;
    }
    Jetzt macht Asuro aber vollends abgefahrene Sachen!
    Er gibt zunächst auf beiden Rädern gas und verringert dann beim rechten Rad abnehmend bis auf 0 die Geschwindigkeit, das linke Rad läuft mit konstanter Geschwindigkeit. Nach einiger Zeit (und ein Paar Runden auf der Stelle...) fängt das gleiche dann wieder von vorne an. Sehr seltsam!

    Interessant ist auch, dass sehr schnell die StatusLED auf RED umschaltet. spd0 / spd1 müssen also sehr schnell 255 erreichen weshalb dann die Geschwindigkeit gedrosselt wird (? oder ).

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    30.10.2007
    Ort
    Meensen
    Alter
    35
    Beiträge
    77
    wenn die Geschwindigkeiten langsamer erhöht werde sollen kannst du ja nen Timer einbauen.

    was gibt denn die Odometrie für werte? Nicht das einer kaputt ist, hat mich einige Zeit gekostet herauszufinden das der rechte odo bei meinem nicht geht.

  10. #10
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo teHIngo

    Du hast schon fast alles geändert was ich so auf Anhieb "bemängelt" habe ("bis auf die Werte werden nie 0"), dafür gibt's natürlich erstmal ein großes Lob von mir. Aber trotzdem finde ich in deinem aktuellen Programm nur ein MotorSpeed():
    Code:
       static unsigned int spd0=190;
       static unsigned int spd1=190;
       MotorDir(FWD,FWD);
       MotorSpeed(spd0,spd1);
    Hab' ich da was überlesen oder ändert dein Programm die Motorpower wirklich nicht mehr nach der Berechnung der Drehzahldifferenzen? Ich hab's aber nur überflogen, weil's schon recht spät ist und ich noch im Weihnachtsrummel stecke...

    Das ENDLOS würde ich wieder rausschmeissen, denn while(1) liest sich besser. Ich mag nicht erst in den #defines nachschauen, was damit gemeint ist... Mit C kann man zwar viel machen , man muss es aber nicht.

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

Seite 1 von 4 123 ... LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Labornetzteil AliExpress