Microsofts Kinect-Sensor hat das Konzept der Distanzmessung wieder populär bzw. für populärwissenschaftliche Anwendungen interessant gemacht. Eine paradoxe Ironie an der Situation ist, dass der Kinect nicht die – insbesondere im militärischen Bereich – seit Jahren verwendete LIDAR-Technologie verwendet, sondern stattdessen mit der Verformung von Infrarotstrahlen arbeitet.

Wohl ob des durch Microsofts immenses Marketing geweckten Interesse wurde in China im Jahr 2015 das Unternehmen YDLidar gegründet, dass die Entwicklung von Lidar-Sensoren „für den Massenmarkt“ zum Ziel hatte.

Zum Zeitpunkt der Drucklegung sind derartige Systeme mit 360°-Coverage ab rund 330 € zu haben. Exemplarisch dafür wird der Autor in den folgenden Schritten ein Lidar vom Typ TG15 in Betrieb nehmen, das im Elektor-Store erhältlich ist (Bild 1).

Bild 1. Das LIDAR ist für etwa 350 Euro erhältlich - vor einigen Jahren hätte man hier zwei Nullen ankleben müssen.

YDLidar zeigt sich im Bereich der Arbeitsumgebungen agnostisch: Neben Windows 7 und Windows 10 unterstützt man auch Ubuntu. Im Interesse der Bequemlichkeit arbeitet der Autor in den folgenden Schritten wie gewohnt mit seiner unter Ubuntu 18.04 laufenden Workstation. Im ersten Schritt müssen Sie das Vorhandensein einiger Pakete überprüfen, die für die Kompilation erforderlich sind:

sudo apt install cmake pkg-config
sudo apt-get install python swig
sudo apt-get install python-pip

Wundern Sie sich nicht, wenn ein Gutteil dieser Pakete schon auf Ihrem Rechner ist – wer mit Python arbeitet und hie und da C-Programme kompiliert, hat die meisten der Produkte schon.

Die eigentliche Bereitstellung des SDKs erfolgt dann, indem wir das Repository von GitHub herunterladen und wie gewohnt durch den Dreikampf von cmake, make und make install kompilieren:

tamhan@TAMHAN18:~$ git clone https://github.com/YDLIDAR/YDLidar-SDK.git
tamhan@TAMHAN18:~$ cd YDLidar-SDK/build
tamhan@TAMHAN18:~/YDLidar-SDK/build$ cmake ..
-- Build files have been written to: /home/tamhan/YDLidar-SDK/build
tamhan@TAMHAN18:~/YDLidar-SDK/build$ make
tamhan@TAMHAN18:~/YDLidar-SDK/build$ sudo make install

 

YDLidar bietet im GitHub-Repository auch eine Prozedur an, die die Installation nur der Python-Teile des SDKs ermöglicht. Da die Kompilationszeit auf der (betagten) Achtkern-Workstation des Autors nur wenige Sekunden betrug, empfiehlt sich die Abarbeitung der „kompletten“ Prozedur.

Inbetriebnahme der Hardware

Wer das Paket auspackt, sieht die in Bild 2 gezeigten Inhalte. Der eigentliche Lidar-Sensor besitzt dabei ein fünfadriges Kabel, über das er unter anderem mit 5 V versorgt wird und einen klassischen UART zur Verfügung stellt. Das rechteckige kleinere Kästchen ist ein USB-Seriell-Wandler, der den Anschluss des TG15 an eine Workstation, einen Raspberry Pi oder einen ähnlichen USB-Host ermöglicht.

Bild 2. Der TG15 ist gefechtsbereit.

Interessant ist hier, dass das beiliegende USBC-Kabel ausschließlich für die Datenkommunikation verantwortlich ist. Die „Energie-Bereitstellung“ erfolgt über den Micro-USB-Port; der Autor dieser Zeilen nutzte ein bei einem großen Kindle beiliegendes Netzgerät mit einer Nenn-Ausgangsstromleistung von 1,8 A.

Nach dem erfolgreichen Anschließen der Konfiguration taucht das Produkt jedenfalls in dmesg auf:

tamhan@TAMHAN18:~/YDLidar-SDK/build$ dmesg
. . .
[ 7043.684654] usb 6-2: cp210x converter now attached to ttyUSB0


