INHOUDSOPGAWE:

Infinity Bike - binnenshuise fietsopleiding videospeletjie: 5 stappe
Infinity Bike - binnenshuise fietsopleiding videospeletjie: 5 stappe

Video: Infinity Bike - binnenshuise fietsopleiding videospeletjie: 5 stappe

Video: Infinity Bike - binnenshuise fietsopleiding videospeletjie: 5 stappe
Video: RÜFÜS DU SOL ●● Innerbloom (Official Video) 2024, Junie
Anonim
Image
Image
Materiaal
Materiaal

Gedurende die winterseisoene, koue dae en slegte weer het fietsryers net 'n paar opsies om hul gunsteling sport te beoefen. Ons was op soek na 'n manier om binnenshuise opleiding met 'n fiets-/afrigteropset 'n bietjie meer vermaaklik te maak, maar die meeste produkte wat beskikbaar is, is duur of eenvoudig vervelig om te gebruik. Daarom het ons begin om Infinity Bike te ontwikkel as 'n Open Source -opleidingsvideospeletjie. Infinity -fiets lees die spoed en rigting van u fiets en bied 'n mate van interaktiwiteit wat nie maklik gevind kan word met fietstrainers nie.

Ons trek voordeel uit die eenvoud wat beskikbaar is by die Arduino -mikrobeheerder en 'n paar 3D -gedrukte onderdele om goedkoop sensors aan 'n fiets op 'n afrigter vas te maak. Die inligting word oorgedra na 'n videospeletjie wat gemaak is met die gewilde spelmotor, Unity. Aan die einde van hierdie instruksies, moet u u eie sensors op u fiets kan opstel en die inligting van u sensors na Unity kan oordra. Ons het selfs 'n baan ingesluit waarop u kan ry en u nuwe opset kan toets. As u belangstel om by te dra, kan u ons GitHub besoek.

Stap 1: materiaal

Materiaal
Materiaal

Die materiaallys wat u benodig, kan 'n bietjie verskil; vir

Byvoorbeeld, die grootte van u fiets bepaal die lengte van die springkabels wat u benodig, maar hier is die belangrikste onderdele wat u benodig. U kan waarskynlik goedkoper pryse vir elke stuk op die webwerf vind, soos AliExpress, maar om 6 maande te wag vir aflewering is nie altyd 'n opsie nie, so as u die effens duurder onderdele gebruik, word die skatting nie skeef nie.

1 x Arduino nano ($ 22,00)

1 x Mini Breadboard ($ 1,33/eenheid)

1 x 220 Ohm weerstand ($ 1,00/kit)

1 x 10K potensiometer ($ 1,80/eenheid)

1 x Hall -sensor ($ 0,96)

20 cm x 6 mm 3D -drukker se riem ($ 3,33)

1 kit x verskillende lengte M3 skroewe en boute ($ 6,82)

1 x fietsspoedmeter magneet ($ 0,98)

Ons het die materiaal hierbo gemonteer met 3D -gedrukte onderdele. Die lêers wat ons gebruik het, word hieronder gelys en het dieselfde nommer as die prent aan die begin van hierdie afdeling. Al die lêers kan op Thingiverse gevind word. U kan dit soos dit is, maar maak seker dat die afmetings wat ons gebruik het, by u fiets pas.

1. FrameConnection_PotentiometerHolder_U_Holder.stl

2. FrameConnection_Spacer.stl

3. BreadboardFrameHolder.stl

4. Katrol_PotentiometerSide.stl

5. Pot_PulleyConnection.stl

6. FrameConnection.stl

7. Katrol_HandleBarSide_Print2.stl

8. FrameToHallSensorConnector.stl

9. PotHolder.stl

10. HallSensorAttach.stl

Stap 2: Lees en dra data na eenheid

Lees en oordra van data na eenheid
Lees en oordra van data na eenheid

Die Arduino- en Unity -kode werk saam om

dra die data van die sensors op die fiets oor en verwerk dit. Unity sal die waarde van die Arduino versoek deur 'n string deur die reeks te stuur en wag totdat die Arduino reageer met die waardes wat versoek word.

Eerstens berei ons die Arduino voor met die Serial Command -biblioteek wat gebruik word om die versoeke van Unity te bestuur deur 'n versoekstring met 'n funksie te koppel. 'N Basiese opset vir hierdie biblioteek kan soos volg gemaak word;

#sluit "SerialCommand.h" in

SerialCommand sCmd; ongeldige opstelling () {sCmd.addCommand ("TRIGG", TriggHanlder); Serial.begin (9600); } leemte -lus () {terwyl (Serial.available ()> 0) {sCmd.readSerial (); }} nietig TriggHandler () { /*Lees en stuur die sensors hier* /}

Die funksie TriggHandler is aan die voorwerp SCmd gekoppel. As die reeks 'n string ontvang wat by die aangehegte opdrag pas (in hierdie geval TRIGG), word die funksie TriggHandler uitgevoer.

Ons gebruik 'n potensiometer om die stuurrigting te meet en 'n saalsensor om die rotasie per minuut van die fiets te meet. Die metings van die potensiometer kan maklik gemaak word met behulp van die ingeboude funksies van die Arduino. Die funksie TriggHandler kan die waarde na die reeks druk met die volgende verandering.

nietig TriggHandler () {

/*Lees die waarde van die potensiometer*/ Serial.println (analogRead (ANALOGPIN)); }

Die Hall -sensor het 'n bietjie meer opgestel voordat ons nuttige metings kan doen. In teenstelling met die potensiometer, is die onmiddellike waarde van die gangsensor nie baie nuttig nie. Aangesien ons probeer het om die snelheid van die wiel te meet, was die tyd tussen die snellers die belangstelling.

Elke funksie wat in die Arduino -kode gebruik word, neem tyd en as die magneet op die verkeerde tyd met die Hall -sensor in lyn kom, kan die meting op sy beste vertraag word of in die ergste geval heeltemal oorgeslaan word. Dit is natuurlik erg, want die Arduino kan 'n spoed wat baie anders is as die werklike snelheid van die wiel, rapporteer.

Om dit te vermy, gebruik ons 'n kenmerk van Arduinos genaamd attach interrupt, waarmee ons 'n funksie kan aktiveer wanneer 'n aangewese digitale pen met 'n stygende sein geaktiveer word. Die funksie rpm_fun is gekoppel aan 'n onderbreking met 'n enkele reël kode wat by die opstellingskode gevoeg is.

ongeldige opstelling () {

sCmd.addCommand ("TRIGG", TriggHanlder); attachInterrupt (0, rpm_fun, RISING); Serial.begin (9600); } // Die funksie rpm_fun word gebruik om die snelheid te bereken en word gedefinieer as; ongetekende lang lastRevolTime = 0; ongetekende lang revolSpeed = 0; leegte rpm_fun () {ongetekende lang revolTime = millis (); ongetekende lang deltaTime = revolTime - lastRevolTime; /*revolSpeed is die waarde wat oorgedra word na die Arduino -kode* / revolSpeed = 20000 / deltaTime; lastRevolTime = revolTime; } TriggHandler kan die res van die inligting dan op versoek stuur. void TriggHanlder () { /*Lees die waarde van die potensiometer* / Serial.println (analogRead (ANALOGPIN)); Serial.println (revolSpeed); }

Ons het nou al die boustene wat gebruik kan word om die Arduino -kode te bou wat data deur die reeks sal oordra na 'n versoek deur Unity. As u 'n afskrif van die volledige kode wil hê, kan u dit op ons GitHub aflaai. Om te toets of die kode korrek opgestel is, kan u die seriële monitor gebruik om TRIGG te stuur; maak seker dat u die reël wat eindig op vervoer terugkeer, stel. Die volgende afdeling fokus op hoe ons Unity -skrifte die inligting van die Arduino kan aanvra en ontvang.

Stap 3: Ontvang en verwerk data

Ontvangs en verwerking van data
Ontvangs en verwerking van data

Unity is 'n uitstekende sagteware wat gratis vir stokperdjies beskikbaar is

belangstel in wildmaak; Dit bevat 'n groot aantal funksies wat die tyd betyds kan besnoei om sekere dinge op te stel, soos threading of GPU -programmering (AKA -skaduwee), sonder om te beperk wat met die C# -scripts gedoen kan word. Unity- en Arduino -mikrobeheerders kan saam gebruik word om unieke interaktiewe ervarings met 'n relatief klein begroting te skep.

