Inhoudsopgave:

Smart Motorcycle HUD-prototype (turn-by-turn navigatie en nog veel meer): 9 stappen
Smart Motorcycle HUD-prototype (turn-by-turn navigatie en nog veel meer): 9 stappen

Video: Smart Motorcycle HUD-prototype (turn-by-turn navigatie en nog veel meer): 9 stappen

Video: Smart Motorcycle HUD-prototype (turn-by-turn navigatie en nog veel meer): 9 stappen
Video: Leap Motion SDK 2024, November
Anonim
Smart Motorcycle HUD-prototype (turn-by-turn navigatie en nog veel meer)
Smart Motorcycle HUD-prototype (turn-by-turn navigatie en nog veel meer)
Smart Motorcycle HUD-prototype (turn-by-turn navigatie en nog veel meer)
Smart Motorcycle HUD-prototype (turn-by-turn navigatie en nog veel meer)
Smart Motorcycle HUD-prototype (turn-by-turn navigatie en nog veel meer)
Smart Motorcycle HUD-prototype (turn-by-turn navigatie en nog veel meer)
Smart Motorcycle HUD-prototype (turn-by-turn navigatie en nog veel meer)
Smart Motorcycle HUD-prototype (turn-by-turn navigatie en nog veel meer)

Hoi !

Deze Instructables is het verhaal van hoe ik een HUD-platform (Heads-Up Display) heb ontworpen en gebouwd dat is ontworpen om op motorhelmen te worden gemonteerd. Het is geschreven in het kader van de "kaarten"-wedstrijd. Helaas was ik niet in staat om dit project op tijd af te ronden voor de deadline van de wedstrijd, maar ik wilde toch mijn voortgang delen en alle vallen en opstaan documenteren die ik had om het te maken.

Het idee voor dit project kwam een paar jaar geleden voor het eerst bij me op, toen ik begon met motorfietsen, en ik begon te onderzoeken welke uitrusting ik zou moeten kopen om mijn ritten aangenamer te maken. Destijds verbaasde het me dat de beste manier om tijdens het rijden wat basis-gps-navigatie te krijgen, was om je smartphone in feite aan het stuur van je fiets te bevestigen. Ik dacht bij mezelf dat er zeker een betere manier zou kunnen zijn om dat soort informatie on-the-fly te krijgen.

Toen drong het tot me door: een heads-up display zou de manier kunnen zijn om tijdens het rijden navigatie te krijgen, zonder de batterij van je telefoon leeg te maken en bloot te stellen aan de elementen.

In de loop van de tijd groeide dit idee in mijn gedachten, en ik dacht dat als ik altijd een HUD voor me had, veel meer gebruik mogelijk zou zijn dan eenvoudige navigatie. Dit is de reden waarom mijn plan is om het platform openbaar en modulair te maken, zodat iedereen een module kan maken die de informatie weergeeft die ze nodig hebben op hun eigen HUD

Hoewel er in de handel verkrijgbare producten zijn die deze taak vervullen, zijn er geen die zo modulair zijn als mijn platform, en ze zijn ook vaak een beetje prijzig. Hoe dan ook, welkom bij dit project.

Wat werkt vanaf nu?

Zoals gezegd, bevindt dit project zich nog in een ontwikkelingsstadium en dit is wat momenteel werkt.

- Communicatie tussen een smartphone en een op ESP32 gebaseerd bord (telefoon wakker)

- Optica-ontwerp klaar (op de lange termijn kan het zijn dat er kleine aanpassingen nodig zijn)

- Android-navigatie-app met behulp van de Mapbox-navigatie-SDK:

- In staat om de positie van de gebruiker op een kaart te berekenen en weer te geven, evenals een route van daaruit naar de bestemming

- Kan verbinding maken met een Bluetooth-apparaat (het MAC-adres van het apparaat is vanaf nu hardcoded)

- Geschikt voor realtime navigatie, inclusief het extraheren en verzenden van de informatie van de komende manoeuvre via seriële Bluetooth (ondersteunt voorlopig alleen bochten)

Wat heeft werk nodig?

Deze lijst bevat items die absoluut noodzakelijk zijn voor het beoogde gebruik van de HUD, maar die nog niet klaar zijn om te worden geïmplementeerd.

