Table des matières:

Prototype Smart Motorcycle HUD (navigation pas à pas et bien plus encore) : 9 étapes
Prototype Smart Motorcycle HUD (navigation pas à pas et bien plus encore) : 9 étapes

Vidéo: Prototype Smart Motorcycle HUD (navigation pas à pas et bien plus encore) : 9 étapes

Vidéo: Prototype Smart Motorcycle HUD (navigation pas à pas et bien plus encore) : 9 étapes
Vidéo: Leap Motion SDK 2024, Novembre
Anonim
Prototype Smart Motorcycle HUD (navigation pas à pas et bien plus encore)
Prototype Smart Motorcycle HUD (navigation pas à pas et bien plus encore)
Prototype Smart Motorcycle HUD (navigation pas à pas et bien plus encore)
Prototype Smart Motorcycle HUD (navigation pas à pas et bien plus encore)
Prototype Smart Motorcycle HUD (navigation pas à pas et bien plus encore)
Prototype Smart Motorcycle HUD (navigation pas à pas et bien plus encore)
Prototype Smart Motorcycle HUD (navigation pas à pas et bien plus encore)
Prototype Smart Motorcycle HUD (navigation pas à pas et bien plus encore)

Salut !

Ce Instructables est l'histoire de la façon dont j'ai conçu et construit une plate-forme HUD (Heads-Up Display) conçue pour être montée sur des casques de moto. Il a été écrit dans le cadre du concours "cartes". Malheureusement, je n'ai pas pu terminer complètement ce projet à temps pour la date limite du concours, mais je voulais quand même partager mes progrès à ce sujet, ainsi que documenter tous les essais et erreurs que j'ai eu en le réalisant.

L'idée de ce projet m'est venue pour la première fois il y a quelques années, lorsque je me suis lancé dans la moto, et je commençais à me demander quel équipement j'aurais besoin d'acheter pour rendre mes balades plus agréables. À l'époque, cela m'a déconcerté que la meilleure façon d'obtenir une navigation GPS de base pendant la conduite consistait essentiellement à attacher votre smartphone au guidon de votre vélo. Je me suis dit qu'il pourrait sûrement y avoir un meilleur moyen d'obtenir ce genre d'informations à la volée.

C'est à ce moment-là que j'ai compris: un affichage tête haute pourrait être le moyen d'obtenir la navigation en roulant, sans vider la batterie de votre téléphone et sans l'exposer aux éléments.

Au fil du temps, cette idée a mûri dans mon esprit, et je pensais qu'avoir un HUD devant moi à tout moment permettrait bien plus d'utilisations qu'une simple navigation. C'est pourquoi mon plan est de rendre la plate-forme publique et modulaire, afin que tout le monde puisse créer un module qui affiche les informations dont il a besoin sur son propre HUD

Bien qu'il existe des produits disponibles dans le commerce qui remplissent cette tâche, il n'y en a pas qui soient aussi modulaires que ma plate-forme, et ils ont également tendance à être un peu chers. Quoi qu'il en soit, bienvenue dans ce projet.

Ce qui fonctionne à partir de maintenant

Comme indiqué, ce projet est encore très en phase de développement, et c'est ce qui fonctionne actuellement.

- Communication entre un smartphone et une carte basée sur ESP32 (téléphone réveillé)

- Conception optique terminée (peut nécessiter de petits ajustements à long terme)

- Application de navigation Android utilisant le SDK de navigation Mapbox:

- Capable de calculer et d'afficher la position de l'utilisateur sur une carte, ainsi qu'un itinéraire de celle-ci à la destination

- Capable de se connecter à un appareil Bluetooth (l'adresse MAC de l'appareil est désormais codée en dur)