Die fokus van hierdie instruksies is om die kommunikasie tussen Unity en die Arduino op te stel, sodat ons nie te diep in die meeste van die funksies wat by Unity beskikbaar is, kan duik nie. Daar is baie wonderlike tutoriale vir eenheid en 'n ongelooflike gemeenskap wat baie beter kan werk om te verduidelik hoe Unity werk. Daar is egter 'n spesiale prys vir diegene wat daarin slaag om deur hierdie instruksies te werk, wat 'n klein toonbeeld is van wat gedoen kan word. U kan op ons Github ons eerste poging aflaai om 'n baan met realistiese fietsfisika te maak.

Eerstens, laat ons deur die minimum gaan wat nodig is om deur middel van die reeks met 'n Arduino te kommunikeer. Dit sal vinnig duidelik word dat hierdie kode nie geskik is vir spel nie, maar dit is goed om deur elke stap te gaan en te leer wat die beperkings is.

Skep in Unity 'n nuwe toneel met 'n enkele leë GameObject met die naam ArduinoReceive by 'n C# -skrif, ook genoem ArduinoReceive. Hierdie script is waar ons al die kode byvoeg wat die kommunikasie met die Arduino hanteer.

Daar is 'n biblioteek wat toegang moet hê voordat ons met die seriële poorte van u rekenaar kan kommunikeer; Daar moet 'n eenheid opgestel word sodat sekere biblioteke gebruik kan word. Gaan na Edit-> ProjectSerring-> Player en langs die Api-verenigbaarheidsvlak onder Configuration switch. NET 2.0 Subset na. NET 2.0. Voeg nou die volgende kode bo -aan die skrif by;

met behulp van System. IO. Ports;

Hiermee kry u toegang tot die SerialPort -klas wat u as 'n voorwerp van die ArduinoReceive -klas kan definieer. Maak dit privaat om inmenging deur 'n ander skrif te vermy.

private SerialPort arduinoPort;

Die voorwerp arduinoPort kan oopgemaak word deur die korrekte poort te kies (byvoorbeeld waarin USB die Arduino gekoppel is) en 'n baud -tempo (dit wil sê die snelheid waarmee die inligting gestuur word). As u nie seker is in watter poort die Arduino is ingeprop nie, kan u dit uitvind in die apparaatbestuurder of deur die Arduino IDE oop te maak. Vir die baud -tempo is die standaardwaarde op die meeste toestelle 9600; maak seker dat u hierdie waarde in u Arduino -kode het, en dit moet werk.

Die kode moet nou so lyk;

met behulp van System. Collections;

