Het in 2015 opgerichte bedrijf YDLidar wil lidar-sensoren ‘voor de massa’ ontwikkelen. In deze bijdrage nemen we een TG15-lidar in gebruik, die verkrijgbaar is in de Elektor-shop.

De Kinect-sensor van Microsoft heeft het concept van afstandsmeting weer populair gemaakt, en interessant voor populair-wetenschappelijke toepassingen. Ironisch genoeg is dat de Kinect niet de lidar-technologie toepast die al jaren vooral in de militaire sector wordt gebruikt, maar in plaats daarvan werkt met infraroodstralen.

Waarschijnlijk vanwege de interesse die gewekt werd door de grote marketingcampagne van Microsoft, werd in 2015 in China het bedrijf YDLidar opgericht met als doel lidar-sensoren ‘voor de massa’ te ontwikkelen.

Zulke systemen met een bereik van 360° zijn (op het moment van schrijven) al vanaf ongeveer € 330 verkrijgbaar. Als voorbeeld beschrijft de auteur de ingebruikneming van een TG15-lidar, die in de Elektor-shop verkrijgbaar is (figuur 1).

Figuur 1. De lidar is verkrijgbaar voor ongeveer € 350 – een paar jaar geleden had u daar nog twee nullen achter kunnen plakken.

YDLidar is niet kieskeurig voor wat betreft het platform: naast Windows 7 en Windows 10 wordt ook Ubuntu ondersteund. Voor het gemak gebruikt de auteur zoals gewoonlijk in de volgende stappen zijn werkstation dat onder Ubuntu 18.04 draait. Als eerste stap moet worden gecontroleerd dat enkele pakketten voorhanden zijn die voor het compileren vereist zijn:

 

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

 

Kijk niet raar op als een groot aantal van deze pakketten al op uw computer voorhanden is – als u met Python werkt en af en toe C-programma’s compileert, zult u de meeste al in uw bezit hebben.

Het daadwerkelijke aanmaken van de SDK gebeurt dan door de repository van GitHub te downloaden en deze zoals gewoonlijk te compileren via het driespan cmake, make en make install:

 

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 biedt ook een procedure in de GitHub-repository aan waarmee alleen de Python-delen van de SDK kunnen worden geïnstalleerd. Aangezien de compilatietijd op het (bejaarde) acht-core werkstation van de auteur slechts enkele seconden bedroeg, is het raadzaam om de ‘volledige’ procedure te doorlopen.

Inbedrijfneming van de hardware

Na uitpakken ziet u de inhoud van figuur 2. De eigenlijke lidar-sensor heeft een vijfaderige kabel, waarmee hij onder meer van 5 V wordt voorzien, en die voor een klassieke UART zorgt. Het kleinere rechthoekige kastje is een USB/serieel-omzetter waarmee de TG15 kan worden aangesloten op een werkstation, Raspberry Pi of vergelijkbare USB-host.

Figuur 2. De TG15 is klaar voor gebruik.

Interessant in dit verband is dat de meegeleverde USBC-kabel alleen voor de datacommunicatie dient. De ‘stroomvoorziening’ vindt plaats via de micro-USB-poort. De auteur gebruikte een netvoeding die bij een grote Kindle was meegeleverd, met een nominale uitgangsstroom van 1,8 A.

Nadat alles met goed gevolg is aangesloten, is het product in dmesg zichbaar:

 

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

 

Ga dan naar het productoverzicht op https://github.com/YDLIDAR/YDLidar-SDK/blob/master/doc/Dataset.md om meer te weten te komen over uw lidarsysteem. YDLidar gebruikt zijn technologie namelijk in verschillende platformgroottes, die onder andere verschillen in de baudrate die voor de UART wordt gebruikt.

In het geval van onze TG15 is de juiste baudrate 512000. Noteer deze waarde en start vervolgens de testapplicatie:
 

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

 

Wanneer u – zoals wij – een TG15 gebruikt, komt u hiermee aan uw doel. Wees overigens niet verbaasd als de lidar nu begint te ‘snorren’. In het ronde, op een puck lijkende element bevindt zich een draaibaar gemonteerde sensor die tijdens het uitvoeren van metingen voortdurend ronddraait. Om het kogellager te ontzien verdient het aanbeveling om het testprogramma nu te beëindigen met Ctrl + C.

En dan nu de software

YDLidar is op het gebied van programmeren flexibel: er zijn API’s voor C, C++ en Python 2. Als u – net als de auteur – meestal met Python 3 werkt, is de eerste stap de oudere versie van enkele ondersteuningsbibliotheken te voorzien:

 

pip install numpy
pip install matplotlib

 

