LBotics.at

In diesem Abschnitt wird gezeigt, wie man einen Roboter mit dem allgemeinen Prinzip der proportionalen Fehlerkorrektur einer Linie mit unterschiedlich stark gekrümmten Kurven noch besser folgen lassen kann. Dabei werden wiederum die Grauwerte, also die Intensitäten von reflektiertem Licht eines Reflexionssensors verwendet, um zu ermitteln, wie weit der Sensor von der Grenze zwischen schwarz und weiß entfernt ist.

Prinzip der proportionalen Fehlerkorrektur

Bei einem Regelkreis werden Messwerte oder Sensorinfotmationen so verarbeitet, dass diese bei der Steuerung von Aktionen, z. B. der Drehgeschwindigkeit von Motoren direkt einfließen. Damit ein Regelkreis seine Aufgabe erfüllt (z. B. das Erreichen und Halten einer bestimmten Temperatur bei eine Heizungssteuerung oder das exakte Fahren eines Roboters entlang einer Linie), muss es laufend Korrekturen geben.

Ausgegangen wird von einem gewünschten Sollwert, der beibehalten werden soll. Gibt es nun eine Abweichung von diesem Wert, so muss es eine Aktion geben, sodass sich die nächsten aktuellen Werte diesem Sollwert nähern. Damit solche Korrenturen nun nicht zu langsam ablaufen und der Sollwert nicht erreiht wird, oder mit einer Korrektur "über das Ziel hinausgeschossen" wird, kann bei Regelkreisen so vorgegangen werden, dass die Größe der Korrektur abhängig von der Größe des aktuellen Fehlers ist.

Das bedeutet: Je größer der Fehler zwischen einem aktuellen Wert und dem gewünschten Sollwert ist, desto stärker muss die Korrektur in Richtung des Sollwerts ausfallen.

Fehlerberechnung beim Folgen einer Linie mit einem Sensor

Im folgenden wird davon ausgegangen, dass ein Reflexionssensor Werte zwischen 0 und 100 liefert. Verwendet man einen Sensor, der andere Werte liefert, so sind diese sinngemäß anzupassen.

Befindet sich ein Reflexionssensor genau über der Grenze zwischen weiß und schwarz, so liefert dieser einen Wert von 50. Ist der Sensor mehr über dem schwarzen Bereich, werden die Werte kleiner (die Intensität des reflektierten Lichts nimmt ab), ist der Sensor über dem weißen Bereich, werden die Werte größer (die Intensität des reflektierten Lichts nimmt zu).

Die Differenz zwischen dem gewünschten Sollwert 50 und dem aktuelle gemessenen Wert wird als Fehler bezeichnet.

Fehler = Sollwert - aktueller Wert

 

 

Position 1

Der Sensor befindet sich genau über der Grenze zwischen weiß und schwarz. Der aktuelle Wert 50 entspricht dem Sollwert 50. Die Differenz ist 0 und somit ist der Fehler = 0.

Fehler = Sollwert - aktueller Wert = 50 - 50 = 0

Hier ist keine Korrektur notwendig, der Roboter soll geradeaus fahren, die beiden Motoren sollen sich also gleich schnell drehen.

Position 2

Der Sensor befindet sich rechts von der Grenze zwischen weiß und schwarz und der aktuelle Wert des Sensors beträgt 20. Die Differenz zwischen Sollwert und aktuellem Wert beträgt hier 30.

Fehler = Sollwert - aktueller Wert = 50 - 20 = 30

Damit sich der Sensor in Richtung des Sollwerts bewegt, muss sich der Roboter nach links bewegen. Der linke Motor muss sich langsamer drehen, der rechte Motor muss sich schneller drehen.

Position 3

Hier befindet sich der Sensor links der Grenze zwischen weiß und schwarz, der aktuelle Wert des Sensors beträgt hier 70 und der Fehler somit -20.

Fehler = Sollwert - aktueller Wert = 50 - 70 = -20

In diesem Fall muss sich der Roboter nach rechts drehen, damit der Sensor zum Sollwert direkt auf der Grenze bewegt wird. Der linke Motor muss sich schneller drehen und der rechte Motor muss sich langsamer drehen.

Proportionale Korrektur der Motorgeschwindigkeiten

Aus den beiden Fällen Position 2 und Position 3 in der Abbildung ergibt sich, dass jeweils die Umdrehungsgeschwindigkeit eines Motors vergrößert und des anderen entgegengesetzt verkleinert werden muss, damit sich der Sensor in Richtung des Sollwerts bewegt und somit der Fehler wieder kleiner wird. Ist der Fehler größer, muss es eine stärkere Korrektur der Motorgeschwindigkeiten geben, ist der Fehler kleiner, so muss die Korrektur der Motorgeschwindigkeiten nicht so groß ausfallen, damit sich der Roboter nicht zu weit dreht.

Die aktuelle Größe des Fehlers kann direkt für die Korrektur der Motorgeschwindigkeiten anhand einer einfachen Berechnung herangezogen werden. Ausgehend von einer festgelegten Startgeschwindigkeit der beiden Motoren wird jeweils ein Betrag des Fehlers, multipliziert mit einem Proportionalitätsfaktor P dazugezählt oder abgezogen.

M1 speed aktuell = M1 speed start + Fehler * P

M2 speed aktuell = M2 speed start - Fehler * P

Im Rahmen einer konkreten praktischen Aufgabenstellung besteht die Herausforderung nun darin, einem optimalen Wert für den Proportionalitätsfaktor P zu finden.

Dieser Proportionalitätsfaktor P kann größer 1 sein, wenn der Wert eines Fehlers zu klein ist, damit dieser Korrekturwerte ergibt, die groß genug sind oder er kann aber auch kleiner 1 sein, wenn der Wert des aktuellen Fehlers vermindert werden muss, da die sich daraus ergebende Korrekturwerte zu groß sind.

  • P < 1: Korrekturwerte sind proportional dem Fehler und kleiner als der Fehler
  • P = 1: Korrekturwerte entsprechen genau dem Fehler
  • P > 1: Korrekturwerte sind proportional dem Fehler und größer als der Fehler

In der folgenden Tabelle wird gezeigt, welchen Einfluss unterschiedliche Proportionalitätsfaktoren P (P = 1, P = 0.5 und P = 2) auf die damit berechneten Korrekturwerte in Bezug auf den vorliegenden Fehler haben.

Fehler Motorgeschwindigkeiten (P = 1)   Fehler Motorgeschwindigkeiten (P = 0.5)
  Fehler Motorgeschwindigkeiten (P = 2)
0 M1 = 50 + 0 * 1 = 50
M2 = 50 - 0 * 1 = 50
  0 M1 = 50 + 0 * 0.5 = 50
M2 = 50 - 0 * 0.5 = 50
  0 M1 = 50 + 0 * 2 = 50
M2 = 50 - 0 * 2 = 50
1 M1 = 50 + 1 * 1 = 51
M2 = 50 - 1 * 1 = 49
  1 M1 = 50 + 1 * 0.5 = 50.5
M2 = 50 - 1 * 0.5 = 49.5
  1 M1 = 50 + 1 * 2 = 52
M2 = 50 - 1 * 2 = 48
2 M1 = 50 + 2 * 1 = 52
M2 = 50 - 2 * 1 = 48
  2 M1 = 50 + 2 * 0.5 = 51
M2 = 50 - 2 * 0.5 = 49
  2 M1 = 50 + 2 * 2 = 54
M2 = 50 - 2 * 2 = 46
3 M1 = 50 + 3 * 1 = 53
M2 = 50 - 3 * 1 = 47
  3 M1 = 50 + 3 * 0.5 = 51.5
M2 = 50 - 3 * 0.5 = 48.5
  3 M1 = 50 + 3 * 2 = 56
M2 = 50 - 3 * 2 = 44
4 M1 = 50 + 4 * 1 = 54
M2 = 50 - 4 * 1 = 46
  4 M1 = 50 + 4 * 0.5 = 52
M2 = 50 - 4 * 0.5 = 48
  4 M1 = 50 + 4 * 2 = 58
M2 = 50 - 4 * 2 = 42
5 M1 = 50 + 5 * 1 = 55
M2 = 50 - 5 * 1 = 45
  5 M1 = 50 + 5 * 0.5 = 52.5
M2 = 50 - 5 * 0.5 = 47.5
  5 M1 = 50 + 5 * 2 = 60
M2 = 50 - 5 * 2 = 40
10 M1 = 50 + 10 * 1 = 60
M2 = 50 - 10 * 1 = 40
  10 M1 = 50 + 10 * 0.5 = 55
M2 = 50 - 10 * 0.5 = 45
  10 M1 = 50 + 10 * 2 = 70
M2 = 50 - 10 * 2 = 30
20 M1 = 50 + 20 * 1 = 70
M2 = 50 - 20 * 1 = 30
  20 M1 = 50 + 20 * 0.5 = 60
M2 = 50 - 20 * 0.5 = 40
  20 M1 = 50 + 20 * 2 = 90
M2 = 50 - 20 * 2 = 10

 

Der Proportionalitätsfakor P muss so gewählt werden, dass die Regelung in einem System - z. B. Motorgeschwindigkeit + / - Korrekturwert - so verläuft, dass ein Sensor in Abhängigkeit unterschiedlich großer Fehler so schnell wie möglich wieder Werte des Sollwerts liefert.

Dies kann beim Fahren eines Roboter entlang einer Linie experimentell ermittelt werden und muss selbstverständlich an die unterschiedlichen Krümmungen der Linie eines vorliegenden Kurververlaufs speziell angepasst werden.

Beispiel - Folgen einer Linie mit einem Sensor und proportionaler Fehlerkorrektur

Mit dem folgenden Code-Beispiel liegt ein vollständiges und funktionierende Skript vor, das mit einem Roboter mit einem Reflexionssensor anhand einer schwarzen Linie mit unterschiedlichen Krümungen getestet werden kann. Dabei handelt es sich um die zuvor beschriebene Umsetzung des Verfahrens der proportionalen Fehlerkorrektur.

Zu Beginn werden alle relevanten Werte in Variablen abgelegt. Es sind dies die Grundgeschwindigkeiten der Motoren mit denen diese grundsätzlich geradeaus fahren, der Sollwert für die gewünschte und optimale Position des Sensor in Bezug auf die schwarze Linie und der Proportionaltätsfaktor.

Zum bestmöglichen Folgen einer vorgegebenen Linie ist der optimale Proprtionalitätsfaktor experimentell zu ermitteln. Dieser muss auch neu bestimmt werden, wenn der Roboter mit einer anderen Grundgeschwindigkeit fahren soll.

In der Funktion loop() befindet sich der eigentliche Regelkreis mit dem Einlesen des aktuellen Sensorwerts, über die Berechung des Fehlers und der Motorgeschwindigkeiten unter Berücksichtigung einer proportionalen Fehlerkorrektur bis zum Setzen der Motorgeschwindigkeiten.

#include "KeplerOpenBOT.h"

uint16_t ML_start;
uint16_t MR_start;

uint16_t Lichtwert;
uint16_t Sollwert;
uint16_t Fehler;
float p;

float ML_speed;
float MR_speed;

void setup()
{
  KeplerOpenBOT_INIT();
  ML_start = 30;
  MR_start = 30;
  Sollwert = 511;
  p = 0.05;
}

void loop()
{
Lichtwert = READ_IO_ANALOG(IO5);

  Fehler = Sollwert - Lichtwert;

ML_speed = ML_start + Fehler * p;
  MR_speed = MR_start - Fehler * p;

  WRITE_MOTOR(ML,(int)ML_speed);
  WRITE_MOTOR(MR,(int)MR_speed);
}

Erklärungen zu diesem Skript

3-12: uint16_t ML_start; ... float MR_speed;

Definition der benötigten Variablen. Dabei ist zu beachten, welche Werte die Variablen annehmen können. Dementsprechend sind diese vom Typ uint16_t (für ganzzahlige Werte) und float (Dezimalzahlen).

17-20: ML_start = 30; MR_start = 30; Sollwert = 511;  p = 0.05;

Hier werden die Werte für die Motorgeschwindigkeiten (ML_start, MR_start), der gewünschte Intensitätswert für den Reflexionssensor (Sollwert) und der Proportionalitätsfaktor (p) festgelegt, mit dem der Fehler später multipliziert wird, bevor diese den Motorgeschwindigkeiten hinzugezählt oder abgezogen wird.

25: Lichtwert = READ_IO_ANALOG(IO5);

Einlesen der aktuell gemessenen Intensität des reflektierten Lichts und Ablegen in der Variable Lichtwert.

27: Fehler = Sollwert - Lichtwert;

Berechnen des Fehlers zwischen dem aktuell gemessenen und dem gewünschten Wert für die Intensität des reflektierten Lichts.

29,30: ML_speed = ML_start + Fehler * p;  MR_speed = MR_start - Fehler * p;

Berechnung der Motorgeschwindigkeiten, ausgehend vom festgelegten Startwert wird der Fehler, multipliziert mit dem Proportionalitätsfaktor addiert bzw. subtrahiert. Das Ergebnis sind Dezimalzahlen, weshalb diese in Variablen vom Typ float abgelegt werden müssen.

32,32: WRITE_MOTOR(ML,(int)ML_speed);  WRITE_MOTOR(MR,(int)MR_speed);

Setzen der zuvor berechneten Motorgeschwindigkeiten. ACHTUNG: Die beiden Variablen ML_speed und MR_speed sind vom Typ float! Deshalb müssen diese Werte zuvor mit (int) in ganzzahlige Werte konvertiert werden, da die Funktion WRITE_MOTOR(motor, speed) ganzzahlige Werte für die Geschwindigkeiten erwartet!