PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : links/rechts Antriebverhältnis für Kreisbogenfahrt



Lurchi
08.04.2010, 13:56
Hallo,

ich bin jetzt schon ein paar Tage aus der Schule und habe erhebliche Schwierigkeiten eine einfache Aufgabe zu lösen:

Ich habe ein dreirädiges Fahrzeug - vorne eine frei bewegliche Rolle, hinten zwei getrennt voneinander angetriebene Räder mit 42 cm Radstand. Raddurchmesser sind 18cm. Pro Umdrehung werden 120 Impulse des Inkrementaldrehgebers geliefert.
Durch unterschiedliche Geschwindgkeit zwischen linkem und rechtem Rad kann ich einen Kreisbogen fahren.

Ich möchte einen - auf die Mitte der Hinterachse bezogenen - Kreisbogen von z.b. 154 Grad mit einem Radius von 2 Metern fahren. Richtung ist unerheblich, da die Richtung ja durch das jeweils schneller drehende Rad vorgegeben wird. Also reduziert sich das ganze auf das Drehzahlverhältnis zwischen links und rechts...

Frage: In welchem Verhältniss muss der linke Drehgeber gegenüber dem rechten seine Impulse pro Sekunde liefern, damit ich diesen Kreisbogen fahre.

Ich bin auf der Suche nach einer Formel mit Radius und Winkel als Variablen.

Vielleicht kann mir ja einer einen Hinweis für die Lösung geben :-)

Grüße

Lurchi

damfino
08.04.2010, 16:13
Die Impulse zu berechnen ist eine einfache Sache:
Du hast einen Radius und Winkel vorgegeben, jetzt musst noch fürs innere und äussere Rad den Weg berechnen. Winkel ist logischweise gleich, Radius-Innen = Radius+Radstand/2, etc.
Dann hast die Wege für beide Räder, und kannst über den Raddurchmesser die Anzahl der Impulse der Wege ausrechnen.
Das war der leichte Teil, wenn du über PWM die Motoren regelst hast leider das Problem das zB 70%PWM nicht 70% der Drehzahl sind.
An einer einfachen Lösung dieses Problems wäre ich auch sehr interessiert :)

LG!

Searcher
08.04.2010, 17:27
ich versuchs mal auf die Gefahr einer Blamage hin:

für einen kompletten Kreis muß das äußere Rad einen Weg von (Kreisdurchmesser + Radstand) * PI zurücklegen.

Dafür muß sich das Rad: Weg / Umfang des Rades drehen.
((Kreisdurchmesser + Radstand) * PI) / (Raddurchmesser * PI)
oder auch (Kreisdurchmesser + Radstand) / Raddurchmesser

Impulse pro komplettem Kreis = 120 * (Kreisdurchmesser + Radstand) / Raddurchmesser

Pulse für 154 Grad mit Dreisatz:

360 Grad => 120 * (Kreisdurchmesser + Radstand) / Raddurchmesser
1 Grad => (120 * (Kreisdurchmesser + Radstand) / Raddurchmesser) / 360

Da läßt sich was kürzen:
1 Grad => ((Kreisdurchmesser + Radstand) / Raddurchmesser) / 3

154 Grad => 154 * ((Kreisdurchmesser + Radstand) / Raddurchmesser) / 3

Impulse äußeres Rad für 154 Grad = 154 * (( 4m + 0,42m) / 0,18m ) / 3 = 1260,51...


Fürs innere Rad analog, nur das man da für den Weg (Kreisdurchmesser - Radstand) * PI hernehmen muß
Impulse inneres Rad für 154 Grad = 154 * (( 4m - 0,42m) / 0,18m ) / 3 = 1020,96...


Deine Formeln dürften sein (Kreisdurchmesser = 2 * Kreisradius):
Impulse äußeres Rad = Winkel in Grad * ((Kreisdurchmesser + Radstand) / Raddurchmesser) / 3
Impulse inneres Rad = Winkel in Grad * ((Kreisdurchmesser - Radstand) / Raddurchmesser) / 3


Ohne Gewähr :-b
Gruß
Searcher

Richard
08.04.2010, 19:54
Ok. damit ist die Anzahl der Impulse für jedes Rad bekannt. Aber beide
Räder sollen ihre jeweilige Impulsanzahl in der gleichen Zeit abarbeiten!
Da wird es jetzt haarig....Bin gerade in der Kur angekommen und beinahe
24 h nicht geschlafen, deshalb versuche ich das heue erst überhaupt nicht. :-)

Gruß Richard

Ps.: Habe mir so einen Surfstick zugelegt, klappt prima und die 5 Euronen/24h
spare ich hier locker an Kippen ein weil quasie überall Rauchverbot herrscht.:-)

Searcher
08.04.2010, 20:48
Ich wußte doch, daß ich da was nicht richtig verstanden habe :oops:

Gute Erhohlung Richard!

Gruß
Searcher

Lurchi
09.04.2010, 10:06
Hallo,

vielen Dank für den Input.
Wäre es nicht eine plausible Möglichkeit den beiden Motortreibern einfach die gewünschte RPM Zahl vorzugeben - die sollen sich drum kümmern, das die Zahl so genau wie möglich eingehalten wird.
Das sollte doch auf dem kurzen Weg zwischen PWM Wert und Drehgeber feedback möglich sein. Das ist zwar nicht 100% genau, aber im mittel sollte es doch ziemlich dem entsprechen was man will.

Dann muss man sich nur noch die Zeit zu überlegen bis die Strecke gefahren ist. (OK - Stichproben alle paar ms könnten sinnvoll sein... )
-> da die rpm ja bekannt sind...
Bei angenommenen 1/4 U/sek (15 U/Min) ist das äußere Rad nach 1260,51 / (120 / 4) also nach 42,017 Sekunden fertig.
Wenn das innere Rad im entsprechend kleinern Verhältniss (also langsamer ist), sollte jetzt der gewünschte kreisbogen gefahren worden sein.

Grüße

Lurchi

@Richard: Auch von mir, gute Erholung.
Oder habe ich mich jetzt verlaufen...

Sternthaler
11.04.2010, 19:09
Hallo zusammen,

genau zu dem mathematischen Ergebnis bin ich auch schon vor ein 'paar' Tagen beim Asuro gestoßen.
Ich hatte das mal in EXCEL gegossen und berücksichtigt auch die Geradeausfahrt. Ist nun im Anhang.

Der oben angegeben Ausdruck "Raddurchmesser) / 3" ist bei mir in einem RadFaktor gelandet und steht im 2ten blau markierten Feld im EXCEL-Kopf. (Rechts die beiden blauen Felder sind nur der Faktor in Werte unter 255 gerechnet. Bei der Geometrie vom Asuro kommt man so mit einer schnellen Byte-Rechnerei aus.)

Interessant ist noch das rechts stehende grüne Feld.
Dort kann man einen Prozentwert eintragen, der Fehler bei der Ermittlung der Drehgeber-Impulse 'schönrechnet'. (Bei meinem Asuro komme ich da mit einem Wert von 97 zum gewünschten Ergebis.)

Um beide Motoren zu regeln, damit sie die Vorgaben in gleicher Zeit abfahren, hatte ich, auch schon vor ein 'paar' Tagen, den waste-Linienverfolgungsregler so angepasst, das der sich darum kümmert.
Hier mal der Reglercode:

/************************************************** ***************************
FUNKTION: MotorPID
Aufgabe: Funktion zur Reglung der Motoren.
Diese Funktion bzw. die eigendliche Berechnung fuer die
Reglung wurde im Forum unter www.roboternetz.de von waste
entwickelt.
Von Sternthaler ist die Moeglichkeit hinzugefuegt, die
Reglerberechnung fuer unterschiedliche Regelaufgaben zu
nutzen.
Die Parameter steuern, welche Sensoren zur Reglung benutzt
werden sollen. Zum einen koennen es die Liniensensoren sein
um eine Linienverfolgung zu realisieren, zum anderen kann
der Regler zur Ueberwachung der Raddecoder genutzt werden.
Parameter:
************************************************** ***************************/
unsigned char MotorPID (
unsigned char regler,
char speed,
int links,
int rechts)
{
int LWert = 0, RWert = 0;
int absLinks = 0, absRechts = 0;
float faktor;
static int x, x1, x2, x3, x4;
static int xalt, drest, isum;
int kp = 0, kd = 0, ki = 0;
int yp, yd, yi, y, y2;
int LSpeed, RSpeed;
unsigned char LDir, RDir;
unsigned char use_regler = TRUE;

switch (regler)
{
case PID_LINIE:
links = rechts = 1; // erzwingt vorwaertsfahrt
LineData (); // Liniensensoren
LWert = sens.linie [LINKS_DUNKEL] - sens.linie [RECHTS_DUNKEL];
RWert = sens.linie [LINKS_HELL] - sens.linie [RECHTS_HELL];
/* DIESE PARAMETER WURDEN VON waste IM FORUM UNTER
https://www.roboternetz.de
ENTWICKELT.
*/
kp = 5; // Parameter kd enthält bereits Division durch dt
ki = 5;
kd = 70;
break;
case PID_ODOMETRIE:
if (links == 0 || rechts == 0)
use_regler = FALSE;
else
{
absLinks = abs (links);
absRechts = abs (rechts);
/* Odometrie-Zaehler so justieren, dass fuer eine Kurvenfahrt
die Tic-Anzahl auf beiden Seiten identisch aussehen.
Die Seite auf der weniger Tic's zu fahren sind wird auf die
hoehere Anzahl 'hochgerechnet'.
*/
if (absLinks < absRechts)
{
faktor = (float)absRechts / (float)absLinks;
LWert = sens.rad_tik [LINKS] * faktor;
RWert = sens.rad_tik [RECHTS];
}
else
{
faktor = (float)absLinks / (float)absRechts;
LWert = sens.rad_tik [LINKS];
RWert = sens.rad_tik [RECHTS] * faktor;
}
kp = g_kp;
ki = g_ki;
kd = g_kd;
}
break;
}

LSpeed = (int)(speed - hw.motor_diff / 2); //Wunschgeschwindigkeit vorgeben
RSpeed = (int)(speed + hw.motor_diff / 2); //Hardware beruecksichtigen

if (use_regler == TRUE)
{
/* AB HIER IST DIE BERECHNUNG VON waste IM FORUM UNTER
https://www.roboternetz.de
ENTWICKELT WORDEN.
*/
x1 = RWert - LWert; // Regelabweichung

x = (x1 + x2 + x3 + x4) / 4; // Filtert die 4 letzten Werte
x4 = x3; x3 = x2; x2 = x1; // Pipe ueber die letzten 4 Werte

isum += x; // I-Anteil berechnen
if (isum > 16000) isum = 16000; // Begrenzung: Überlauf vermeiden
if (isum < -16000) isum = -16000;
yi = isum / 625 * ki;

yd = (x - xalt) * kd; // D-Anteil berechnen und mit nicht
yd += drest; // berücksichtigtem Rest addieren
if (yd > 255) drest = yd - 255; // Eventuellen D-Rest merken
else if (yd < -255) drest = yd + 255;
else drest = 0;

yp = x * kp; // P-Anteil berechnen

y = yp + yi + yd; // Gesamtkorrektur
y2 = y / 2; // Aufteilung auf beide Motoren
xalt = x; // x merken

if (y > 0) // Abweichung nach rechts
{
LSpeed += y2; // links beschleunigen
if (LSpeed > 255) // wenn Wertebereich ueberschritten
{
y2 += (LSpeed - 255); // dann Rest rechts berücksichtigen
LSpeed = 255; // und Begrenzen
}
RSpeed -= y2; // rechts abbremsen
if (RSpeed < 0) // Auch hier Wertebereich
{
RSpeed = 0; // beruecksichtigen
}
}
if (y < 0) // Abweichung nach links
{
RSpeed -= y2; // rechts beschleunigen
if (RSpeed > 255) // wenn Wertebereich ueberschritten
{
y2 -= (RSpeed - 255); // dann Rest links berücksichtigen
RSpeed = 255; // und Begrenzen
}
LSpeed += y2; // links abbremsen
if (LSpeed < 0) // Auch hier Wertebereich
{
LSpeed = 0; // beruecksichtigen
}
}
}

/* Und wieder (fast) waste
*/
if (links >0) LDir = FWD; else if (links <0) LDir = RWD; else LDir = BREAK;
if (rechts>0) RDir = FWD; else if (rechts<0) RDir = RWD; else RDir = BREAK;

if (LSpeed < 20) LDir = BREAK; // richtig bremsen
if (RSpeed < 20) RDir = BREAK;
MotorDir ( LDir, RDir);
MotorSpeed (abs (LSpeed), abs (RSpeed));

return 0;
}
Folgende Variablen sind zu berücksichtigen:
- sens.rad_tik [LINKS | RECHTS ] : Aktuelle Zählerstände der Drehgeber
- g_kp, g_ki, g_kd : Globale PID-Werte. (Bei meinem Asuro 65, 5, 90
- hw.motor_diff : Kann 0 sein. Berücksichtigt unterschiedliche Motoren

Die benutzten Defines sollten selbsterklärend sein :-)

Ach so, wichtig wäre es noch zu erwähnen, dass die Reglerfunktion alle 2 ms aufgerufen werden sollte. Das Timing ist von waste mal so berechnet worden.

Viel Erfolg mit der Kurvenfahrt.
Sternthaler

P.S.: Hier auch noch mal eine Aufrufstelle der Regler-Funktion:
if (v_fahren == TRUE)
{
MotorPID (
PID_ODOMETRIE, // Reglerwahl
150, // Mittlere Geschwindigkeitsvorgabe
v_weg_l, // Anzahl Takte linkes Rad (Odometrie)
v_weg_r); // Anzahl Takte rechtes Rad (Odometrie)

if (sens.rad_tik [LINKS] >= v_weg_l &&
sens.rad_tik [RECHTS] >= v_weg_r)
{
v_fahren = FALSE;
v_weg_l = 0;
v_weg_r = 0;
MotorSpeed (0, 0);
MotorDir (BREAK, BREAK);
}
}