Wippe

Team: Martin, Tom, Lukas

 

 

Problem

Um nun den Gyrosensor kennen zu lernen, welchen wir für die Programmierung unseres Endziels, dem Segway, benötigen, beschäftigen wir uns zunächst mit einer “einfacheren” Wippe. Diese Liegt auf einem Zahnkranz, welcher durch einen Motor bewegt werden kann. In der Mitte der Wippe ist unser Sensor angebracht.

Ansatz

Um nun diese Wippe nach leichtem Anstoßen wieder auszubalanchieren, nutzen wir ein PID-Regelungssystem (Proportional-Integral-Differential Regelungssystem). In diesem System wird versucht den Eingangswert durch die einzelnen P-, I- und D-Anteile auf einen Sollwert zu regeln.

PID-Regler:

Der PID-Regler besteht, wie gesagt, aus den drei oben aufgezählten Komponenten. Der Proportionalanteil ist direkt-proportional zum Mess-/Sensorwert. Der Diffenentialanteil besteht aus der 1. Ableitung der Mess-/Sensorwerte und der Integralanteil ist die Integration der der Mess-/Sensorwerte.
In unserem Fall spricht der Proportionalanteil auf den Winkel der Wippe an. Desto größer der Winkel abweicht von der Horizontale, desto stärker wird entgegen geregelt. Im Fall der Wippe regelt der Differentialanteil stärker entgegen, wenn die Windelgeschwindigkeit groß ist. Der Vorteil des Differentials ist, dass auch bei kleinen Winkeln, aber großen Winkelgeschwindkeiten der Differentialanteil “vorausschauend” der Winkeländerung entgegenwirkt. Der Integralanteil hat eine dämpfende Wirkung und glättet das Schwingen. Desweiteren reagiert Er rückblickend auf die vorhergehende mittlere Abweichung der gemessenen Sollwerte.

Gyrosensor

Der Gyrosensor registriert ein Lageänderung auf einer Ebene. Wir mussten auch feststellen, dass die ausgegebenen Werte nicht Winkel, in Bezug zur Ausgangslage waren, sondern nur die Winkelgeschwindigtkeit, mit den Werten kann man also nicht sagen in welcher Lage sich der Sensor befindet, sondern nur mit welcher Geschwindigkeit er sich von einer Lage zur Anderen bewegt.
Für den PID-Regler hatten wir also schon den Diffentialanteil anhand von den Werten des Sensors und mussten lediglich zweimal integrieren um Proportional- und Integralanteil zu erhalten.

task get_angle()
{while (true)
{
zeitvorher=zeitjetzt;   // Die Messzeit der letzte Runde wird
// in  zeitvorher gespeichert.
zeitjetzt=CurrentTick();  // Das ist die aktuelle Messzeit.

mess0=SensorHTGyro(S1,0);

gyrodiffvorher=gyrodiff;
gyrodiff=0.5*(mess0-gyrosensorOffset)+0.5*gyrodiff;
/* Glättung der Winkelgeschwindigkeit: macht das
System träger, aber weniger empfindlich gegen einzelne
falsche Messwerte, bzw. gegen Messrauschen. */

gyroangle += gyrodiff*(zeitjetzt-zeitvorher)/1000.;
gyroacc=0.95*gyroacc+0.05*(gyrodiff-gyrodiffvorher)/((zeitjetzt-zeitvorher)/1000.);
gyroint =0.99*gyroint+0.01*gyroangle*(zeitjetzt-zeitvorher)/1000.;
}
}

