- 1866 views
Ce blog montre comment concevoir une voiture autonome capable de rouler le long d'une voie et de réagir aux panneaux de signalisation, aux obstacles et aux marqueurs RFID intelligents, propulsée par OpenCV et Embedded Linux.
Choses utilisées dans ce projet:
- 1 platine Zybo
- 1 caméra Pcam 5C
- 1 module Pmod MAXSONAR
- 1 module Pmod ACL
- 1 adaptateur Wifi USB TPLink WN722N
- 1 Servomoteur à pignons métalliques (haute vitesse/couple élevé)
- 1 Module de pilotage de moteur à base de DVR8835
- 1 régulateur de tension 5V (D24V22F5)
- 1 Régulateur 6 V (pour alimenter le servomoteur)
- 1 lecteur RFID pour carte NXP PN532
- 1 Batterie Li-Po 2200 mAh
- 1 châssis de moteur 4WD avec moteur cc
Applications logicielles nécessaires
- Xilinx Vivado Design Suite
- Kit de développement logiciel Xilinx
- Kit de développement logiciel Xilinx Petalinux
- Digilent WaveForms
- OpenCV
Outillages complémentaires nécessaires
- Fer à souder
- Pistolet à colle
- Imprimante 3D
- Tournevis et autres petits outils à main
L'histoire
L'une des principales forces motrices de l'industrie dans les domaines du traitement d'image et des systèmes de contrôle automatique est le concept d'un véhicule autonome capable de faire tout ce qu'un conducteur humain peut faire et plus encore, comme la navigation automatique, une meilleure conscience de l'environnement et des algorithmes de sécurité améliorés. et systèmes.
Nous avons décidé d'implémenter un véhicule autonome sur une plate-forme Zybo Z7-20, en utilisant un capteur vidéo PCAM Digilent comme caméra principale pour capturer la route et les panneaux routiers à venir, avec une gamme supplémentaire de capteurs comprenant un accéléromètre, un sonar et un scanner RFID pour recueillir des données supplémentaires sur son parcours.
Nos objectifs sont d'avoir une voiture modèle qui:
- Peut rester en sécurité sur la route
- Tenir sa voie
- Suivre les panneaux de signalisation et les règlements
- Ne dépend d'aucune intervention humaine pour une opération réussie
Cadre, moteurs et direction
La plate-forme matérielle est construite autour d'un châssis de voiture en plastique à 2 niveaux, avec tout le matériel de montage et les supports supplémentaires conçus en CAO et en 3D imprimés en plastique PLA. Le cadre comprend également 2 moteurs électriques "cc" à balais avec un couple suffisant pour assurer le déplacement de la voiture à une vitesse décente. Le système de direction ressemble à celui d'un kart (direction Ackerman), le servo poussant un moyeu de roue qui transfère également le mouvement au second via une tige de poussée. Le système de direction est entièrement imprimé en 3D et nécessite un assemblage minimal.
Le cadre lui-même nécessite des trous et des points de montage supplémentaires selon vos besoins personnels, selon la façon dont vous souhaitez placer les différents composants / capteurs.
Vidéo du système de direction en action
Batterie et alimentation Alimentation
L'alimentation de tous les systèmes à bord est fournie par une batterie Li-Po dans une configuration 3S1P, fournissant 12,6 V sur une charge complète. Ceci est transmis par 2 régulateurs de tension qui produisent 6 V pour le servomoteur et les moteurs et un 5 V faible bruit, à faible chute et stable au Zybo (et à ses périphériques). La batterie est surveillée avec une alarme / moniteur de tension Li-Po, pour éviter une décharge excessive.
Caméra
Le PCAM est monté à l'avant du véhicule, sur un support imprimé en 3D qui fournit l'angle et la hauteur de vision optimaux. Nous avons utilisé un objectif fisheye avec l'original pour étendre le champ de vision, comme l'exige l'algorithme de détection de voie.
Scanner RFID
Sous le véhicule, entre les roues avant se trouve un scanner RFID connecté via I2C à la carte principale qui est utilisé pour détecter et lire les étiquettes / cartes / autocollants RFID au sol pour fournir à la voiture des informations sur la route, telles que les limites de vitesse et les panneaux de signalisation (à la fois comme sécurité intégrée pour la caméra et comme système secondaire, disponibles même dans de mauvaises conditions d'éclairage).
Sonar
Le sonar est placé à l'avant, et son but est de détecter les obstacles sur la route et de fournir une sensation de distance à l'algorithme de traitement.
Accéléromètre
L'accéléromètre est monté sur le dessus du véhicule et est utilisé pour mesurer la vitesse actuelle de la voiture en échantillonnant périodiquement les données d'accélération en 3 axes via I2C et en exécutant un algorithme sur celles-ci.
Adaptateur WiFi
Nous utilisons un dongle wifi USB pour que notre voiture soit sans fil à des fins de débogage, étroitement intégrée à la distribution Embedded Linux fonctionnant à bord.
Conception matérielle VHDL
Nous avons implémenté 2 adresses IP AXI en VHDL pour agir en tant que pilotes pour le matériel personnalisé réel sur la voiture, à savoir les moteurs et le servo et le sonar.
Le pilote de moteur a des commutateurs d'activation / désactivation du matériel (pour la sécurité et la sécurité), ainsi que des contrôleurs de registre, et exposant le matériel de base (le pilote de moteur Pololu réel et le servo lui-même) en tant que registres inscriptibles (tout est piloté par PWM à la fin , de sorte que les registres commandent un tableau de pilotes PWM à fréquence variable et à résolution variable conçus en VHDL).
Le pilote sonar est basé sur le Pmod MAXXSONAR IP, c'est un compteur de signaux PWM.
Pipeline vidéo
Le pipeline vidéo est basé sur la démo PCAM de Digilent. Nous avons modifié l'IP AXI Bayer-to-rgb pour produire des pixels au format 8 bits / canal, 3 canaux de couleur (24 bits par pixel) et nous avons supprimé le composant de flux de sortie (M2SS) et la sortie HDMI. La caméra Omnivision OV5640 est contrôlée via I2C depuis l'espace utilisateur, configurée selon sa fiche technique disponible en ligne.
Conception de logiciels
Le projet est centré sur une distribution Linux embarqué de Xilinx, Petalinux 2017.4. Nous avons décidé d'emprunter cette voie car notre projet comprend de nombreux modules différents (matériels et logiciels), et le système d'exploitation Linux agit comme un terrain d'entente entre eux, gérant les processus et fournissant des outils de débogage, une mémoire persistante sur la carte SD, un accès SSH, etc. .
La distribution Linux exécute un noyau hautement modifié qui est adapté à nos besoins et fournit un support pour les périphériques physiques (caméra, sonar, moteurs et servo) via des modules de noyau personnalisés (pilotes de périphériques) et un support pour l'adaptateur WiFi via un pilote USB modifié basé sur le pilote TP-Link disponible en ligne. Xilinx incluait déjà des pilotes pour Zynq I2C, utilisés pour se connecter avec l'appareil photo et d'autres appareils.
Nous avons inclus un ensemble diversifié d'applications de test, essentiellement utilisées pour tester à l'unité les différents modules, avant de les intégrer pleinement à l'application OpenCV principale qui gère l'ensemble du processus.
Modules du noyau
Il existe 4 modules de noyau personnalisés intégrés à la carte, qui gèrent des composants matériels spécifiques, interagissant avec les IP VHDL AXI connectées au cœur de traitement Zynq.
- Videodriver: fournit un accès de base / dev / vidéo aux tampons d'image VDMA pour lire les images stockées le plus rapidement possible, minimisant ainsi les transferts de mémoire. Il fournit également un accès ioctl à différents paramètres de configuration pour configurer correctement les applications de l'espace utilisateur.
- Motiondriver: fournit / dev / motors et / dev / servo un accès en écriture aux applications de l'espace utilisateur et gère ces appareils, affichant une API facile à utiliser pour contrôler les moteurs et la direction de la voiture.
- Sonardriver: fournit un accès en lecture à / dev / sonar aux applications de l'espace utilisateur pour lire facilement la distance signalée par le sonar.
- Pilote 8188eu mis à jour pour le périphérique WiFi USB TP-Link WN722N, porté du noyau 4.3 à 4.9 et adapté pour une utilisation continue, avec des fonctions d'économie d'énergie minimales pour limiter les frais généraux.
Programme de contrôle principal
Le contrôle de la voiture est composé du module OpenCV qui traite l'image de chaque trame et définit les indicateurs et variables correspondants pour que le module de contrôle de la voiture prenne des mesures en conséquence.
Module OpenCV
Le flux de traitement d'image est divisé en deux parties, chacune s'exécutant sur son propre thread. Un fil contrôle la détection de voie et inclut l'algorithme de contrôle de la voiture et l'autre détecte constamment les signes.
- Composant de détection de voie:
La caméra Pcam 5C fournit une image 720p avec la partie la plus proche des voies mise au point car c'est la partie la plus importante pour savoir comment contrôler la direction de la voiture.
L'image 720p est redimensionnée à la moitié de sa taille pour faciliter le traitement, et désormais toutes les images utilisées dans le composant de détection de voie seront 360p.
resize(image_read, frame, cv::Size(), 0.5f, 0.5f);
La plupart du traitement d'image se fait en niveaux de gris, la prochaine étape consiste donc à convertir l'image redimensionnée de RVB en niveaux de gris.
cvtColor(frame, gray_image, CV_RGB2GRAY);
Image en niveaux de gris 360p
Pour la partie de détection des bords du processus, nous devons rendre l'image floue afin que la méthode Canny ne détecte pas les bords petits et insignifiants et ne prenne en compte que les bords importants.
GaussianBlur(gray_image, blurred_image, Size(5, 5), 0, 0);
Une fois le prétraitement terminé, la partie principale de vision par ordinateur est lancée.
La méthode Canny renvoie les bords importants de l'image, comme prévu, qui seront utilisés plus tard pour détecter la position des lignes par rapport à la voiture.
Canny(blurred_image, canny_image, 50, 150);
Pour ne traiter que certaines parties pertinentes du résultat rusé, nous devons appliquer un masque sur l'image rémanente. Ce masque est réalisé à partir d'une image vide sur laquelle les régions d'intérêt sont blanches, nous le faisons avec les lignes de fonction.
mask = cv::Mat::zeros(frame.size(), canny_image.type());
lines(mask);
Après le bitwise_et l'image résultante ( ROI_image ) contient juste les points sur la ligne qui seront plus tard utilisés dans la partie contrôle de direction du programme.
bitwise_and(mask, canny_image, ROI_image);
- Composant de détection des panneaux d'arrêt:
Le prétraitement de détection de panneau d'arrêt est le même que le prétraitement de détection de voie, avec la mention que seule la partie droite de l'image est traitée (nous n'avons considéré que la partie droite de l'image car les signes réels se trouvent principalement du côté droit de la route, pour les conditions de conduite du côté gauche, la fonction de recadrage peut être modifiée pour mettre à jour les conditions définies).
Le thread en charge de la détection du panneau d'arrêt attend d'avoir une image disponible de la caméra et appelle la fonction detect_and_display qui renvoie 1 si un panneau est considéré comme étant à proximité de la voiture et 0 sinon.
stop_sign = detect_and_display(image, param);
Étant donné que le champ de vision de la caméra est quelque peu réduit, nous ne pouvons pas évaluer la distance entre la voiture et le panneau (comme dans une situation normale où vous vous arrêteriez à côté d'un panneau d'arrêt), de sorte que la voiture s'arrête lorsqu'elle a vu un arrêt. signe dans la dernière image traitée et ledit panneau d'arrêt quitte son champ de vision dans l'image traitée actuelle.
Partie de contrôle de voiture:
L'image ROI_ est envoyée à l'algorithme d'asservissement qui renvoie la valeur d'asservissement correspondante pour les lignes détectées. Cela se fait avec la fonction servo_comand_line.
servo_out = servo_comand_line(ROI_image, frame, param, new_speed);
La fonction renvoie une valeur d'asservissement dans la plage de travail du servomoteur, cette valeur est ajustée avec la vitesse de la voiture, comme dans la situation réelle lorsque la voiture roule plus vite, de sorte que la direction doit tourner moins pour le même mouvement . Si la fonction rencontre de mauvaises données, ce qui signifie une ligne de voie cassée ou une image défectueuse, la fonction renverra -1 signalisation à la prochaine pièce de la partie de contrôle pour garder le même angle de virage.
La vitesse de la voiture est calculée en plusieurs étapes:
Tout d'abord, déterminer si la voiture peut avancer ou non, à l'aide du sonar (lecture / dev / sonar ).
read(sonar->_fileno, &clk_edges, 4);
dist = clk_edges * clk_to_cm;
Deuxièmement, la voiture vérifie les panneaux d'arrêt, en utilisant l' indicateur stop_sign qui a été défini dans la partie de détection des panneaux d'arrêt du processus de contrôle.
if (stop_sgn == 0 && old_stop_sgn == 1) {
//STOP THE CAR
}
Enfin, la voiture lit les cartes RFID, s'il y en a sous la voiture, elle exécute l'action spécifique de la carte, soit l'accélération, le ralentissement ou l'arrêt.
card_now = popCard(c_queue);
if (card_now != NULL) {
switch (card_now->type) {
//CASE FOR EACH TYPE OF CARD
}
}
Si aucune de ces étapes n'est remplie, la voiture continue sa route avec les derniers paramètres définis.
Une fois que les paramètres d'asservissement et de vitesse sont corrects, ils sont transmis aux modules du noyau (via / dev / servo et / dev / motors) afin que l'action calculée soit exécutée.
write(motors->_fileno, &speed, 4);
Obtenez des images pertinentes
Parce que les humains ne sont pas aussi bons avec les chiffres que les ordinateurs, nous devons ajouter les informations pertinentes à l'écran.
Ressources complémentaires:
- Les pièces et boîtiers personnalisés de ce projet
- Les schémas détaillés de ce projet
- Le code de ce projet
sont disponibles sur le lien de cette page (en bas de page).
Traduction du blog Digilent https://projects.digilentinc.com/catalin-bitire/zybo-autonomous-car-2d343d
Texte et photos @ Digilent Inc
Crédits : Catalin Bitire - Ionascu Andrei - Mircea Cojocaru