Benutzer-Werkzeuge

Webseiten-Werkzeuge


Seitenleiste

ws1314:dokumentation

Dies ist eine alte Version des Dokuments!


Robotik - Dokumentation

1 Vorstellung und Grundidee
2 Verschiedene Wege zum Ziel
  2.1 Der Anfangsplan: GPS
  2.2 Erste Planänderung: Funkwellen
  2.3 Der endgültige Plan: Kameras
3 Die Umsetzung
4 Fazit

1 Die Idee

Einen Quadrocopter Fotos aus der Luft schießen lassen - das war die ursprüngliche Idee, unter der sich die Gruppe „Robotik“ in Mathesis zusammengefunden hat. Die Gruppe Robotik, das sind/waren Maximilian O., Konstantin D. und Robin N.. Natürlich gehörten zu der Idee noch viele andere Dinge: Das Gleichgewicht des Quadrocopters programmieren, feste Punkte bestimmen, die der Quadrocopter selbstständig ansteuert und - natürlich - dabei auch noch Hindernissen ausweicht. Im Endeffekt kam es doch etwas anders.

2 Verschiedene Wege zum Ziel

Zunächst einmal: Die Idee, das Gleichgewicht des Quadrocopters auch zu programmieren, wurde uns von Stefan und Felix relativ früh wieder ausgetrieben: Das Projekt wäre auch so schon schwierig genug, wir sollten das vorprogrammierte Gleichgewicht nehmen, war die Aussage. Es hat sich herausgestellt, dass dies ein sehr guter Rat war, denn auch so hatten wir genug zu tun.

2.1 Der Anfangsplan: GPS

Unsere erste Idee beinhaltete die Benutzung von GPS: Dem Quadrocopter sollten feste Koordinaten mitgegeben werden, die er mit Hilfe von GPS anfliegt. Dabei sollte eine Kamera an Bord Hindernisse erkennen und der Quadrocopter diese umfliegen. An speziellen Punkten sollten dann Bilder gemacht werden, und schließlich sollte der Quadrocopter wieder zum Start zurückkehren. Das erste Problem an diesen Plan war ein technisches: Quadrocopter sind energietechnisch sehr ungünstige Flugobjekte, die nur sehr wenig Gewicht tragen können. Von daher war es, außer mit einem sehr großen Quadrocopter, faktisch unmöglich, sowohl ein GPS-Modul als auch eine Kamera UND einen Computer auf den Quadrocopter zu tun. Für den großen Quadrocopter, der durchaus in der Uni vorhanden war, ergaben sich aber andere Schwierigkeiten: Zunächst ist dieser Quadrocopter äußerst gefährlich: Seine Rotoren sind durchaus in der Lage, Finger abzuschneiden, wenn sie dem Quadrocopter in die Quere kommen. Außerdem ist er sehr teuer - und eine Fehlfunktion, die ihn zerstört, schlicht nicht leistbar. Das nächste Problem galt für alle Quadrocopter: Für Draußen-Flüge sind Genehmigungen vonnöten. Gerade für den großen Quadrocopter werden solche Genehmigungen aber nur selten erteilt. Auch sind Quadrocopter sehr wasseranfällig und gerade im Winter daher nur schwer nutz- oder testbar. Damit war ein Draußen-Fliegen faktisch unmöglich - und daher auch die Idee mit GPS hinfällig. Eine neue Idee musste her.

2.2 Erste Planänderung: Funkwellen

Die nächste Idee war es, mit Funkwellen zu arbeiten. Das funktioniert - in einem kleinen Bereich - sowohl drinnen als auch draußen und kann somit auch im Winter mit Quadrocoptern gemacht werden. Zwei Möglichkeiten waren vorhanden: WLAN und Bluetooth. Für Bluetooth entdeckten wir bald ein Programm - - so dass wir Hoffnungen hatten, dass diese Idee funktioniert. Eine Triangulation wäre mit drei Bluetooth-Sendern möglich, ein Einblick liefert dieses kleine Programm zum Plotten:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.path as mpath
import matplotlib.lines as mlines
import matplotlib.patches as mpatches
 
 
W = { }
N = 5
 
qx = np.random.randint(30)
qy = np.random.randint(30)
W["Referenzpunkt X"] =  qx
W["Referenzpunkt Y"] =  qy
 
plt.figure()
ax=plt.subplot(111)
ax.set_xlim([0,30])
ax.set_ylim([0,30])
ax.add_patch(mpatches.Circle((qx, qy), radius=1,color="red",alpha=0.1))
 
for i in range(0,N):                             #scatterplot handles data nonlinear, its not legible for triangulation-use
 
	x = np.random.randint(30)
	y = np.random.randint(30)
	ankathete = float(x - qx)
	gegenkathete = float(y - qy)
	radius = np.sqrt((ankathete**2) + (gegenkathete**2))
	kreisumfang = 2*np.pi*radius
	area = np.pi * (radius)**2 
	W[i] =  x,y,radius,area
 
	ax.add_patch(mpatches.Circle((x,y),radius=radius,color='blue',alpha=0.1))
	#plt.scatter(x, y, s=area*190 , alpha=0.1)
 
plt.draw()
plt.show()
print W

Bald darauf erkannten wir jedoch, dass die Entfernungsmessung viel zu ungenau funktionierte - und daher nicht in Frage kam. Also war auch diese Idee gescheitert.

2.3 Der endgültige Plan

An diesem Punkt erinnerten wir uns an eine Idee, die uns Stefan anfangs vermitteln wollte: Den Quadrocopter mit Hilfe von Kameras im Raum erkennen und dadurch steuern. Also vertieften wir uns in die Theorie dahinter: Wie man mit Hilfe von 2 Kameras aus 2-D Punkten 3-D Punkte zu konstruiert. Dies funktioniert zum Beispiel mit dem Lochkamera-Modell. Dieses baut darauf auf, dass Bildpunkte immer aus Linien im dreidimensionalen Raum besteht (siehe Bild). Im Schnitt zweier solcher Linien liegt also ein Punkt im dreidimensionalen. Wie man diesen Punkt bekommt - das war die Frage, die wir uns ab dann gestellt haben.

3 Die Umsetzung

Zunächst einmal stellte sich die Frage, welche Punkte von Kameras besonders gut erkannt werden können. Nach ein wenig überlegen und den ersten (fruchtlosen) Versuchen erkannten wir, dass farbige Dioden am besten geeignet sind: Sie senden Licht in einer relativ konstanten Wellenlänge aus, die gute aus Bildern herausgefiltert werden kann. Dafür wandelt man das Bild aus dem ursprünglichen BGR-Farbraum in den HSV-Farbraum um. Der HSV-Farbraum bildet sich aus der Farbe, der Sättigung und der Helligkeit, es ist also leicht, nur Punkte mit bestimmten Werten in diesen drei Bereichen zu betrachten. Hier der Programmcode, der aus diesen Überlegungen sowie viel herumprobieren entstand. Dabei muss beachtet werden, dass für unterschiedliche Dioden und unterschiedliche Kameras unterschiedliche Ergebnisse für diese Werte erreicht werden!

Unsere Gruppe wollte sich zuerst mit dem Quadrocopter beschäftigen und dessen Gleichgewichtsstörungen beheben und danach gucken, was man noch alles implementieren könnte: z.B. eigenständig Routen abfliegen, an bestimmten Orten Aufnahmen mit einer Kamera machen oder auch ferngesteuert Fotos machen. Dafür wollten wir GPS und eine Kamera zur Kollisionserkennung benutzen.

Dann kam das Treffen mit Felix (Leiter des Robotiklabors). Der hat uns dann erstmal erklärt, dass der große Quadrocopter aufgrund seiner Größe nicht in zu kleinen Innenräumen fliegen darf, weil ihn aufgrund seiner Größe seine eigens verursachte Luftzirkulation selber behindert. Man kann ihn also in Innenräumen nicht ausprobieren. Draußen ist auch eher schlecht. Für Draußen-Flüge braucht man eine Genehmigung und generell ist das Gerät sehr wasseranfällig und sollte deshalb nach Möglichkeit nur sehr sehr wenig bis gar nicht mit ihm in Berührung kommen, was im Winter (sollte der irgendwann noch kommen) generell eher schwierig ist. Außerdem kann es bei Fehlprogrammierung durchaus vorkommen, dass der Quadrocopter ohne Möglichkeit, ihn aufzuhalten, davonfliegt und dabei sich oder anderen Schaden zufügt.

