Hier werden die Unterschiede zwischen zwei Versionen gezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
ws1314:dokumentation [2014/03/03 11:56] maximilian.obst |
ws1314:dokumentation [2016/05/10 14:46] (aktuell) |
||
---|---|---|---|
Zeile 27: | Zeile 27: | ||
== 2.2 Erste Planänderung: Funkwellen == | == 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: | + | 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 - BlueProximity - 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: |
<code python> | <code python> | ||
Zeile 72: | Zeile 72: | ||
</code> | </code> | ||
- | Bald darauf erkannten wir jedoch, dass die Entfernungsmessung viel zu ungenau funktionierte - und daher nicht in Frage kam. Also war auch diese Idee gescheitert. | + | Bald darauf erkannten wir jedoch, dass die Entfernungsmessung viel zu ungenau funktionierte - und daher nicht in Frage kam. Die Funkwellen waren zu schnell, al dass der Computer sie hätte auswerten können. Also war auch diese Idee gescheitert. |
== 2.3 Der endgültige Plan == | == 2.3 Der endgültige Plan == | ||
Zeile 490: | Zeile 490: | ||
</code> | </code> | ||
- | Nun besteht noch die Möglichkeit, die Bilder zu normen, indem man alle geraden Linien aneinander angleicht. Soll heißen: Die Bilder werden so gedreht, dass | + | Nun besteht noch die Möglichkeit, die Bilder zu normen, indem man alle geraden Linien aneinander angleicht. Soll heißen: Die Bilder werden so gedreht, dass alle Linien in beiden Bildern die gleiche Ausrichtung haben. Dies ist zur Berechnung von dreidimensionalen Bildern wichtig, für einzelne Punkte jedoch nicht weiter von Bedeutung, daher wird es hier weggelassen. |
+ | Nun war es soweit, dass das Blockseminar angefangen hatte, die Vorlesungsfreie Zeit hatte also begonnen. Damit wir in der restlichen Zeit ein vorzeigbares Programm erstellen konnten, wurde uns ein schon weiter fortgeschrittenes Programm übergeben: Das Erkennen der Punkte durch eine Kamera im zweidimensionalen funktionierte. Auch bekamen wir bessere Dioden gestellt, deren Helligkeit gleichmäßiger und stärker war. | ||
+ | Um nun bis zum Ende etwas Vorzeigbares zu erstellen, einigten wir uns in der Gruppe darauf, keinen Versuch der Lenkung eines Quadrocopters mehr zu starten, sondern uns darauf zu beschränken, ein mit Dioden bestücktes Objekt im Raum zu verfolgen und aus den gewonnenen Daten die Geschwindigkeit des Objektes zu berechnen. | ||
+ | Hier der Quellcode von Stefan, der zur Erkennung der 2D-Punkte benötigt wird: | ||
+ | <code python> | ||
+ | #!/usr/bin/env python | ||
+ | # -*- coding: utf-8 -*- | ||
+ | # | ||
+ | # finde_punkte.py | ||
+ | # | ||
+ | # Copyright 2014 Stefan Born <born@math.tu-berlin.de> | ||
+ | # | ||
+ | # This program is free software; you can redistribute it and/or modify | ||
+ | # it under the terms of the GNU General Public License as published by | ||
+ | # the Free Software Foundation; either version 2 of the License, or | ||
+ | # (at your option) any later version. | ||
+ | # | ||
+ | # This program is distributed in the hope that it will be useful, | ||
+ | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
+ | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
+ | # GNU General Public License for more details. | ||
+ | # | ||
+ | # You should have received a copy of the GNU General Public License | ||
+ | # along with this program; if not, write to the Free Software | ||
+ | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
+ | # MA 02110-1301, USA. | ||
+ | # | ||
+ | # | ||
- | Nun stehen noch arbeiten zur genauen Einstellung der Kameras an, damit die Leuchtdioden auf den Bildern gefunden werden. Auch die Bestimmung, welcher Abstand der Dioden welche Entfernung von den Kameras verrät, folgt noch. Wir sind momentan zuversichtlich, dass wir es schaffen, bis zur Vorstellung der Projekte die Bestimmung im Raum zu erreichen. Das ist allerdings aufgrund verschiedenster Rückschläge am Anfang und nicht funktionierender Programme mittendrin auch schon das Maximum, was wir vermutlich erreichen werden... | + | import numpy as np |
+ | import cv2 | ||
+ | from ps3camera import * | ||
- | === 4 Fazit === | + | #wichtigste methode, findet in einem hsvbild farbbereiche, die einem bestimmten kriterium unterliegen |
+ | def finde_zentrum_farbbereich(hsvbild,HSV1,HSV2): | ||
+ | '''Erwartet ein HSV-Bild, gibt den Schwerpunkt des größten | ||
+ | Flecks im Farbbereich zwischen HSV1 und HSV2 zurück''' | ||
+ | hsv1=np.array(HSV1,dtype=np.uint8) | ||
+ | hsv2=np.array(HSV2,dtype=np.uint8) | ||
+ | thresh = cv2.inRange(hsvbild, hsv1,hsv2) | ||
+ | threshc = thresh.copy() # Beim Bestimmen der Kontouren wird 'thresh' verändert, deswegen eine Kopie | ||
+ | |||
+ | # Kontouren im Schwellenwertbild | ||
+ | contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE) | ||
+ | |||
+ | |||
+ | # Finde Kontour mit maximaler Fläche | ||
+ | max_area = -1 | ||
+ | for cnt in contours: | ||
+ | area = cv2.contourArea(cnt) | ||
+ | if area > max_area: | ||
+ | max_area = area | ||
+ | best_cnt = cnt | ||
+ | |||
+ | if contours and max_area>1: | ||
+ | # Finde Schwerpunkt (mit Hilfe der 'Momente') | ||
+ | M = cv2.moments(best_cnt) | ||
+ | cx,cy = int(M['m10']/M['m00']), int(M['m01']/M['m00']) | ||
+ | ort=np.array([cx,cy]) | ||
+ | return True, threshc, ort | ||
+ | else: | ||
+ | return False,threshc,None | ||
- | An dieser Stelle kann natürlich nur ein Zwischenfazit erfolgen, der Rest kommt noch ;) | + | # Folgende Funktionen entsprechen vier Leuchtdioden, verwendet 02/14 |
+ | # Conrad 184433 184447 194460 184473 | ||
+ | |||
+ | #abwandlung von finde zentrum für die vier farben | ||
+ | def finde_zentrum_rot(hsvbild): | ||
+ | return finde_zentrum_farbbereich(hsvbild,(5,70,100),(12,255,255)) | ||
+ | |||
+ | def finde_zentrum_blau(hsvbild): | ||
+ | return finde_zentrum_farbbereich(hsvbild,(90,100,70),(120,255,255)) | ||
+ | |||
+ | def finde_zentrum_gruen(hsvbild): | ||
+ | return finde_zentrum_farbbereich(hsvbild,(55,70,70),(65,255,255)) | ||
+ | |||
+ | def finde_zentrum_orange(hsvbild): | ||
+ | return finde_zentrum_farbbereich(hsvbild,(15,70,70),(25,255,255)) | ||
+ | |||
+ | def main(): | ||
+ | '''Testet die Farbbunktermittlung durch Schwellenwert''' | ||
+ | KAMERA_NR=1 | ||
+ | capture=initialize_camera_cv(KAMERA_NR) | ||
+ | sleep(2) | ||
+ | set_camera_properties_dark(KAMERA_NR) | ||
+ | _,frame = capture.read() | ||
+ | frame2=np.zeros_like(frame) | ||
+ | |||
+ | rotgefunden=False # Diese Variablen werden True, sobald der erste Punkt gefunden | ||
+ | blaugefunden=False | ||
+ | gruengefunden=False | ||
+ | orangegefunden=False | ||
+ | |||
+ | while(1): | ||
+ | #print "Hund" | ||
+ | # read the frames | ||
+ | |||
+ | _,frame = capture.read() | ||
+ | |||
+ | frame = cv2.blur(frame,(3,3)) | ||
+ | |||
+ | #convert to hsv and find range of colors | ||
+ | |||
+ | hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV) | ||
+ | |||
+ | resrot, threshrot, ortrot = finde_zentrum_rot(hsv) | ||
+ | resblau, threshblau, ortblau= finde_zentrum_blau(hsv) | ||
+ | resorange,threshorange,ortorange=finde_zentrum_orange(hsv) | ||
+ | resgruen,threshgruen, ortgruen=finde_zentrum_gruen(hsv) | ||
+ | |||
+ | if resrot: | ||
+ | cv2.circle(frame,(ortrot[0],ortrot[1]),6,(0,0,0)) | ||
+ | cv2.circle(frame,(ortrot[0],ortrot[1]),5,(0,0,255),-1) | ||
+ | cv2.circle(frame2,(ortrot[0],ortrot[1]),2,(0,0,255),-1) | ||
+ | if rotgefunden: | ||
+ | cv2.line(frame2,(ortrot[0],ortrot[1]),(ortrotalt[0],ortrotalt[1]),(0,0,255),2) | ||
+ | rotgefunden=True | ||
+ | ortrotalt=ortrot.copy() | ||
+ | if resblau: | ||
+ | cv2.circle(frame,(ortblau[0],ortblau[1]),6,(0,0,0)) | ||
+ | cv2.circle(frame,(ortblau[0],ortblau[1]),5,(255,0,0),-1) | ||
+ | cv2.circle(frame2,(ortblau[0],ortblau[1]),2,(255,0,0),-1) | ||
+ | if blaugefunden: | ||
+ | cv2.line(frame2,(ortblau[0],ortblau[1]),(ortblaualt[0],ortblaualt[1]),(255,0,0),2) | ||
+ | |||
+ | blaugefunden=True | ||
+ | ortblaualt=ortblau.copy() | ||
+ | if resgruen: | ||
+ | cv2.circle(frame,(ortgruen[0],ortgruen[1]),6,(0,0,0)) | ||
+ | cv2.circle(frame,(ortgruen[0],ortgruen[1]),5,(0,255,0),-1) | ||
+ | cv2.circle(frame2,(ortgruen[0],ortgruen[1]),2,(0,255,0),-1) | ||
+ | if gruengefunden: | ||
+ | cv2.line(frame2,(ortgruen[0],ortgruen[1]),(ortgruenalt[0],ortgruenalt[1]),(0,255,0),2) | ||
+ | |||
+ | gruengefunden=True | ||
+ | ortgruenalt=ortgruen.copy() | ||
+ | |||
+ | if resorange: | ||
+ | cv2.circle(frame,(ortorange[0],ortorange[1]),6,(0,0,0)) | ||
+ | cv2.circle(frame,(ortorange[0],ortorange[1]),5,(0,255,255),-1) | ||
+ | cv2.circle(frame2,(ortorange[0],ortorange[1]),2,(0,255,255),-1) | ||
+ | if orangegefunden: | ||
+ | cv2.line(frame2,(ortorange[0],ortorange[1]),(ortorangealt[0],ortorangealt[1]),(0,255,255),2) | ||
+ | |||
+ | orangegefunden=True | ||
+ | ortorangealt=ortorange.copy() | ||
+ | |||
+ | # Show it, if key pressed is 'Esc', exit the loop | ||
+ | cv2.imshow('Bild',frame) | ||
+ | cv2.imshow('Rotanteil',threshrot) | ||
+ | cv2.imshow('Blauanteil', threshblau) | ||
+ | cv2.imshow('Spuren', frame2) | ||
+ | if cv2.waitKey(20)== 27: | ||
+ | ende=True | ||
+ | break | ||
+ | |||
+ | #pass | ||
+ | |||
+ | return 0 | ||
+ | |||
+ | if __name__ == '__main__': | ||
+ | |||
+ | main() | ||
+ | |||
+ | </code> | ||
+ | |||
+ | Mit dieser neuen Idee der Geschwindigkeitsberechnungvor Augen machten wir uns an die Arbeit. Zunächst programmierten wir die Erstellung der 3D-Koordinaten aus den 2D-Punkten. Ausnahmsweise verwendeten wir hierfür nicht die Python-Funktion (triangulate_Points), sondern schrieben unsere eigene. Zusätzlich plottet die Funktion die Bahn der Dioden im Raum, sodass ein 3D-Bild der Bewegung der Dioden ensteht. Hier der Quellcode: | ||
+ | <code python> | ||
+ | #!/usr/bin/env python | ||
+ | # -*- coding: utf-8 -*- | ||
+ | from __future__ import division | ||
+ | |||
+ | import cv | ||
+ | import pickle | ||
+ | import cv2 | ||
+ | import numpy as np | ||
+ | import finde_punkte | ||
+ | |||
+ | |||
+ | from visual import * | ||
+ | from scipy import linalg | ||
+ | from thread import start_new_thread | ||
+ | from ps3camera import * | ||
+ | |||
+ | def lies_kamera(): | ||
+ | ''' Endloschleife um Kamera auslesen; | ||
+ | das zuletzt gelesene Bild befindet sich in der globalen Variable bild_aktuell''' | ||
+ | global bild1_aktuell | ||
+ | global bild2_aktuell | ||
+ | n=0 | ||
+ | while not STOP_FLAG: | ||
+ | n+=1 | ||
+ | #print "Frame " ,n | ||
+ | |||
+ | # Ein Bild auslesen | ||
+ | res,bild=capture1.read() | ||
+ | bild1_aktuell=bild.copy() | ||
+ | res,bild=capture2.read() | ||
+ | bild2_aktuell=bild.copy() | ||
+ | |||
+ | #berechnet aus zwei gegebenen Punkten einen 3D-Punkt | ||
+ | def berechne_3d_Punkte (a,b): | ||
+ | |||
+ | #Lädt die gespeicherten Matrizen aus den Kalibrierungsprogrammen | ||
+ | K1=file("Kameramatrix1","r") | ||
+ | p=pickle.Unpickler(K1) | ||
+ | camera_matrix1=p.load() | ||
+ | K1.close() | ||
+ | |||
+ | K2=file("Kameramatrix2","r") | ||
+ | p=pickle.Unpickler(K2) | ||
+ | camera_matrix2=p.load() | ||
+ | K2.close() | ||
+ | |||
+ | Rot=file("Rotationsmatrix","r") | ||
+ | p=pickle.Unpickler(Rot) | ||
+ | R=p.load() | ||
+ | Rot.close() | ||
+ | |||
+ | Trans=file("Translationsmatrix","r") | ||
+ | p=pickle.Unpickler(Trans) | ||
+ | T=p.load() | ||
+ | Trans.close() | ||
+ | |||
+ | bild_matrix1=np.append(camera_matrix1,np.array([[0],[0],[0]]), axis=1) | ||
+ | bild_matrix2=np.dot(camera_matrix2,np.append(R,T,axis=1)) | ||
+ | |||
+ | if a != None and b != None : | ||
+ | |||
+ | a=a*(-1) | ||
+ | b=b*(-1) | ||
+ | |||
+ | #erstellt die Matrix M aus K1,K2 und den beiden gegebenen Punkten | ||
+ | M1=np.concatenate((bild_matrix1,bild_matrix2), axis=0) | ||
+ | M2=np.concatenate((M1,np.append(a,np.array([[0],[0],[0]]), axis=0)), axis=1) | ||
+ | M=np.concatenate((M2,np.append(np.array([[0],[0],[0]]),b, axis=0)), axis=1) | ||
+ | U, D, V=linalg.svd(M) | ||
+ | L=V[5,0:4] | ||
+ | x=L[0] | ||
+ | y=L[1] | ||
+ | z=L[2] | ||
+ | f=L[3] | ||
+ | x=x/float(f) | ||
+ | y=y/float(f) | ||
+ | z=z/float(f) | ||
+ | |||
+ | return{'X':x,'Y':y,'Z':z} | ||
+ | return None | ||
+ | |||
+ | #sucht die Dioden in der ersten Kamera | ||
+ | def CamOneDots(): | ||
+ | |||
+ | frame=bild1_aktuell.copy() | ||
+ | |||
+ | frame = cv2.blur(frame,(3,3)) | ||
+ | #rgb zu hsv umwandlung | ||
+ | hsvbild = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV) | ||
+ | |||
+ | #transformation der ersten kamerapunkte | ||
+ | resrot,threshrot,rot1 = finde_punkte.finde_zentrum_rot(hsvbild) | ||
+ | resblau,threshblau,blau1 = finde_punkte.finde_zentrum_blau(hsvbild) | ||
+ | resgruen,threshgruen,gruen1 = finde_punkte.finde_zentrum_gruen(hsvbild) | ||
+ | resorange,threshorange,orange1 = finde_punkte.finde_zentrum_orange(hsvbild) | ||
+ | |||
+ | #erstellt die 3x1 Matrix für alle Punkte | ||
+ | if resrot: | ||
+ | rot1 = rot1.reshape((2,1)) | ||
+ | rot1=np.concatenate((rot1,np.array([[1]])), axis=0) | ||
+ | if resblau: | ||
+ | blau1 =blau1.reshape((2,1)) | ||
+ | blau1=np.concatenate((blau1,np.array([[1]])), axis=0) | ||
+ | if resgruen: | ||
+ | gruen1 =gruen1.reshape((2,1)) | ||
+ | gruen1=np.concatenate((gruen1,np.array([[1]])), axis=0) | ||
+ | if resorange: | ||
+ | orange1 =orange1.reshape((2,1)) | ||
+ | orange1=np.concatenate((orange1,np.array([[1]])), axis=0) | ||
+ | |||
+ | return{'rot':rot1,'blau':blau1,'gruen':gruen1,'orange':orange1} | ||
+ | |||
+ | #sucht die Dioden in Kamera 2 | ||
+ | def CamTwoDots(): | ||
+ | |||
+ | frame=bild2_aktuell.copy() | ||
+ | |||
+ | frame = cv2.blur(frame,(3,3)) | ||
+ | hsvbild = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV) | ||
+ | |||
+ | #transformation der zweiten kamerapunkte | ||
+ | resrot,threshrot,rot2 = finde_punkte.finde_zentrum_rot(hsvbild) | ||
+ | resblau,threshblau,blau2 = finde_punkte.finde_zentrum_blau(hsvbild) | ||
+ | resgruen,threshgruen,gruen2 = finde_punkte.finde_zentrum_gruen(hsvbild) | ||
+ | resorange,threshorange,orange2 = finde_punkte.finde_zentrum_orange(hsvbild) | ||
+ | |||
+ | #Umwandlung in 3x1 Matrix | ||
+ | if resrot: | ||
+ | rot2=rot2.reshape((2,1)) | ||
+ | rot2=np.concatenate((rot2,np.array([[1]])), axis=0) | ||
+ | if resblau: | ||
+ | blau2=blau2.reshape((2,1)) | ||
+ | blau2=np.concatenate((blau2,np.array([[1]])), axis=0) | ||
+ | if resgruen: | ||
+ | gruen2=gruen2.reshape((2,1)) | ||
+ | gruen2=np.concatenate((gruen2,np.array([[1]])), axis=0) | ||
+ | if resorange: | ||
+ | orange2=orange2.reshape((2,1)) | ||
+ | orange2=np.concatenate((orange2,np.array([[1]])), axis=0) | ||
+ | |||
+ | return{'rot':rot2,'blau':blau2,'gruen':gruen2,'orange':orange2} | ||
+ | |||
+ | #funktion,die die vektorenlänge zwischen zwei 3D-Punkten berechnet | ||
+ | def vektorcalc(alt,neu): | ||
+ | altX = alt['X'] | ||
+ | altY = alt['Y'] | ||
+ | altZ = alt['Z'] | ||
+ | |||
+ | neuX = neu['X'] | ||
+ | neuY = neu['Y'] | ||
+ | neuZ = neu['Z'] | ||
+ | |||
+ | vektorX = neuX - altX | ||
+ | vektorY = neuY - altY | ||
+ | vektorZ = neuZ - altZ | ||
+ | |||
+ | vektorlen = sqrt((vektorX**2) + (vektorY**2) + (vektorZ**2)) | ||
+ | return vektorlen | ||
+ | |||
+ | #init von kamera 1 und 2 durch ps3camera | ||
+ | KAMERA_NR1=1 | ||
+ | capture1=initialize_camera_cv(KAMERA_NR1) | ||
+ | sleep(2) | ||
+ | set_camera_properties_dark(KAMERA_NR1) | ||
+ | |||
+ | KAMERA_NR2=2 | ||
+ | capture2=initialize_camera_cv(KAMERA_NR2) | ||
+ | sleep(2) | ||
+ | set_camera_properties_dark(KAMERA_NR2) | ||
+ | |||
+ | sleep(1) | ||
+ | STOP_FLAG=False | ||
+ | |||
+ | start_new_thread(lies_kamera,()) | ||
+ | sleep(4) | ||
+ | |||
+ | #starten der trails für alle dioden | ||
+ | rottrail = curve(color=color.red) | ||
+ | blautrail = curve(color=color.blue) | ||
+ | gruentrail = curve(color=color.green) | ||
+ | orangetrail = curve(color=color.yellow) | ||
+ | |||
+ | rotalt = {'X':0,'Y':0,'Z':0} | ||
+ | blaualt = {'X':0,'Y':0,'Z':0} | ||
+ | gruenalt = {'X':0,'Y':0,'Z':0} | ||
+ | orangealt = {'X':0,'Y':0,'Z':0} | ||
+ | |||
+ | #hauptmethode | ||
+ | while True: | ||
+ | X1 = CamOneDots() | ||
+ | X2 = CamTwoDots() | ||
+ | |||
+ | #3D-Punkt berechnung | ||
+ | rot3d = berechne_3d_Punkte(X1['rot'],X2['rot']) | ||
+ | if rot3d != None: | ||
+ | #rotvektor | ||
+ | if vektorcalc(rotalt,rot3d) < 20: | ||
+ | #diorot = sphere(pos=(rot3d["X"],rot3d["Y"],rot3d["Z"]),radius= 2,color=color.red) ausweichcode | ||
+ | rottrail.append(pos=(rot3d["X"],rot3d["Y"],rot3d["Z"])) | ||
+ | rotalt = rot3d | ||
+ | |||
+ | blau3d = berechne_3d_Punkte(X1['blau'],X2['blau']) | ||
+ | if blau3d != None: | ||
+ | #blauvektor | ||
+ | if vektorcalc(blaualt,blau3d) < 20: | ||
+ | #dioblau = sphere(pos=(blau3d["X"],blau3d["Y"],blau3d["Z"]),radius= 2,color=color.blue) ausweichcode | ||
+ | blautrail.append(pos=(blau3d["X"],blau3d["Y"],blau3d["Z"])) | ||
+ | blaualt = blau3d | ||
+ | |||
+ | gruen3d = berechne_3d_Punkte(X1['gruen'],X2['gruen']) | ||
+ | if gruen3d != None: | ||
+ | #gruenvektor | ||
+ | if vektorcalc(gruenalt,gruen3d) < 20: | ||
+ | #diogruen = sphere(pos=(gruen3d["X"],gruen3d["Y"],gruen3d["Z"]),radius= 2,color=color.green) ausweichcode | ||
+ | gruentrail.append(pos=(gruen3d["X"],gruen3d["Y"],gruen3d["Z"])) | ||
+ | gruenalt = gruen3d | ||
+ | |||
+ | orange3d = berechne_3d_Punkte(X1['orange'],X2['orange']) | ||
+ | if orange3d != None: | ||
+ | #orangevektor | ||
+ | if vektorcalc(orangealt,orange3d) < 20: | ||
+ | #dioorange = sphere(pos=(orange3d["X"],orange3d["Y"],orange3d["Z"]),radius= 2,color=color.yellow) ausweichcode | ||
+ | orangetrail.append(pos=(orange3d["X"],orange3d["Y"],orange3d["Z"])) | ||
+ | orangealt = orange3d | ||
+ | |||
+ | #abbruchkey q für visual-python | ||
+ | if scene.kb.keys: | ||
+ | ch=scene.kb.getkey() | ||
+ | if ch == "q": | ||
+ | break | ||
+ | STOP_FLAG = True | ||
+ | |||
+ | </code> | ||
+ | |||
+ | Nun wäre als letzter Punkt die Geschwindigkeitsbestimmung gekommen. Auch die Bewegung von Robotern, also Quadrocoptern oder anderen beweglichen Objekten, wäre mit dieser Grundlage möglich, da nun deren Position im Raum bekannt ist. Wegen Zeitmangel und dadurch, dass das Programm nicht sehr performant ist, haben wir aber an dieser Stelle abgebrochen. Die Bewegung war viel zu aufwendig, um sie in der verbliebenen Zeit zu schaffen und die Geschwindigkeitsbestimmung wurde durch die Langsamkeit des Programms unmöglich. | ||
+ | |||
+ | === 4 Fazit === | ||
- | Bisher ist wohl leider vor allem ein Fazit zu ziehen: Auch wenn etwas am Anfang sehr leicht zu programmieren aussieht: Es kann verdammt schwierig sein und noch viel länger dauern! Mit viel Frusttoleranz ist man in jedem Fall gut beraten. Wenn aber dann doch mal etwas funktioniert, macht es auch viel Freude, dass man bis dahin gekommen ist. | + | Es ist wohl vor allem ein Fazit zu ziehen: Auch wenn etwas am Anfang sehr leicht zu programmieren aussieht: Es kann verdammt schwierig sein und noch viel länger dauern! Mit viel Frusttoleranz ist man in jedem Fall gut beraten. Wenn aber dann doch mal etwas funktioniert, macht es auch viel Freude, dass man bis dorthin gekommen ist. |
Des Weiteren bringt dieses Projekt natürlich ein vergrößertes Verständnis der Verarbeitung von 3D-Bildern in der Informatik mit sich. Wenn man sich durch die vielen, häufig sehr komplizierten Erklärungen hindurchkämpft, kann man am Ende auf eine doch erstaunliche Ansammlung von Wissen zurückblicken. Selbst, wenn wir es später nicht mehr brauchen sollten: Es war ein sehr interessantes Projekt über ein Thema, was man häufig für selbstverständlich nimmt (und daher unterschätzt) und mit dem man sich ohne dieses Labor vermutlich nie so intensiv beschäftigt hätte. Danke dafür! | Des Weiteren bringt dieses Projekt natürlich ein vergrößertes Verständnis der Verarbeitung von 3D-Bildern in der Informatik mit sich. Wenn man sich durch die vielen, häufig sehr komplizierten Erklärungen hindurchkämpft, kann man am Ende auf eine doch erstaunliche Ansammlung von Wissen zurückblicken. Selbst, wenn wir es später nicht mehr brauchen sollten: Es war ein sehr interessantes Projekt über ein Thema, was man häufig für selbstverständlich nimmt (und daher unterschätzt) und mit dem man sich ohne dieses Labor vermutlich nie so intensiv beschäftigt hätte. Danke dafür! | ||
+ | Leider mussten wir unsere Erwartungen und Ziele immer weiter herabsetzen, weil das Anfangsprojekt einfach zu umfangreich war. Aber auch hierraus kann man sicher etwas lernen: Nämlich, dass man Ziele eben manchmal auch nicht erreichen kann und Abstriche machen muss. | ||
Die Gruppe Robotik im Labor Mathesis | Die Gruppe Robotik im Labor Mathesis |