Tartalomjegyzék:

Infinity Bike - Beltéri Bike Training Videojáték: 5 lépés
Infinity Bike - Beltéri Bike Training Videojáték: 5 lépés

Videó: Infinity Bike - Beltéri Bike Training Videojáték: 5 lépés

Videó: Infinity Bike - Beltéri Bike Training Videojáték: 5 lépés
Videó: ALL INDIAN BIKE CHEAT CODE Colour changing indian Bikes Driving 3D CODE Indian bike game 3d code 2024, Június
Anonim
Image
Image
Anyagok
Anyagok

A téli szezonban, a hideg napokon és a rossz időjárás során a kerékpáros rajongóknak csak néhány lehetőségük van a kedvenc sportjukat gyakorolni. Kerestük a módját annak, hogy a beltéri edzéseket egy kerékpár/tréner beállítással egy kicsit szórakoztatóbbá tegyük, de a legtöbb rendelkezésre álló termék költséges vagy egyszerűen unalmas. Ezért kezdtük el az Infinity Bike fejlesztését nyílt forráskódú oktató videojátékként. Az Infinity bike leolvassa a sebességet és az irányt a kerékpárról, és olyan szintű interaktivitást kínál, amelyet nem könnyű megtalálni kerékpár -edzőkkel.

Kihasználjuk az Arduino mikrokontroller és néhány 3D nyomtatott alkatrész egyszerűségét, hogy olcsó érzékelőket rögzítsünk a trénerre szerelt kerékpárhoz. Az információkat a népszerű játékgyártó motorral, a Unity -vel készített videojátékhoz továbbítják. Ennek az utasításnak a végére képesnek kell lennie arra, hogy beállítsa saját érzékelőit a kerékpárra, és továbbítsa az érzékelők adatait a Unity-nek. Még egy pályát is beiktattunk, amelyen végiglovagolhat és kipróbálhatja új beállításait. Ha szeretne hozzájárulni, ellenőrizze GitHub oldalunkat.

1. lépés: Anyagok

Anyagok
Anyagok

A szükséges anyagok listája kissé eltérhet; számára

Például a kerékpár mérete határozza meg a szükséges áthidaló kábelek hosszát, de itt vannak a fő alkatrészek, amelyekre szüksége lesz. Valószínűleg olcsóbb árakat találhat az egyes darabokért az olyan webhelyeken, mint az AliExpress, de 6 hónapot várni a szállításra nem mindig választható, ezért a kissé drágább alkatrészeket használta, így a becslés nem torzul.

1 x Arduino nano (22,00 USD)

1 x Mini Breadboard (1,33 USD/egység)

1 x 220 ohmos ellenállás (1,00 USD/készlet)

1 x 10K potenciométer (1,80 USD/egység)

1 x Hall -érzékelő (0,96 dollár)

20 cm x 6 mm -es 3D nyomtató vezérműszíja (3,33 USD)

1 készlet x Különböző hosszúságú M3 csavarok és csavarok (6,82 USD)

1 x kerékpáros sebességmérő mágnes (0,98 USD)

A fenti anyagot 3D nyomtatott alkatrészekkel szereltük fel. Az általunk használt fájlok az alábbiakban vannak felsorolva, és ugyanazzal a konvencióval vannak számozva, mint a jelen szakasz elején található kép. Az összes fájl megtalálható a Thingiverse webhelyen. Használhatja őket úgy, ahogy vannak, de győződjön meg arról, hogy az általunk használt méretek megegyeznek a kerékpárjával.

1. FrameConnection_PotentiometerHolder_U_Holder.stl

2. FrameConnection_Spacer.stl

3. BreadboardFrameHolder.stl

4. Csiga_PotentiometerSide.stl

5. Pot_PulleyConnection.stl

6. FrameConnection.stl

7. Pulley_HandleBarSide_Print2.stl

8. FrameToHallSensorConnector.stl

9. PotHolder.stl

10. HallSensorAttach.stl

2. lépés: Adatok olvasása és átvitele a Unity -be

Adatok olvasása és átvitele a Unity -hez
Adatok olvasása és átvitele a Unity -hez

Az Arduino és a Unity kód együtt fog összegyűjteni, továbbítsa és dolgozza fel a kerékpár érzékelőinek adatait. A Unity az értéket kéri az Arduino -tól, ha egy karakterláncot küld a sorozaton keresztül, és várja, hogy az Arduino válaszoljon a kért értékekkel.