met behulp van System. Collections. Generic; gebruik UnityEngine; met behulp van System. IO. Ports; openbare klas ArduinoReceive: MonoBehaviour {private SerialPort arduinoPort; // Gebruik dit vir inisialisering leemte Start () {arduinoPort = nuwe SerialPort ("COM5", 9600); arduinoPort. Open (); WriteToArduino ("TRIGG"); }}

Jou COM -nommer sal waarskynlik anders wees. As u 'n MAC het, kan u COM -naam 'n naam hê wat so lyk /dev/cu.wchusbserial1420. Maak seker dat die kode uit afdeling 4 na die Arduino gelaai word en dat die seriële monitor vir die res van hierdie afdeling gesluit is en dat hierdie kode sonder probleme saamgestel word.

Laat ons nou elke raam 'n versoek aan die Arduino stuur en die resultate na die konsolvenster skryf. Voeg die WriteToArduino -funksie by die klas ArduinoReceive. Die koetsretour en die nuwe reël is nodig om die inkomende instruksie behoorlik te ontleed deur die Arduino -kode.

private leemte WriteToArduino (string boodskap)

{boodskap = boodskap + "\ r / n"; arduinoPort. Write (boodskap); arduinoPort. BaseStream. Flush (); }

Hierdie funksie kan dan in die opdateringslus genoem word.

ongeldige opdatering ()

{WriteToArduino ("TRIGG"); Debug. Log ("Eerste waarde:" + arduinoPort. ReadLine ()); Debug. Log ("Tweede waarde:" + arduinoPort. ReadLine ()); }

Die kode hierbo is die minimum wat u nodig het om die data van 'n Arduino te lees. As u baie aandag gee aan die FPS wat deur eenheid gegee word, behoort u prestasie aansienlik te daal. In my geval gaan dit van ongeveer 90 FPS sonder om te lees/skryf na 20 FPS. As u projek nie gereeld opdaterings benodig nie, is dit moontlik voldoende, maar vir 'n videospeletjie is 20 FPS veel te laag. Die volgende afdeling dek hoe u die prestasie kan verbeter deur multi -threading te gebruik.

Stap 4: Optimalisering van data -oordrag

Die vorige afdeling het gedek hoe om basies op te stel

kommunikasie tussen die Arduino- en Unity -program. Die grootste probleem met hierdie kode is die prestasie. In die huidige implementering moet Unity wag totdat die Arduino die versoek ontvang, verwerk en beantwoord. Gedurende hierdie tyd moet die Unity -kode wag totdat die versoek gedoen word en niks anders doen nie. Ons het hierdie probleem opgelos deur 'n draad te skep wat die versoeke hanteer en die veranderlike op die hoofdraad stoor.

Om te begin, moet ons die threading -biblioteek insluit deur by te voeg;

met behulp van System. Threading;

Vervolgens stel ons die funksie wat ons begin in die drade op. AsynchronousReadFromArduino begin deur die versoek aan die Arduino te skryf met die WrtieToArduino -funksie. Die lesing is ingeslote in 'n probeer-vang-blok, as die leestyd-uit, die veranderlikes ongeldig bly en die OnArduinoInfoFail-funksie in plaas van die OnArduinoInfoReceive genoem word.

Vervolgens definieer ons die funksies OnArduinoInfoFail en OnArduinoInfoReceive. Vir hierdie instruksies druk ons die resultate op die konsole, maar u kan die resultate stoor in die veranderlikes wat u benodig vir u projek.

privaat leemte OnArduinoInfoFail ()

{Debug. Log ("Lees misluk"); } private leemte OnArduinoInfoReceived (stringrotasie, stringsnelheid) {Debug. Log ("Readin Sucessfull"); Debug. Log ("Eerste waarde:" + rotasie); Debug. Log ("Tweede waarde:" + spoed); }

Die laaste stap is om die drade wat die waardes van die Arduino vra, te begin en te stop. Ons moet seker maak dat die laaste draad met die laaste taak klaar is voordat ons met 'n nuwe een begin. Andersins kan verskeie versoeke tegelyk aan die Arduino gerig word, wat die Arduino/eenheid kan verwar en onvoorspelbare resultate kan lewer.

private draad activeThread = null;

void Update () {if (activeThread == null ||! activeThread. IsAlive) {activeThread = new Thread (AsynchronousReadFromArduino); activeThread. Start (); }}

As u die prestasie van die kode vergelyk met die kode wat ons in afdeling 5 geskryf het, moet die prestasie aansienlik verbeter word.

privaat leemte OnArduinoInfoFail ()

{Debug. Log ("Lees misluk"); }

Stap 5: waarna volgende?

Waar volgende?
Waar volgende?

Ons het 'n demo voorberei wat u op ons Github (https://github.com/AlexandreDoucet/InfinityBike) kan aflaai, die kode en die speletjie aflaai en deur ons baan kan ry. Alles is gereed vir 'n vinnige oefensessie, en ons hoop dat dit u 'n voorsmakie kan gee van wat u kan bou as u dit wat ons u geleer het, gebruik.

Krediete

Projek bydraers

Alexandre Doucet (_Doucet_)

Maxime Boudreau (MxBoud)

Eksterne hulpbronne [The Unity game engine] (https://unity3d.com)

Hierdie projek het begin nadat ons die tutoriaal van Allan Zucconi gelees het oor "hoe om Arduino met Unity te integreer" (https://www.alanzucconi.com/2015/10/07/how-to-int…)

Die versoek van die Arduino word hanteer met behulp van die SerialCommand-biblioteek (https://github.com/kroimon/Arduino-SerialCommand)

Aanbeveel: