- 12V Akku mit 280 Ah bauen         
Seite 5 von 7 ErsteErste ... 34567 LetzteLetzte
Ergebnis 41 bis 50 von 67

Thema: Regelung fürs Geradeausfahren

  1. #41
    Neuer Benutzer Öfters hier
    Registriert seit
    30.12.2006
    Ort
    Wien
    Beiträge
    20

    Taktzahl zwischen Flanken regeln

    Anzeige

    Powerstation Test
    Auch wir haben schon einige Versuche mit dem Geradeausfahren gemacht. Zuerst haben wir auch einfach die Flanken (S/W-Übergänge mit Hysterese) gezählt und die Leistungszufuhr zu den Motoren so geregelt, dass die Flankenanzahl links und rechts gleich ist.

    Das Problem dabei war, dass im Falle, dass beide Räder sich wunderbar gleichschnell drehen, trotzdem z.B. links die Flanke früher vorbeikommt als rechts (wäre ja ein Zufall, dass immer beide Flanken genau im selben Takt vorbeikommen). So glaubt der Regler, dass das linke Rad sich schneller dreht und dass er links weniger Leistung zuführen muss (obwohl eh beide sich gleich schnell drehen und es sich nur um eine Phasenverschiebung handelt). Asuro macht also eine Kurve nach links. Gleich danach kommt rechts auch die Flanke, somit ist die linke und die rechte Flankenzahl wieder gleich und der Regler inkrementiert wieder die Leistungszufuhr am Linken Rad und Asuro fährt wieder geradeaus.
    Das wiederholt sich bei jeder Flanke - in Summe entsteht so ein Links-Drift.

    Mein Sohn Jakob (er ist 14) hat die Idee gehabt, nicht die Flankenzahl zu zählen, sondern die Anzahl der Takte zwischen zwei Flanken (ein Maß für den Kehrwert der Geschwindigkeit). So spielt die Phasenverschiebung keine Rolle. Funktioniert bei uns sehr gut

    Programm berücksichtigt (noch) nicht unterschiedliche Lichtverhältnisse; gibt am Schluss den Offset aus - den sollte man als Startwert für das nächste Mal eingeben, damit Asuro gleich von beginn an geradeaus fährt.
    Damit der inkrementelle I-Regler nicht überschwingt, wird der I-Anteil durch 16 dividiert (also um 4 Bit nach rechts verschoben).

    Wir haben damit auf 3m Fahrt 5-10cm seitliche Ablenkung und 0-3mm Längenfehler.

    Bitte wundert Euch nicht über die Veriablennamen - ist kindergerecht.



    Code:
    #include "asuro.h"
    #define MAXI 3825 //(durch 15= 255)
    #define StartwertUmSoVielBrauchtLinksMehrAlsRechts 0 // wird durch 16 dividiert
    #define SchwellwertLinksSchwarz 675	  //Schwellwert über dem das linke Zahnrad als Schwarz gilt
    #define SchwellwertLinksWeiss 625	  //Schwellwert unter dem das linke Zahnrad als Weiß gilt
    #define SchwellwertRechtsSchwarz 675  //Schwellwert über dem das rechte Zahnrad als Schwarz gilt
    #define SchwellwertRechtsWeiss 625	  //Schwellwert unter dem das rechte Zahnrad als Weiß gilt
    #define AnfangskoordinateX 0		  //Anfangskoordinate in x-Richtung in mm, Ziel ist 0
    #define AnfangskoordinateY -5000	  //Anfangskoordinate in y-Richtung in mm, Ziel ist 0
    
    
    int KoordinateX=AnfangskoordinateX;
    int KoordinateY=AnfangskoordinateY;
    int MerkerLinksWarSchonWeiss;
    int MerkerRechtsWarSchonWeiss;	
    int MerkerLinksWarSchonSchwarz;
    int MerkerRechtsWarSchonSchwarz;
    //int StartdurchgangLinks;
    //int StartdurchgangRechts;
    int MerkerLinksWarSchonEineGanzePeriode;
    int MerkerRechtsWarSchonEineGanzePeriode;
    int TakteZaehlerSchwarzLinks; // Zaehlt wie viele Takte zwischen zwei W/S-Übergängen liegen
    int TakteZaehlerWeissLinks;
    int TakteZaehlerSchwarzRechts;
    int TakteZaehlerWeissRechts;
    int TaktzahlLinks; // Ergebnis wie viele Takte zwischen zwei W/S-Übergängen Links liegen
    int TaktzahlRechts;
    int GeschwindigkeitsKorrekturLinks; //Zahl zwischen theoretisch -255 und + 255, die zur Sollgeschwindigkeit dazuaddiert wird, um die unterschiedlichen Motoren auszugleichen
    unsigned int UebergangszaehlerLinks; //max. 65535; zaehlt wie viel S/W und W/S-Übergaenge seit dem letzten Rücksetzen links passiert sind
    unsigned int UebergangszaehlerRechts; //max. 65535; zaehlt wie viel S/W und W/S-Übergaenge seit dem letzten Rücksetzen rechts passiert sind
    
    int ReglerZurueckSetzen(void)
    {
    MerkerLinksWarSchonWeiss=FALSE;
    MerkerRechtsWarSchonWeiss=FALSE;
    MerkerLinksWarSchonSchwarz=FALSE;
    MerkerRechtsWarSchonSchwarz=FALSE;
    MerkerLinksWarSchonEineGanzePeriode=FALSE;
    MerkerRechtsWarSchonEineGanzePeriode=FALSE;
    //StartdurchgangLinks=TRUE;
    //StartdurchgangLinks=TRUE;
    TakteZaehlerSchwarzLinks=0; 
    TakteZaehlerWeissLinks=0;
    TakteZaehlerSchwarzRechts=0;
    TakteZaehlerWeissRechts=0;
    TaktzahlLinks=0; 
    TaktzahlRechts=0;
    
    GeschwindigkeitsKorrekturLinks=StartwertUmSoVielBrauchtLinksMehrAlsRechts;
    UebergangszaehlerLinks=0;
    UebergangszaehlerRechts=0;
    
    return 0;
    }
    
    int fahr(int SollGeschwindigkeit, int SollKurve) 		//SollGeschwindigkeit = Zahl zwischen 0 (stop) und 255 (vorwaerts)
    {														//SollKurve = .....muss noch definiert werden.......Derzeit: 0
    
    unsigned int Zahnraddunkelheit[2];		// Zahnraddunkelheit[0]: Odometriedaten links, Zahnraddunkelheit[1]: rechts	
    int ZahnradstatusLinks=99;	//weiß=0, undefiniert=1, schwarz=2, nicht zugewiesen=99
    int ZahnradstatusRechts=99;	//weiß=0, undefiniert=1, schwarz=2, nicht zugewiesen=99
    
    
    OdometrieData(Zahnraddunkelheit);
    TakteZaehlerSchwarzLinks++; 
    TakteZaehlerWeissLinks++;
    TakteZaehlerSchwarzRechts++;
    TakteZaehlerWeissRechts++;
    
    //Abfrage nach Zahnradstatus Links:
    if (Zahnraddunkelheit[0] > SchwellwertLinksSchwarz) 
    	ZahnradstatusLinks=2;					//links ist schwarz
    else if (Zahnraddunkelheit[0] < SchwellwertLinksWeiss)
    	ZahnradstatusLinks=0;					//links ist weiß
    else 
    	ZahnradstatusLinks=1;					//links ist undefiniert
    
    //Abfrage nach Zahnradstatus Rechts:
    if (Zahnraddunkelheit[1] > SchwellwertRechtsSchwarz) 
    	ZahnradstatusRechts=2;					//rechts ist schwarz
    else if (Zahnraddunkelheit[1] < SchwellwertRechtsWeiss)
    	ZahnradstatusRechts=0;					//rechts ist weiß
    else 
    	ZahnradstatusRechts=1;					//rechts ist undefiniert
    
    if (ZahnradstatusLinks==0) MerkerLinksWarSchonWeiss=TRUE; //auf wahr setzen
    if (ZahnradstatusRechts==0) MerkerRechtsWarSchonWeiss=TRUE; //auf wahr setzen
    if (ZahnradstatusLinks==2) MerkerLinksWarSchonSchwarz=TRUE; //auf wahr setzen
    if (ZahnradstatusRechts==2) MerkerRechtsWarSchonSchwarz=TRUE; //auf wahr setzen
    
    //Feststellen ob S/W oder W/S-Übergang links oder rechts:
    if ((ZahnradstatusLinks==2)&&(MerkerLinksWarSchonWeiss==TRUE)) 
    	{TaktzahlLinks=TakteZaehlerSchwarzLinks; TakteZaehlerSchwarzLinks=0;
    	MerkerLinksWarSchonWeiss=FALSE;
    	UebergangszaehlerLinks++;
    	if (MerkerLinksWarSchonEineGanzePeriode<3) MerkerLinksWarSchonEineGanzePeriode++;
    	}
    	//Linkes Zahnrad hat neu Schwarz erreicht (W/S-Übergang) => Zaehler++
    else if ((ZahnradstatusLinks==0)&&(MerkerLinksWarSchonSchwarz==TRUE)) 
    	{TaktzahlLinks=TakteZaehlerWeissLinks; TakteZaehlerWeissLinks=0; 
    	MerkerLinksWarSchonSchwarz=FALSE;
    	UebergangszaehlerLinks++;}
    	//Linkes Zahnrad hat neu Weiß erreicht (S/W-Übergang) => Zaehler++
    else; //weder S/W noch W/S-Übergang
    
    if ((ZahnradstatusRechts==2)&&(MerkerRechtsWarSchonWeiss==TRUE)) 
    	{TaktzahlRechts=TakteZaehlerSchwarzRechts; TakteZaehlerSchwarzRechts=0; 
    	MerkerRechtsWarSchonWeiss=FALSE;
    	if (MerkerRechtsWarSchonEineGanzePeriode<3) MerkerRechtsWarSchonEineGanzePeriode++;
    	UebergangszaehlerRechts++;}
    	//Rechtes Zahnrad hat neu Schwarz erreicht (W/S-Übergang) => Zaehler--
    else if ((ZahnradstatusRechts==0)&&(MerkerRechtsWarSchonSchwarz==TRUE)) 
    	{TaktzahlRechts=TakteZaehlerWeissRechts; TakteZaehlerWeissRechts=0; 
    	MerkerRechtsWarSchonSchwarz=FALSE;
    	UebergangszaehlerRechts++;}
    	//Rechtes Zahnrad hat neu Weiß erreicht (S/W-Übergang) => Zaehler--
    else; //weder S/W noch W/S-Übergang
    
    //Geradeausregler (inkrementeller I-Regler):
    if ((MerkerLinksWarSchonEineGanzePeriode > 2)&&(MerkerRechtsWarSchonEineGanzePeriode > 2))
    {
    if ((TaktzahlLinks < TaktzahlRechts)&&(SollGeschwindigkeit+GeschwindigkeitsKorrekturLinks > 0)) 
    	{GeschwindigkeitsKorrekturLinks--;StatusLED(GREEN);}
    	//wenn das linke Rad zu schnell dreht, dann soll es langsamer werden => Korrektur --
    else if ((TaktzahlLinks > TaktzahlRechts)&&(SollGeschwindigkeit+GeschwindigkeitsKorrekturLinks < MAXI)) 
    	{GeschwindigkeitsKorrekturLinks++;StatusLED(RED);}
    	//wenn das link Rad sich zu langsam dreht und es nicht eh schon Vollgas gibt, dann soll es schneller werden => Korrektur ++
    else;
    };
    
    MotorSpeed(SollGeschwindigkeit + (GeschwindigkeitsKorrekturLinks>>4) , SollGeschwindigkeit);		//korrigiertes Motorkommando, auf vorgegebene Kurvenkrümmung geregelt
    return SollGeschwindigkeit+GeschwindigkeitsKorrekturLinks;
    }
    
    int main(void)
    {
    //	int p,i=0; //Zaehler initialisieren
    	int s=0;					
    //	unsigned int j,k;
    	char string[]="        test         \n\r";	// Ausgabestring initialisieren
    //	unsigned int odoleft[MAXI], odoright[MAXI];
    	
    	Init();
    	ReglerZurueckSetzen();
    	MotorDir(FWD,FWD);
    //	SerWrite(string,20);	
    	
    	StatusLED(GREEN);			//
    while(UebergangszaehlerRechts<1000)
    {
    	s=fahr(140,0);				// Aufruf der Funktion fahre mit 130 Geradeaus (geregelt)
    }
    MotorDir(BREAK,BREAK);
    sprintf(string, "Korr.= %4d\n\r",GeschwindigkeitsKorrekturLinks);
    SerWrite(string,13);
    sprintf(string, "ZahlL= %4d\n\r",UebergangszaehlerLinks);
    SerWrite(string,13);
    sprintf(string, "ZahlR= %4d\n\r",UebergangszaehlerRechts);
    SerWrite(string,13);
    
    while(1);
    return 0;
    }

  2. #42
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    12.06.2005
    Ort
    Südwestdeutschland
    Beiträge
    1.147
    Blog-Einträge
    3
    Hallo Dorothea,

    mich würde interssieren, wie Deine Regelung gegenüber der Go-Funktion aus der ASURO-Lib 2.7 https://www.roboternetz.de/phpBB2/vi...=26594&start=0 abschneidet. Wenn Ihr gerade so schön am experimentieren seid, könntet Ihr die vielleicht auch noch ausprobieren.

    Gruss,
    stochri

    Nachtrag:
    Uihh, eure Variablennamen sind tatsächlich ganz schön lang

  3. #43
    Moderator Robotik Einstein Avatar von damaltor
    Registriert seit
    28.09.2006
    Ort
    Milda
    Alter
    38
    Beiträge
    4.068
    Zitat Zitat von austin2power
    Wieso hat eigentlich noch keiner 'ne Fast-Fourier-Transformation für die Frequenzerfassung der Odometriedaten benutzt?

    Sollte doch das zuverlässigste und flexibelste sein, da es ermöglicht, den Offset herauszufiltern, und als Endergebnis die Grundfrequenz ausspuckt, demnach wären Umgebungslichtwechsel und Radstillstand kein Problem mehr - theoretisch die sauberste Lösung.

    Viele Grüße
    Henning
    Nicht fragen, machen! Viel Spaß, zeig uns dann mal deine Ergebnisse...
    Read... or die.
    ff.mud.de:7600
    Bild hier  

  4. #44
    Neuer Benutzer Öfters hier
    Registriert seit
    17.10.2006
    Beiträge
    6
    Zitat Zitat von damaltor
    Nicht fragen, machen! Viel Spaß, zeig uns dann mal deine Ergebnisse...
    Bin schon dabei

    Falls Interesse besteht, darauf kann man aufbauen: Auszug aus "Numerical Recipes in C"

    reinhaun
    Henning

  5. #45
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    Hallo dorothea,
    die Idee mit dem Kehrwert der Geschwindigkeit finde ich sehr gut. Dickes Lob an deinen 14-er.

    Zu der Abweichung von 5-10 cm auf 300 cm mal eine kleine Rechnung:
    Folgendes:
    Unter der Annahme, dass sich die Räder bei einer perfekter Reglung gleich schnell drehen aber trotzdem einen Differenz zur geraden Linie vorliegt, muss der Asuro somit im Bogen fahren.
    Wenn der Asuro also auf einem Kreis fährt, fährt er bei deiner Angabe 300 cm auf dem Umfang und bekommt einen Abstand von 10 cm zur Tangente.
    Wenn ich mal wieder Excel bemühe, bekomme ich einen Radius für diesen Kreis von 4505 cm raus.
    Somit hätten wir, bei einem Radstand am Asuro mit 10,4 cm einen inneren Radius von 4499,8 cm und einen Außenradius von 4510,2 cm.
    Das ist ein Verhältnis von ca. 1,0023
    Dieses Verhältnis müssen dann aber auch die Asuro-Räder untereinander haben.
    Hat das eine Rad so ca. einen Durchmesser von 3,8 cm, hätte das andere dann etwa 3,8087 cm. Das liegt bestimmt bestens in der Fertigungstoleranz

    Ich bin mir ziemlich sicher, dass unser Asuro niemals eine perfekte Linie abfahren wird. (Was habe ich hier falsch bedacht?)

    Trotzdem muss man natürlich alles ausschöpfen um immer besser zu werden. Also weiter mit Kehrwerten und frischen Ideen.

    @austin2power
    Wenn ich deinen Link anklicke bekommen ich nur folgende Meldung:
    'Das für diesen Befehl erforderliche Sicherheitsusatzmodul ist nicht verfügbar'
    Ich nutze den Mozilla Firefox in Version 2.0.0.1. Weißt du hier weiter?
    P.S.: Ich wäre auch an einer FFT interessiert, die in den Asuro passt. Hier würde ich sogar sehr gerne bei dir abschreiben, da ich mal versucht hatte Barcodes zu lesen die seitlich an einer vom Asuro zu verfolgenden Linie angebracht sind. Bitte um Code \/
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken abweichung.jpg  
    Lieber Asuro programieren als arbeiten gehen.

  6. #46
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    62
    Beiträge
    5.799
    Blog-Einträge
    8
    Na, so neu ist die Idee auch nicht, gleiche Probleme ergeben gleiche Lösungen. Als "Zeitbasis" verwende ich da die Anzahl der Schleifendurchgänge zwischen den Bitwechseln.
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  7. #47
    Neuer Benutzer Öfters hier
    Registriert seit
    17.10.2006
    Beiträge
    6
    Zitat Zitat von Sternthaler
    Wenn ich deinen Link anklicke bekommen ich nur folgende Meldung:
    'Das für diesen Befehl erforderliche Sicherheitsusatzmodul ist nicht verfügbar'
    Ich nutze den Mozilla Firefox in Version 2.0.0.1. Weißt du hier weiter?
    Hi Sternthaler, Windows-Nutzer brauchen 'n Plugin, hier zu beziehen: http://www.nrbook.com/a/bookcpdf.php

  8. #48
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    @austin2power
    Danke, hat nach einer Firewall-Anpassung für den Acrobat-Reader funktioniert. (Einmaliges Zulassen reichte)
    Lieber Asuro programieren als arbeiten gehen.

  9. #49
    Neuer Benutzer Öfters hier
    Registriert seit
    01.10.2006
    Beiträge
    19
    Hi Leute,


    beschäftige micht jetzt auch mit dem geradeausfahren meines Asuro.

    Hab eure ganzen Beiträge gelesen und mir sind ein paar Fragen entstanden:

    1. Hysterese? Was ist das?
    2. Was meint ihr mit Flanken.

    Hab dann auch mal versucht die Werte die mir die Odometrie liefert zu loggen aber mir ist nicht ganz klar wie ich die Werte interpretieren soll.

    Könnt ihr mir helfen?

    Hänge das Programm mit dem ich die Werte erfasst habe und die Excel-Tabelle für 500 Werte der Linkensensoren an.

    Viele Grüße

    Tom
    Angehängte Dateien Angehängte Dateien

  10. #50
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    62
    Beiträge
    5.799
    Blog-Einträge
    8
    SerWrite(messl[i],1);
    Das funktioniert nicht. messl[] ist vom Type integer, SerWrite() möchte aber Strings. In der aktuellen asuro.c gibt es für diesen Fall die Funktion PrintInt() die Integerwerte sendet.

    Ansonsten sieht das Progi richtig aus. Lediglich die grüne StatusLED zu Beginn ist sinnfrei, da sie bei Init() eh auf grün gesetzt wird.

    Hysterese nennt man z.B. den Unterschied zwischen Ein- und Ausschaltpunkt. Flanke ist der Anstieg bzw. der Abfall des Wertes.

    Mein (einfacher) Odo-Ansatz geht so:
    Ich teile den Wertebereich in drei Teile, unteres Drittel ist low, oberes Drittel high, dazwischen ist nichts.
    Bit wird high wenn aktuell low und Wert im oberen Drittel
    Bit wird low wenn aktuell high und Wert im unteren Drittel

    Das nichts-Drittel dient zur sauberen Trennung verhindert z.B. dass der Odozähler im Stillstand zählt, weil der Wert auf einer Flanke steht.

    Das funktioniert übrigens bei Mikrokontrollern ähnlich, unter ca. 1V ist low, über ca. 3,5V ist high, dazwischen passiert nichts.

    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 5 von 7 ErsteErste ... 34567 LetzteLetzte

Berechtigungen

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

LiFePO4 Speicher Test