- Algeheel ontwerp (helmbevestiging, hoekverstelmechanisme van de reflector,..)

- Android-app:

- Off-route detectie en correctie implementeren

- Mogelijkheid voor de gebruiker om het bestemmingsadres in te voeren

- Waypoints?

- Ergonomie / Esthetiek

Benodigdheden:

Benodigdheden

- Een op esp32 gebaseerd ontwikkelbord

- Elke enigszins recente Android-smartphone (Bluetooth ingeschakeld)

- Een SSD1306 of ander ingeschakeld 96" OLED-scherm (de mijne was 128x64 pixels, zie het gedeelte "The brains: Microcontroller & Screen")

- Een reflector (elk stuk acryl/glas/plexiglas is voldoende)

- Een Fresnel lens (de mijne had een F.lengte van ongeveer 13cm, zie "Lens keuze" gedeelte)

Gereedschap

- Soldeerbout

- Broodplank

- Een paar startkabels

- 3D-printer / 3D-afdrukservice

Stap 1: Hoe het allemaal werkt: ontwerpkeuzes uitgelegd

Hoe het allemaal werkt: ontwerpkeuzes uitgelegd
Hoe het allemaal werkt: ontwerpkeuzes uitgelegd
Hoe het allemaal werkt: ontwerpkeuzes uitgelegd
Hoe het allemaal werkt: ontwerpkeuzes uitgelegd
Hoe het allemaal werkt: ontwerpkeuzes uitgelegd
Hoe het allemaal werkt: ontwerpkeuzes uitgelegd

Het basisidee van een Heads Up Display is om een afbeelding voor iemands visie weer te geven, zodat ze niet weg hoeven te kijken van wat ze ook aan het doen zijn (of het nu gaat om een vliegtuig besturen of een motorfiets besturen, wat onze voorbeeld geval).

Optiek

Technisch gezien zou dit kunnen worden bereikt door een scherm recht voor de ogen van de gebruiker te plaatsen. Een scherm is echter niet transparant en zou daarom het zicht van de gebruiker belemmeren. Je zou het scherm dan voor een reflecterend oppervlak kunnen plaatsen, dat de inhoud van het scherm zou weerspiegelen en tegelijkertijd voldoende doorzichtig is zodat de gebruiker kan zien wat zich voor hem bevindt.

Deze benadering heeft echter een enorme tekortkoming: het eigenlijke scherm bevindt zich meestal dichter bij de ogen van de gebruiker dan waarop de gebruiker zich moet concentreren (bijv. de weg die voor hem ligt). Dit betekent dat, om te kunnen lezen wat er op het reflecterende oppervlak staat, de ogen van de gebruiker zich moeten aanpassen aan de afstand van het scherm tot zijn ogen (laten we zeggen 20 cm), en zich dan opnieuw moeten aanpassen om zich op de weg te kunnen concentreren. (~2/5 meter). De tijd die deze hele operatie in beslag neemt, is kostbare tijd die besteed zou moeten worden aan het kijken naar de weg, en het regelmatig aanpassen kan al na een paar minuten ongemakkelijk zijn voor de gebruiker.

Daarom heb ik besloten om een lens toe te voegen tussen het scherm en de reflector. Deze lens zou, indien zorgvuldig gekozen, het mogelijk moeten maken een virtueel beeld van het scherm te creëren (zie het schema hierboven), dat dan verder van de ogen van de gebruiker lijkt te zijn zoals het in werkelijkheid is, waardoor minder abrupte aanpassingen (of helemaal geen, in een perfect scenario). Dankzij dit ontwerp kan de gebruiker snel naar de reflector kijken, de informatie krijgen die hij nodig heeft en meteen weer omhoog kijken naar de weg.

De rol van de smartphone

Omdat het onrealistisch was om te proberen een hele navigatietoepassing alleen op de ESP32 te implementeren, besloot ik een Android-app te maken die hiervoor zou zorgen. De app hoeft dan alleen de ESP32 te vertellen wat de gebruiker moet doen om zijn bestemming te bereiken, en de ESP32 geeft die informatie door via de HUD (zie de afbeelding "Hoe de module werkt").