Also entfernten wir uns etwas von dem Gedanken mit diesem großen Quadrocopter uns zu beschäftigen und überlegten uns mehr mit kleineren Versionen zu arbeiten, da diese ohne große Probleme drinnen fliegen können. Damit hatten wir auch nicht mehr das Problem mit dem Gleichgewicht.

Wir hatten uns daraufhin auf das Ziel fokussiert das Fluggerät soweit zu programmieren, dass es sich eigenständig im (Innen)Raum bewegen kann und zwar ohne irgendwo gegen zu stoßen. Dafür muss es sowohl wissen, wie der Raum aussieht, als auch wo es sich selbst in diesem Raum befindet.

Seitdem haben wir uns des zweiten Teils dieses Problems angenommen: Die Ortung von sich selbst.

Unser erster Gedankenansatz lief über die Triangulation. D.h. wir haben mehrere festgesetzte Punkte, deren Standort klar ist und die messen den Abstand zu dem Fluggerät, woraus wir dessen genaue Position im Raum bestimmen können. Da wir zeitgleich das Plotten mit Python im Labor kennen gelernt haben, haben wir versucht unsere Idee zumindest im 2-dimensionalen-Raum darzustellen. Dabei hatten wir auch schon ein paar Probleme, da wir nicht genau wussten, wie die Funktion, welche wir aus dem Internet hatten funktioniert. Deshalb haben wir viel rumprobiert, bis uns Stefan eine bessere gegeben hat.

Am Ende bei rausgekommen ist folgende Funktion:

</code>

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.path as mpath
import matplotlib.lines as mlines
import matplotlib.patches as mpatches
 
 
W = { }
N = 5
 
qx = np.random.randint(30)
qy = np.random.randint(30)
W["Referenzpunkt X"] =  qx
W["Referenzpunkt Y"] =  qy
 
plt.figure()
ax=plt.subplot(111)
ax.set_xlim([0,30])
ax.set_ylim([0,30])
ax.add_patch(mpatches.Circle((qx, qy), radius=1,color="red",alpha=0.1))
 
for i in range(0,N):                             #scatterplot handles data nonlinear, its not legible for triangulation-use
 
	x = np.random.randint(30)
	y = np.random.randint(30)
	ankathete = float(x - qx)
	gegenkathete = float(y - qy)
	radius = np.sqrt((ankathete**2) + (gegenkathete**2))
	kreisumfang = 2*np.pi*radius
	area = np.pi * (radius)**2 
	W[i] =  x,y,radius,area
 
	ax.add_patch(mpatches.Circle((x,y),radius=radius,color='blue',alpha=0.1))
	#plt.scatter(x, y, s=area*190 , alpha=0.1)
 
plt.draw()
plt.show()
print W

<code>

Es wird etwas komisch angezeigt, aber wenn ihr auf bearbeiten klickt, könnt ihr, wenn ihr wollt, den Code gut rauskopieren und selbst ausprobieren.

Als wir das Grundkonzept hatten, mussten wir allerdings noch eine Möglichkeit finden das Grundkonzept technisch umzusetzen. Wir haben erst über Lichtsignale nachgedacht, haben dann ein wenig im Internet nach Möglichkeiten der Entfernungsmessung gesucht und sind dann auf WLAN und Bluetooth gestoßen. Bei Bluetooth haben wir auch gleich eine passende Mod mit Funktion gefunden und das ausprobiert

import bluetooth as bluetooth

print „performing inquiry…“

nearby_devices = bluetooth.discover_devices(lookup_names = True)

print „found %d devices“ % len(nearby_devices)

for addr, name in nearby_devices:

  print "  %s - %s" % (addr, name)

find_service(name=None, uuid=None, address=None)

Ähnliche Anzeigeprobleme: Deshalb bei Bedarf bitte wie oben. Allerdings müsst ihr vorher bluepy downloaden

