- Labornetzteil AliExpress         
Seite 2 von 7 ErsteErste 1234 ... LetzteLetzte
Ergebnis 11 bis 20 von 67

Thema: Regelung fürs Geradeausfahren

  1. #11
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    18.05.2006
    Alter
    36
    Beiträge
    150

    Waste - Alle Achtung

    Anzeige

    Powerstation Test
    Hallo!

    An Waste:
    Hab dein Programm ausprobiert und hab erstmal gestaunt. So toll gerade wie er gefahren ist, ist er bei mir noch nie. Aber ich war auch mal da wo dein Programm steht. Es hat bei Dunkel - bis Halbdunkel sehr gut, ja sogar phänomenal funtkioniert. Dann ist er in eine von Sonne beleuchtete Gegend gekommen und er machte nur noch Müll. Aber in Dunkln - extrem gut.

    Ich werd jetzt dein Programm genauer studieren. Henk hat recht, wenn er sagt, dass die Vergeleichstwerte flexibel sein müssen. Sonst hat mal halt auf einmal Probleme. So wie ich bei Sonneneinstrahlung.

    theodrin

  2. #12
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    29.04.2005
    Ort
    Weilburg
    Beiträge
    676
    Arexx-Henk,
    ich habe mit deinem Programm meinen ASURO getunt.
    Code:
                                  Left min/max, right min/max values
    1. +00066 +00202  +00138 +00212 // Test dunkel
    2. +00061 +00199  +00135 +00209 // Test mit Licht  
    3. +00007 +00140  +00007 +00134 // Test 2 cm unter meiner Schreibtischlampel 
    4. +00009 +00199  +00011 +00195 // Test " " + Haube auf Lichtschranke
    5. +00056 +00201  +00105 +00205 // Test " "  + Haube + schwarzen  Filzstift auf der Encoderscheibe.
    Angehängte Dateien Angehängte Dateien
    Prostetnic Vogon Jeltz

    2B | ~2B, That is the Question?
    The Answer is FF!

  3. #13
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    08.08.2004
    Ort
    Zwolle
    Alter
    67
    Beiträge
    531
    Hallo vogon,

    danke fur die datalogs, die Daten wird ich benutzen bei meinem Programme.

    Die erste zwei datalogs haben irgendwo ein fehler, vermutlich ein Datenempfang Storung. Die Werte hab ich dann handmassig geandert.

    Wass ist mit 11L?

    Ich wollte die Daten wie Grafiken zufugen, aber die Datei
    ist scheinbar zu gross (400KB).

    Du kannst ihn hier downloaden:

    http://home.planet.nl/~winko001/vogo...g_graphics.zip

    Gruss

    Henk

  4. #14
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    08.08.2004
    Ort
    Zwolle
    Alter
    67
    Beiträge
    531
    Hallo waste,

    Ich mochte mich gerne etwas mehr vertiefen in die Asuro Fahrtkontrolle.
    Dazu habe ich dein Program nochmal angeguckt um aus zu finden warum es sich hier handelt. Ich mochte es hier mal posten denn vielleicht hilft es jemanden.

    Einige Bemerkungen:

    - so ein schwarzes oder weisses flach am odo Rad nenne ich mal 'Odoflach'

    - da wird immmer uber 'speed' gesprochen aber in wirklichkeit ist es eher
    ein Mass fur die zugefuhrte Leistung. (Power)


    Dein Program:

    - zahlt den anzahl an vorbeigehende Odoflache

    - zahlt links und rechts unabhangig von einander

    - messt einmal pro 240us beide odometers

    - fahrt ein rad schneller als die ander wird vom schnelleren rad die
    motor Leistung mit 1 verringert

    - fahren beide rader gleich schnell, wird die standard
    Leistung an beide motoren zugefuhrt


    Zusammengefasst:

    - ein schnelleres Rad passt sich seine geswindigkeit an an dass
    langsameres Rad

    - jeden 240us wird die leistung vom eine oder beide
    motoren korrigiert

    - es regelt sich die gleichumdrehung von beide Rader

    - es wird eine feste Leistung zugefuhrt

    - die Asuro geschwindigkeit hangt ab vom reibung



    Mit dem Oszi gemessen in Freilauf: 14,3ms zwischen zwei
    gleichfarbigen odoflache.
    Da es 5 gleichfarbigen odoflache fur jedes 1 centimeter
    Radversetzung braucht ist die Zeit fur 1cm Radversetzung
    gleich wie 5 * 14,3ms = 71,5ms/centimeter = 14cm pro Sekunde

    Da flashst mir ein Idee fur den Augen, vielleicht ist so ein
    Wie-Gross-Ist-Meine-Asuro-Mechanische-Reibung test zu machen...
    (inklusief Batteriespannung Messung)


    Gruss

    Henk

  5. #15
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.05.2005
    Beiträge
    734
    Hallo Henk,

    deine Analyse von meinem Programm ist richtig. Ich habe auch noch eine Variante des Programms, da wird die Variable speed anstatt um eins zu erniedrigen gleich auf 0 gesetzt. Man braucht dann nicht mehr den Grenzwert von 0 zu überprüfen und das Programm ist dadurch kürzer.

    Ich habe in meinem Archiv auch noch ein Programm mit Geschwindigkeitsregelung gefunden. Das Programm habe ich mal ins Codefenster kopiert, ohne es nochmal zu prüfen. Es sollte eigentlich funktionieren. Leider hat es wenig Kommentare, aber dafür ist der Lerneffekt beim Analysieren größer.

    Gruß Waste

    Code:
    /*******************************************************************************
    *
    * Description: Geschwindigkeitsregelung
    *
    *****************************************************************************/
    #include "asuro.h"
    #include <stdlib.h>
    volatile unsigned char count36kHz;
    volatile unsigned long timebase;
    unsigned int takte;
    int w, x, e, y, kp, ki, esum[2];
    unsigned char speedLeft,speedRight;
    unsigned long zeit[2];
    
    void ReglerL (void)
    {
    	takte = (timebase*256)+count36kHz - zeit[0];
    	zeit[0]=(timebase*256)+count36kHz;
    	x = 27000/takte;
    	e = w - x;
    	esum[0] = esum[0] + e;
    	if (esum[0] < -130) {esum[0] = -130;}
    	if (esum[0] > 130) {esum[0] = 130;}
    	y = kp*e + ki*esum[0];
    	if (y < 0) {y = 0;}
    	if (y > 255) {y = 255;}
    	speedLeft = y;
    	MotorSpeed(speedLeft,speedRight);
    }
    
    void ReglerR (void)
    {
    	takte = (timebase*256)+count36kHz - zeit[1];
    	zeit[1]=(timebase*256)+count36kHz;
    	x = 27000/takte;
    	e = w - x;
    	esum[1] = esum[1] + e;
    	if (esum[1] < -130) {esum[1] = -130;}
    	if (esum[1] > 130) {esum[1] = 130;}
    	y = kp*e + ki*esum[1];
    	if (y < 0) {y = 0;}
    	if (y > 255) {y = 255;}
    	speedRight = y;
    	MotorSpeed(speedLeft,speedRight);
    }
    
    int main(void)
    {
    	unsigned char flagl, flagr, sw;
    	unsigned int data[2];
       
    	Init();
    	MotorDir(FWD,FWD);
    	MotorSpeed(150,150);
    	kp = 18; ki = 2;		//ki enthält bereits Multiplikation mal dt=0.01
    	w = 75;
    	sw = PollSwitch();
    	if (sw & 0x01)
    		{w=5;}
    	if (sw & 0x02)
    		{w = 10;}
    	if (sw & 0x04)
    		w = 20;
    	if (sw & 0x08)
    		w = 40;
    	if (sw & 0x10)
    		w = 75;
    	if (sw & 0x20)
    		w = 150;
    	OdometrieData(data);
    	OdometrieData(data);
    	if (data[0] > 600) flagl = TRUE;		// Flag setzen
    	else flagl = FALSE;
    	if (data[1] > 600) flagr = TRUE;		// Flag setzen
    	else flagr = FALSE;
    	zeit[0]=(timebase*256)+count36kHz;
    	zeit[1]=(timebase*256)+count36kHz;
    	while(1){
    		OdometrieData(data);			// messe Odometrie
    		if ((data[0] < 550) && (flagl == TRUE)) {flagl = FALSE; ReglerL();}
    		if ((data[0] > 650) && (flagl == FALSE)) {flagl = TRUE; ReglerL();}
    		if ((data[1] < 550) && (flagr == TRUE)) {flagr = FALSE; ReglerR();}
    		if ((data[1] > 650) && (flagr == FALSE)) {flagr = TRUE; ReglerR();}
    	}
    	return 0;
    }

  6. #16
    Neuer Benutzer Öfters hier
    Registriert seit
    30.03.2006
    Alter
    36
    Beiträge
    15
    vllt. kann mir da jemand helfen : also...
    ich hab mal ne frage zu deinem code waste !

    wozu hast du die flags benötigt ??? für mich ist das noch ein rätsel, ansonst versteh ich grob wie das programm funktioniert

    Code:
          OdometrieData(data);
          if ((data[0] < 550) && (flagl == TRUE)) {flagl = FALSE; wegl++;}
          if ((data[0] > 650) && (flagl == FALSE)) {flagl = TRUE; wegl++;}
          if ((data[1] < 550) && (flagr == TRUE)) {flagr = FALSE; wegr++;}
          if ((data[1] > 650) && (flagr == FALSE)) {flagr = TRUE; wegr++;}
    wäre echt nett wenn mir jemand erklären könnte wozu die dienen...also man braucht sie glaube ich irgendwie bei der bestimmung von den rädern welches schneller ist oder ???? das ist nur geraten...also bitte kan mir es jemand erklären, wäre echt nett von euch

    MfG kungfuman

  7. #17
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    Hallo kungfuman,
    nee, nee, die Flags haben nichts mit dem Geradeausfahren zu tun.
    Die werden benötigt, damit die Zähler wegl bzw. wegr NUR dann mit dem ++ hintendran hochgezählt werden, wenn ein Wechsel von Schwarz auf Weiss bzw. von Weiss auf Schwarz erkannt wird.
    Wenn also einmal der Wert in data[0] > 650 wurde, und das flagl halt noch false ist, nur dann wird EINMAL wegl hochgezählt. Es wird dann aber eben auch das flagl auf true gesetzt. Nun kann die Schleife so oft sie will die Odometriedaten lesen, der Wert in data[0] ist dann bis zum nächsten Helligkeitswechsel immer noch > 650, aber ein weiteres zählen erfolgt eben erst dann, wenn der Wert wieder unter 550 gesunken ist und das Flag dann umgeschaltet wird.
    Somit wird erreicht, dass ein HelligkeitsWECHSEL nur einmal den Zähler erhöht.

    Hoffe, das war verständlich.

    EDIT: 22.06.06 Oh man oh man, was waren da Rechtschreibfehler drin.
    Lieber Asuro programieren als arbeiten gehen.

  8. #18
    Neuer Benutzer Öfters hier
    Registriert seit
    30.03.2006
    Alter
    36
    Beiträge
    15
    hey ! dankeschön Sternthaler !
    echt nett von dir mir das zu erklären !
    Ich habs gerafft
    ich freu mich , danke nochmal

    MfG kungfuman

  9. #19
    Neuer Benutzer
    Registriert seit
    03.09.2006
    Alter
    42
    Beiträge
    3

    Guten Tag,

    Das ist mein erster Eintrag in diesem Forum. Ich habe von euren Darstellungen gelernt, vielen Dank! Nun möchte ich auch einen programmvorschlag beisteuern: Es benutzt im Gegensatz zu dem Programm von waste variable Entscheidungswerte für die Zählung der OdoFeld-Wechsel.
    Code:
    #include "asuro.h"
    #include "stdlib.h"
    
    	
    int countChanges(int *d);
    int findMd(int *d);
    
    int popSize=500;			//Anzahl der Messwerte, die zur Regelung gesammelt werden
    
    
    
    int main (void){
      
      int speedL = 200;
      int speedR = 200;  
      
      int odoIn[2];							//zum Einlesen der Odometriedaten
      int dL[popSize], dR[popSize];			//speichern Odometriedaten
      int changesDiff=0;						//Differenz der OdoFeldWechsel zw. l. & r. Rad
      
      Init();
      StatusLED(GREEN);
      MotorDir(FWD, FWD);
      MotorSpeed(speedL, speedR);
      
     
      while(1){
        int i;
    
        for (i=0; i<popSize; i++){
    	  OdometrieData(odoIn);
    	  dL[i] = odoIn[0];
    	  dR[i] = odoIn[1];}
    	  
    	changesDiff=countChanges(dL)-countChanges(dR);  
    
    
       if (changesDiff>0){
         if (speedR<255&&speedL>0){
    	    speedL--;
    		speedR++;}}
    	  
        else if (changesDiff<0){
    	  if (speedL<255&&speedR>0){
    	    speedL++;
    		speedR--;}}
    
        MotorSpeed(speedL, speedR);}
    
      return 0;}
    	  
    	  
    
    
    
    int countChanges(int* d){
      int i;
      int color;			    //0=black, 1=white
      int changes=0;			//Anzahl der OdoFeldWechsel
      int md=findMd(d);		//Helligkeits-Median
      
      if (d[0]<md) color=0;	//erster Messwert war schwarzes Feld
      else color=1;			//bzw weisses Feld
      
      for(i=0; i<popSize; i++){
        if (d[i]<md && color==1){			//Wechsel von weiss nach schwarz
    	  color=0;						
          changes++;}
    	  
    	else if(d[i]>md && color==0){		//... von s nach w
          color=1;
    	  changes++;}}
      
      return changes;}
    
    
    
    
    
    int findMd(int* d){
      int i, j;
      int md=0;							//Median			
      int c;							//zählt den Rang des Wertes
        
      for (i=0; i<popSize; i++){
        c=0;
    	
    	for(j=0; j<popSize; j++){  
          if (i!=j && d[i]>d[j]) c++;}		    //Bestimmung der Helligkeits-Rangordnung
    	  
    	if (c>=popSize/2){ 						//wenn mind.s die Hälfte aller Werte kleiner sind
          if (md==0) md=d[i];						//...dann übernehme den Wert als Median
    	  else md=(d[i]<md)?d[i]:md;}} 	    	//...finde den kleinsten Wert der oberen Hälfte
    	
      return md;}
    Es speichert 500 Odo-Werte und ermittelt den Median, also den Wert, unter dem min. 50% der Werte liegen. Damit fährt er meistens relativ gerade. Ich habe es für speed 90 - 200 getestet. probiert es mal aus und sagt mir was ihr davon haltet,

    beste grüsse

    florian


    PS.: kann mir jemand von euch sagen, in welchem Takt die Odometriedaten eingelesen werden?


    edit: hups, hatte RWD statt FWD bei MotorDir.

  10. #20
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    Hallo flobot,
    erst einmal herzlich willkommen hier im Forum.

    Dein Ansatz zur Geradeausfahrt finde ich nicht schlecht. Leider ist nicht immer alles so einfach wie es scheint.
    Ich habe mal ein paar Fotos (Film ist zu viel Datenzeugs) angehängt um dir mal das Problem mit meinem Asuro zu zeigen.
    Bei mir ist der rechte Motor miserabel (Tschuldigung, einige von euch wissen das schon.), so dass mein Asuro immer mit einer Rechtskurve startet wenn man nichts dagen tut.
    Trotzdem ist dein Ansatz auch bei meinem Asuro ungefähr nach 3 Metern funktionsfähig und der Asuro fährt recht ordentlich geradeaus. Klasse Arbeit!

    Was ich an deiner Lösung besonders toll finde, ist dass die Reglung ja einen interessanten Ansatz zum lösen des Umgebungslichtproblems hat.
    Hierzu ist meines Wissens nach noch kein 'herzhafter' Versuch im Forum aufgetaucht. Ich habe auch gleich eine dicke Taschenlampe zum ärgern vom Asuro rausgekramt und bin echt begeistert wie klein die Abweichungen vom rechten Weg dann sind. Licht aus machen und freudig den geraden Weg sehen war auch nicht schlecht.
    Natürlich kommt jetzt nach dem Lob auch gleich das große Fragezeichen in Form von 2 Anmerkungen.
    Wenn du auch den Asuro benutzt, hast du als CPU den ATmega8 eingebaut. Das Ding hat gerade mal 1K-Byte RAM.
    Du hast in deinem Program aber schon 2 int-Variablen (a 2 Byte) als Array mit jeweils 500 Elementen angelegt. Somit benötigst du eigendlich 2 * 500 * 2 Byte. Ist ein bisschen zu viel. Ich habe bei mir im Programm das ganze über popSize=220 auf 'nur' 880 Byte reduziert. Dann bleibt noch ein Rest für die anderen Variablen und hoffentlich genug für den Stack übrig.
    Als 2-tes finde ich deine geschachtelte Schleife in der Funktion findMd sehr 'brutal'. Du loopst mit deinen 500 aus popSize immerhin 250.000 mal da drin rum. Ist es wirklich sinnvoll den Median zu berechnen? Wäre hier ein Mittelwert nicht genauso gut?


    Nun noch eine kleine Überschlagsrechnung zu deiner Frage zum Takt der Odometriedaten.
    Überschlagen deshalb, da ich nicht zu jedem Maschinenbefehl nachgesehen habe, ob da 1 oder 2 oder auch mal 3 Takte verballert werden.
    Ich habe im compilierten Output einfach mal nur die Assemblerbefehle gezählt. Das sind die Angaben mit dem T dahinter.

    Deine Loop über OdometrieData
    popSize * (29T + 1 * OdometrieData)

    Funktion OdometrieData
    31T + 2 * ADC

    ADC-Wandlung (Hier ist die Zeitangabe recht genau. Maximal plus einen Quarz-Takt)
    Quarztakt (1/8Mhz) * 64 (ADC-Vorteiler-In-Init) * 13
    (Die 13 gilt ab der 2.ten Wandlung nachdem ADEN eingeschaltet wurde. Für die erste Wandlung muss da ne 25 hin. Vergessen wir das mal ganz schnell wieder, ist ja Haarspalterei)


    Ergibt ca.:
    ADC-Wandlung = (1 / 8000000) * 64 * 13 = 0,000104 Sekunden
    Funktion OdometrieData = 31T + 2 * 0,000104 = 0,000211875 Sekunden
    Deine Loop = 500 * (29T + 1 * 0,000211875) = 0,10775 Sekunden

    Die Loop in findMd müsste ca. folgende Zeiten haben:
    500 * (10 + 2 + 500 * (6 + 17) + 33) = 5772500 Takte = 0,7215625 Sekunden

    In Summe verbrennt dein Programm also ca.
    2 * findMD + 1 * Loop-Odometrie = 1,55 Sekunden für eine Schleife im Main

    Wenn ich für popSize 220 einsetzet, komme ich auf ungefähr 0,68 Sekunden.

    Wenn ich die Zeit mal nehme und ein bisschen weiterrechne kommt da folgendes raus:
    Ich weiss von meinem Asuro, dass ich ungefähr eine Differenz von 50 in MotorSpeed brauche um halbwegs gerade zu fahren.
    Somit brauche ich also ca. 25 mal die Main-Loop. Das sind dann ca. 17 Sekunden.
    Da ich die Startgeschwindigkeit mit 150 angegeben habe sollten danach ungefähr die Werte für links und rechts von 125 und 175 rauskommen.
    Wenn ich nun schätze, dass ich bei diesen Werten ca. 20 cm pro Sekunde zurücklege und dann knapp 17 Sekunden brauche, müsste mein Asuro nach ca. 340 cm geradeaus fahren.
    Scheint also mit meinen oben geschätzten 3 Metern ganz gut im Rennen zu liegen.

    So, ich hoffe hier niemanden allzu stark gelangweilt zu haben.

    @flobot: Mach weiter so mit guten Ideen.
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken img_8791-8798.jpg  
    Lieber Asuro programieren als arbeiten gehen.

Seite 2 von 7 ErsteErste 1234 ... LetzteLetzte

Berechtigungen

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

12V Akku bauen