Stap 2: Onderdelen - de hersenen: microcontroller en scherm

Onderdelen - de hersenen: microcontroller en scherm
Onderdelen - de hersenen: microcontroller en scherm
Onderdelen - de hersenen: microcontroller en scherm
Onderdelen - de hersenen: microcontroller en scherm

Zoals hierboven vermeld, was ik van plan om mijn module navigatie-informatie te laten weergeven, terwijl het niet de werkelijke positionering, tracking en realtime navigatie zou laten berekenen. de telefoon van de gebruiker zou in plaats daarvan communiceren met de module en deze de informatie sturen om vervolgens op de HUD te worden weergegeven.

Om de communicatie tussen de telefoon van de gebruiker en de module te vergemakkelijken, heb ik ervoor gekozen om voor dit project een op ESP32 gebaseerd bord te gebruiken. Deze keuze was te wijten aan deze specifieke module met geïntegreerde Bluetooth-mogelijkheden, evenals enkele andere interessante specificaties (gemakkelijk te gebruiken niet-vluchtige opslag, dual-core CPU, voldoende RAM om het OLED-scherm daadwerkelijk aan te sturen via I2C, …). Het is relatief eenvoudig om PCB's te ontwerpen op basis van de ESP32, waar ik wel rekening mee heb gehouden. Ik heb ook professionele ervaring met het gebruik en ontwerpen van circuits met de ESP32, wat mijn keuze zeker heeft beïnvloed.

De keuze van het scherm kwam in feite neer op alles wat ik kon vinden dat ik echter helder genoeg zou zijn voor gebruik, terwijl het ook zo klein mogelijk zou zijn. Ik was niet erg bezorgd over het aantal pixels van het scherm, omdat het mijn doel was om een zeer minimalistische en eenvoudige gebruikersinterface te hebben.

Opgemerkt moet worden dat het schermstuurprogramma moet worden ondersteund door een bibliotheek die het spiegelen van afbeeldingen mogelijk maakt. Dat komt omdat het weergegeven beeld wordt omgedraaid wanneer het door de lens komt en op de reflector verschijnt, en het niet handmatig hoeven omkeren van wat wordt weergegeven, is een enorm gewicht van onze schouders als bouwers.

Stap 3: Onderdelen - Optica: een compromis vinden

Onderdelen - Optica: een compromis vinden
Onderdelen - Optica: een compromis vinden
Onderdelen - Optica: een compromis vinden
Onderdelen - Optica: een compromis vinden
Onderdelen - Optica: een compromis vinden
Onderdelen - Optica: een compromis vinden

