- fchao-Sinus-Wechselrichter AliExpress         
Seite 2 von 2 ErsteErste 12
Ergebnis 11 bis 13 von 13

Thema: Roomba gezielt saugen lassen

  1. #11
    Benutzer Stammmitglied
    Registriert seit
    19.06.2004
    Alter
    51
    Beiträge
    66
    Anzeige

    E-Bike
    So, nach einigen Tagen und vielen Rückschlägen meine bisherigen Ergebnisse:

    AtMega 8 Modul (Link: http://www.chip45.com/index.pl?page=Crumb8-USB&lang=de) endlich da und kann nun in AvrStudio entwickeln.

    Das AtMega8 Modul kommuniziert inzwischen selbstständig mit dem Roomba und akkumuliert wichtige Daten:

    - aktuelle X/Y Position (+/- 32767mm) in der Wohnung
    diese Daten kommen von den Odometrie-Sensoren die im Roomba enthalten sind.
    - aktuelle Ausrichtung (statt 0..359° hier 0..811)

    Er ist inzwischen in der Lage gezielt selbständig Punkte in der Wohnung anzufahren.
    Da die MAP im AtMega 8 noch nicht enthalten sendet derzeit noch der PC die Kommandos "Fahre nach X/Y". Ziel wird es sein dass der PC später nicht mehr benötigt wird.

    Der Roomba dreht sich in die korrekte Richtung und fährt dann los. Anschließend wird, falls die Abweichung zu groß ist, die Fahrt nochmals korrigiert.

    Eine Hindernisserkennung ist zwar enthalten, bin aber noch nicht dazu gekommen dem Robi den Code zum "Ausweichen" zu implementieren.

    Der Speicher des AtMega8 ist inzwischen zu 50% voll (Flash-RAM). Es wird inzwischen sehr eng im Flash, der Code der MAP wird ca. 2000 Worte benötigen. Dann ist der Speicher voll.

    Die Odometriedaten des Roombas sind derzeit ausreichend. Ich muss dazu sagen dass er derzeit noch am Kabel hängt und sich bisher nur auf einer Fläche von 1qm bewegen kann (wg dem Kabel).

    Ich musste einen Software-UART implementieren. Als Vorlage habe ich dies (Link: https://www.roboternetz.de/wissen/in...RT_mit_avr-gcc) verwendet und feststellen müssen dass ich zu viele Übertragungsfehler hatte. Musste den Code geringfügig ändern damit ich tatsächlich 100% fehlerfreie Kommunikation hatte.

    Ebenfalls Probleme machen noch die Signale "Motor hängt". Gerade beim Anfahren signalisiert der Roomba eine Überlastung der Motoren. Hiermit beschäftige ich mich später.

    Der AtMega 8 aktualisiert seine Daten mit dem Roomba inzwischen knapp 60mal pro Sekunde, gerade noch ausreichend um bei einer Kollision mit einem Stuhlbein den Robi zum stehen zu bringen.

    Als nächstes folgt die MAP und die eigentliche Intelligenz des AtMega 8.

  2. #12
    Benutzer Stammmitglied
    Registriert seit
    19.06.2004
    Alter
    51
    Beiträge
    66
    Die Logic und die MAP ist inzwischen implementiert. Das Programm wurde mittlerweile zu groß.
    Es passt nur noch in den Roomba wenn ich das Programm von AVR Studio optimieren lasse (Code-Größe verkleinern).
    Ich bin leider noch nicht dazu gekommen das Programm zu testen. Ich musste den Speicherplatz (RAM) für die MAP etwas verkleinern da es auch hier eng wurde.
    Mittlerweile passen "nur" noch etwa 80qm in die MAP.
    Konnte den AtMega 8 schon diverse Routen in der MAP suchen lassen (wo wurde noch nicht gereinigt, wie komme ich dort hin?) und musste feststellen dass er diese Aufgaben sehr viel schneller berechnet als in der Simulation von AVR Studio.
    Mag mit daran liegen dass der "echte" ATMega 8 mit 14Mhz getaktet ist und nicht zu letzt die Code-Optimierung von AVR Studio.

  3. #13
    Benutzer Stammmitglied
    Registriert seit
    19.06.2004
    Alter
    51
    Beiträge
    66
    Hatte gehofft heute dazu zu kommen den Roomba mal tatsächlich laufen zu lassen - mit seiner internen Intelligenz.

    Leider zeigte sich dass der Compiler, dank der Code-Optimierung zur Speicherplatz Reduzierung, mist gebaut hat. Die gestrigen Routen waren falsch, das habe ich inzwischen heraus gefunden.

    Man möge es nicht glauben oder ich habe heute Tomaten auf den Augen.

    Kann mir jemand erklären was der Unterschied zwischen diesen zwei Varianten ist?

    Variant 1 (funktioniert):

    Code:
    unsigned char PATH_CheckField (unsigned char x, unsigned char y, unsigned char Type) // Prüfen ob das Feld X/Y näher am aktuellen Standort des Robis liegt
    // Prüft ob das angegebene Feld ein Hinderniss enthält
    // und falls nicht ob der Aufwand dort hin zu gelangen
    // kleiner ist als bisher bekannt. 
    {
      if ((x>=PATH_SizeX)||
          (y>=PATH_SizeY)) return 0;
      if (!Type)
      { // Nach Hindernissen suchen:
        if (PATH_Field[x][y].bWall==0)                       // Es darf kein Hinderniss sein
    	{
          if (PATH_NewDistance>PATH_Field[x][y].b6Distance)  // Ist es näher?
    	  {
            PATH_Field[x][y].b6Distance = PATH_NewDistance;
          }
        }
    	return 0;
      }
      else
      { // Nach ungereinigten (noch unbefahrene Stelle) suchen
        if (PATH_Field[x][y].bClean==0)                       // noch ungereinigt?
    	{
          if (PATH_NewDistance>PATH_Field[x][y].b6Distance)   // Ist es näher?
    	  {
            PATH_Field[x][y].b6Distance = PATH_NewDistance;
    	    PATH_DestinationX = x;
    		PATH_DestinationY = y;
    		return 1;                                         // ungereinigte Stelle gefunden
          }
        }
    	else
    	{  // Es ist schon gereinigt, wenn kein Hinderniss dann ggf. neue
    	   // Entfernung speichern
           if (PATH_Field[x][y].bWall==0)                       // Es darf kein Hinderniss sein
    	   {
             if (PATH_NewDistance>PATH_Field[x][y].b6Distance)  // Ist es näher?
    		 {
               PATH_Field[x][y].b6Distance = PATH_NewDistance;	  
             }
           }
    	}
      }
      return 0;
    }
    Variante 2 (funktioniert nicht):

    Code:
    unsigned char PATH_CheckField (unsigned char x, unsigned char y, unsigned char Type) // Prüfen ob das Feld X/Y näher am aktuellen Standort des Robis liegt
    // Prüft ob das angegebene Feld ein Hinderniss enthält
    // und falls nicht ob der Aufwand dort hin zu gelangen
    // kleiner ist als bisher bekannt. 
    {
      if ((x>=PATH_SizeX)||
          (y>=PATH_SizeY)) return 0;
      if (!Type)
      { // Nach Hindernissen suchen:
        if (PATH_Field[x][y].bWall==0)                       // Es darf kein Hinderniss sein
          if (PATH_NewDistance>PATH_Field[x][y].b6Distance)  // Ist es näher?
            PATH_Field[x][y].b6Distance = PATH_NewDistance;
      }
      else
      { // Nach ungereinigten (noch unbefahrene Stelle) suchen
        if (PATH_Field[x][y].bClean==0)                       // noch ungereinigt?
    	{
          if (PATH_NewDistance>PATH_Field[x][y].b6Distance)   // Ist es näher?
    	  {
            PATH_Field[x][y].b6Distance = PATH_NewDistance;
    	    PATH_DestinationX = x;
    		PATH_DestinationY = y;
    		return 1;                                         // ungereinigte Stelle gefunden
          }
        }
    	else
    	{  // Es ist schon gereinigt, wenn kein Hinderniss dann ggf. neue
    	   // Entfernung speichern
           if (PATH_Field[x][y].bWall==0)                       // Es darf kein Hinderniss sein
             if (PATH_NewDistance>PATH_Field[x][y].b6Distance)  // Ist es näher?
               PATH_Field[x][y].b6Distance = PATH_NewDistance;	  
    	}
      }
      return 0;
    }
    Inhaltlich sollten beide das selbe durchführen.

    Egal, hat lange gedauert das heraus zu finden.

    Er findet jetzt übrigens den Weg in maximal 60ms, hatte nochmals Simulationen laufen lassen (in AVR Studio).

Seite 2 von 2 ErsteErste 12

Berechtigungen

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

12V Akku bauen