Először előkészítjük az Arduino programot a Serial Command könyvtárral, amelyet a Unity kéréseinek kezelésére használunk egy kérés karakterlánc és egy függvény párosításával. Ennek a könyvtárnak az alapbeállítása az alábbiak szerint végezhető el;

#include "SerialCommand.h"

SerialCommand sCmd; void setup () {sCmd.addCommand ("TRIGG", TriggHanlder); Sorozat.kezdet (9600); } void loop () {while (Serial.available ()> 0) {sCmd.readSerial (); }} void TriggHandler () { /*Olvassa el és továbbítsa az érzékelőket itt* /}

A TriggHandler függvény az SCmd objektumhoz van csatolva. Ha a sorozat a csatolt paranccsal (ebben az esetben TRIGG) megegyező karakterláncot kap, akkor a TriggHandler függvény kerül végrehajtásra.

A kormányzás irányát potenciométerrel, a kerékpár percenkénti fordulatszámát csarnokérzékelővel használjuk. A potenciométer leolvasása könnyen elvégezhető az Arduino beépített funkcióival. A TriggHandler függvény ezután ki tudja nyomtatni az értéket a sorozatba a következő módosítással.

void TriggHandler () {

/*A potenciométer értékének leolvasása*/ Serial.println (analogRead (ANALOGPIN)); }

A Hall -érzékelő egy kicsit több beállítással rendelkezik, mielőtt hasznos méréseket végezhetünk. A potenciométerrel ellentétben a hall -érzékelő pillanatnyi értéke nem túl hasznos. Mivel a kerék sebességét próbálták mérni, a kiváltások közötti idő érdekelt.

Az Arduino kódban használt minden funkció időbe telik, és ha a mágnes nem megfelelő időben illeszkedik a Hall -érzékelőhöz, a mérés a legjobb esetben késleltethető, vagy rosszul teljesen kihagyható. Ez nyilvánvalóan rossz, mert az Arduino olyan sebességet tud jelenteni, amely SOKKAL eltér a kerék tényleges sebességétől.

Ennek elkerülése érdekében az Arduinos egy olyan funkcióját használjuk, amelyet csatolás megszakításnak hívnak, amely lehetővé teszi számunkra, hogy aktiváljunk egy funkciót, amikor egy kijelölt digitális tűt növekvő jelzéssel aktiválnak. Az rpm_fun függvény egy megszakításhoz van csatolva, egyetlen sor kóddal a beállítási kódhoz hozzáadva.

void setup () {

sCmd.addCommand ("TRIGG", TriggHanlder); attachInterrupt (0, rpm_fun, RISING); Sorozat.kezdet (9600); } // Az rpm_fun függvény a sebesség kiszámítására szolgál, és a következőképpen van definiálva: unsigned long lastRevolTime = 0; előjel nélküli hosszú fordulatszám = 0; void rpm_fun () {unsigned long revolTime = millis (); előjel nélküli hosszú deltaTime = revolTime - lastRevolTime; /*revolSpeed az Arduino kódba továbbított érték* / revolSpeed = 20000 / deltaTime; lastRevolTime = revolTime; } A TriggHandler kérésre továbbítja a többi információt. void TriggHanlder () { /*A potenciométer értékének leolvasása* / Serial.println (analogRead (ANALOGPIN)); Serial.println (revolSpeed); }

Most már rendelkezünk az összes olyan építőelemmel, amely felhasználható az Arduino kód felépítéséhez, amely az adatokat a sorozaton keresztül továbbítja a Unity kérésére. Ha meg szeretné kapni a teljes kód másolatát, letöltheti azt a GitHub oldalunkról. Annak ellenőrzéséhez, hogy a kód megfelelően lett-e beállítva, a soros monitor segítségével küldheti el a TRIGG-t; győződjön meg róla, hogy a sor végét Carriage return értékre állította. A következő szakasz arra fog összpontosítani, hogy Unity -szkriptjeink hogyan kérhetik és fogadhatják az Arduino -tól származó információkat.

3. lépés: Adatok fogadása és feldolgozása

Adatok fogadása és feldolgozása
Adatok fogadása és feldolgozása

A Unity egy nagyszerű szoftver, amely ingyenesen elérhető a hobbisták számára