Nu kunt u proberen het testprogramma plot_tof_test.py te starten. Dit verschilt van de commandoregel-client die tot nu toe is gebruikt doordat het Matplotlib gebruikt om een polair diagram te genereren:

 

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


Als de uitvoering – zoals in dit voorbeeld – mislukt met de foutmelding dat functools-lru-cache ontbreekt, moet u dit pakket installeren met behulp van de APT-GET-pakketbeheerder:
 

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


Bij de auteur resulteerde het gebruik van PIP of PIP3 telkens weer in programma dat hoe dan ook niet wilde draaien.

Nadat we met succes aan de eerste afhankelijkheid hebben voldaan, kunnen we het programma opnieuw starten – om weer op een ontbrekend onderdeel geattendeerd te worden. Gemakshalve printen we de foutmelding en het installatiecommando hier bij elkaar:
 

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

 

Nadat aan alle nog ontbrekende vereisten is voldaan, kunnen we het programma starten – de demo maakt een realtime plot van de omgeving op een manier die doet denken aan een radarscherm. Een interessante test is om de radar met uw hand te omsluiten, zoals te zien in figuur 3. De matplotlib berekent automatisch de buitenste punten van het diagram, daarom ‘krimpt’ het weergegeven gebied in dit geval.

Figuur 3. Wie de lidar in zijn hand houdt, ziet kleine maximale afstandswaarden.

Houd er bij het testen in een echte omgeving rekening mee dat het ‘actieve’ vlak zich slechts enkele centimeters boven de onderkant van het apparaat bevindt. De auteur heeft het apparaat – zoals in figuur 4 – daarom op een doos gezet.

Figuur 4. Ook een elektronicus moet soms improviseren.

Omdat lidars relatief simpele beestjes zijn – ze leveren ‘gewoon’ een afstand voor elke poolcoördinaat – kunnen we het gedrag van het apparaat het beste visualiseren door het bestand in een editor van onze keuze te laden. De initialisatie van de matplotlib begint – het is belangrijk dat het commando set_rmax dat wordt gebruikt om de maximale waarde te schrijven, door het ontwikkelteam op een onrealistische waarde 32 is ingesteld. Een eerste stap op weg naar ‘stabilisatie’ zou zijn om hier een kleinere waarde in te stellen via de constante RMAX:

 

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)

 

De volgende officiële handeling van de voorbeeldcode is het contact opnemen met de USB/serieel-converter, die de gegevens van de lidar toegankelijk maakt voor de computer:

 

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


De bibliotheek is door de ontwikkelaar bedoeld om een hele reeks verschillende sensorsystemen te ondersteunen. Daarom moet bij de start het een en ander worden geconfigureerd – u ziet dat we naast de poort en de baudrate ook de scanfrequentie moeten opgeven, bijvoorbeeld:
 

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()

 

De volgende stap in dit programma is de functie animate, die de ‘verwerking’ van de aangeleverde informatie voor zijn rekening neemt:
 

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)


De for-lus in het midden van de functie, die zich herhaalt over de inhoud van het Scan.Points-array, is van bijzonder belang. Deze voegt de waarden in arrays in, die uiteindelijk worden overgedragen naar de lidar polar-instantie en er zo voor zorgen dat het diagram wordt geactualiseerd.

Het enige wat nog ontbreekt, is de bespreking van de hoofdlus van het programma, die verantwoordelijk is voor het ontvangen van de informatie:
 

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();


De functie TurnOn is van bijzonder belang. Deze ‘activeert’ de eigenlijke lidar en retourneert de waarde False wanneer dat niet goed is gegaan. Interessant genoeg bewaakt de sensor ook de voeding zodat ‘bij problemen’ überhaupt niet gestart wordt.

En nu?

Iedereen die thuis is in de militaire of avionica-sector, kan moeiteloos een heleboel toepassingen voor lidarsystemen bedenken. Een toepassingsgebied waar YDLidar telkens weer op wijst, is robotica; er bestaan kant-en-klare integratiemogelijkheden voor het veelgebruikte robotbesturingssysteem ROS.

Een andere zeer interessante toepassing is directe toegang tot de UART-datastroom. In dat geval zou de ‘evaluerende’ microcontroller ietwat primitiever kunnen uitvallen, wat gewicht bespaart in drones of andere systemen waar elke gram telt.

Last but not least moet er nogmaals op worden gewezen dat de – relatief dure – TG15 slechts één van de vele vertegenwoordigers van zijn soorte is. In de Elektor-shop vindt u ook goedkopere apparaten die zich qua programmering min of meer vergelijkbaar gedragen.