Flexibilität: Fallunterscheidung
"Ja" oder "Nein", das ist hier die Frage
Bislang sind unsere Programme eine Hintereinanderausführung von Anweisungen / Befehlen / "Aussagen mit Ausrufezeichen", das Markenzeichen der imperativen Programmiersprachen. Nun wollen wir in dem Programm Fragen stellen, und zwar genau solche, die man mit Ja oder Nein beantworten können muss.
Hindernis im Weg?
Angenommen der Roboter fährt ein Stück geradeaus. Dann kann es vorkommen, dass die Weiterfahrt nicht möglich ist, weil z.B. eine Kiste im Weg steht (Abbildung 1). Man stellt das fest, indem man eine entsprechende Bedingung formuliert, z.B.:
"Ist der mit dem Ultraschallsensor gemessene Abstand < 10cm?"
In diesem Fall soll der Roboter wieder zurückfahren. Mit dieser textuellen Beschreibung des Problems fertigen wir zunächst ein Flussdiagramm an. Dabei machen wir erneuten Gebrauch von der (aus dem vorangegangenen Abschnitt Wiederverwendung) bekannten parametrisierten Methode geradeausfahrt(dist)
:
Da in der EV3-Version das Messen von Sensordaten komplexer geworden ist, haben wir den Messvorgang zum Bestimmen des Abstands in die Methode missAbstand()
ausgelagert. Diese liefert den Abstand in Zentimetern. Weitere Informationen findet man beim Ultraschallsensor.
Eine berechtigte Frage ist an dieser Stelle: "Wieso lässt man den Roboter ein 'Stück' fahren und startet nicht einfach die Motoren?" Antwort: Dann müsste man nicht zu einem (Zeit)-Punkt im Programm den Abstand messen, sondern mehrfach, wozu man eine Schleife benötigt. Somit verschieben wir diesen Gedanken vorerst, bis wir zu den Schleifen kommen.
In der zum Flussdiagramm gehörigen Implementierung ist die Fallunterscheidung durch ein if/else-Statement
abgebildet:
import lejos.hardware.motor.EV3LargeRegulatedMotor;
import lejos.hardware.port.MotorPort;
import lejos.hardware.port.SensorPort;
import lejos.hardware.sensor.EV3UltrasonicSensor;
import lejos.robotics.RegulatedMotor;
import lejos.robotics.SampleProvider;
public class EV3Hindernis
{
static EV3UltrasonicSensor ultra = new EV3UltrasonicSensor(SensorPort.S1);
static RegulatedMotor reMo = new EV3LargeRegulatedMotor(MotorPort.A);
static RegulatedMotor liMo = new EV3LargeRegulatedMotor(MotorPort.D);
public static void main(String[] args)
{
int speed = 200;
int x = 200;
reMo.setSpeed(speed);
liMo.setSpeed(speed);
reMo.rotate(x,true);
liMo.rotate(x);
//miss Abstand
int abstand = missAbstand();
if(abstand < 10)
{
reMo.rotate(-x,true);
liMo.rotate(-x);
}
else
{
reMo.rotate(x,true);
liMo.rotate(x);
}
}
public static int missAbstand()
{
SampleProvider sp = ultra.getDistanceMode();
float [] sample = new float[sp.sampleSize()];
sp.fetchSample(sample, 0);
return (int)(sample[0]*100);
}
}
import lejos.nxt.Motor;
import lejos.nxt.NXTRegulatedMotor;
import lejos.nxt.SensorPort;
import lejos.nxt.UltrasonicSensor;
public class Hindernis
{
static UltrasonicSensor ultra = new UltrasonicSensor(SensorPort.S1);
static NXTRegulatedMotor reMo = Motor.A;
static NXTRegulatedMotor liMo = Motor.B;
public static void main(String[] args)
{
int speed = 900;
int x = 1500;
reMo.setSpeed(speed);
liMo.setSpeed(speed);
reMo.rotate(x,true);
liMo.rotate(x);
//miss Abstand
int abstand = ultra.getDistance();
if(abstand < 10)
{
reMo.rotate(-x,true);
liMo.rotate(-x);
}
else
{
reMo.rotate(x,true);
liMo.rotate(x);
}
}
}
Aufgaben - Modifiziere die Bedingungen
- Verändere die Bedingung, z.B. den Schwellenwert von 10cm.
- Verändere die Befehle, die an die Bedingung geknüpft sind. Wenn die Bedingung erfüllt ist, soll der Roboter z.B. stehen bleiben, statt zurückzufahren.
Quellen
- [1]: Fallunterscheidung: Hindernis im Weg? - Urheber: mks - Lizenz: inf-schule.de
- [2]: Flussdiagramm: Fallunterscheidung - Urheber: mks - Lizenz: inf-schule.de