Im nächsten Schritt besucht man die unter https://github.com/YDLIDAR/YDLidar-SDK/blob/master/doc/Dataset.md bereitstehende Produktübersicht, um mehr über das vorliegende Lidar-System zu erfahren. YDLidar nutzt seine Technologie nämlich in mehreren Plattform-Größen, die sich unter anderem in Bezug auf die am UART verwendete Baudrate unterscheiden.

Im Fall unseres TG15 lautet die korrekte Baudrate 512000. Merken Sie sich diese Informationen, und starten Sie danach die Testapplikation:
 

tamhan@TAMHAN18:~/YDLidar-SDK/build$ ./ydlidar_test
Please select the lidar baudrate:4
Whether the Lidar is one-way communication[yes/no]:yes
. . .


Wer – wie wir – mit einem TG15 arbeitet, kommt mit den hier gegebenen Eingaben zum Ziel. Wundern Sie sich übrigens nicht, wenn das Lidar an dieser Stelle zu „sirren“ anfängt. Innerhalb des runden, puckartigen Elements findet sich ein drehbar gelagerte Sensor, der während der Ausführung der Mess-Tätigkeit permanent rotiert. Zur Schonung des Kugellagers bietet es sich an, das Testprogramm danach durch Drücken von Strg + C zu beenden.

Software, zur Zweiten

YDLidar zeigt sich im Bereich der Programmierung flexibel: Man bietet APIs für C, C++ und Python 2 an. Wer – wie der Autor – im Allgemeinen mit Python 3 arbeitet, muss der älteren Version im ersten Schritt einige Unterstützungsbibliotheken einschreiben:

pip install numpy
pip install matplotlib


An dieser Stelle ist es Zeit für einen ersten Startversuch des Programms plot_tof_test.py. Es unterscheidet sich vom bisher verwendeten Kommandozeilen-Client dadurch, dass es Matplotlib zum Erzeugen eines Polar-Diagramms einspannt:

tamhan@TAMHAN18:~/YDLidar-SDK/python/examples$ python plot_tof_test.py
. . .
ImportError: No module named functools_lru_cache

 

Sollte die Ausführung – wie hier gezeigt – mit einem auf das Fehlen von functools-lru-cache hinweisenden Fehler scheitern, so müssen Sie dieses Paket unter Verwendung der APT-GET-Paketverwaltung installieren:

sudo apt install python-backports.functools-lru-cache


Die Verwendung von PIP oder PIP3 führte in Tests des Autors reproduzierbar zu einem nach wie vor nicht laufenden Programm.

Nach dem erfolgreichen Befriedigen der ersten Abhängigkeit können wir einen weiteren Programmstart befehligen, der abermals mit einer fehlenden Komponente endet. Im Interesse der Bequemlichkeit drucken wir Fehlermeldung und Nachinstallationsbefehl hier en bloc ab:

ImportError: No module named _tkinter, please install the python-tk package
tamhan@TAMHAN18:~/YDLidar-SDK/python/examples$ sudo apt install python-tk

 

Nachdem die noch fehlenden Voraussetzungen erfüllt sind, können wir das Programm anwerfen – die Demo fertigt in Echtzeit ein an einen Radar-Screen erinnernden Plot der Umgebung an. Ein interessanter Test besteht darin, das Radar - wie in Bild 3 gezeigt - komplett in der Hand einzufassen. Die matplotlib berechnet die Außenpunkte des Diagramms automatisch, weshalb der angezeigte Bereich in diesem Fall „schrumpft“.

Bild 3. Wer das Radar umarmt, sieht kleine Maximal-Distanzwerte.

Beim Test in einer realen Umgebung müssen Sie bedenken, dass die „aktive“ Ebene nur wenige Zentimeter über dem Boden des Geräts liegt. Der Autor dieser Zeilen behalf sich damit, das Gerät – wie in Bild 4 gezeigt – auf seinen Versandcontainer zu stellen.

Bild 4. Der Elektroniker darf dumm sein, muss sich aber zu helfen wissen.

Da die Lidare vergleichsweise einfache Tiere sind - sie liefern „einfach“ für jede Polar-Koordinate eine Distanz - können wir uns das Verhalten des Geräts am einfachsten veranschaulichen, wenn wir die Datei in einen Editor unserer Wahl laden. Als Erstes beginnt dabei die Initialisierung der Matplotlib - wichtig ist, dass der zum Einschreiben des maximalen Werts verwendete Befehl set_rmax vom Entwicklerteam auf unrealistische 32 gesetzt wird. Ein erster Schritt zur „Stabilisierung“ würde darin bestehen, hier über die Konstante RMAX einen kleineren Wert anzuliefern:
 