task loop()
{
while(true){

/*
float g;

//NumOut(0,LCD_LINE3,gyroint);
if (gyroangle>200)
{g=200.0;}
else
if (gyroangle<-200)
{g=-200.0;}
else {g=gyroangle;} */

/* Für dieses System taugt der Integralanteil nichts */
/* Dafür war es nötig, die zweite Winkelbeschleunigung,
d.h. die  Ableitung der gemessenen Winkelgeschwindigkeit
zu berücksichtigen.  */
Dreh1= -gyroangle*0.45-gyrodiff*(0.40)-gyroacc*0.15-gyroint*0.0;

OnFwd(OUT_A,Dreh1);

ClearScreen();
NumOut(0,LCD_LINE1, mess0);
NumOut(0,LCD_LINE2,gyrodiff);
NumOut(0,LCD_LINE3,gyroangle);
NumOut(0, LCD_LINE4 , gyrosensorOffset);
NumOut(0,LCD_LINE5,zeitjetzt-zeitvorher);
NumOut(0,LCD_LINE6,Dreh1);
NumOut(0,LCD_LINE7,gyroint);
if (ButtonPressed(BTN4,false)==1) {
gyroangle=0.0;
gyroint=0.0;}

}
}

 

 

Wie Ihr im Quelltext wohlmöglich schon gelesen habt, war der Integralanteil für unsere Wippe von wenig Nutzen. Deswegen haben wir die 2. Ableitung (Winkelgeschwindigkeit abgeileitet nach der Zeit), sprich die Winkelbeschleunigung, mit in den Regler einbezogen.

Ein weiteres Hindernis auf Das wir gestoßen sind, war die Kalibrierung des Sensors. Damit in Ruhelage keine Lageänderungen angezeigt werden, mussten wir den Offset (Fehler) des Sensors ermitteln. Später wurde auch festgestellt, dass wenn der Motor läuft, die Ausgabe des Sensors gestört wurde. Das wurde dann auch in der Kalibrierung berücksichtigt.
Hier der dazugehörige Quelltext:


sub Calibrate()
{

SetSensorHTGyro(S1);
float addOffset=0.0;
int i;
int j;
float sens;

/*for(i=0; i<10000; i++) {
sens=SensorHTGyro(S1,0);

}*/

/* Kalbrierung: Leider h‰ngt der Wert, den der
Sensor liefert, von der Auslesegeschwindigkeit ab.
Auflerdem h‰ngt er davon ab, ob der Motor gerade
l‰uft: Deshalb eine mehrteilige Kalibrierung:
mit Motor, ohne, etc.
*/

ResetSensor(S1);
OnFwd(OUT_A,80)   ;
Wait(1000);
Off(OUT_A);
//Wait(1000);
//Off(OUT_A);
for (j=0; j<8; j++) {
for(i=0; i<400; i++) {
sens=SensorHTGyro(S1,0);
NumOut(0, LCD_LINE1, sens);
NumOut(0, LCD_LINE2, addOffset);
OnFwd(OUT_A,2) ;
addOffset=addOffset+sens;
Wait(4);
}
if (j<4){
OnFwd(OUT_A,80)   ;
Wait(200);
OnFwd(OUT_A,-80);
Wait(200);
Off(OUT_A)    ; }
}

gyrosensorOffset=addOffset/3200.0;
NumOut(0, LCD_LINE1, gyrosensorOffset);
Wait(1000);
}

In dem folgendem Video wird die fertiggestellte Wippe mit dem Skript veranschaulicht:

Wippe – Video

Segway

Team: Lukas, Tom, Martin

 

Wir haben nun die Wippe mit Erfolg programmieren können. Dieser Quellcode wird als Vorlage für den Segway verwendet. Doch zunächst wird dafür ein Segwayroboter zusammengebaut, der sich dann von selbst auf zwei Rädern balancieren kann.

 

Ansatz

Wie bei der Wippe verwenden wir beim Segway ein PID-Regelungssystem. Wir verwenden den selben Skript wie von der Wippe. Der Unterschied ist, dass der Segway zwei Räder/Motor besitzt. Zuerst haben wir uns gedacht, desto tiefer der Schwerpunkt, desto leichter kann man die Stabilität halten. Dies hat sich jedoch als Nachteil bewertet. So haben wir den Schwerpunkt des Segways höher gesetzt.

 

Problem

