- fchao-Sinus-Wechselrichter AliExpress         
Ergebnis 1 bis 3 von 3

Thema: Fehler bei Winkelberechnungen [gelöst]

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    06.08.2008
    Ort
    Graz
    Beiträge
    521

    Fehler bei Winkelberechnungen [gelöst]

    Anzeige

    Powerstation Test
    Hallo,

    Ich steh bei meiner Positionsberechnung über Odometrie vor einem Rätsel, und zwar kommt am Anfang der richtige Winkel und Weg raus, mit der Zeit sind die Ergebnisse aber falsch.
    Die Winkeleinteilung entspricht einem Kompass, 0°=Norden, 90=Osten, etc. x = positiv nach Osten, y positiv nach Norden.
    Am Anfang passt es, bei zB 50° wird pos_x und pos_y größer. Aber auf einmal ist zB pos_x negativ, und bleibt negativ (wird in negativ immer größer), egal ob bei Fahrtrichtung 50° oder 300°. Bei Zahlenwerten um 1000 habe ich da sicher keinen Variablenüberlauf. Hab schon alles mögliche mit anderen Definitionen, Casten, etc probiert, ändert nichts.


    Hier der Auszug vom Code, vielleicht findet jemand einen Fehler.

    Code:
    static inline void Pos_odo()
    {
    short odo_li_temp, odo_re_temp, richtung_temp;
    long weg,pos_x_temp, pos_y_temp; 
    double si, co;
    	
    	odo_li_temp=(short)odo_li; odo_re_temp=(short)odo_re;
    	odo_li_temp=odo_li_temp*48;odo_re_temp=odo_re_temp*48;
    
    	weg= (long)((odo_li_temp+odo_re_temp)/20);
    	richtung_temp=((odo_li_temp-odo_re_temp)*3); //*1000/320 
    
    
    	if (richtung_temp>6282) richtung_temp=richtung_temp-6282;  // ^2*pi*1000
    	if (richtung_temp<0) richtung_temp=richtung_temp+6283;
    	
    	richtung=richtung+richtung_temp;
    	
    	if (richtung>6282) richtung=richtung-6282;  // ^2*pi*1000
    	if (richtung<0) richtung=richtung+6283; 
    	//  0° = N	 	90° = O    180° = S    270° = W 
    	// 	0=2*pi		pi/2		pi			3*pi/4
    
    	
    
    	odo_li=0; odo_re=0;
    
    	
    	si=128*sin((double)(richtung)/1000);
    	co=128*cos((double)(richtung)/1000);
    
    	pos_x_temp=weg*((long)(si)); 
    	pos_y_temp=weg*((long)(co)); // sin+cos in x,y vertauscht damit +y=Norden=0°, +x=Osten
    	
    	pos_x_temp=pos_x_temp/128; // die 128von weg  wieder rausrechnen
    	pos_y_temp=pos_y_temp/128;
    
    
    pos_x=pos_x+pos_x_temp;
    pos_y=pos_y+pos_y_temp;
    }
    Alle anderen Variablen sind global.

    LG

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    15.06.2008
    Ort
    Wien
    Beiträge
    162
    Hi, ich habe zwar beim schnellen drüberschauen noch nichts gefunden, aber es wäre bestimmt hilfreich wenn du zeigen würdest wie oft (bzw. wo) die Funktion aufgerufen wird und wie deine globalen Variablen definiert sind.

    Warum du allerdings vorher multiplizierst und dannach wieder dividierst ist mir nicht ganz klar.
    Wenn du versuchst mit Integer-Rechnungen Performance rauszuholen dann ist das die falsche Stelle
    die Sinus/Cosinus Berechnungen dauern vermutlich länger als der Rest der Funktion.
    Also entweder alles Fixkomma oder alles Gleitkomma

    LG

    Edit: versuche globale variablen möglichst zu vermeiden (außer wenn es nicht anders möglich ist, z.b bei Interrupts) und verwende wenn du die Variablen selbst verändern willst lieber Zeiger.

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    06.08.2008
    Ort
    Graz
    Beiträge
    521
    Hi!
    Die Mischung aus Gleit und Fixkomma kommt aus den vielen Versuchen ein vernünftiges Ergebnis zu bekommen, es war ursprünglich alles mit Integer, und ich dachte dass dort der Fehler liegt. Das wird wieder vereinheitlicht, Ziel ist Fixkomma.

    Vorher multiplizieren und nachher dividieren bringt bei Fixkomma eine höhere Genauigkeit, ohne dem wären mit Fixkomma die Winkelfunktionen nur 0 oder 1, und damit ist die Positionsberechnung hinfällig.

    Bin aber jetzt draufgekommen dass die Funktion passt, der Fehler kommt aus der Umrechnung Rad in Grad und itoa.
    Ich musste ein Variable von unsigned auf signed ändern, und habe damit eine Berechnung richtiggestellt, aber dafür in der nächsten einen Überlauf produziert....


    Mir ist klar das globale Variablen nicht ideal sind, aber mit den Pointern stehe ich noch auf Kriegsfuß, ich kapier noch nicht wie ich mit zB 6 verschiedenen arbeiten kann, bzw welchen Vorteil der Pointer gegenüber einer 8Bit Variable hat.

    LG

Berechtigungen

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

12V Akku bauen