Arduino LIDAR-System mit VL6180X und Servomotor bauen
Komponenten und Zubehör
| Komponente | Menge | Hinweis |
|---|---|---|
| Arduino UNO | 1 | |
| SparkFun ToF Entfernungsmesser VL6180 | 1 | VL53L0X für große Reichweite, VL6180X für kurze Reichweite. Hier VL6180X verwendet. |
| Servomotor | 1 |
Apps und Online-Dienste
- Arduino IDE
- Processing
Über dieses Projekt
Einiges über LiDAR
LIDAR (Light Detection and Ranging) ist ein optisches Fernerkundungssystem, das die Entfernung eines Ziels durch Bestrahlung mit Licht messen kann. LIDAR-Technologie wird in der Robotik zur Umgebungswahrnehmung und Objektklassifizierung eingesetzt. Die Fähigkeit, 2D-Höhenkarten des Geländes, hochpräzise Bodenentfernungen und Anfluggeschwindigkeiten bereitzustellen, ermöglicht sichere Landung von robotischen und bemannten Fahrzeugen mit hoher Präzision.
LIDAR besteht aus einem Sender, der ein Ziel mit einem Laserstrahl beleuchtet, und einem Empfänger, der den komponenten des Lichts detektiert, der im Wesentlichen koaxial zum gesendeten Strahl ist. Empfängersensoren berechnen die Entfernung basierend auf der Zeit, die das Licht benötigt, um das Ziel zu erreichen und zurückzukehren. Ein mechanischer Mechanismus mit einem Spiegel fegt den Lichtstrahl, um die erforderliche Szene in einer Ebene oder sogar in drei Dimensionen abzudecken, indem ein nickender Rotationsspiegel verwendet wird.
Eine Methode zur Mess der Flugzeit des Lichtstrahls ist die Verwendung eines gepulsten Lasers und die direkte Messung der verstrichenen Zeit. Dafür sind Elektronikkomponenten erforderlich, die Pikosekunden auflösen können – diese Geräte sind daher sehr teuer. Eine andere Methode misst die Phasenverschiebung des reflektierten Lichts.
Kollimiertes Infrarotlaserlicht wird für die Phasenverschiebungsmessung verwendet. Bei Oberflächen mit einer Rauheit größer als die Wellenlänge des einfallenden Lichts tritt diffuse Reflexion auf. Die Komponente des Infrarotlichts kehrt für Objekte fast parallel zum gesendeten Strahl zurück.
Der Sensor misst die Phasenverschiebung zwischen gesendetem und reflektiertem Signal. Die Formel zeigt, wie diese Technik zur Entfernungsmessung verwendet werden kann. Die Wellenlänge des Modulationssignals gehorcht der Gleichung:
c = f · τ
wobei c die Lichtgeschwindigkeit, f die Modulationsfrequenz und τ die bekannte Modulationswellenlänge ist.
Die gesamte vom emittierten Licht zurückgelegte Strecke D' beträgt:
D' = B + 2A = B + (θ · τ) / 2π
wobei A die gemessene Entfernung ist. B ist die Distanz von der Phasenmesseinheit. Die erforderliche Distanz D zwischen Strahlteiler und Ziel ist daher:
D = τ · θ / 4π
wobei θ der elektronisch gemessene Phasenunterschied zwischen gesendetem und reflektiertem Lichtstrahl ist.
Es lässt sich zeigen, dass der Messbereich umgekehrt proportional zum Quadrat der empfangenen Signalamplitude ist, was die Genauigkeit des Sensors direkt beeinflusst.
(Quelle: home.roboticlab.eu)
Als Teil meines Abschlussprojekts benötige ich eine 2D-Karte der Umgebung für mein autonomes Fahrzeug, daher wählte ich LiDAR, da es so schnell und präzise ist. Im Gegensatz zu Sonaren, die Ultraschallwellen reflektieren, ist der "Kegel" der Erfassung sehr schmal.
VL6180X oder VL53L0X sind optische Sensoren von STMicroelectronics. VL53L0X ist präziser und hat keine Linearitätsprobleme oder "Doppelbilder", bei denen man nicht sagen kann, ob ein Objekt sehr weit oder sehr nah ist.
Dieser Time-of-Flight-Sensor wird tatsächlich in unseren Mobiltelefonen verwendet, um den Kamerafokus einzustellen.
Schaltplan
Adafruit Bibliothek installieren
Arduino Code
#include <Wire.h>
#include "Adafruit_VL6180X.h"
#include <Servo.h>
Adafruit_VL6180X vl = Adafruit_VL6180X();
Servo myservo;
float pos = 0;
const float Pi = 3.14159;
void setup() {
myservo.attach(9);
Serial.begin(115200);
while (!Serial) { delay(1); }
if (!vl.begin()) { while (1); }
}
void loop() {
for (pos = 0; pos <= 180; pos += 0.5) {
myservo.write(pos);
uint8_t range = vl.readRange();
Serial.println(String(range) + "p" + String(pos * Pi / 180) + "p" + String(pos));
delay(10);
}
/* Rückwärtsbewegung auskommentiert
for (pos = 180; pos >= 0; pos -= 0.5) {
myservo.write(pos);
uint8_t range = vl.readRange();
Serial.println(String(range) + "p" + String(pos * Pi / 180) + "p" + String(pos));
delay(10);
}
*/
myservo.write(0);
delay(2000);
}
Processing Code
(Siehe andere Radar-Projekte für bessere Radar-Oberfläche) Ändern Sie die Arduino-Portnummer (z. B. "COM 3") vor dem Ausführen.
import processing.serial.*;
Serial myPort;
String val;
int range, i = 0;
float pos;
void setup() {
size(550, 500);
String portName = "COMx"; // x = Ihre Arduino-Portnummer
myPort = new Serial(this, portName, 115200);
background(255);
}
void draw() {
if (myPort.available() > 0) {
val = myPort.readStringUntil('\n');
if (val != null) {
String[] nums = split(val, "p");
if (nums.length == 3) {
range = int(nums[0]);
pos = float(nums[1]);
i = int(nums[2]);
if (i == 180) { background(255); }
}
}
}
translate(25, -50);
line(250, 500, 250 - 2 * (range * cos(pos)), 500 - 2 * (range * sin(pos)));
}
Die Sensorgeschwindigkeit ist auf 10 Hz begrenzt und die Servoreaktion ist bei höherer Geschwindigkeit schlecht. Für High-Speed-LIDAR sollten Schrittmotoren oder DC-Motoren mit Rückführsystem verwendet werden. Für kontinuierliche Rotation Schlupfringe nutzen (Adafruit Slip Rings).
Fragen und Anregungen sind willkommen!
Code
Arduino Code
#include <Wire.h>
#include "Adafruit_VL6180X.h"
#include <Servo.h>
Adafruit_VL6180X vl = Adafruit_VL6180X();
Servo myservo;
float pos = 0;
const float Pi = 3.14159;
void setup() {
myservo.attach(9);
Serial.begin(115200);
while (!Serial) { delay(1); }
if (!vl.begin()) { while (1); }
}
void loop() {
for (pos = 0; pos <= 180; pos += 0.5) {
myservo.write(pos);
uint8_t range = vl.readRange();
Serial.println(String(range) + "p" + String(pos * Pi / 180) + "p" + String(pos));
delay(10);
}
myservo.write(0);
delay(1000);
}
Processing Code
import processing.serial.*;
Serial myPort;
String val;
int range, i = 0;
float pos;
void setup() {
size(550, 500);
frameRate(36);
String portName = "COMx"; // x = Ihre Arduino-Portnummer
myPort = new Serial(this, portName, 115200);
background(255);
}
void draw() {
if (myPort.available() > 0) {
val = myPort.readStringUntil('\n');
if (val != null) {
String[] nums = split(val, "p");
if (nums.length == 3) {
range = int(nums[0]);
pos = float(nums[1]);
i = int(nums[2]);
if (i == 180) { background(255); }
}
}
}
translate(25, -50);
line(250, 500, 250 - 2 * (range * cos(pos)), 500 - 2 * (range * sin(pos)));
}
Herstellungsprozess
- Gaslaternen: Entwicklung, Design und moderne Fertigung
- Laserpointer: Design, Fertigung und Sicherheitsübersicht
- Taschenlampe: Von der Erfindung zur modernen Innovation
- Das Kaleidoskop: Von Brewsters Wissenschaft zum modernen Design
- Halbleiterlaser: Präzise Lichtgenerierung für moderne Technologie
- Die Kunst und Wissenschaft fotografischer Prozesse: Von Daguerreotypien zum modernen Film
- Verkehrsampeln: Technik, Geschichte und zukünftige Innovationen
- Vom Feuer zum Glühfaden: Die Entwicklung und Produktion der modernen Glühbirne
- Lichtwellenleiter: Technologie, Produktion und Zukunft
- Kodiak 3D LiDAR: Präzise weltraumgestützte Entfernungsmessung für High-Orbit-Missionen