- Capable de navigation en temps réel, y compris l'extraction et l'envoi des informations de la manœuvre à venir via Bluetooth série (ne prend en charge que les virages pour l'instant)

Ce qui a besoin de travail

Cette liste contient des éléments qui sont absolument nécessaires pour l'utilisation prévue du HUD, mais qui ne sont pas encore prêts à être mis en œuvre.

- Conception globale (Fixation casque, mécanisme de réglage de l'angle du réflecteur,..)

- Application Android:

- Mettre en œuvre la détection et la correction hors route

- Possibilité pour l'utilisateur de saisir l'adresse de destination

- Points de passage ?

- Ergonomie / Esthétique

Fournitures:

Essentiel

- Une carte de développement basée sur esp32

- Tout smartphone android un peu récent (Bluetooth activé)

- Un SSD1306 ou autre écran OLED 96" activé (le mien faisait 128x64 pixels, voir partie " The brains: Microcontroller & Screen")

- Un réflecteur (n'importe quel morceau d'acrylique/verre/plexiglas fera l'affaire)

- Un objectif Fresnel (le mien avait une longueur F d'environ 13cm, voir partie "Choix de l'objectif")

Outils

- Fer à souder

- Planche à pain

- Quelques câbles de démarrage

- Imprimante 3D / Service d'impression 3D

Étape 1: Comment tout cela fonctionne: les choix de conception expliqués

Comment tout fonctionne: les choix de conception expliqués
Comment tout fonctionne: les choix de conception expliqués
Comment tout fonctionne: les choix de conception expliqués
Comment tout fonctionne: les choix de conception expliqués
Comment tout fonctionne: les choix de conception expliqués
Comment tout fonctionne: les choix de conception expliqués

L'idée de base d'un affichage tête haute est d'afficher une image devant la vision de quelqu'un, afin qu'il n'ait pas à détourner le regard de ce qu'il fait (que ce soit piloter un avion ou conduire une moto, ce qui sera notre cas d'exemple).

Optique

Techniquement, cela pourrait être réalisé en plaçant directement un écran devant les yeux de l'utilisateur. Or, un écran n'est pas transparent, et gênerait donc la vision de son utilisateur. Vous pouvez ensuite placer l'écran devant une surface réfléchissante, qui refléterait le contenu de l'écran tout en étant suffisamment transparent pour que l'utilisateur puisse voir ce qui se trouve devant lui.

Cependant, cette approche a un énorme défaut: l'écran réel est généralement plus proche des yeux de l'utilisateur que ce sur quoi l'utilisateur doit réellement se concentrer (par exemple la route devant lui). Cela signifie que, pour lire ce qui se trouve sur la surface réfléchissante, les yeux de l'utilisateur devraient s'adapter à la distance de l'écran par rapport à ses yeux (disons 20 cm), puis devraient s'adapter à nouveau afin de se concentrer sur la route à venir. (~2/5 mètres). Le temps que prend toute cette opération est un temps précieux qu'il faut consacrer à regarder la route, et s'adapter fréquemment peut être inconfortable pour l'utilisateur au bout de quelques minutes seulement.

C'est pourquoi j'ai décidé d'ajouter une lentille entre l'écran et le réflecteur. Cette lentille, si elle est choisie avec soin, devrait permettre de créer une image virtuelle de l'écran (voir schéma ci-dessus), qui apparaîtrait alors plus éloignée des yeux de l'utilisateur qu'elle ne l'est en réalité, nécessitant ainsi des adaptations moins brusques (ou aucun, dans un scénario parfait). Cette conception permet à l'utilisateur de jeter un coup d'œil rapide sur le réflecteur, d'obtenir les informations dont il a besoin et de regarder instantanément la route.

Le rôle du smartphone

Parce qu'il n'était pas réaliste d'essayer d'implémenter une application de navigation complète sur l'ESP32 seul, j'ai décidé de créer une application Android qui s'occuperait de cela. L'application aurait alors juste besoin d'indiquer à l'ESP32 ce que l'utilisateur doit faire pour se rendre à sa destination, et l'ESP32 transmettra cette information via le HUD (voir la figure "Comment fonctionne le module").

Étape 2: Pièces - les cerveaux: Microcontrôleur et écran

Pièces - les Cerveaux: Microcontrôleur & Écran
Pièces - les Cerveaux: Microcontrôleur & Écran
Pièces - les Cerveaux: Microcontrôleur & Écran
Pièces - les Cerveaux: Microcontrôleur & Écran

Comme indiqué ci-dessus, j'avais prévu que mon module affiche les informations de navigation, sans qu'il calcule réellement le positionnement, le suivi et la navigation en temps réel. le téléphone de l'utilisateur communiquerait à la place avec le module et lui enverrait les informations à afficher ensuite sur le HUD.

Pour faciliter la communication entre le téléphone de l'utilisateur et le module, j'ai choisi d'utiliser une carte basée sur ESP32 pour ce projet. Ce choix était dû à ce module spécifique ayant des capacités Bluetooth intégrées, ainsi qu'à quelques autres spécifications intéressantes (stockage non volatile facile à utiliser, CPU dual-core, suffisamment de RAM pour piloter réellement l'écran OLED via I2C, …). Il est relativement simple de concevoir des PCB autour de l'ESP32, ce que j'ai pris en compte. J'ai également une expérience professionnelle dans l'utilisation et la conception de circuits avec l'ESP32, ce qui a définitivement influencé mon choix.

Le choix de l'écran se résumait essentiellement à tout ce que je pouvais trouver et qui, selon moi, serait suffisamment lumineux pour votre utilisation, tout en étant aussi petit que possible. Je n'étais pas très inquiet du nombre de pixels de l'écran, car mon objectif était d'avoir une interface utilisateur très minimaliste et simple.

Il convient de noter que le pilote d'écran doit être pris en charge par une bibliothèque qui permet la mise en miroir d'images. C'est parce que l'image affichée est retournée lorsqu'elle passe à travers l'objectif et apparaît sur le réflecteur, et ne pas avoir à inverser manuellement ce qui est affiché est un poids énorme sur nos épaules en tant que constructeurs.

Étape 3: Pièces - Optique: Trouver un compromis

Pièces - Optique: Trouver un compromis
Pièces - Optique: Trouver un compromis
Pièces - Optique: Trouver un compromis
Pièces - Optique: Trouver un compromis
Pièces - Optique: Trouver un compromis
Pièces - Optique: Trouver un compromis

L'optique de ce projet était assez difficile à aborder, car je n'avais aucune idée de ce que je cherchais même lorsque j'ai commencé ce projet. Après quelques recherches, j'ai compris que ce que je voulais faire était de créer une "image virtuelle" de mon écran OLED, qui semblerait plus éloignée de l'œil qu'elle ne l'est en réalité. La distance idéale pour que cette image virtuelle se forme serait d'environ 2 à 5 mètres devant le conducteur, cela semble être la distance aux objets sur lesquels nous nous concentrons en conduisant (autres voitures, bosses sur la route, etc…).

Pour atteindre cet objectif, j'ai choisi d'utiliser une lentille de Fresnel, car elles sont assez grandes, bon marché, elles semblaient offrir une distance focale suffisante pour mon projet, et elles peuvent être coupées avec de simples ciseaux (ce qui n'est pas le cas pour verres ronds plus raffinés). Les lentilles de Fresnel peuvent être appelées « loupe de poche » ou « loupe de carte de lecture », car elles sont très appropriées pour aider les personnes malvoyantes à lire.

En gros, l'astuce ici consistait à trouver le bon compromis entre:

- Avoir une distance d'image virtuelle raisonnable (c'est-à-dire à quelle distance le HUD semblera être à l'utilisateur, ou à quelle distance l'utilisateur devra ajuster ses yeux pour voir ce qu'il y a sur le HUD)

- Faire en sorte que le texte à l'écran ne soit pas trop agrandi par l'objectif (qui est essentiellement une loupe)

- Avoir une distance raisonnable entre l'écran OLED et l'objectif, ce qui conduirait sinon à un module très encombrant

J'ai personnellement commandé quelques objectifs différents sur amazon, et déterminé leurs distances focales respectives, avant d'en choisir un avec une longueur F d'environ 13 cm. J'ai trouvé que cette longueur F, avec une distance OLED-Lens de 9 cm, m'a donné une image satisfaisante sur mon réflecteur (voir les dernières images ci-dessus).

Comme vous le verrez sur mes illustrations, afin de bien faire la mise au point sur le texte affiché, l'appareil photo utilisé pour prendre ces photos doit s'ajuster comme s'il faisait la mise au point sur un objet lointain, ce qui rend tout sur le même plan que le réflecteur semble flou. C'est exactement ce que nous voulons pour notre HUD.

Vous pouvez trouver les fichiers 3D pour le support d'objectif ici.

Étape 4: Pièces - un conteneur pour les contenir toutes

Pièces - un conteneur pour les contenir toutes
Pièces - un conteneur pour les contenir toutes
Pièces - un conteneur pour les contenir toutes
Pièces - un conteneur pour les contenir toutes

Au moment où j'écris ces Instructables, le conteneur réel qui contiendra chaque élément de l'affichage tête haute n'est pas tout à fait conçu. J'ai cependant quelques idées sur sa forme générale et sur la façon d'aborder certains problèmes (comme comment maintenir un réflecteur immobile et le faire résister à des vents de plus de 100 km/h). Il s'agit encore d'un travail en cours.

Étape 5: Création d'un protocole pour notre module

Afin d'envoyer les instructions de navigation du téléphone à la carte de développement, j'ai dû concevoir mon propre protocole de communication qui me permettrait d'envoyer facilement les données requises depuis le téléphone, tout en facilitant son traitement une fois reçu.

Au moment de la rédaction de ces Instructables, les informations qui devaient être transmises depuis le téléphone pour naviguer avec le module étaient:

- Le type de manœuvre à venir (virage simple, rond-point, fusion sur une autre route, …)

- Les consignes précises de la manœuvre à venir (selon le type de manœuvre: droite/gauche pour un virage; quelle sortie prendre pour un rond-point, …)

- La distance restante avant la manœuvre à venir (en mètres pour l'instant)

J'ai décidé d'organiser ces données en utilisant la structure de trame suivante:

:type.instructions, distance;

Sans être une belle solution, celle-ci nous permet de séparer et distinguer facilement chaque champ de notre protocole, ce qui a facilité le codage côté ESP32.

Il est important de garder à l'esprit que, pour les fonctionnalités futures, d'autres informations devront peut-être être ajoutées à ce protocole (comme le jour et l'heure exacts, ou la musique jouée sur le téléphone de l'utilisateur), ce qui serait facilement réalisable en utilisant le même logique de construction comme maintenant.

Étape 6: Le Code: Côté ESP32

Le Code: Côté ESP32
Le Code: Côté ESP32
Le Code: Côté ESP32
Le Code: Côté ESP32

Le code de l'ESP32 est actuellement assez simple. Il utilise la bibliothèque U8g2lib, qui permet un contrôle facile de l'écran OLED (tout en permettant la mise en miroir de l'image affichée).

Fondamentalement, tout ce que fait l'ESP32 est de recevoir des données série via Bluetooth lorsque l'application les envoie, de les analyser et d'afficher ces données ou images en fonction de ces données (c'est-à-dire afficher une flèche au lieu de la phrase "tourner à gauche/droite"). Voici le code:

/*Programme pour contrôler un HUD à partir d'une application Android via Bluetooth série*/#include "BluetoothSerial.h" //Fichier d'en-tête pour Bluetooth série, sera ajouté par défaut dans Arduino#include #include #ifdef U8X8_HAVE_HW_SPI#include #endif# ifdef U8X8_HAVE_HW_I2C#include #endif//Constructeur de bibliothèque OLED, doit être modifié en fonction de votre screenU8G2_SSD1306_128X64_ALT0_F_HW_I2C u8g2(U8G2_MIRROR, /* reset=*/ U8X8_PIN_NONE); // Machine d'état valeurs de champ_détecté + variable#define manoeuvrField 1#define instructionsField 2#define distanceField 3#define endOfFrame 4int detect_field = endOfFrame;BluetoothSerial serialBT; // Objet pour Bluetoothchar entrant_char;char manoeuvr[10];char instructions[10];char distance[10];char tempManeuver[10];char tempInstructions[10];char tempDistance[10];int nbr_char_maneuver = 0;int nbr_char_instructions = 0;int nbr_char_distance = 0;boolean fullsentence = false;void setup() { Serial.begin(9600); // Démarrer le moniteur série en 9600 bauds u8g2.begin(); // Init le contrôle OLED serialBT.begin("ESP32_BT"); // Nom du délai de signal Bluetooth(20); Serial.println("Le périphérique Bluetooth est prêt à être couplé");}void loop() { if (serialBT.available() && !fullsentence) // Caractères reçus via Bluetooth serial {incoming_char = serialBT.read(); Serial.print("Reçu:"); Serial.println(incoming_char); } switch (detected_field) { case manoeuvrField: Serial.println("Detected field: manoeuvre"); if (incoming_char == '.') // Champ suivant détecté { champ_détecté = champ d'instructions; } else { // Remplir le tableau d'informations sur le type de manœuvre manœuvre[nbr_char_maneuver] = entrant_char; nbr_char_manoeuvre ++; } Pause; case instructionsChamp: Serial.println("Champ détecté: instructions"); if (incoming_char == ', ') // Champ suivant détecté { champ_détecté = distanceField; } else { // Remplir le tableau d'informations sur les instructions instructions[nbr_char_instructions] =coming_char; nbr_char_instructions ++; } Pause; case distanceChamp: Serial.println("Champ détecté: distance"); if (incoming_char == ';') // Fin de la trame détectée { champ_détecté = endOfFrame; Serial.print("manoeuvre:"); Serial.println(manœuvre); Serial.print("instructions:"); Serial.println(instructions); Serial.print("distance:"); Serial.println(distance); phrase complète = vrai; update_Display(); // Pleine trame reçue, l'analyse et affiche les données du récepteur } else { // Remplit le tableau d'informations de distance distance[nbr_char_distance] = entrant_char; nbr_char_distance ++; } Pause; case endOfFrame: if (incoming_char == ':') detect_field = manoeuvrField; // Nouvelle pause détectée dans le cadre; par défaut: // Ne rien interrompre; } delay(20);}void update_Display(){ // Cache chaque tableau de caractères pour éviter d'éventuels conflits memcpy(tempManeuver, manoeuvre, nbr_char_maneuver); memcpy(tempInstructions, instructions, nbr_char_instructions); memcpy(tempDistance, distance, nbr_char_distance); parseCache(); // Analyse et traite les tableaux de caractères fullsentence = false; // Phrase traitée, prête pour la suivante}void parseCache(){ u8g2.clearBuffer(); // efface la mémoire interne u8g2.setFont(u8g2_font_ncenB10_tr); // choisissez une police appropriée // tableaux de caractères -> chaîne obligatoire pour utiliser la fonction substring() String manoeuvrString = tempManeuver; Instructions de chaîneString = tempInstructions; //Implémentation du protocole ici. Ne prend en charge que les virages pour le moment. if (maneuverString.substring(0, 4) == "turn") { // Vérifier le type de manœuvre Serial.print("TURN DETECTED"); if (instructionsString.substring(0, 5) == "right") { // Vérifier les instructions spécifiques et afficher en conséquence u8g2.drawStr(5, 15, "-"); } else if (instructionsString.substring(0, 4) == "left") { // Vérifier les instructions spécifiques et afficher en conséquence u8g2.drawStr(5, 15, "<---"); } else u8g2.drawStr(5, 15, "Err."); // Champ d'instructions invalide } /* Implémenter d'autres types de manœuvres (giratoires, etc.) * else if (tempManeuver == "rdbt"){ * *] */ u8g2.drawStr(5, 30, tempDistance); // Affiche la distance restante u8g2.sendBuffer(); // transfère la mémoire interne vers l'écran // Réinitialise tous les tableaux de caractères avant la prochaine lecture memset(maneuver, 0, 10); memset(instructions, 0, 10); memset(distance, 0, 10); memset(tempManoeuvre, 0, 10); memset(tempInstructions, 0, 10); memset(TempDistance, 0, 10); // Réinitialiser le nombre d'éléments dans les tableaux nbr_char_distance = 0; nbr_char_instructions = 0; nbr_char_manoeuvre = 0;}

Étape 7: Le Code: Côté Android

Le Code: Côté Android
Le Code: Côté Android
Le Code: Côté Android
Le Code: Côté Android
Le Code: Côté Android
Le Code: Côté Android

Pour l'application pour smartphone, j'ai décidé d'utiliser le SDK de navigation de Mapbox, car il offre de nombreuses fonctionnalités utiles pour créer une carte de navigation à partir de zéro. Il permet également l'utilisation de nombreux écouteurs utiles, qui aident certainement à faire fonctionner ce module. J'ai également utilisé la bibliothèque android-bluetooth-serial de harry1453 pour Android, car elle rendait la communication série Bluetooth beaucoup plus facile à mettre en place.

Si vous souhaitez créer cette application à la maison, vous aurez besoin d'un jeton d'accès Mapbox, qui est gratuit jusqu'à un certain nombre de demandes par mois. Vous devrez mettre ce jeton dans le code et créer l'application de votre côté. Vous devrez également coder l'adresse MAC Bluetooth de votre ESP32.

Dans l'état actuel des choses, l'application peut vous guider de votre position actuelle à n'importe quel endroit sur lequel vous pouvez cliquer sur la carte. Comme mentionné dans l'intro, cependant, il ne prend en charge aucune autre manœuvre que les virages et ne gère pas encore les hors-routes.

Vous pouvez trouver l'intégralité du code source sur mon github.

Étape 8: Et ensuite ?

Maintenant que l'application est suffisamment fonctionnelle pour guider son utilisateur sur un itinéraire défini (s'il n'y a pas d'écart par rapport à l'itinéraire défini), mon objectif principal sera d'améliorer l'application pour smartphone et de mettre en œuvre les quelques fonctionnalités qui feraient du module un appareil de navigation viable. Cela inclut l'activation de la communication Bluetooth depuis le téléphone même lorsque l'écran est éteint, ainsi que la prise en charge d'autres types de manœuvres (giratoires, fusion, …). Je mettrai également en œuvre une fonction de reroutage si l'utilisateur s'écarte de l'itinéraire d'origine.

Lorsque tout cela sera fait, j'améliorerai le conteneur et son mécanisme de fixation, je l'imprimerai en 3D et j'essaierai de prendre le module pour un premier essai.

Si tout se passe bien, mon objectif à long terme est de concevoir un PCB personnalisé pour l'électronique embarquée de ce projet, ce qui permettrait d'économiser beaucoup d'espace sur le produit final.

Je pourrais également ajouter d'autres fonctionnalités à ce module à l'avenir, notamment un affichage de l'heure, ainsi qu'une alarme de notification téléphonique, qui pourrait faire apparaître une icône lorsque l'utilisateur reçoit un message texte ou un appel. Enfin, j'aimerais ajouter des capacités Spotify à ce module, en tant que grand fan de musique. Cependant, à ce stade, ce n'est qu'un agréable à avoir.

Étape 9: Conclusion et remerciements spéciaux

Conclusion et merci spécial !
Conclusion et merci spécial !

Comme indiqué dans l'intro, bien que ce projet soit loin d'être terminé, je voulais vraiment le partager avec le monde, dans l'espoir qu'il puisse inspirer quelqu'un d'autre. Je voulais également documenter mes recherches sur ce sujet, car il n'y a pas vraiment beaucoup d'intérêt des amateurs pour les AR et les HUD, ce qui, je pense, est dommage.

Je tiens à remercier chaleureusement Awall99 et Danel Quintana, dont le projet respectif de réalité augmentée m'a beaucoup inspiré dans la réalisation de ce module.

Merci à tous pour votre attention, je ne manquerai pas de publier une mise à jour lorsque ce projet sera amélioré dans un proche avenir. En attendant, à plus tard !

Conseillé: