Construire un système LIDAR Arduino avec VL6180X et servomoteur
Composants et fournitures
| Composant | Quantité | Notes |
|---|---|---|
| Arduino UNO | 1 | |
| Capteur de distance ToF SparkFun - VL6180 | 1 | VL53L0X pour longue portée, VL6180X pour courte portée. Ici j'ai utilisé VL6180X |
| Servomoteur | 1 |
Applications et services en ligne
- Arduino IDE
- Processing (pour visualisation)
À propos du projet
Quelques notions sur le LiDAR
Le LIDAR (Light Detection and Ranging) est un système de télédétection optique qui mesure la distance d'une cible en l'illuminant avec de la lumière. La technologie LIDAR est utilisée en robotique pour la perception de l'environnement et la classification d'objets. La capacité du LIDAR à fournir des cartes d'élévation 2D du terrain, une distance de haute précision au sol et une vitesse d'approche permet un atterrissage sûr de véhicules robotisés et habités avec une haute précision.
Un LIDAR se compose d'un émetteur qui illumine une cible avec un faisceau laser, et d'un récepteur capable de détecter la composante de lumière essentiellement coaxiale avec le faisceau émis. Les capteurs récepteurs calculent une distance basée sur le temps nécessaire à la lumière pour atteindre la cible et revenir. Un mécanisme mécanique avec un miroir balaie le faisceau lumineux pour couvrir la scène requise dans un plan, voire en trois dimensions, en utilisant un miroir rotatif nodant.
Une façon de mesurer le temps de vol du faisceau lumineux est d'utiliser un laser pulsé et de mesurer le temps écoulé directement. Des électroniques capables de résoudre des picosecondes sont requises et sont donc très chères. Une autre méthode consiste à mesurer le décalage de phase de la lumière réfléchie.
Un laser infrarouge collimaté est utilisé pour la mesure de décalage de phase. Pour les surfaces ayant une rugosité supérieure à la longueur d'onde de la lumière incidente, une réflexion diffuse se produit. La composante de la lumière infrarouge revient presque parallèle au faisceau émis pour les objets. Le capteur mesure le décalage de phase entre les signaux émis et réfléchis.
La longueur d'onde du signal modulant obéit à l'équation : c = f × τ où c est la vitesse de la lumière, f la fréquence de modulation et τ la longueur d'onde de modulation connue. La distance totale D' parcourue par la lumière émise est : D' = B + 2A = B + (θ × τ) / 2π où A est la distance mesurée, B la distance de l'unité de mesure de phase. La distance requise D, entre le séparateur de faisceau et la cible, est : D = τ × θ / 4π où θ est la différence de phase mesurée électroniquement entre les faisceaux émis et réfléchis. La portée est inversement proportionnelle au carré de l'amplitude du signal reçu, affectant directement la précision du capteur. (Source : roboticlab.eu)
Dans le cadre de mon projet de fin d'études, j'ai besoin d'une carte 2D de l'environnement pour mon véhicule autonome, j'ai choisi le LiDAR car il est très rapide et précis. Contrairement aux sonars qui rebondissent des ondes ultrasoniques, le "cône" de détection est très étroit. Le VL6180X ou VL53L0X est un capteur optique de STMicroelectronics. Le VL53L0X est bien plus précis et n'a pas de problèmes de linéarité ni de "double image" où l'on ne peut pas dire si un objet est très loin ou très près. Ce capteur temps de vol est en fait utilisé dans nos téléphones pour ajuster la mise au point de la caméra.
Schéma de câblage
Installer la bibliothèque Adafruit
Code Arduino
#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);
}
/* Balayage retour (commenté)
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);
}
Code Processing (visualisation radar)
Changez le numéro de port Arduino (ex "COM3") avant d'exécuter.
import processing.serial.*;
Serial myPort;
String val;
int range, i = 0;
float pos;
void setup() {
size(550, 500);
String portName = "COMx"; // x = votre numéro de port Arduino
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)));
}
La vitesse du capteur est limitée à 10 Hz et la réponse du servomoteur est médiocre à haute vitesse. Pour un LIDAR haute vitesse, utilisez un moteur pas-à-pas ou un moteur CC avec système de rétroaction. Utilisez des bagues collectrices pour une rotation continue (Adafruit 736).
Questions et suggestions bienvenues !
Code
Code Arduino
#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);
}
Code Processing
import processing.serial.*;
Serial myPort;
String val;
int range, i = 0;
float pos;
void setup() {
size(550, 500);
frameRate(36);
String portName = "COMx"; // x = votre numéro de port Arduino
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)));
}
Processus de fabrication
- Les lanternes à gaz : évolution, conception et fabrication moderne
- Pointeur laser : conception, fabrication et aperçu de la sécurité
- Lampe Torche : De l'Invention à l'Innovation Moderne
- Le kaléidoscope : de la science de Brewster au design moderne
- Lasers à semi-conducteurs : Génération de lumière de précision pour la technologie moderne
- L'art et la science des procédés photographiques : du daguerréotype au film moderne
- Feux de signalisation : ingénierie, histoire et innovations futures
- Du Feu au Filament : L'Évolution et la Production de l'Ampoule Moderne
- Kodiak LiDAR 3D : Télémétrie spatiale de précision pour missions en orbite haute