- 3D-Druck Einstieg und Tipps         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 23

Thema: zufallszahlen "auf" asuro erzeugen

  1. #11
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    15.08.2004
    Ort
    Graz
    Beiträge
    342
    Anzeige

    E-Bike
    wenn man nur das niederwerigste bit vom ADC-Sampling hernimmt, hat man "echte" zufallszahlen, egal ob mit 50/100Hz Rauschen oder nicht. das ergibt ziemlich genau ein weisses rauschen.
    Allerdings ist die datenrate nicht besonders hoch (eben 1Bit/Sample), eignet sich also nicht wirklich zur direkten zufallszahlenerzeugung, wohl aber als Seed für einen Pseudogenerator.
    für einen 8-Bit generator also einfach 8xADC-Sample einlesen, jeweils das niederwertigste bit nehmen, dann jeweils auf die richtige Position shiften und addieren. heraus kommt eine wunderschöne, 8-Bit Zufallszahl.

    Pseudocode:
    Code:
    RandomNr = 0
    FOR SampleNr = 0 TO 7
        ADC_Val = GetSample()
        ADC_Val = ADC_Val And &B00000001
        ShiftLeft ADC_Val, SampleNr
        RandomNr = RandomNr + ADC_Val
    NEXT

  2. #12
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    27.12.2008
    Ort
    Dresden
    Alter
    38
    Beiträge
    100
    super.

    das klingt wunderbar und dein programm ist auch logisch und einfach zu verstehen. allerdigns weiß ich nicht, wie ich das a) in c umsetzt und b) den wert des ADC vom asuro bekomme...

    Code:
    /*Funktion, die eine Zufallszahl zwischen min und max liefert*/
    int zufall(int min, int max)
    {
    	static uint8_t RandomNr=0;
    	uint8_t ADC_Val;
    	int n;
    	
    	for(n=0;n<8;n++)
    	{
    		/*hier müsste jetzt der Wert aus dem ADC geholt werden, aber wie?!*/
    		ADC_Val=GetWert();
    
    		ADC_Val&=0x01;
    		ADC_Val=ADC_Val<<n;
    
    		RandomNr=RandomNr+ADC_Val;
    	}
    	
    	return min+(RandomNr%(max-min+1));
    }
    kann man das so machen?! und wenn ja, mit welcher funktion oder wie auch immer, kann ich an den wert aus dem ADC rankommen?!

    und dann gleich noch ne frage: geht das auch mit 16bit?! müsste doch ansich, oder?

    z.b. so:

    Code:
    /*Funktion, die eine Zufallszahl zwischen min und max liefert*/
    int zufall(int min, int max)
    {
    	static uint16_t RandomNr=0;
    	uint8_t ADC_Val;
    	int n;
    	
    	for(n=0;n<16;n++)
    	{
    		/*hier müsste jetzt der Wert aus dem ADC geholt werden, aber wie?!*/
    		ADC_Val=GetWert();
    
    		ADC_Val&=0x01;
    		ADC_Val=ADC_Val<<n;
    
    		RandomNr=RandomNr+ADC_Val;
    	}
    	
    	return min+(RandomNr%(max-min+1));
    }
    ?!

    (edit: ich hab natürlich in meinem eifer das eigentliche erzeugen der zufallszahl vergessen. soll heißen: das prgramm liefert uns jetzt den seed, mit dem wir dann die rand() initialisieren müssen... nicht wundern! )
    Der Optimist: \"Das Glas ist halb voll.\"
    Der Pessimist: \"Das Glas ist halb leer.\"
    Der Ingenieur: \"Das Glas ist doppelt so groß wie es sein müßte.\"

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

    Die sechs ADCs des asuros kann man mit seiner Library bequem einlesen:

    ADC0/1: OdometrieData()
    ADC2/3: LineData()
    ADC4: PollSwitch()
    ADC5: Batterie()

    Das sind zwar keine freien ADC-Eingänge, aber besser als 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!

  4. #14
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    27.12.2008
    Ort
    Dresden
    Alter
    38
    Beiträge
    100
    ach mehr isses nicht?! ich dachte wunder, was ich da jetzt machen muss

    ok... also sollte es so gehen: (oder?!)


    Code:
    /*Funktion, die eine Zufallszahl zwischen min und max liefert*/
    int zufall(int min, int max)
    {
       static uint16_t RandomNr=0;
       uint8_t ADC_Val;
       int n;
       
       for(n=0;n<16;n++)
       {
          /*hier müsste jetzt der Wert aus dem ADC geholt werden, aber wie?!*/
          ADC_Val=(ReadADC(WHEEL_LEFT,0)+ReadADC(WHEEL_RIGHT,0)+ReadADC(IR_LEFT,0)+ReadADC(IR_RIGHT,0)+ReadADC(BATTERIE,0))/5;
    
          ADC_Val&=0x01;
          ADC_Val=ADC_Val<<n;
    
          RandomNr=RandomNr+ADC_Val;
       }
    
       srand(RandomNr);
       return min+(rand()%(max-min+1));
    }
    ich hab jetzt hier die funktion ReadADC() benutzt, da diese in der aktuellen lib schon so existiert. somit kann man direkt darauf zugreifen.

    ist die maskierung ADC_Val&=0x01; so richtig?

    wenn ja, sollte ja alles klappen...
    Der Optimist: \"Das Glas ist halb voll.\"
    Der Pessimist: \"Das Glas ist halb leer.\"
    Der Ingenieur: \"Das Glas ist doppelt so groß wie es sein müßte.\"

  5. #15
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    27.12.2008
    Ort
    Dresden
    Alter
    38
    Beiträge
    100
    zusammenfassend lässt sich sagen:

    Code:
    /*Funktion, die eine Zufallszahl zwischen min und max liefert*/
    int Zufall(int min, int max)
    {
    	static uint16_t zahl=0;
    	uint8_t adc;
    	int n;
       
    	for(n=0;n<16;n++)
    	{
    		adc=(ReadADC(WHEEL_LEFT,0)+ReadADC(WHEEL_RIGHT,0)+ReadADC(IR_LEFT,0)+ReadADC(IR_RIGHT,0)+ReadADC(BATTERIE,0))/5;
    
    		adc&=0x01;
    		adc=adc<<n;
    
    		zahl=zahl+adc;
    	}
    
    	srand(zahl);
    	return min+(rand()%(max-min+1));
    }
    so funktioniert die zufallsfunktion sehr gut. ich denke die art der umsetzung ist auch recht sauber. ein test mit folgendem programm:

    Code:
    int main(void)
    {
      Init();
      EncoderInit();
    
    	while(1)
    	{
    	if (Taster()!=0)
    	{
    	Msleep(1000);
    	while(1)
    	{
    		int i=0;
    		int n;
    		SerPrint("Zufallszahlen zw. 0 und 1");
    		SerPrint("\n\r");
    		for (n=0;n<10;n++)
    		{
    			i=Zufall(0,1);
    			PrintInt(i);
    			SerPrint(" - ");
    			Msleep(500);
    		}
    		Msleep(1500);
    		SerPrint("\n\r");
    		SerPrint("Zufallszahlen zw. 0 und 50");
    		SerPrint("\n\r");
    		for (n=0;n<10;n++)
    		{
    			i=Zufall(0,50);
    			PrintInt(i);
    			SerPrint(" - ");
    			Msleep(500);
    		}
    		SerPrint("\n\r");
    		SerPrint("Zufallszahlen zw. 80 und 500");
    		SerPrint("\n\r");
    		Msleep(1500);
    		for (n=0;n<10;n++)
    		{
    			i=Zufall(80,500);
    			PrintInt(i);
    			SerPrint(" - ");
    			Msleep(500);
    		}
    		SerPrint("\n\r");
    		SerPrint("Zufallszahlen zw. 0 und 60000");
    		SerPrint("\n\r");
    		Msleep(1500);
    		for (n=0;n<10;n++)
    		{
    			i=Zufall(0,60000);
    			PrintInt(i);
    			SerPrint(" - ");
    			Msleep(500);
    		}
    		SerPrint("\n\r");
    		SerPrint("Zufallszahlen zw. 0 und 50");
    		SerPrint("\n\r");
    		Msleep(1500);
    		for (n=0;n<10;n++)
    		{
    			i=Zufall(0,50);
    			PrintInt(i);
    			SerPrint(" - ");
    			Msleep(500);
    		}
    		Msleep(1500);
    	}
    	}
    	else Blinken('S');
    	}
    	
      while (1);
      return 0;
    }
    lieferte bei mir dieses ergebnis:

    Zufallszahlen zw. 0 und 1
    0 - 1 - 1 - 0 - 0 - 0 - 1 - 1 - 0 - 0 -
    Zufallszahlen zw. 0 und 50
    22 - 22 - 1 - 17 - 12 - 28 - 50 - 33 - 14 - 28 -
    Zufallszahlen zw. 80 und 500
    332 - 141 - 201 - 246 - 427 - 361 - 365 - 174 - 371 - 155 -
    Zufallszahlen zw. 0 und 60000
    656 - 4886 - 947 - 4516 - 577 - 1505 - 2142 - 4125 - 3851 - 90 -
    Zufallszahlen zw. 0 und 50
    50 - 24 - 26 - 16 - 37 - 8 - 24 - 5 - 4 - 3 -

    Zufallszahlen zw. 0 und 1
    0 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 0 - 0 -
    Zufallszahlen zw. 0 und 50
    11 - 45 - 19 - 11 - 39 - 29 - 39 - 28 - 14 - 23 -
    Zufallszahlen zw. 80 und 500
    216 - 303 - 348 - 488 - 244 - 320 - 250 - 339 - 431 - 108 -
    Zufallszahlen zw. 0 und 60000
    933 - 1135 - 2625 - 2625 - 2625 - 2005 - 491 - 2289 - 0967 - 3539 -
    Zufallszahlen zw. 0 und 50
    38 - 33 - 35 - 4 - 42 - 23 - 11 - 18 - 40 - 19 -
    daran sieht man, dass die zahlen doch sehr zufällig vorkommen und vor allem, dass 2 aufrufe der funktion mit den gleichen min- und maxwerten nicht zu den gleichen (und damit zu keinen pseudozufallszahlen) führen.

    einzig verwunderliche ist, dass bei der zufallszahl zw. 0 und 60000 kein wert größer ist als 5000. leigt das vielleicht am wertebereich des int?!
    Der Optimist: \"Das Glas ist halb voll.\"
    Der Pessimist: \"Das Glas ist halb leer.\"
    Der Ingenieur: \"Das Glas ist doppelt so groß wie es sein müßte.\"

  6. #16
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Durch den Wertebereich von Int, sollten keine Werte über rund 32000 vorkommen. Durch das berechenen mit rand() % (max-min) kommen die kleinen Werte eventuell schon mal doppelt so oft vor wie die großen. Der Rest kann also einfach nur Pech sein.
    Die häufiger vorkommenden kleinen Werte kann man aber vermeiden.



    Da ist aber eventuell auch ein Problem bei der binär-> dez. Wandlung: die 0967 sieht komisch aus.

    Durch die vielen AD-Wandlungen ist diese Routine aber wirklich langsam.

  7. #17
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    27.12.2008
    Ort
    Dresden
    Alter
    38
    Beiträge
    100
    ja stimmt. di 0967 ist mir noch gar nicht aufgefallen. hab eher darauf geachtet, dass sich nichts verdoppelt.

    die geschwindigkeit ist ok, wenn asuro fliegen könnte, wär es vielleicht etwas langsam, aber für die bodenanwendungen reichts in der regel. man könnt das ganze sicher beschleunigen, indem man nur einen ADC ausliest. ich dachte mir jedoch, dass beim auslesen und mittelwertbilden von 5 ADCs ein schönerer zufallswert zustande kommt.

    danke euch allen für eure hilfe.

    malediction.
    Der Optimist: \"Das Glas ist halb voll.\"
    Der Pessimist: \"Das Glas ist halb leer.\"
    Der Ingenieur: \"Das Glas ist doppelt so groß wie es sein müßte.\"

  8. #18
    hallo leute, vielleicht kann mir von euch jemand helfen.

    und zwar brauche ich eine methode für den asuro die mir zufallszahlen im wertebereich -45 bis 45 liefert!

    hintergrund ist, ich will meinen asuro radom mäßig durch einen raum navigieren lassen (random walk).

    die move methode etc ist alles schon fertig...

    das einzige problem im moment sind noch die zufallszahlen

    danke schonmal für die hilfe

  9. #19
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    27.12.2008
    Ort
    Dresden
    Alter
    38
    Beiträge
    100
    Nimm doch einfach die obige Routine; als Grenzen 0 und 91 und dann "addiere" am Ende einen Offset von -45 dazu. Schon hast Du den gesuchten Bereich...
    Der Optimist: \"Das Glas ist halb voll.\"
    Der Pessimist: \"Das Glas ist halb leer.\"
    Der Ingenieur: \"Das Glas ist doppelt so groß wie es sein müßte.\"

  10. #20
    ich kanns grad leider nicht testen, weil ein freund grad den asuro hat.

    das problem ist, ich hatte bei den letzten versuchen immer probleme mit dem datentyp uint8_t....den kennt mein compiler nich...

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Berechtigungen

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

12V Akku bauen