fig = plt.figure()
fig.canvas.set_window_title('YDLidar LIDAR Monitor')
lidar_polar = plt.subplot(polar=True)
lidar_polar.autoscale_view(True,True,True)
lidar_polar.set_rmax(RMAX)
lidar_polar.grid(True)


Die nächste Amtshandlung des Beispielcodes besteht darin, Kontakt zum USB-Seriell-Wandler aufzunehmen, der die Daten des Lidars für den Rechner ansprechbar macht:

ports = ydlidar.lidarPortList();
port = "/dev/ydlidar";
for key, value in ports.items():
    port = value;


Die Bibliothek ist von Seiten des Entwicklers zur Unterstützung einer ganzen Gruppe verschiedener Sensorsysteme vorgesehen. Im Rahmen des Starts sind deshalb einige Konfigurationshandlungen erforderlich – sie sehen, dass wir dem Laser-Objekt neben dem Port und der Baudrate beispielsweise auch die Scanfrequenz einschreiben müssen:
 

laser = ydlidar.CYdLidar();
laser.setlidaropt(ydlidar.LidarPropSerialPort, port);
laser.setlidaropt(ydlidar.LidarPropSerialBaudrate, 512000)
laser.setlidaropt(ydlidar.LidarPropLidarType, ydlidar.TYPE_TOF);
laser.setlidaropt(ydlidar.LidarPropDeviceType, ydlidar.YDLIDAR_TYPE_SERIAL);
laser.setlidaropt(ydlidar.LidarPropScanFrequency, 10.0);
laser.setlidaropt(ydlidar.LidarPropSampleRate, 20);
laser.setlidaropt(ydlidar.LidarPropSingleChannel, False);
scan = ydlidar.LaserScan()


Als Nächstes folgt im vorliegenden Programm die Funktion animate, die sich um die „Aufbereitung“ der angelieferten Informationen kümmert:
 

def animate(num):
   
    r = laser.doProcessSimple(scan);
    if r:
        angle = []
        ran = []
        intensity = []
        for point in scan.points:
            angle.append(point.angle);
            ran.append(point.range);
            intensity.append(point.intensity);
        lidar_polar.clear()
        lidar_polar.scatter(angle, ran, c=intensity, cmap='hsv', alpha=0.95)


Von besonderer Wichtigkeit ist die in der Mitte der Funktion befindliche for-Schleife, die über den Inhalt des Arrays Scan.Points iteriert. Sie fügt die Werte danach in Arrays ein, die zu guter Letzt an die Lidar-Polar-Instanz übergeben werden und so für eine Aktualisierung des Diagramms sorgen.

Damit fehlt uns nur noch die Besprechung der Hauptschleife des Programms, die für das Entgegennehmen der Informationen verantwortlich ist:

 

ret = laser.initialize();
if ret:
    ret = laser.turnOn();
    if ret:
        ani = animation.FuncAnimation(fig, animate, interval=50)
        plt.show()
    laser.turnOff();
laser.disconnecting();
plt.close();


Von besonderer Wichtigkeit ist die Funktion TurnOn. Sie „aktiviert“ das eigentliche Lidar, und liefert bei Fehl-Aktivierungen den Wert False zurück. Interessanterweise überwacht der Sensor dabei auch die Spannungsversorgung, um „im Problemfall“ gar nicht erst mit der Arbeit zu beginnen.

Was nun?

Wer sich im Rüstungs- oder Avionik-Bereich gut auskennt, nennt aus dem Stehgreif 20 verschiedene Anwendungen für Lidar-Systeme. Ein von YDLidar immer wieder forcierte Anwendungsbereich ist die Robotik; es gibt schlüsselfertige Integrationen für das weitverbreitete Roboter-Betriebssystem ROS.

Eine weitere sehr interessante Anwendung wäre der direkte Zugriff auf den UART-Datenstrom. In diesem Fall könnte der zur Auswertung verwendete Mikrocontroller primitiver ausfallen, was in Drohnen oder anderen gewichtskritischen Systemen wertvolle Ressourcen einspart.

Zu guter letzt sei abermals darauf hingewiesen, dass der - vergleichsweise teure – TG15 nur einer von vielen Vertretern seiner Zunft ist. Im Elektor-Shop finden sich auch billigere Geräte, die sich von der Programmierung her – im Großen und Ganzen – analog verhalten.