érdekli a játékkészítés; nagyszámú funkcióval rendelkezik, amelyek valóban lerövidíthetik az idő beállítását bizonyos dolgok, például a szálazás vagy a GPU programozás (AKA árnyékolás) beállításához anélkül, hogy korlátoznák a C# szkriptekkel végrehajtható műveleteket. A Unity és az Arduino mikrokontrollerek együttesen egyedülálló interaktív élményeket hozhatnak létre viszonylag kis költségvetéssel.

Ennek az utasításnak a középpontjában az Unity és az Arduino közötti kommunikáció kialakításának elősegítése áll, hogy ne merüljünk túl mélyen a Unity által elérhető legtöbb funkcióban. Rengeteg NAGY oktatóanyag létezik az egységhez és egy hihetetlen közösséghez, amelyek sokkal jobban meg tudnák magyarázni az Unity működését. Van azonban különdíj azoknak, akiknek sikerül végigcsinálniuk ezt az oktatható anyagot, amely egy kis bemutatója annak, hogy mit lehetne tenni. Letöltheti a Github -ról az első kísérletünket egy pálya elkészítésére realisztikus kerékpárfizikával.

Először nézzük végig a minimumot, amit meg kell tenni annak érdekében, hogy kommunikálni tudjunk egy Arduino -val a sorozaton keresztül. Gyorsan nyilvánvalóvá válik, hogy ez a kód nem alkalmas játékra, de jó, ha minden lépést végigmegy, és megtudja, milyen korlátok vannak.

A Unity -ben hozzon létre egy új jelenetet egyetlen üres GameObject -el, ArduinoRecept néven, és csatoljon egy C# szkriptet, más néven ArduinoRecept -et. Ebben a szkriptben adjuk hozzá az Arduino -val való kommunikációt kezelő összes kódot.

Van egy könyvtár, amelynek hozzáféréssel kell rendelkeznie, mielőtt kommunikálni tudunk a számítógép soros portjaival; A Unity-t úgy kell beállítani, hogy bizonyos könyvtárak használhatók legyenek. Lépjen a Szerkesztés-> ProjectSerring-> Lejátszó menübe, majd az Api kompatibilitási szint mellett a Konfiguráció kapcsoló alatt. NET 2.0 alhalmaz. NET 2.0-ra. Most adja hozzá a következő kódot a szkript tetejéhez;

a System. IO. Ports használatával;

Ez lehetővé teszi a hozzáférést a SerialPort osztályhoz, amelyet objektumként definiálhat az ArduinoReception osztályhoz. Tegye priváttá, hogy elkerülje a másik szkript beavatkozását.

privát SerialPort arduinoPort;

Az arduinoPort objektum a megfelelő port (pl. Melyik USB -hez csatlakoztatva van az Arduino) és az adatátviteli sebesség (azaz az információ küldésének sebessége) kiválasztásával nyitható meg. Ha nem biztos abban, hogy az Arduino melyik portjához van csatlakoztatva, akkor az eszközkezelőben vagy az Arduino IDE megnyitásával megtudhatja. Az átviteli sebesség esetében a legtöbb eszköz alapértelmezett értéke 9600, csak győződjön meg róla, hogy ez az érték szerepel az Arduino kódban, és működnie kell.

A kódnak most így kell kinéznie;

a System. Collections használatával;

