Lidar ist die Abkürzung für Light detection and ranging. Man versteht also darunter die Entfernungsbestimmung mittels Laserlicht. Scannt man einen Raumwinkelbereich ab, so kann man auch ein 3D-Abbild der Umgebung erzielen (engl. laserscanning).
Zur Abstandsbestimmung verwende ich einen gewöhnlichen Laserdistanzmesser vom Typ UNI-T UT390b. Dieser ist auf einer mit 2 Servos betriebenen Montierung fixiert. Per Knopfdruck rastert die Montierung/der Sensor einen größeren Raumwinkelbereich ab und bestimmt somit die Entfernung d in Abhängigkeit der beiden Winkel φ (horizontal) und θ (vertikal). Mit diesen Daten (φ, θ, d) kann man sodann ein 3D-Abbild erstellen. Ich setzte dies mit der Uraltsprache Turbo-Pascal um. Um das 3D-Abbild realistischer erscheinen zu lassen, verbinde ich sämtliche Raumpunkte mit Geraden. So kommt ein schönes Gitternetz zustande.
Da der Laserentfernungsmesser während des Scans immer wieder einmal abstürzt (fehlerhafte Messung), habe ich einen Reset-Schalter installiert. Dadurch verliere ich keine Werte während der Messung.
Mit dem Lidar Lite-V3 oder dem Sharp GP2Y0A710K0F gibt es speziell auf den Einsatz mit dem Arduino abgestimmte Lidar-Entfernungsmesser.
Bildquelle: https://twitter.com/LeeMargetts/status/1137249835369803776/photo/1
Arduino-Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
// ========================================================= // ====== Programm zur Erstellung eines 3D-Raumbilds ======= // ========= mit dem UT390b-Laserentfernungsmesser ========= // ========================================================= // ======================================= // ====== Fehlermeldungen des Geräts ===== // ======================================= /* ERR_BATTERY_LOW = 101, ERR_CALCULATION = 104, ERR_HIGH_TEMP = 152, ERR_LOW_TEMP = 153, ERR_OUT_OF_RANGE = 154, ERR_WEAK_SIGNAL = 155, ERR_STRONG_SIGNAL = 156, ERR_BACKGROUND_ILLUM = 157, ERR_DEVICE_SHAKING = 160 */ #include <Servo.h> // Inkludiert die Servodateien #include <i2cmaster.h> // Inkludiert die i2c-Bus-Dateien #include <UT390B.h> UT390B laser(Serial1); // create a laser object Servo servo_horiz; // Definiert den horizontalen servo Servo servo_verti; // Definiert den vertikalen servo int taste; // Tastaturpin für Start des Scans int horiz_start = 60; // horizontaler Startwinkel int verti_start = 0; // vertikaler Startwinkel int schritte = 30; // horizontale bzw. vertikale Schritte int schrittweite = 2; // Schrittweite der Servos long lastMeasurement = -10000; boolean recdata = true; boolean data; int buf[64]; int rc=0; int Distanz; // ************************************ // ************** SETUP *************** // ************************************ void setup() { Serial.begin(115200); //Serial1.begin(115200); servo_horiz.attach(9); // Set horizontalen servo to digital pin 9 servo_verti.attach(10); // Set vertikalen servo to digital pin 10 pinMode(13, OUTPUT); } // ******************************************** // ************** HAUPTSCHLEIFE *************** // ******************************************** void loop() { taste = analogRead(A0); // Abfrage, ob die Taste gedrückt wird und der Scan gestartet werden kann servo_horiz.write(horiz_start); servo_verti.write(verti_start); if (taste < 500) { // ********** Messung gestartet ************ digitalWrite(13, HIGH); // set the LED on delay(1000); // wait for a second digitalWrite(13, LOW); // set the LED off for (int i = 0; i < schritte; i++) { servo_horiz.write(horiz_start + i * schrittweite); servo_verti.write(verti_start); delay(50); for (int j = 0; j < schritte; j++) { servo_verti.write(verti_start + j * schrittweite); delay(20); // Einlesen der Distanz // ==================== laser.triggerMeasurement(); // Triggerung einer neuen Messung do { if(laser.measurementAvailable()) { Distanz = laser.readMeasurement(); // Distanzmessung lastMeasurement = millis(); // Rücksetzung der Messzeit } else // keine Messung erfolgt { laser.triggerMeasurement(); Distanz = -1; } /* if(millis() - lastMeasurement > 2000) // Überprüfung, ob letzte Messung zu lange her { laser.triggerMeasurement(); lastMeasurement = millis(); } */ } while(Distanz <= 0); // Wiederholung bis korrekte Distanz > 0 Serial.print(horiz_start + i * schrittweite); Serial.print(" "); Serial.print(verti_start + j * schrittweite); Serial.print(" "); Serial.println(Distanz/10); // Ausgabe der gemessenen Distanz in cm } } // ********** Messung beendet ************ digitalWrite(13, HIGH); // set the LED on delay(1000); // wait for a second digitalWrite(13, LOW); // set the LED off servo_horiz.write(horiz_start); servo_verti.write(verti_start); } } |