De optica voor dit project was vrij moeilijk te benaderen, omdat ik geen idee had waar ik naar op zoek was toen ik voor het eerst aan dit project begon. Na wat onderzoek begreep ik dat ik een "virtueel beeld" van mijn OLED-scherm wilde maken, dat verder van het oog zou lijken dan het in werkelijkheid is. De ideale afstand om dit virtuele beeld te vormen zou ongeveer 2-5 meter voor de bestuurder zijn, a dit lijkt de afstand te zijn tot de objecten waarop we ons concentreren tijdens het rijden (andere auto's, hobbels op de weg, enz …).

Om dat doel te bereiken, heb ik ervoor gekozen om een Fresnel-lens te gebruiken, omdat deze vrij groot en goedkoop zijn, ze een voldoende brandpuntsafstand leken te bieden voor mijn project, en ze kunnen worden gesneden met een eenvoudige schaar (wat niet het geval is voor meer verfijnde ronde glazen lenzen). Fresnel-lenzen zijn te vinden met namen als "pocket magnifier" of "reading card magnifier", omdat ze zeer geschikt zijn om mensen met een slecht gezichtsvermogen te helpen bij het lezen.

Kortom, de truc hier was het vinden van het juiste compromis tussen:

- Een redelijke virtuele beeldafstand hebben (dat wil zeggen, hoe ver de HUD voor de gebruiker lijkt te zijn, of hoe ver de gebruiker zijn ogen moet aanpassen om te zien wat er op de HUD staat)

- Zorg ervoor dat de tekst op het scherm niet te vergroot wordt door de lens (wat in feite een vergrootglas is)

- Een redelijke afstand hebben tussen het OLED-scherm en de lens, wat anders zou leiden tot een zeer omvangrijke module

Ik heb persoonlijk een paar verschillende lenzen besteld bij amazon, en hun respectievelijke brandpuntsafstanden bepaald, voordat ik er een koos met een F.lengte van ongeveer 13 cm. Ik vond dat deze F.lengte, met een OLED-lensafstand van 9 cm, me een bevredigend beeld op mijn reflector gaf (zie de laatste paar afbeeldingen hierboven).

Zoals je op mijn illustraties zult zien, moet de camera die wordt gebruikt om deze foto's te maken, zich aanpassen alsof hij op een ver object scherpstelt, waardoor alles in hetzelfde vlak als de reflector wazig lijkt om goed scherp te stellen op de weergegeven tekst. Dit is precies wat we willen voor onze HUD.

De 3D-bestanden voor de lenshouder vind je hier.

Stap 4: Onderdelen - een container om ze allemaal op te bergen

Onderdelen - een container om ze allemaal op te bergen
Onderdelen - een container om ze allemaal op te bergen
Onderdelen - een container om ze allemaal op te bergen
Onderdelen - een container om ze allemaal op te bergen

Terwijl ik deze Instructables aan het schrijven ben, is de eigenlijke container die elk onderdeel van het heads-up display zal bevatten niet helemaal ontworpen. Ik heb echter wel een paar ideeën over de algemene vorm en over hoe bepaalde problemen aan te pakken (zoals hoe een reflector stil te houden en bestand te maken tegen wind van meer dan 100 km/u). Dit is nog volop werk in uitvoering.

Stap 5: Een protocol voor onze module maken

Om de navigatie-instructies van de telefoon naar het ontwikkelbord te sturen, moest ik een eigen communicatieprotocol bedenken waarmee ik gemakkelijk de vereiste gegevens vanaf de telefoon kon verzenden, terwijl ik ook de verwerking ervan na ontvangst zou vergemakkelijken.

Op het moment van schrijven van deze Instructables was de informatie die vanaf de telefoon moest worden verzonden om met de module te navigeren:

- Het type van de komende manoeuvre (eenvoudige afslag, rotonde, invoegen op een andere weg, …)

- De precieze instructies van de komende manoeuvre (afhankelijk van het type manoeuvre: rechts/links voor een afslag; welke afslag voor een rotonde, …)

- De resterende afstand voor de komende manoeuvre (voorlopig in meters)

Ik besloot deze gegevens te ordenen met behulp van de volgende framestructuur:

:type.instructies, afstand;

Hoewel het geen mooie oplossing is, stelt deze ons in staat om elk veld van ons protocol gemakkelijk te scheiden en te onderscheiden, wat de codering aan de ESP32-kant vergemakkelijkte.

Het is belangrijk om in gedachten te houden dat voor toekomstige functies mogelijk andere informatie aan dit protocol moet worden toegevoegd (zoals de exacte dag en tijd, of de muziek die wordt afgespeeld op de telefoon van de gebruiker), wat gemakkelijk haalbaar zou zijn met hetzelfde bouwlogica zoals nu.

Stap 6: De Code: ESP32 Side

De code: ESP32 kant
De code: ESP32 kant
De code: ESP32 kant
De code: ESP32 kant

De code voor de ESP32 is momenteel vrij eenvoudig. Het maakt gebruik van de U8g2lib-bibliotheek, die eenvoudige bediening van het OLED-scherm mogelijk maakt (terwijl spiegelen van het weergegeven beeld mogelijk is).

Kortom, het enige dat de ESP32 doet, is seriële gegevens ontvangen via Bluetooth wanneer de app deze verzendt, deze ontleden en deze gegevens of afbeeldingen weergeven op basis van deze gegevens (dwz een pijl weergeven in plaats van de zin "draai links/rechts"). Hier is de code:

/*Programma om een HUD te bedienen vanaf een Android-app via seriële bluetooth*/#include "BluetoothSerial.h" //Headerbestand voor seriële Bluetooth, wordt standaard toegevoegd aan Arduino#include #include #ifdef U8X8_HAVE_HW_SPI#include #endif# ifdef U8X8_HAVE_HW_I2C#include #endif//OLED-bibliotheekconstructor, moet dienovereenkomstig worden gewijzigd in uw schermU8G2_SSD1306_128X64_ALT0_F_HW_I2C u8g2(U8G2_MIRROR, /* reset=*/ U8X8_PIN_NONE); // Status machine gedetecteerde_veldwaarden + variabele#definieer manoeuvreField 1#definieer instructiesField 2#define distanceField 3#define endOfFrame 4int detected_field = endOfFrame;BluetoothSerial serialBT; // Object voor Bluetoothchar inkomende_char;char manoeuvre[10];char instructies[10];char afstand[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); // Start seriële monitor in 9600 bauds u8g2.begin(); // Init OLED-besturing serialBT.begin ("ESP32_BT"); // Naam van de vertraging van het Bluetooth-signaal (20); Serial.println ("Bluetooth-apparaat is klaar om te koppelen");}void loop() { if (serialBT.available() && !fullsentence) // Tekens die worden ontvangen via Bluetooth-serieel {inkomende_char = serialBT.read(); Serial.print("Ontvangen:"); Serial.println(inkomende_char); } switch (detected_field) { case manoeuvreField: Serial.println("Gedetecteerd veld: manoeuvre"); if (incoming_char == '.') // Volgend veld gedetecteerd {discovery_field = InstructionsField; } else { // Vul het type manoeuvre info array manoeuvre [nbr_char_maneuver] = inkomende_char; nbr_char_maneuver ++; } pauze; case-instructiesField: Serial.println("Gedetecteerd veld: instructies"); if (incoming_char == ', ') // Volgend veld gedetecteerd {discovery_field = distanceField; } else { // Vul de instructies in info array-instructies [nbr_char_instructions] = inkomende_char; nbr_char_instructions ++; } pauze; case distanceField: Serial.println ("Gedetecteerd veld: afstand"); if (incoming_char == ';') // Einde van frame gedetecteerd {detecteerde_field = endOfFrame; Serial.print("manoeuvre:"); Serial.println(manoeuvre); Serial.print("instructies:"); Serial.println(instructies); Serial.print("afstand:"); Serial.println(afstand); volledige zin = waar; update_Display(); // Full frame ontvangen, ontleden en ontvang gegevens weergeven } else { // Vul de afstand info array distance [nbr_char_distance] = inkomende_char; nbr_char_distance ++; } pauze; case endOfFrame: if (incoming_char == ':') detect_field = manoeuvreField; // Nieuw frame gedetecteerde pauze; standaard: // Niets breken; } delay(20);}void update_Display(){ // Cache elke char array om mogelijke conflicten te voorkomen memcpy(tempManeuver, manoeuvre, nbr_char_maneuver); memcpy(tempInstructions, instructies, nbr_char_instructions); memcpy(tempDistance, afstand, nbr_char_distance); ontledenCache(); // Ontleden en verwerken char arrays fullsentence = false; // Zin verwerkt, klaar voor de volgende}void parseCache(){u8g2.clearBuffer(); // wis het interne geheugen u8g2.setFont (u8g2_font_ncenB10_tr); // kies een geschikt lettertype // char arrays -> string verplicht om substring() functie te gebruiken String manoeuvreString = tempManeuver; String instructiesString = tempInstructions; // Protocol hier implementeren. Ondersteunt voorlopig alleen beurten. if (maneuverString.substring (0, 4) == "turn") { // Controleer op type manoeuvre Serial.print ("TURN DETECTED"); if (instructionsString.substring(0, 5) == "right") { // Controleer specifieke instructies en geef dienovereenkomstig weer u8g2.drawStr(5, 15, "-"); } else if (instructionsString.substring(0, 4) == "left") { // Controleer specifieke instructies en geef dienovereenkomstig weer u8g2.drawStr(5, 15, "<---"); } else u8g2.drawStr(5, 15, "Err."); // Ongeldig instructieveld } /* Implementeer andere manoeuvretypes (rotondes, etc..) * else if (tempManeuver == "rdbt"){ * *] */ u8g2.drawStr(5, 30, tempDistance); // Resterende afstand weergeven u8g2.sendBuffer (); // breng intern geheugen over naar het display // Reset alle char-arrays voor de volgende lezing memset (manoeuvre, 0, 10); memset (instructies, 0, 10); memset(afstand, 0, 10); memset(tempManoeuvre, 0, 10); memset(tempInstructions, 0, 10); memset(tempDistance, 0, 10); // Reset aantal elementen in arrays nbr_char_distance = 0; nbr_char_instructions = 0; nbr_char_maneuver = 0;}

Stap 7: De code: Android-kant

De code: Android-kant
De code: Android-kant
De code: Android-kant
De code: Android-kant
De code: Android-kant
De code: Android-kant

Voor de smartphone-app heb ik besloten om de navigatie-SDK van Mapbox te gebruiken, omdat deze veel handige functies biedt als het gaat om het helemaal opnieuw bouwen van een navigatiekaart. Het maakt het ook mogelijk om veel nuttige luisteraars te gebruiken, wat zeker helpt om deze module te laten werken. Ik gebruikte ook de android-bluetooth-seriële bibliotheek van harry1453 voor android, omdat het de seriële Bluetooth-communicatie een stuk eenvoudiger maakte om samen te stellen.

Als je deze app thuis wilt bouwen, heb je een Mapbox-toegangstoken nodig, dat gratis is tot een bepaald aantal verzoeken per maand. U moet dit token in de code plaatsen en de app aan uw zijde bouwen. U moet ook het Bluetooth MAC-adres van uw eigen ESP32 coderen.

Zoals het er nu uitziet, kan de app u van uw huidige locatie naar elke locatie leiden waarop u op de kaart kunt klikken. Zoals vermeld in de intro, ondersteunt het echter geen andere manoeuvres dan bochten en kan het nog geen off-routes aan.

Je kunt de hele broncode vinden op mijn github.

Stap 8: Wat nu?

Nu de app functioneel genoeg is om de gebruiker daadwerkelijk op een ingestelde route te begeleiden (als er geen afwijkingen van de ingestelde route zijn), zal mijn belangrijkste focus liggen op het verbeteren van de smartphone-app en het implementeren van de weinige mogelijkheden die de module een levensvatbaar navigatieapparaat. Dit omvat het inschakelen van Bluetooth-communicatie vanaf de telefoon, zelfs wanneer het scherm is uitgeschakeld, evenals ondersteuning voor andere soorten manoeuvres (rotondes, samenvoegen, …). Ik zal ook een herrouteringsfunctie implementeren als de gebruiker afwijkt van de oorspronkelijke route.

Wanneer dit allemaal is gebeurd, zal ik de container en het bevestigingsmechanisme verbeteren, deze in 3D printen en proberen de module voor het eerst te gebruiken.

Als alles goed gaat, is mijn langetermijndoel het ontwerpen van een aangepaste PCB voor de embedded elektronica van dit project, wat veel ruimte zou besparen op het eindproduct.

Ik zou in de toekomst mogelijk ook enkele andere functies aan deze module kunnen toevoegen, waaronder een tijdweergave, evenals een alarm voor een telefoonmelding, waardoor een pictogram kan verschijnen wanneer de gebruiker een sms-bericht of een oproep ontvangt. Tot slot zou ik als grote muziekliefhebber graag Spotify-mogelijkheden aan deze module willen toevoegen. Op dit moment is dit echter alleen maar leuk om te hebben.

Stap 9: Conclusie en speciale dank

Conclusie en speciale dank!
Conclusie en speciale dank!

Zoals vermeld in de intro, hoewel dit project nog lang niet klaar is, wilde ik het echt met de wereld delen, in de hoop dat het iemand anders zou kunnen inspireren. Ik wilde ook mijn onderzoek over dit onderwerp documenteren, omdat er niet echt veel hobbyisten zijn in AR en HUD's, wat ik jammer vind.

Ik wil Awall99 en Danel Quintana enorm bedanken, wiens respectieve augmented reality-project me enorm heeft geïnspireerd bij het maken van deze module.

Ik dank u allen voor uw aandacht, ik zal zeker een update plaatsen wanneer dit project in de nabije toekomst wordt verbeterd. In de tussentijd, tot later allemaal!

Aanbevolen: