- Labornetzteil AliExpress         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 14

Thema: Stopp am Abgrund

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    01.10.2006
    Beiträge
    23

    Stopp am Abgrund

    Anzeige

    Praxistest und DIY Projekte
    Hi

    Nachdem ich das Programm "Stop am Abgrund" vom Asuro Buch begriffen hatte, versuchte ich ein eigenes Programm zu schreiben.
    Zuerst; das Programm vom Buch funktionierte einwandfrei.
    Nachdem ich mein Programm geladen hatte kroch asuro nur anstelle einer Geschwindigkeit von 200 und reagierte auch nicht auf die Ergebnisse.
    Sieht jemand den Fehler?
    Angehängte Dateien Angehängte Dateien

  2. #2
    Moderator Robotik Einstein Avatar von damaltor
    Registriert seit
    28.09.2006
    Ort
    Milda
    Alter
    37
    Beiträge
    4.063
    ich verstehe dein programm nicht so wirklich. könntest du es etwas kommentieren? einfacher wäre es auch, wenn du mit dem [code]button postest.
    Read... or die.
    ff.mud.de:7600
    Bild hier  

  3. #3
    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

    ich habe das Buch nicht und kenne deshalb auch das Programm nicht, dass zur Vorlage diente.

    So auf den ersten Blick würde ich mal hier den Wert vergrössern:

    if(diff>5)

    Das ist der Schwellwert der zwischen Anhalten oder Weiterfahren entscheidet. Wenn dieser Wert zu klein ist (weil die eingelesenen Werte schwanken) wird laufend schnell zwischen Fahren und Stoppen umgeschaltet und das Ergebnisse dürfte ein dahinschleichen sein.

    Aber Achtung! Bei zu großem Wert werden kleine echte Änderungen "ausgefiltert" und nicht als Abgrund erkannt!

    Das "Spielfeld" sollte bei dieser einfachen Funktion möglichst gleichmässig ausgeleuchtet sein, dann ist der Wertesprung am Abgrund besser zu erkennen. Übrigens kann man auch einen ebenen Hell/Dunkel-Übergang zum Testen verwenden, z.b. verschiedenfarbiges Papier/Karton.

    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!

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    01.10.2006
    Beiträge
    23
    Hier nochmal mein Code

    Mein Programm sollte als erstes die Werte der Fotodioden einlesen, diese Werte speichern und später in der while Schleife wieder Einlesen. Somit bekommt man zwei Werte. Diese Werte sollen verglichen werden und der kleinere Wert vom grösseren Abziehen.
    Ist die Differenz grösser als der Eingestellte Wert, soll er stehen bleiben. Was bedeuten würde, dass sich der Untergrund geändert hat.
    Am Schluss wird der erste Eingelesene Wert aktualisiert.

    Den Einstellwert habe ich nochmals angepasst. Nun fährt er jedoch, reagiert aber nicht mehr auf die Ergebnisse.

    Code:
    #include "asuro.h" 
    
    
    int main (void)
    {
      unsigned int lineData[2];
      unsigned int erg,erg2;
      unsigned char diff;
      
        Init();
    	LineData(lineData);
    	erg=lineData[0]+lineData[1];
    	FrontLED(ON);
    	while (1)
    	{
    	    
    	  LineData(lineData);
    	  erg2=lineData[0]+lineData[1];
    	  if (erg>erg2)
    	  {
    	  diff=erg-erg2;
    	  }
              else
              {
              diff=erg2-erg;
              }
              if(diff>10)
              {
              MotorDir(BREAK,BREAK);
    	  MotorSpeed(0,0);
    	  StatusLED(RED);
    	  }
    	  else 
    	  {
    	  MotorDir(FWD,FWD);
    	  MotorSpeed(200,200);
    	  StatusLED(YELLOW);
    	  }
              erg=erg2;
    	}
    }

  5. #5
    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

    Ist doch schon mal prima wenn er jetzt fährt. Nun hast du folgendes Problem:

    Nach diesem Befehl

    erg=erg2;

    ganz am Ende der Schleife "vergisst" der asuro den Abgrund der sich vor im auftut. Er startet denn nächsten Schleifendurchlauf mit dem soeben eingelesenen und abgespeicherten Helligkeitswert des Abgrunds und vergleicht diesen mit dem nächsten Wert bis er unten aufschlägt.

    Eine Lösung wäre eine Endlosschleife im Stopp-Teil der Abfrage (oder eine Variable die das Ereigniss speichert oder eine Flucht...):

    ...
    {
    MotorDir(BREAK,BREAK);
    MotorSpeed(0,0);
    StatusLED(RED);
    while(1); // stehenbleiben und auf Hilfe warten
    }
    ...

    Wenn du das jetzt änderst wird er vermutlich überhaupt nicht mehr losfahren wegen:

    Init();
    LineData(lineData);
    erg=lineData[0]+lineData[1];
    FrontLED(ON);

    Der allererste Wert wird mit ausgeschalteter FrontLED eingelesen. Der nächste Wert, der dann in der Schleife mit eingeschalteter FrontLED eingelesen wird, könnte als Abgrund interpretiert werden. Genau weis ich es nicht, bin zu faul zum Testen. *gg*

    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!

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    01.10.2006
    Beiträge
    23
    Danke für deine Hilfe
    funktioniert jetzt einwandfrei und zuverlässig

  7. #7
    Benutzer Stammmitglied Avatar von Herbert A.
    Registriert seit
    24.02.2010
    Alter
    27
    Beiträge
    46
    vielleicht auch mit diesem Programm:
    PHP-Code:
    #include "asuro.h"

    #define STOP 1

    int main(void)

    {

    unsigned int lineData[2];

    unsigned int erst[2];

    int x;

    int i;

    Init();

    LineData(erst);

    for(
    0x<  100000000i++){

    for(
    0i<  3i++){


    FrontLED(ON);

    MotorDir (FWD,FWD);

    MotorSpeed(120,120);

        
    LineData(lineData);
        
        if ((
    lineData[0]- erst[0] < STOP ) && (lineData[1] - erst[1] <  STOP))  {
        
        
    MotorSpeed(120,120);
        
        
    MotorDir(RWD,RWD);
        
            for(
    0i<  200i++){
        
        
    Sleep(255);
        
        }
        
        
    MotorSpeed(140,0);
        
        
    MotorDir(RWD,BREAK);
            
        
    BackLED(ON,ON);
        
        for(
    0i<  400i++){
        
        
    Sleep(255);
        
        }
        
        
    BackLED(OFF,OFF);
        
        }
        
        else;
        
        {
        
        
    MotorSpeed(100,100);
        
        
    MotorDir(FWD,FWD);
        
        }
        
        }
        
        }
        
    while (
    1);

    return (
    0);


    mfG

    [Edit von radbruch]
    Hast du das Programm selbst mal ausprobiert? Mir ist nicht ganz klar wie das funktioniert:

    if ((lineData[0]- erst[0] < STOP )...

    Wenn ( der immer wieder mit Beleuchtung neu eingelesene Linienwert links) minus ( der beim Start ohne Beleuchtung eingelesene Linienwert links) insgesamt kleiner als STOP ist...

    Wäre nicht ein || sinnvoller als das && ? Wenn der Abgrund von einem Liniensensor erkannt wird würde dann gestoppt.

    Der else-Zwieg endet direkt nach dem ; hinter else, alles was danach kommt wird unabhängig von der if-Bedingung ausgeführt.

    Verschachtelte For-Schleifen dürfen nicht dieselbe Variable verwenden, i wird nie größer als 401. Maxwert einer Integervariable ist 32.767, 100000000 wird deshalb sowieso nie erreicht:

    for(i = 0; x< 100000000; i++){
    for(i = 0; i< 3; i++){
    ...
    for(i = 0; i< 200; i++)
    ...
    for(i = 0; i< 400; i++)

    Etwas umformatiert und mit allen Änderung sieht dein Programm dann so aus:
    PHP-Code:
    #include "asuro.h"

    #define STOP 1

    int main(void)
    {
        
    unsigned int ilineData[2], erst[2];

        
    Init();
        
    LineData(erst);   // die erste Lesung ist immer Schrott!
        
    LineData(erst);
        
    FrontLED(ON);
        
    Sleep(10);
        
    MotorDir (FWD,FWD); // vorwärts fahren
        
    MotorSpeed(120,120);

         while(
    1)
        {
            
    LineData(lineData);
            if ((
    lineData[0]- erst[0] < STOP ) && (lineData[1] - erst[1] <  STOP))
            {
                
    MotorSpeed(120,120); // zurückstoßen
                
    MotorDir(RWD,RWD);
                for(
    0i<  200i++)
                    
    Sleep(255);

                
    MotorSpeed(140,0); // drehen
                
    MotorDir(RWD,BREAK);
                
    BackLED(ON,ON);
                for(
    0i<  400i++)
                    
    Sleep(255);
                
    BackLED(OFF,OFF);
            }
            else
            {
                
    MotorDir (FWD,FWD); // vorwärts fahren
                
    MotorSpeed(120,120);
            }
        }
        return (
    0);

    (ungetestet)

    Ich hoffe, ich habe nichts übersehen.
    Geändert von radbruch (09.03.2011 um 21:43 Uhr)
    while (!asleep()) sheep++;

  8. #8
    Benutzer Stammmitglied Avatar von Herbert A.
    Registriert seit
    24.02.2010
    Alter
    27
    Beiträge
    46
    danke für die Korrektur.
    hat irgendjemand eine Idee, wie man den Wert der Liniensensoren einlesen und den
    dann 5(z.B.) mal hintereinander mit dem aktuellen Wert vergleichen kann?
    mfG
    while (!asleep()) sheep++;

  9. #9
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    03.07.2007
    Beiträge
    349
    @Herbert: Mach ein Array, also int links[5] und int rechts[5].
    Dann schiebst du die Werte jeweils eins nach hinten, bevor du ganz vorne den aktuellsten Wert reintust.
    Du hast dann eine schöne Zeitreihe in den Arrays, wobei [0] das aktuellste, und [4] der älteste Wert ist. Das Rauschen der Sensoren lässt sich hiermit ganz gut eliminieren, wenn du z.B. die ersten beiden Werte addierst sowie die letzten beide Werte addierst, und dann schaust, wie die Differenz der beiden ist (ist eine Minimalversion eines Tiefpasses!).


    Hab vor Jahren mal ein Programm für die Kantenerkennung geschrieben, wobei die erste Funktion zum initialisieren aufgerufen wird, und die zweite um zu erkennen ob man über eine Kante gefahren ist(1==>Kante, 0==>keine Kante).
    Ich mach es allerdings auf die einfache Art und Weise, also aktuellsten mit dem vorherigen Wert vergleichen.
    Eleganter wäre es, eine längere Zeitspanne zu verwenden um das Rauschen auszugleichen(Tiefpass)==>siehe oben!

    hs_abgrund.h
    PHP-Code:
    #ifndef HSASURO
    #define HSASURO
    /*Helligkeitsunterschied bei dem eine Kante erkannt wird*/
    #define ABGRUND_DIFF 20


    /*Variablen für Abgrunderkennung*/
    int abgrund_ldata_ref[2];




    /*Muss aufgerufen werden,
    bevor die Funktion fkt_abgrund_erkennung verwendet wird.*/
    void fkt_init_abgrund_erkennung(void);

    /*Erkennt Kanten(z.B. beim Tisch). Am besten funktioniert die Erkennung
    mit einer Vorwärtsgeschwindigkeit von 100.*/
    unsigned char fkt_abgrund_erkennung(void);




    unsigned char fkt_abgrund_erkennung(void)
    {
        
    int ldata[2],diff_l=0,diff_r=0,schnitt_l=0,schnitt_r=0;
        
    unsigned char c=0;

        for(
    c=0;c<10;c++)
        {
            
    LineData(ldata);
            
    schnitt_l=schnitt_l+ldata[0];
            
    schnitt_r=schnitt_r+ldata[1];
        }
        
    schnitt_l=schnitt_l/10;
        
    schnitt_r=schnitt_r/10;

        
    diff_l=abs(schnitt_l-abgrund_ldata_ref[0]);
        
    diff_r=abs(schnitt_r-abgrund_ldata_ref[1]);

        if(
    diff_l>ABGRUND_DIFF || diff_r>ABGRUND_DIFF)
        {
            
    FrontLED(OFF);
            return 
    1;
        }

        return 
    0;

    }


    void fkt_init_abgrund_erkennung(void)
    {
        
    unsigned char c=0;
        
    int schnitt_l=0,schnitt_r=0;

        
    FrontLED(ON);
        for(
    c=0;c<10;c++)
        {
            
    LineData(abgrund_ldata_ref);
            
    schnitt_l=schnitt_l+abgrund_ldata_ref[0];
            
    schnitt_r=schnitt_r+abgrund_ldata_ref[1];
        }
        
    abgrund_ldata_ref[0]=schnitt_l/10;
        
    abgrund_ldata_ref[1]=schnitt_r/10;
    }


    #endif 
    Grüße,
    Harri

  10. #10
    Benutzer Stammmitglied Avatar von Herbert A.
    Registriert seit
    24.02.2010
    Alter
    27
    Beiträge
    46
    könntest du das vielleicht auch für mich einmal im ganzen Programm posten?
    danke
    mfG
    while (!asleep()) sheep++;

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

Labornetzteil AliExpress