-         

Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 23

Thema: zufallszahlen "auf" asuro erzeugen

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    27.12.2008
    Ort
    Dresden
    Alter
    30
    Beiträge
    100

    zufallszahlen "auf" asuro erzeugen

    Anzeige

    hi...

    ich würde gern anständige zufallszahlen auf asuro erzeugen.
    jetzt hab ich zunächst mal gegooglet, wie man das am besten in c anstellt und bin zu folgendem code gekommen:

    Code:
    :
    #include <time.h>
    :
    int zufall(int min, int max)
    {
    	srand((unsigned)time(NULL)); 
    	return min+(rand()%(max-min+1));
    }
    :
    dabei erzeugt die rand()-funktion die zufallszahlen und der term hinter dem return grenzt mittels modulo die folge zwischen minimalwert und maximalwert ein. leider arbeitet diese rand() nach einem gewissen schema, sodass nur pseudozufallszaheln entstehen (also immer wieder die gleichen). dazu initialisiert man die rand()-funktion mittels srand() (man weist der rand() sozusagen einen startwert zu). um das möglichst zweckmäßig zu machen und hier nicht immer dei gleichen werte zu liefern, benutzt man dazu die aktuelle zeit. (daher auch das #include time.h)

    nun hab ich 2 probleme:
    1. winavr hat die time.h-lib nicht und ich weiß auch nicht wie ich sie einbinden kann.
    2. da der asuro ja nach dem flashen autonom arbeitet, bin ich mir nicht sicher, ob das überhaupt funktioniert, weil ich nicht weiß, ob es auf dem asuro sowas wie eine "uhrzeit" gibt, die ich auslesen kann.

    kann mir da jemand helfen?
    oder gibt es sogar eine elegantere lösung um zufallszahlen zu erzeugen?

    danke schon mal.
    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.\"

  2. #2
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.782
    Blog-Einträge
    8
    Hallo

    kann mir da jemand helfen?
    oder gibt es sogar eine elegantere lösung um zufallszahlen zu erzeugen?
    Eine Suche hier im RN-Forum nach "zufallszahlen AND asuro" findet genau drei Threads. Deinen hier, einen mit einer netten kleinen Zufallsfunktion:
    http://www.roboternetz.de/phpBB2/zei...lszahlen+asuro

    Der dritte Thread erklärt, wie man sowas anstellen kann und wie ich es auch machen würde:
    http://www.roboternetz.de/phpBB2/zei...lszahlen+asuro

    Alle zur Verfügung stehenden ADC-Werte verknüpfen:
    Code:
    #include "asuro.h"
    
    #define versuche 5000 // Anzahl der Versuche
    #define max 50 // Werte von 0 bis max-1 erzeugen
    #define balken 0 // 1 für Anzeige mit Balken
    
    unsigned char j, zahlen[max];
    unsigned int i;
    
    unsigned int rnd(unsigned char bereich)
    {
    	static unsigned int alter_zufall;
    	unsigned int zufall, odo[2], line[2], bat, ports[2];
    	
    	OdometrieData(odo);
    	LineData(line);
    	bat=Batterie();
    	ports[0]=256*PINB+PINC;
    	ports[1]=256*PINC+PIND;
    	zufall=~alter_zufall^odo[0]^odo[1]^line[0]^line[1]^bat^ports[0]^ports[1]^TCNT2;
    	alter_zufall=zufall;
    	while(zufall>=bereich) zufall-=bereich;
    	return(zufall);
    }
    int main(void)
    {
    	Init();
    	for(i=0; i<max; i++) zahlen[i]=0;
    	SerWrite("\n\rZufallszahlen mit dem asuro\n\n\r", 32);
    	while(1)
    	{
    		i=versuche;
    		while(i-- && ++zahlen[rnd(max)]); // Zufallswerte einlesen (0 bei Überlauf!)
    		
    		SerWrite("\n\rVerteilung nach ", 18);
    		PrintInt(versuche);
    		SerWrite(" Versuchen mit Maxwert ", 23);
    		PrintInt(max);
    		SerWrite(":\n\n\r", 4);
    
    		for(i=0; i<max; i++) // Verteilung der Werte ausgeben
    		{
    			PrintInt(i);
    			if(balken==1) for(j=0; j<zahlen[i]; j++) SerWrite(".",1);
    			SerWrite(" ", 1);
    			PrintInt(zahlen[i]);
    			SerWrite("\n\r", 2);
    		}
      		while(1);
    	}
      	return(0);
    }
    Es funktioniert leidlich ;)

    Gruß

    mic

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  3. #3
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Nur die AD werte sollte man nicht nehmen. Da sollte man schon eine Pseudozufallszahl und eine echte zufallszahl kombinieren. Wenn die zwei unabhängig sind (das sollte bei AD Wandler Wert und Pseudozufall der Fall sein) kann das Ergebnis eigentlich nicht schlechter, also eher besser werden als jedes Verfahren für sich.

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    27.12.2008
    Ort
    Dresden
    Alter
    30
    Beiträge
    100
    ich hab es jetzt so gelöst:

    Code:
    /*Funktion, die eine Zufallszahl zwischen min und max liefert*/
    uint8_t zufall(int min, int max)
    {
    	static uint16_t startwert=0x0AA;
    
    	uint16_t temp;
    	uint8_t n;
    	
        for(n=1;n<8;n++)
    	{
    		temp=startwert;
    		startwert=startwert << 1;
           
    		temp ^= startwert;
    		if ((temp & 0x4000)==0x4000)
    		{
    			startwert |= 1;
    		}
    	}
    	
    	return min+(startwert%(max-min+1));
    }
    das ist die funktion von M1.R aus diesem thread.
    ich hab sie nur dahingehend verändert, dass ich sie auf einen wählbaren bereich zwinge.

    funktioniert hinreichend gut auch wenn ich nciht zu 100% verstehe, was da gemacht wird, aber hey

    danke euch trotzdem für die antworten.

    male...
    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. #5
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Das Programm sieht auch nicht sonderlich gut aus. Die Folge der Pseudozufallszahlen wird sich nach spätestens rund 16000 Elementen wiederhohlen. Das ist relativ wenig. Da sollte schon GCC (edit: natürlich nicgt GCC selber sondern libc: in <stdlib.h>) eine wesenlich bessere Routine mitbringen.
    Die Zahlen sind auch nicht mal gut gleichverteilt, denn kleine Reste kommen von der Tendens ein kleine wenig häufiger vor. Einen ähnlichen Fehler haben die Deutschen Banken aber immerhin bei der ersten Generation EC karten auch gemacht.
    Besser ist es da den Rest, der sich nicht mehr Teilen läßt ganz wegfallen zu lassen und dann lieber die nächste "Zufallszahl" zu nehmen.

  6. #6
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    15.08.2004
    Ort
    Graz
    Beiträge
    342
    am praxistauglichsten ist meiner meinung nach die vorgehensweise, einen pseudozufallsgenerator mit einer echten zufallszahl zu initialisieren und nach in diesem fall, laut besserwessi, 16000 zyklen (je nach generator) neu zu initialisieren.

    dies kann man am einfachsten mit einem ADC-eingang, der "in der luft" hängt, machen. Der ADC hat soweit ich weiß eine Entropie von 2 Bit, würde aber nur mit einem, sprich dem niederwertigsten arbeiten, dieses 8 (oder 16 etc, je nachdem) mal samplen und das dem Generator geben.

    in der c't war jetzt ein sehr informativer artikel über (Pseudo-) Zufallszahlen.

  7. #7
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.782
    Blog-Einträge
    8
    Dann habe ich ja schon einiges richtig gemacht:

    zufall=~alter_zufall^odo[0]^odo[1]^line[0]^line[1]^bat^ports[0]^ports[1]^TCNT2;

    TCNT2 läuft zwar nur von 25 nach 0, aber mit dem hier wird zusätzlich die Ausführungszeit variabel:

    while(zufall>=bereich) zufall-=bereich

    Modula mit aktiven Interrupts, viel zufälliger gehts wohl nimmer... Aber ich bin eher Zufalls-Laie..

    Zufällig ist nicht gleichverteilt, auch 6 Sechser nacheinander sind Zufall.

    Wie zufällig muss es denn sein? Manchmal ist es auch sinnvoll ein Programm mit immer den selben zufälligen Werten zu testen. Wie ich das mit meiner "Formel" nachvollziehen sollte ist mir schleierhaft *lol*

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  8. #8
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    27.12.2008
    Ort
    Dresden
    Alter
    30
    Beiträge
    100
    ok ok...
    ich komm grad nicht mehr so ganz mit

    also die idee mit der psudozufallszahl und einer initialisierung mit einer echten zufallszahl habe ich ja oben schon gepostet.
    hier war eben mein problem, weil asuro das mit der funktion time() nicht hinbekommt (weil er wohl keine zeit kennt, denke ich mal).

    die pseudozufallszahl liefert die funktion rand(). (edit: initialisieren kann man das ganze mittels srand(unsigned int seed), wobei seed der neue ausgangswert für rand() ist.) das hätten wir also. die frage ist jetzt nur, wie ich aus dem ADC so eine "echte" zufallszahl bekomme. die variante von netzmann verstehe ich ehrlich gesagt nicht.

    Wie zufällig muss es denn sein?
    ansich war das o.g. beispiel schon ausreichend. ok, die meisten zahlen waren oft sehr groß, oder sehr klein, aber das war nicht weiter schlimm. eigentlich wollte ich nur ein kleines testprogramm schreiben, in dem asuro mittels ir hindernisse erkennt und dann "zufällig" in eine richtung (also "zufällige" kurve rechts oder links mit "zufälliger" gradzahl) ausweicht.
    hätte ich geahnt was auf mich zukommt, hätte ich es anders implementiert... aber nu isses zu spät

    vielleicht ist es aber auch ganz gut so. so könnte man eine anständige, funktionstüchtige, ECHTE zufallszahl auf asuro erzeugen. und wenn die funktion gut ist, könnte man diese in die lib einbauen.

    also um aufs problem zurückzukommen: woher die echte zufallszahl aus dem ADC bekommen?!
    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.\"

  9. #9
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Wenn man den ADC Ausgang offen läßt, fängt der sich eine Menge Störungen ein. Im wesenlichen wohl 50 Hz. Das ist dann zwar noch keine wirklich zufällige Spannung aber doch relativ ungregelmäßig. Wenn man es etwas besser haben will gibt es schaltungen die einfach eine elektronisches Rauchen (z.B. Widerstand oder Zenderdiode) genügend stark verstärken und so gute echte Zufallsspannungen erzeugen. Die Kunst dabei ist es dann Einkopplungen der 50 Hz / 100 Hz zu vermeiden.

    Das mit der Verknüpfung verschiedener Zufallszahlen funktioniert nur gut wenn die wirklich unabhängig sind. Aufeinanderfolgen Werte eines Pseudzufallsgenerators sind da relativ schlecht. Selbst bei mehreren verschiedenen Pseudozufallszahlen kann das daneben gehen. Aber die Verknüpfung von einer Pseudozufallszahl und einer wenn auch schlechten echten Zufallszahl wie dem AD-wert hilft.

  10. #10
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    27.12.2008
    Ort
    Dresden
    Alter
    30
    Beiträge
    100
    ok. das klingt ja ganz gut.

    die frage ist jetzt, wie ich in c die werte aus dem ADC auslesen und in einer variablen speichern kann, sodass ich sie für die srand() funktion benutzen kann. geht das überhaupt?!
    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.\"

Seite 1 von 3 123 LetzteLetzte

Berechtigungen

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