Es sind fast die selben Probleme wie bei der Wippe vorhanden. Der Segwayroboter besitzt zwei Motoren, die sich jedoch je nach Abhängigkeit des Akkus weniger/stärker unterschiedlich rotieren. Hinzu kommt, dass man durch den Gyrosensor zu wenig Daten herausbekommt. Dies hat ebenfalls Auswirkungen auf die Stabilität des Segways. Zudem kommt noch dazu, dass der Segway nur auf den zwei Rädern steht. Kippt der Segway jedoch auf ein bestimmten kritischen Winkel nach vorn oder nach hinten, so ist es sehr schwer den Segway wieder zu stabilisieren.

 

Lösungsansatz

Man könnte an dem Segway ein zweiten Sensor anbringen und zwar einen Beschleunigungssensor. Dieser Sensor misst die Beschleunigung. So kann man die Geschwindigkeitszunahme bzw. -abnahme bestimmen. Dadurch kann man mehr Daten erfassen und können die Stabilität bzw. Balance des Segways verbessern.

Robotik-Gruppe (Mathesis Labor WS_2012)

Team: Tom, Martin, Lukas

Unser Ziel für dieses Semester ist es, einen Wagen zu bauen der ein in zwei Richtungen bewegliches Pendel in aufrechter Position balancieren kann.

Für die Konstruktion benutzen wir Lego Mindstorms. Um uns mit der Regelungstechnik und dem Programm NXC(Not_eXactlyC) vertraut zu machen, setzen wir uns ersteinmal kleinere Ziele.

1. Problem

Zunächst beschäftigen wir uns mit folgender Aufgabe, um NXC kennen zu lernen: Ein Roboter auf Rädern ausgestattet mit einem Lichtempfindlichen Sensor soll einer Schwarzen Linie (ca. 4cm breit) auf dem Boden folgen. Der Sensor gibt einen Wert zwischen 1 und 100 zurück wobei wir einen Wert <50 als Schwarz und >50 als Weiß interpretieren.

2.  Ansatz

Die Idee ist, dasa der Roboter(Rob) sich an einem Rand entlang bewegt und bspw. wenn er auf Schwarz ist, immer leicht nach links steuert, wenn er auf weiß ist, immer leicht nach rechts, und so immer auf der linie bleibt.

Nach einigen Versuchen haben wir festgestellt, dass wir, sobald die Geschwindigkeit richtig eingestellt ist, ein Problem mit dem Neigungswinkel bei den Kurven bekommen haben.

Fährt Rob nun nämlich eine steile Außenkurve, so braucht er sehr lange, um wieder auf die Linie zurück zu kommen. Um diesem vorzubeugen ist in dem Skript unten  ein Ansatz umgesetzt; je länger sich Rob entweder auf Schwarzen oder weißem Untergrund befindet, desto enger wird die Kurve, die er fährt.

3.   Ergebnis

Den im Beispielvideo zu sehenden Parcour haben unsere Roboter an der Außenkante entlang bewältigt. Auf der Innenseite ist eine Kurve, die mit unserem Ansatz so nicht zu lösen war. Zumindest nicht bei einer zufriedenstellenden Geschwindigkeit.

 

task main()

{
int r=25;
int l=-25;

SetSensorLight(S3);
int b=Sensor(S3);
NumOut(0,LCD_LINE1,b);

until(b<50){
   OnFwd(OUT_BC,60);
   b=Sensor(S3);
   NumOut(0,LCD_LINE1,b);
}

repeat(999999){
   b=Sensor(S3);

   if(b<50){
      b=Sensor(S3);
     NumOut(0,LCD_LINE1,b);
     OnFwdSync(OUT_BC,50,l);
     Wait(50);
     l=l-2;
     r=25;
   }

   else{
     b=Sensor(S3);
     NumOut(0,LCD_LINE1,b);
     OnFwdSync(OUT_BC,50,r);
     Wait(50);
     r=r+2;
     l=-25;
   }
}

}

Beispielvideo:

MVI_0001

 

20.12.2012