a System. Collections. Generic használatával; a UnityEngine használatával; a System. IO. Ports használatával; nyilvános osztály ArduinoRecept: MonoBehaviour {private SerialPort arduinoPort; // Használja ezt az inicializáláshoz void Start () {arduinoPort = new SerialPort ("COM5", 9600); arduinoPort. Open (); WriteToArduino ("TRIGG"); }}

A COM -szám valószínűleg más lesz. Ha MAC -t használ, akkor a COM neve is így nézhet ki: /dev/cu.wchusbserial1420. Győződjön meg arról, hogy a 4. szakaszból származó kódot feltöltötte az Arduino -ba, és a soros monitor zárva van a szakasz további részében, és hogy ez a kód gond nélkül összeáll.

Most küldjünk egy kérést az Arduino -nak minden képkockára, és írjuk az eredményeket a konzol ablakába. Adja hozzá a WriteToArduino függvényt az ArduinoRecept osztályhoz. A kocsivissza és az új sor szükséges ahhoz, hogy az Arduino kód megfelelően elemezze a bejövő utasítást.

private void WriteToArduino (karakterlánc)

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

Ezt a funkciót ezután meg lehet hívni az Update ciklusban.

érvénytelen frissítés ()

{WriteToArduino ("TRIGG"); Debug. Log ("Első érték:" + arduinoPort. ReadLine ()); Debug. Log ("Második érték:" + arduinoPort. ReadLine ()); }

A fenti kód a minimum, amire szüksége van az Arduino adatainak olvasásához. Ha nagy figyelmet fordít az egység által adott FPS -re, akkor jelentősen csökken a teljesítmény. Az én esetemben ez körülbelül 90 FPS -ről megy olvasás/írás nélkül 20 FPS -re. Ha a projekt nem igényel gyakori frissítéseket, akkor elegendő lehet, de egy videojátékhoz a 20 FPS túl alacsony. A következő szakasz bemutatja, hogyan javíthatja a teljesítményt a többszálú menet használatával.

4. lépés: Az adatátvitel optimalizálása

Az előző szakasz az alapvető beállításokat ismertette

kommunikáció az Arduino és a Unity program között. Ennek a kódnak a fő problémája a teljesítmény. A jelenlegi megvalósításban az Unity -nek meg kell várnia, amíg az Arduino megkapja, feldolgozza és válaszol a kérésre. Ez idő alatt a Unity kódnak meg kell várnia a kérés végrehajtását, és nem tesz mást. Ezt a problémát úgy oldottuk meg, hogy létrehoztunk egy szálat, amely kezeli a kéréseket és tárolja a változót a fő szálon.

Kezdésként be kell vennünk a szálkötő könyvtárat hozzáadásával;

a System. Threading használatával;

Ezután a szálakban beállítjuk a megkezdett függvényt. Az AsynchronousReadFromArduino azzal kezdődik, hogy a WrtieToArduino függvénnyel megküldi a kérést az Arduino -nak. Az olvasást egy try-catch blokk zárja, ha az olvasási időtúllépés, a változók nullák maradnak, és az OnArduinoInfoFail függvényt hívják meg az OnArduinoInfoRecept helyett.

Ezután meghatározzuk az OnArduinoInfoFail és az OnArduinoInfoRecept függvényeket. Ebből az utasításból kinyomtatjuk az eredményeket a konzolra, de az eredményeket eltárolhatja a projekthez szükséges változókban.

private void OnArduinoInfoFail ()

{Debug. Log ("Az olvasás sikertelen"); } private void OnArduinoInfoReceived (karakterlánc forgatás, karakterlánc sebesség) {Debug. Log ("Readin Successfull"); Debug. Log ("Első érték:" + forgatás); Debug. Log ("Második érték:" + sebesség); }

Az utolsó lépés a szálak elindítása és leállítása, amelyek az értékeket kérik az Arduino -tól. Biztosítanunk kell, hogy az utolsó szál befejeződött az utolsó feladattal, mielőtt újat kezdenénk. Ellenkező esetben egyszerre több kérést is el lehet intézni az Arduino -hoz, ami megzavarhatja az Arduino/Unity -t, és kiszámíthatatlan eredményeket hozhat.

private Thread activeThread = null;

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

Ha összehasonlítja a kód teljesítményét azzal, amelyet az 5. szakaszban írtunk, a teljesítmény jelentősen javul.

private void OnArduinoInfoFail ()

{Debug. Log ("Az olvasás sikertelen"); }

5. lépés: Hol tovább?

Hol tovább?
Hol tovább?

Készítettünk egy demót, amelyet letölthet a Github -ról (https://github.com/AlexandreDoucet/InfinityBike), letöltheti a kódot és a játékot, és végigjárhatja a pályánkat. Mindez egy gyors edzésre van beállítva, és reméljük, hogy ízelítőt adhat abból, amit felépíthet, ha felhasználja azt, amit tanítottunk ezzel az utasítással.

Hitelek

Projekt közreműködői

Alexandre Doucet (_Doucet_)

Maxime Boudreau (MxBoud)

Külső erőforrások [The Unity game engine] (https://unity3d.com)

Ez a projekt azután kezdődött, hogy elolvastuk Allan Zucconi oktatóanyagát "hogyan integrálhatjuk az Arduinot az Unity-val" (https://www.alanzucconi.com/2015/10/07/how-to-int…)

Az Arduino kérését a SerialCommand könyvtár segítségével kezeljük (https://github.com/kroimon/Arduino-SerialCommand)

Ajánlott: