KI-bungs- und Praktikumsaufgaben Serie 2: Constraintprogrammierung I

Aufgabe zum 13.12.2006

Debora Baumann (198687)
Patrick Ladig (197987)
Jonathan Fischer (194193)


Wir definieren unser Constraintnetz ber die Variablen X und Y, die gemeinsam den Raum der
Positionen auf dem Spielfeld bilden. Das Koordinatensystem ist das in der Aufgebenstellung
beschriebene, d.h. X ist aus [-3000, 3000] und Y aus [-2000,2000]

Die Constraints legen die Entfernungen des Roboters (des Kamerabrennpunktes) zu den drei
auf den Bildern sichtbaren Flaggen (im Programmquelltext "Fahnen" genannt) fest. Fr jede
Fahne wird also festgelegt, dass sich der Roboter auf einem Kreis um die Flagge mit einem
bestimmten Radius befindet. Der Radius, also der Abstand zur Flagge wird aus der Hhe der
Flagge auf dem Bild berechnet. Da der betreffende Peilungswinkel mit einem bestimmten
Fehler bermittelt wird, berechnen wir eine obere Grenze und eine untere Grenze fr den
Radius und legen daraus zwei Constraints (pro Flagge) fest: Ein Constraint beinhaltet das
Innere des greren der zwei konzentrischen Kreise, das andere beinhaltet genau alle
Punkte auerhalb des kleineren Kreises. Zusammen legen beide Constraints also fest, dass
sich der Roboter auf einem bestimmten Kreisring um die Flagge aufhlt.

Fr jedes der drei Bilder wird der Radius folgendermaen berechnet:
Bezeichnungen:
	r - kleiner Radius (in mm)
	R - groer Radius (in mm)
	hf - Hhe der Flagge auf dem Bild (in mm oder Pixeln, muss gemessen werden.)
	Hf - tatschliche Hhe der Flagge (in mm)
	w - vertikaler Peilungswinkel fr die Flaggenhhe
	wf - Fehlerabweichung fr den Peilungswinkel
	V - vertikaler Kameraffnungswinkel
	hb - Hhe des Bildes (gleiche Einheit wie hf, muss gemessen werden.)

Zunchst berechnen wir den Winkel w:
	w := V * hf / hb

	Diese Formel folgern wir aus dem Verhltnis: w/V = hf/hb
	Es ist nicht ganz exakt, reicht aber fr unsere Zwecke aus, da die Winkel recht
	klein sind.
	
