Zur Entwicklung von Algorithmen ist es oftmals nicht unbedingt von Vorteil mit realen Messwerten zu arbeiten. Zum einen gibt es eine Vielzahl von Einflüssen, die eventuell den Ausgang des Algorithmus‘ beeinflussen, andererseits ist es schwer ein „Soll“ für das Verhalten zu definieren, wenn die Eingangsmesswerte mit Störungen behaftet sind.
Zwar kann man jede Umfeldbedingung auch mit Video festhalten, aber damit kann nur ein visueller Eindruck der aufgenommenen Situation gewonnen werden. Ob ein Laserstrahl korrekt ein Objekt getroffen hat, ob er reflektiert oder geschluckt wurde, ob er durch die Scheibe hindurch drang oder abgelenkt wurde, all das ist in jeder realen Szene mehr oder weniger stochastisch.
Synthetische Daten, welche tatsächlich ein immer wieder definiertes Soll vorgeben, können mit dem Zusatzplugin BlenSor für die 3D Authoring OpenSource Software Blender generiert werden.
Mehr zu BlenSor kann
Gschwandtner, M., Kwitt, R., Uhl, A., & Pree, W. (2011). BlenSor: blender sensor simulation toolbox. Advances in Visual Computing, 6939(Isvc), 199–208. Retrieved from http://www.rkwitt.org/files/Gschwandtner11b.pdf
entnommen werden.
3D Szene erstellen mit BlenSor
Die Software Blender, welche über eine große, aktive Community verfügt, macht es möglich eine beliebige 3D Szene zu erstellen. Hier sind wirklich nur durch eigene Fähigkeiten und Kreativität Grenzen gesetzt. [Beispiel]
Zusatz BlenSor ermöglicht Laserumfeldsensorik
Der von Michael Gschwandtner entwickelte Zusatz BlenSor ermöglicht nun das Einfügen von Umfeldsensoren. Beispielhaft erstellt sind
- ibeo Lux
- Velodyne HDL 64-E
- Kinect
- Time of Flight Camera
jeweils mit ihren zugehörigen physikalischen Eigenheiten (Standardabweichung, Auflösung für Winkel und Entfernungsmessung usw.)
Beispielszene
Beispielhaft wurde folgende Szene erstellt und gerendert:
Nun kann der ibeo Laserscanner in beliebiger Ausrichtung und mit beliebiger Trajektorie durch diese Szene „fahren“ und Messwerte aufzeichnen. Diese lassen sich anschließend in Textformat (.pcd – Point Cloud Library Format) exportieren und entsprechend weiterverarbeiten.
Beispielhaft kann die exportierte „Motion.pcd“ sowie die „scanxxxxx.pcd“, welche jeweils die Messpunkte jedes einzelnen Scans beinhaltet, in das Dateiformat umgespeichert werden, welches Octomap bzw. Octovis benötigt. Das Python Script ist am Ende dieses Beitrags zu finden.
Von BlenSor zu OctoVis
httpvh://www.youtube.com/watch?v=VSJb5oGl9jE
Die mit BlenSor generierten Messwerte können nun entsprechend weiterverarbeitet werden. Beispielhaft können diese in Octovis eingelesen und dort als Occupancy Grid dargestellt werden.
Pointcloud
Occupancy Grid
Python Script zur Konvertierung von BlenSor .pcd zu Octovis Add NODE Format
[python]
# -*- coding: utf-8 -*-
# <nbformat>3.0</nbformat>
# <codecell>
import csv
import numpy as np
import math
# <codecell>
def readscanpcd(filename):
x=[]
y=[]
z=[]
with open(filename, ‚rb‘) as f:
reader = csv.reader(f, delimiter=‘ ‚)
try:
# skip headerlines
for i in range(11):
reader.next()
# get values for scanner endpoints
for row in reader:
x.append(float(row[0]))
y.append(float(row[1]))
z.append(float(row[2]))
except csv.Error as e:
sys.exit(‚file %s, line %d: %s‘ % (filename, reader.line_num, e))
return x, y, z
# <codecell>
def readmotionpcd(filename):
timestamp=[]
xnode=[]
ynode=[]
znode=[]
pitch=[]
roll=[]
yaw=[]
v=[]
with open(filename, ‚rb‘) as f:
reader = csv.reader(f, delimiter=‘ ‚)
try:
xnodetemp= -10.0
timestamptemp=0.0
# get values for scanner position and direction
for row in reader:
timestamp.append(float(row[1]))
xnode.append(float(row[5]))
ynode.append(float(row[7]))
znode.append(float(row[9]))
roll.append(float(row[11]))
pitch.append(float(row[13]))
yaw.append(float(row[15]))
# Geschwindigkeitsberechnung
v.append(3.6*(float(row[5])-xnodetemp)/(float(row[1])-timestamptemp))
xnodetemp = float(row[5])
timestamptemp = float(row[1])
except csv.Error as e:
sys.exit(‚file %s, line %d: %s‘ % (filename, reader.line_num, e))
return timestamp, xnode, ynode, znode, pitch, roll, yaw, v
# <codecell>
[timestamp, xnode, ynode, znode, pitch, roll, yaw, v] = readmotionpcd(‚motion.pcd‘)
# <codecell>
# octomap file leeren
ofile = ‚octomap.txt‘
f = open(ofile, "w")
f.truncate()
f.close()
tstart = float(timestamp[0])
# für alle Timestamps auch Messungen suchen
for scan in range(len(timestamp)):
try:
# scan Datei öffnen
filename = ’scan%05d.pcd‘ % (scan+1)
# Laserendpunkte heraus holen (im lokalen Laser KOS)
[x, y, z] = readscanpcd(filename)
print ‚Verarbeite \“ + filename + ‚\“
# wenn keine Messung mehr dazu vorhanden
except Exception, e:
break
tend = float(timestamp[scan])
with open(ofile, ‚ab‘) as csvfile: #ab means append & binary
ow = csv.writer(csvfile, delimiter=‘ ‚)
nodeheader = [‚NODE‘] + \
[‚%2.3f‘ % xnode[scan]] + \
[‚%2.3f‘ % ynode[scan]] + \
[‚%2.3f‘ % znode[scan]] + \
[‚%3.3f‘ % roll[scan]] + \
[‚%3.3f‘ % pitch[scan]] + \
[‚%3.3f‘ % yaw[scan]]
ow.writerow(nodeheader)
ow.writerow([‚#v=‘] + [‚%2.1f‘ % v[scan]] + [‚km/h‘])
for point in range(len(x)):
ow.writerow([‚%3.3f‘ % x[point], \
‚%3.3f‘ % y[point], \
‚%3.3f‘ % z[point]])
# <codecell>
print str(tend-tstart) + ’s Messung (‚ + str(scan) + ‚ scans) in \“ + ofile + ‚\‘ geschrieben.‘
[/python]