Das haben wir dann mehrfach ausprobiert, aber es war deutlich zu ungenau für unsere Zwecke. Dann haben wir überlegt unsere eigene Funktion zu schreiben, durch die wir die Entfernung messen können über elektromagnetische Wellen. Diese bewegen sich aber viel zu schnell für einen Computer, um daraus vernünftige Ergebnisse raus zuziehen. Außerdem bräuchte man sehr starke Sender für die Distanz, sodass wir uns auch von dieser Idee verabschieden mussten.

Die letzte Idee war, über 2 oder mehr Kameras Dioden auf dem Quadrocopter zu erkennen und den Quadrocopter dadurch Koordinaten im von den Kameras überblickten Raum zuzuordnen. Dafür haben wir zunächst versucht, verschiedene Kameras so einzustellen, dass möglichst nur noch die Dioden auf den Bildern zu sehen waren. Dann haben wir die Bilder in den HSV-Farbraum umgewandelt, um das Bild so zu bearbeiten, dass Bildteile bestimmter Helligkeit, Farbe und Sättigung weiß und alle anderen Bildteile schwarz gefüllt werden. Dies gelang uns recht gut, einzig die Lichtbrechung an den Deckenlampen bewirkt teilweise eine Störung. Die jetzige Aufgabe ist es, die Kameras zu kalibrieren. Dafür wird mithilfe eines Schachbrettes bekannter Größe zunächst für die Kameras jeweils eine Kalibrierungsmatrix erstellt. Mit diesen Matrizen kann wird dann über die Funktion stereoCalibrate die Rotations- und Translationsmatrix und daher dann die Fundamental Matrix bestimmt.

Für alle, die, wie wir anfangs, keine Ahnung von den obigen Themen haben, hier ein kleiner Einstieg: Das Problem bei der Bestimung von Koordinaten im Raum durch Kamerabilder ist, dass die Bilder 2-dimensional, der Raum jedoch 3-dimensional ist. Alle Punkte auf dem Kamerabild entsprechen also einer Linie im Raum mit dem Ursprung in den Kamera. Gelöst werden kann das Problem durch verwenden mehrerer Kameras, die einen Punkt auch 3-dimensional erkennen können. Zunächst wird daher ein Koordinatensystem für eine Kamera aufgebaut, bestehend aus einer Kalibrierungsmatrix, die kameraspezifisch ist, und einer um eine Nullspalte erweiterte Einheitsmatrix. Dann wird ein an die erste Kamera angepasstes Koordinatensystem für die zweite Kamera aufgebaut. Dieses Koordinatensystem besteht ebenfalls aus einer Kalibrierungsmatrix, multipliziert mit einer Rotationsmatrix erweitert um eine einspaltige Translationsmatrix. Dafür muss zunächst die Drehung und der Abstand der einen Kamera zu der anderen bestimmt werden. Dafür werden die Rotations- und die Translationsmatrix benötigt. Diese werden durch Kalibrierung bestimmt, wobei die Kameras danach für den Versuch nicht mehr verschoben werden dürfen. Sie müssen also jedes mal kalibriert werden! In diesem Koordinatensystem wird jedem Punkt auf der Bildebene einer Kamera eine Linie auf der Bildebene der anderen Kamera zugeordnet. Dies kann für mehrere Punkte gemacht werden. Jede der entstehenden Linien trifft sich in einem Punkt, dem Epipolar. Dieser Punkt entspricht den Punkten auf der Bildebene der anderen ersten Kamera. Mit diesen einander zugeordneten Punkten kann man dann den 3-dimensionalen Punkt berechnen.

Quelle: http://pille.iwr.uni-heidelberg.de/~kinect01/img/pinhole-camera.png (23.01.2014; 17:25 Uhr)

Die vorher bestimmten Matrizen werden nun mit Hilfe der Funktion stereoRectify umgeformt, um sie in der Funktion triangulatePoints endlich so zu nutzen, dass 3D-Punkte bestimmt werden können.

Soweit zur Berechnung der 3d-Punkte. Nach diesem Problem mussten wir uns wieder dem Problem der Punkterkennung widmen: Aus einem Kamerabild nötige Punkte herauszufiltern, die man in die Funktion triangulatePoints einsetzen kann.

Robotik

ws1314/dokumentation.1392306703.txt.gz · Zuletzt geändert: 2016/05/10 14:46 (Externe Bearbeitung)