Berechnung der Radien:
	r:= Hf / (2 * tan ((w + wf) / 2)
	R:= Hf / (2 * tan ((w - wf) / 2)

	Bei dieser Formel nehmen wir an, dass sich die Kamera etwa auf halber Flaggenhhe,
	also in 200 mm Hhe befindet. Wir berachten dann das rechtwinklige Dreieck, dessen
	Seiten die obere Flaggenhlfte, die Verbindungslinie zwischen Flaggenspitze und
	Kamera sowie die Verbindungslinie zwischen Flaggenmittelpunkt und Kamera bilden.
	w/2 ist der Innenwinkel an der Kamera. Sein Tanges ist das Verhltnis zwischen der
	Lnge Hf/2 der oberen Flaggenhlfte und des Abstandes r von der Kamera zur Flagge,
	also tan(w/2) = (Hf/2)/r. Wenn man nun noch die Fehlerabweichung wf fr den
	Peilungswinkel zu diesem addiert, bzw davon subtrahiert, erhlt man

	tan((w+wf)/2) = Hf/(2*r) bzw. tan((w-wf)/2) = Hf/(s*R)

	und daraus die obigen Formeln zur Berechnung der Radien.

Nun definieren wir die Constraints.
	Wir bentigen dafr noch die Koordinaten fr den Kreismittelpunkt, also die
	Koordinaten der Position der betreffenden Flagge. Wir nennen diese (Xf,Yf).

	Das erste Constraint C1 beinhaltet das innere des greren Kreises:
		C1 = {[X,Y] | (X-Xf)^2 + (Y-Yf)^2 <= R^2}
	Das zweite Constraint C2 beinhaltet alle Punkte auerhalb des kleineren Kreises:
		C2 = {[X,Y] | (X-Xf)^2 + (Y-Yf)^2 >= r^2}
	
Wenn wir diese beiden Constraints fr jedes der drei Bilder definieren, erhalten wir ein
Constraintnetz zur ungefhren Bestimmung der Roboterposition.

Unsere Messungen der nicht gegebenen Werte aus den drei Bildern:
	Hhe des Bildes (fr alle drei Bilder gleich): hb = 59
	1.Flagge (Blick 90 links):  hf = 11.7
	2.Flagge (Blick nach vorn):  hf = 16.5
	3.Flagge (Blick 90 rechts): hf = 14.5



_________________________________________________________________________________________
Zu unserem Programm "robocopo"
_________________________________________________________________________________________
-----------------------------------------------------------------------------------------

Wir haben in Java eine Darstellung fr Constraints sowie Funktionen zu
Constraintpropagation auf diesen Constraints definiert.

Erklrung der Constraintimplementierung und der Lsungsstrategie:
----------------------------------------------------------------
Ein Constraint ist in unserem Programm ein Objekt der Klasse robocopo.Constraint.
Man kann Erweiterungen dieser Klasse schreiben, um bestimmte Sorten von Constraints
zu definieren. Zum Beispiel haben wir die Klasse robocopo.Kreis als Unterklasse von
robocopo.Constraint definiert, um so die oben definierten Constraints zu implementieren.
Jedes Constrain-Objekt hat die beiden folgenden Memberfunktionen:
	maxLokalKonsistEinschr ()
	erfuellt()
Erstere erhlt als Parameter eine Wertebereichteilmenge (aktuelle Domain) und berechnet
daraus die maximale lokal-konsistente Einschrnkung.
Zweitere prft lediglich, ob ein gegebener Punkt das Constraint erfllt oder nicht.

Zur Lsung der Constraintproblems verfolgen wir in robocopo die folgende Strategie:
Zunchst fhren wir eine Constraintpropagation durch, wobei wir als Einschrnkung
bezglich eines Constraints immer die maximale lokal-konistente Einschrnkung whlen, also
die entsprechende Funktion maxLokalKonsistEinschr() nuten.
Sollten bei diesem Vorgang mehrere nicht miteinander verbundene Wertebereichkomponenten
(also mehrere Teilgebiete auf dem Spielfeld, die nicht mehr miteinander verbunden sind)
entstehen, so reduzieren wir jede dieser Komponenten wieder mit der eben beschriebenen
Constraintpropagation.
Dies wird so lange fortgefhrt, bis sich keine Komponente mehr weiter durch maximale
lokal-konistente Einschrnkung reduzieren lsst.
Diesen Vorgang (bis hier hin) nennen wir rekursive Constraintpropagation.
In den erhaltenen Komponenten suchen wir nach Lsungspunkten, indem wir bestimmte Punkte
mit erfuellt() darauf berprfen, ob sie allen Constraints gengen.
Falls wir keinen Lsungspunkt finden, wenden wir die rekursive Constraintpropagation
erneut an, diesmal aber auf Teile der Komponenten.
Danach wird wieder nach Lsungspunkten gesucht.
Wie oft dieser Kreislauf hchstens statt findet, ist durch den Parameter maxTeilTiefe
bestimmt.

Wie man unser Programm benutzt ...
----------------------------------
... wird in den ersten Zeilen des Quelltextes "robocopo.java" beschrieben. Hier sei nur
gesagt, dass es sich um ein gewhnliches Java-Programm handelt, was im "normalen" oder
im "debub-Modus" ausgefhrt werden kann.

Testergebnisse
---------------
Mit den sechs oben definierten Kreis-Constraints haben wir unser Programm untersucht.
Es findet sofort Lsungspunkte in der Komponente, die sich durch die rekursive
Constraintpropagation ergibt. Diese wird also nicht geteilt und die Constraintpropagation
wird nicht erneut durchgefhrt. Auch wird die Wertebereichsteilmenge durch die Anwendung
der Constraints nicht in mehrere Komponenten geteilt, bleibt also immer zusammenhngend,
obwohl eine Teilung durch die Art der Constraint prinzipiell nicht ausgeschlossen ist.

Da sofort Lsungspunkte gefunden werden, ist der Parameter maxTeilTiefe nicht relevant.
Durch eine grere Wahl des Parameters suchTiefe (Erklrung im Quelltext) knnen jedoch
mehr Lsungspunkte in der erhaltenen Wertebereichteilmenge gefunden werden.

Fr suchTiefe := 3 erhlt man das folgende Ergebnis (Zitat Programmausgabe)
>>
Die (induktive) Constraintpropagation ergibt 1 Gebiet(e):
X aus [-280.69683869235087,-98.40983823733632; Y aus [386.5877299121769,528.3146466174021]
Es wurden die folgenden Lsungspunkte gefunden (X|Y):
(-189.5533384648436|457.4511882647895)
(-166.76746340796677|475.1670528529427)
(-235.12508857859723|492.8829174410958)
(-212.3392135217204|475.1670528529427)
<<

Wir haben das Programm mit verschiedenen Werten fr den absoluten Fehler des
Peilungswinkels laufen lassen. Dabei stellte sich heraus, dass bis zu einem Fehler von
0.168 Grad die Wertebereich auf eine leere Menge reduziert wurde, dass also das System der
Constraints global inkonsistent war.
Ab einer "Fehlertoleranz" von 0.169 werden Lsungspunkte gefunden, und zwar in etwa
(-198|463) im Koordinatensystem aus der Aufgabenstellung.
