LIDAR-Abstandsmessung

Aus toolbox_interaktion
Wechseln zu: Navigation, Suche

Im Rahmen des Praktikums im Fach Interaktion (WS 2017/18) entstand ein Näherungssensor unter Verwendung eines Lidar Sensors.

Idee

Die ursprüngliche Zielsetzung unseres Projekts war eine Schrittdetektion. Also jedes Mal, wenn man im Messbereich mit einem Fuß den Boden berührt, sprich auftritt, sollte ein Signal wiedergegeben werden, in unserem Fall ein Ton. Um die damit verbundenen Schwierigkeiten bessert verstehen zu können, werden wir Euch nun erst die Messmethode des Lidar Lasers (light detection and ranging Laser) näher bringen.


Funktionsweise

Grundsätzlich sendet der Laser pro Umdrehung eine Anzahl an Scans aus, die jeweils einen Entfernungswert zurück geben. Im Zusammenhang mit dem dazugehörigen Winkel lässt sich damit ein 2D-Bild des Raumes erfassen, allerdings mit entsprechenden Schatten. Je nach Farbe des Objektes auf welches die Laserstrahlen treffen ist die Reichweite größer oder kleiner.

LIDAR-scanned-SICK-LMS-animation.gif
(Animation gemeinfrei auf Wikipedia veröffentlicht.)

Da die Schrittdetektion mit dieser Messtechnik jedoch sehr schwierig in vorgegebener Zeit umzusetzen war, haben wir uns, nach langer Tüftelei und zahlreich neu gewonnenen Erfahrungen, für eine, durch das Messverfahren des Lasers besser zu bewerkstelligende Aufgabe, entschieden: Die Detektion der Entfernung einer beliebigen Person im Messbereich Ziel war es also die Entfernung eines Gegenstandes (oder Person) im Messfeld des Lasers zu bestimmen. Um ein schlüssiges akustisches Feedback zur erfassten Distanz zu erzeugen, verwenden wir bei einem kurzen Abstand zum Laser ein schnelles und bei einer größeren ein langsameres Piepsen, ähnlich einem Einparksensor.

Lidar abstandsmessung pepperl software.png
Zu sehen ist die offizielle Pepperl + Fuchs Software zur einfachen Visualisierung der Sensordaten und für Konfigurationen.
Allerdings bietet die Software keinerlei API oder Möglichkeiten zur direkten Verwendung der Daten daher musste dieser Part mithilfe eines Treibers selber geschrieben werden.


Hardware

Pepperl+fuchs+lidar.jpg
Pepperl + Fuchs Lidar Sensor, zu sehen ist das Balkendiagramm welches die Entfernung von Objekten in der Umgebung visualisiert.
Der Pepperl und Fuchs R2000 Lidar Sensor wird über ein proprietäres LAN-kabel an einem Computer angeschlossen um die Daten zu erhalten.


Software

- Open Frameworks
- AddOn für Open Frameworks
- Pepperl + Fuchs Software
- Apple XCode


Umsetzung

Konkret umgesetzt haben wir das Projekt mit Open Frameworks und einem dafür erhältlichen AddOn, das speziell für den Pepperl & Fuchs geschrieben wurde. Dieses enthält auch den Treiber für den Laser, geschrieben ist das Programm sowie das AddOn in C++ . Zunächst haben wir zur besseren Visualisierung ein Balkendiagram erzeugt, welches die Abstände 360° um den Laser herum anzeigt. Für jedes Grad wird ein Balken angezeigt, die Länge bestimmt den Abstand. Weiterhin haben wir einen bestimmten Bereich festgelegt, für welchen der Sensor für die weitere Verarbeitung der Daten anspricht. Es sollen lediglich in einem festgelegten Winkel sowie nur Abstände unter einer gewissen Distanz registriert werden. Nähert sich in diesem Bereich ein Gegenstand oder Mensch an, wird der Ton abgespielt.

Lidar abstandsmessung screenshot2.png


Grafische Darstellung des Entfernungsdiagrammes

void ofApp::draw(){
   
   graphScaling = 0.5;
   bool playSound = false;
   minimumAngle = 90;
   maximumAngle = 200;
   
   if ( data_available) {
       for (int i = 0; i < samplesPerScan; i++) {                                  //360-mal
           if( i > minimumAngle && i < maximumAngle ){                             //defines area of interest
               makeAoiGreen(i, graphScaling, lastScanData);                        // paints are of interest green
               angle = i;
               for (angle; angle < maximumAngle-minimumAngle; angle ++) {
                   distanceArray[angle] = lastScanData.distance_data[angle];           //writing the distance values into a new array
               }
               calculateMinimalDistance(angle, distanceArray);                      //calculating the minimal distance
               // if something approaches the laser, activate sound playback
               if (minimalDistance < maximumScanDistance) {
                   playSound = true;
               }
           } else {
               // paint area outside of scan area (red)
               makeGraphOutsideOfAoIRed(i, graphScaling, lastScanData);
           }
       }
   }
}

Abspielen eines Tones mit OF

Dank OpenFrameworks ließ sich die Ausgabe eines Tones und dessen Manipulation (Geschwindigkeit, Tonhöhe, usw.) leicht erledigen.

void ofApp::update(){
   
   ofSoundUpdate();
   
   // get available scans
   scans_available = driver.getFullScansAvailable();
   
   if (scans_available > 0) {
       
       // lock scan data mutex
       ofScopedLock lock(scanDataMutex);
       
       data_available = true;
       
       ScanData data;
       
       lastSampleValid = true;
       
       // get all the scans
       for (size_t i = 0; i < scans_available; i++)
       {
           data = driver.getScan();
       }
       
       lastScanData = data;
   }
   soundOutput(minimalDistance, playSound);
   
}
void ofApp::soundOutput(int minimalDistance, bool playSound){
   counter++;
   if (minimalDistance < maximumScanDistance && speedLevel != 0) {
       if ((counter % speedLevel) == 0) {
           synth.play();
//            cout << "blub" << endl;
       }
   }
   
}


Download Projektdateien im OCS