Obsah:

Infinity Bike - Vnútorná školenie bicykla Videohra: 5 krokov
Infinity Bike - Vnútorná školenie bicykla Videohra: 5 krokov

Video: Infinity Bike - Vnútorná školenie bicykla Videohra: 5 krokov

Video: Infinity Bike - Vnútorná školenie bicykla Videohra: 5 krokov
Video: Fast and easy way to assemble Infinity Boss Three Disc Bicycle in less than 8 mins 2024, Jún
Anonim
Image
Image
Materiály
Materiály

V zimnom období, chladných dňoch a zlom počasí majú cyklistickí nadšenci len niekoľko možností, ako cvičiť a robiť svoj obľúbený šport. Hľadali sme spôsob, ako urobiť školenie v interiéri s nastavením bicykla/trenažéra o niečo zábavnejším, ale väčšina dostupných produktov je buď nákladná, alebo je používanie jednoducho nudné. Preto sme začali vyvíjať Infinity Bike ako tréningovú videohru s otvoreným zdrojom. Bicykel Infinity číta rýchlosť a smer z vášho bicykla a ponúka úroveň interaktivity, akú s cyklotrenažérmi len tak ľahko nenájdete.

Využívame jednoduchosť, ktorú ponúka mikrokontrolér Arduino a niekoľko 3D tlačených dielov, na zaistenie lacných senzorov k bicyklu upevnenému na trenažéri. Informácie sú prenášané do videohry vytvorenej pomocou populárneho enginu na tvorbu hier, Unity. Na konci tohto návodu by ste mali byť schopní nastaviť vlastné senzory na svojom bicykli a prenášať informácie o svojich senzoroch do Unity. Zahrnuli sme dokonca aj trať, na ktorej sa môžete povoziť a vyskúšať si svoje nové usporiadanie. Ak máte záujem prispieť, môžete sa prihlásiť na náš GitHub.

Krok 1: Materiály

Materiály
Materiály

Zoznam materiálov, ktorý budete potrebovať, sa môže trochu líšiť; pre

napríklad veľkosť vášho bicykla bude diktovať dĺžky prepojovacích káblov, ktoré potrebujete, ale tu sú hlavné časti, ktoré budete potrebovať. Na webových stránkach, ako je AliExpress, by ste pravdepodobne mohli nájsť lacnejšie ceny za každý kus, ale 6 mesiacov čakať na odoslanie nie je vždy možné, preto sme používali o niečo drahšie diely, takže odhad nie je skreslený.

1 x Arduino nano (22,00 dolárov)

1 x Mini Breadboard (1,33 USD/jednotka)

1 x odpor 220 ohmov (1,00 dolára/súprava)

1 x 10 000 potenciometer (1,80 USD/jednotka)

1 x Hallov senzor (0,96 USD)

Rozvodový remeň 3D tlačiarne 20 cm x 6 mm (3,33 USD)

1 súprava x rôzne skrutky a skrutky s dĺžkou M3 (6,82 USD)

1 x magnet na rýchlomer bicykla (0,98 dolára)

Materiál sme namontovali vyššie pomocou 3D tlačených dielov. Súbory, ktoré sme použili, sú uvedené nižšie a sú očíslované rovnakým spôsobom ako obrázok na začiatku tejto sekcie. Všetky súbory nájdete na Thingiverse. Môžete ich používať tak, ako sú, ale uistite sa, že rozmery, ktoré sme použili, zodpovedajú vášmu bicyklu.

1. FrameConnection_PotentiometerHolder_U_Holder.stl

2. FrameConnection_Spacer.stl

3. BreadboardFrameHolder.stl

4. Pulley_PotentiometerSide.stl

5. Pot_PulleyConnection.stl

6. FrameConnection.stl

7. Pulley_HandleBarSide_Print2.stl

8. FrameToHallSensorConnector.stl

9. PotHolder.stl

10. HallSensorAttach.stl

Krok 2: Čítanie a prenos údajov do Unity

Čítanie a prenos údajov do Unity
Čítanie a prenos údajov do Unity

Kód Arduino a Unity budú spolupracovať na zhromažďovaní, prenášať a spracovávať údaje zo senzorov na bicykli. Unity vyžiada hodnotu od Arduina odoslaním reťazca cez sériový port a počká, kým Arduino odpovie požadovanými hodnotami.

Najprv pripravíme Arduino s knižničným sériovým príkazom, ktorý sa používa na správu požiadaviek z Unity spárovaním reťazca požiadaviek s funkciou. Základné nastavenie pre túto knižnicu je možné vykonať nasledovne;

#include "SerialCommand.h"

SerialCommand sCmd; neplatné nastavenie () {sCmd.addCommand ("TRIGG", TriggHanlder); Serial.begin (9600); } void loop () {while (Serial.available ()> 0) {sCmd.readSerial (); }} neplatné TriggHandler () { /*Tu si prečítajte a preneste senzory* /}

K objektu SCmd je pripojená funkcia TriggHandler. Ak seriál dostane reťazec, ktorý zodpovedá priloženému príkazu (v tomto prípade TRIGG), vykoná sa funkcia TriggHandler.

Potenciometrom meriame smer riadenia a Hallovým senzorom otáčky bicykla za minútu. Hodnoty z potenciometra je možné ľahko vykonať pomocou vstavaných funkcií z Arduina. Funkcia TriggHandler potom môže vytlačiť hodnotu do seriálu s nasledujúcou zmenou.

neplatné TriggHandler () {

/*Odčítanie hodnoty potenciometra*/ Serial.println (analogRead (ANALOGPIN)); }

Hallův senzor má trochu viac nastavení, než budeme mať k dispozícii užitočné merania. Na rozdiel od potenciometra nie je okamžitá hodnota Hallovho senzora príliš užitočná. Pretože sa pokúšali zmerať rýchlosť kolesa, zaujímal sa čas medzi spúšťami.

Každá funkcia použitá v kóde Arduino potrebuje čas a ak sa magnet zarovná s Hallovým senzorom v nesprávnom čase, meranie sa môže prinajlepšom oneskoriť alebo v najhoršom prípade preskočiť. To je samozrejme zlé, pretože Arduino dokázal nahlásiť rýchlosť, ktorá je MNOHEM odlišná od skutočnej rýchlosti kolesa.

Aby sme tomu zabránili, používame funkciu Arduinos nazývanú pripojiť prerušenie, ktorá nám umožňuje spustiť funkciu vždy, keď je určený digitálny pin spustený so stúpajúcim signálom. Funkcia rpm_fun je pripojená k prerušeniu jediným riadkom kódu pridaným do inštalačného kódu.

neplatné nastavenie () {

sCmd.addCommand ("TRIGG", TriggHanlder); attachInterrupt (0, rpm_fun, RISING); Serial.begin (9600); } // Funkcia rpm_fun sa používa na výpočet rýchlosti a je definovaná ako; unsigned long lastRevolTime = 0; nepodpísaná dlhá revolSpeed = 0; void rpm_fun () {unsigned long revolTime = millis (); nepodpísaný dlhý deltaTime = revolTime - lastRevolTime; /*revolSpeed je hodnota prenášaná do kódu Arduino* / revolSpeed = 20 000 / deltaTime; lastRevolTime = revolTime; } TriggHandler potom môže na požiadanie odoslať ostatné informácie. neplatné TriggHanlder () { /*Čítanie hodnoty potenciometra* / Serial.println (analogRead (ANALOGPIN)); Serial.println (revolSpeed); }

Teraz máme všetky stavebné bloky, ktoré je možné použiť na zostavenie kódu Arduino, ktorý bude prenášať údaje cez sériové číslo na žiadosť Unity. Ak chcete mať kópiu celého kódu, môžete si ho stiahnuť na našom GitHube. Ak chcete otestovať, či bol kód správne nastavený, môžete na odoslanie TRIGG použiť sériový monitor; uistite sa, že ste nastavili koniec riadka na Návrat na koniec. Nasledujúca časť sa zameria na to, ako naše skripty Unity môžu požadovať a prijímať informácie z Arduina.

Krok 3: Príjem a spracovanie údajov

Prijímanie a spracovanie údajov
Prijímanie a spracovanie údajov

Unity je skvelý softvér, ktorý je k dispozícii zadarmo pre domácich majstrov

záujem o tvorbu hier; prichádza s veľkým počtom funkcií, ktoré môžu skutočne obmedziť čas pri nastavovaní určitých vecí, ako je napríklad vytváranie vlákien alebo programovanie GPU (tieňovanie AKA), bez obmedzenia toho, čo je možné robiť so skriptmi C#. Mikrokontroléry Unity a Arduino je možné použiť spoločne na vytváranie jedinečných interaktívnych zážitkov s relatívne malým rozpočtom.

Cieľom tohto pokynu je pomôcť nastaviť komunikáciu medzi Unity a Arduino, aby sme sa neponáhľali príliš hlboko do väčšiny funkcií dostupných v Unity. Existuje množstvo VEĽKÝCH návodov pre jednotu a neuveriteľnú komunitu, ktoré by dokázali lepšie fungovať a vysvetliť, ako funguje Unity. Pre tých, ktorým sa podarí prepracovať sa cez tento návod, ktorý slúži ako malá ukážka toho, čo sa dá urobiť, však existuje špeciálna cena. Na našom serveri Github si môžete stiahnuť náš prvý pokus o vytvorenie trate s realistickou fyzikou bicykla.

Najprv si prejdeme úplné minimum, ktoré je potrebné vykonať, aby sme mohli komunikovať s Arduinom prostredníctvom seriálu. Rýchlo sa ukáže, že tento kód nie je vhodný na hranie, ale je dobré prejsť každým krokom a zistiť, aké sú obmedzenia.

V Unity vytvorte novú scénu s jediným prázdnym objektom GameObject s názvom ArduinoReceive a pripojte skript C# s názvom ArduinoReceive. V tomto skripte pridáme všetok kód, ktorý zvláda komunikáciu s Arduinom.

Aby sme mohli komunikovať so sériovými portami vášho počítača, musí mať prístup knižnica; Jednota musí byť nastavená tak, aby umožňovala používanie určitých knižníc. Prejdite na položku Upraviť-> ProjectSerring-> Hráč a vedľa úrovne kompatibility Api v časti Konfigurácia prepnite podmnožinu. NET 2.0 na. NET 2.0. Teraz pridajte nasledujúci kód do hornej časti skriptu;

pomocou System. IO. Ports;

To vám umožní prístup k triede SerialPort, ktorú by ste mohli definovať ako objekt triedy ArduinoReceive. Nastavte ho ako súkromný, aby ste predišli rušeniu iným skriptom.

súkromný SerialPort arduinoPort;

Objekt arduinoPort je možné otvoriť výberom správneho portu (napr. V ktorom USB je Arduino pripojené) a prenosovej rýchlosti (t.j. rýchlosti, ktorou sa informácie odosielajú). Ak si nie ste istí, v ktorom porte je Arduino zapojené, môžete to zistiť buď v správcovi zariadení, alebo otvorením Arduino IDE. Pre prenosovú rýchlosť je predvolená hodnota pre väčšinu zariadení 9600, uistite sa však, že máte túto hodnotu v kóde Arduino a mala by fungovať.

Kód by teraz mal vyzerať takto;

pomocou System. Collections;

pomocou System. Collections. Generic; pomocou UnityEngine; pomocou System. IO. Ports; verejná trieda ArduinoReceive: MonoBehaviour {private SerialPort arduinoPort; // Použite to na inicializáciu void Start () {arduinoPort = new SerialPort ("COM5", 9600); arduinoPort. Open (); WriteToArduino ("TRIGG"); }}

Vaše číslo COM bude s najväčšou pravdepodobnosťou odlišné. Ak používate MAC, vaše meno COM môže mať názov, ktorý vyzerá takto /dev/cu.wchusbserial1420. Uistite sa, že kód z časti 4 je nahraný do Arduina a sériový monitor je zatvorený pre zvyšok tejto sekcie a že tento kód sa kompiluje bez problémov.

Teraz pošleme požiadavku Arduinu na každý rámec a zapíšeme výsledky do okna konzoly. Pridajte funkciu WriteToArduino do triedy ArduinoReceive. Návrat na vozík a nový riadok sú potrebné na to, aby kód Arduino správne analyzoval prichádzajúce inštrukcie.

súkromné neplatné WriteToArduino (reťazcová správa)

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

Túto funkciu je potom možné vyvolať v slučke Update.

zrušiť aktualizáciu ()

{WriteToArduino ("TRIGG"); Debug. Log („Prvá hodnota:“+ arduinoPort. ReadLine ()); Debug. Log ("Druhá hodnota:" + arduinoPort. ReadLine ()); }

Vyššie uvedený kód je nevyhnutné minimum, ktoré potrebujete na prečítanie údajov z Arduina. Ak budete venovať veľkú pozornosť FPS daným jednotou, mali by ste vidieť výrazný pokles výkonu. V mojom prípade to ide od zhruba 90 FPS bez čítania/zápisu do 20 FPS. Ak váš projekt nevyžaduje časté aktualizácie, môže to stačiť, ale pre videohry je 20 snímok za sekundu príliš málo. Nasledujúca časť sa bude zaoberať tým, ako môžete zlepšiť výkon pomocou viacvláknového vlákna.

Krok 4: Optimalizácia prenosu údajov

Predchádzajúca časť sa zaoberala tým, ako nastaviť základné

komunikácia medzi programom Arduino a Unity. Hlavným problémom tohto kódu je výkon. V súčasnej implementácii musí Unity počkať, kým Arduino žiadosť prijme, spracuje a odpovie. Za ten čas musí kód Unity počkať, kým sa žiadosť dokončí, a neurobí nič iné. Tento problém sme vyriešili vytvorením vlákna, ktoré bude spracovávať požiadavky a ukladať premennú do hlavného vlákna.

Na začiatok musíme zahrnúť knižnicu vlákien pridaním;

pomocou System. Threading;

Ďalej nastavíme funkciu, ktorú začíname vo vláknach. AsynchronousReadFromArduino začína napísaním požiadavky na Arduino s funkciou WrtieToArduino. Čítanie je uzavreté v bloku try-catch, ak časový limit čítania zostane, premenné zostanú prázdne a namiesto funkcie OnArduinoInfoReceive sa zavolá funkcia OnArduinoInfoFail.

Ďalej definujeme funkcie OnArduinoInfoFail a OnArduinoInfoReceive. Pre tento návod vytlačíme výsledky do konzoly, ale výsledky môžete uložiť do premenných, ktoré potrebujete pre svoj projekt.

súkromná prázdnota OnArduinoInfoFail ()

{Debug. Log ("Čítanie zlyhalo"); } súkromné neplatné OnArduinoInfoReceived (striedanie reťazcov, rýchlosť reťazca) {Debug. Log ("Readin Sucessfull"); Debug. Log ("Prvá hodnota:" + otočenie); Debug. Log ("Druhá hodnota:" + rýchlosť); }

Posledným krokom je spustenie a zastavenie vlákien, ktoré budú požadovať hodnoty od Arduina. Pred spustením nového vlákna musíme zaistiť, aby bolo posledné vlákno dokončené s jeho poslednou úlohou. V opačnom prípade by bolo možné na Arduino odoslať viac žiadostí naraz, čo by mohlo zamieňať Arduino/Unity a priniesť nepredvídateľné výsledky.

private Thread activeThread = null;

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

Ak porovnáte výkonnosť kódu s tým, ktorý sme napísali v časti 5, výkon by sa mal výrazne zlepšiť.

súkromná prázdnota OnArduinoInfoFail ()

{Debug. Log ("Čítanie zlyhalo"); }

Krok 5: Kam ďalej?

Kam ďalej?
Kam ďalej?

Pripravili sme demo, ktoré si môžete stiahnuť na našom Github (https://github.com/AlexandreDoucet/InfinityBike), stiahnuť kód a hru a prejsť sa po našej trati. Všetko je pripravené na rýchle cvičenie a dúfame, že vám môže poskytnúť predstavu o tom, čo by ste mohli vybudovať, ak použijete to, čo sme vás naučili pomocou tohto návodu.

Kredity

Prispievatelia projektu

Alexandre Doucet (_Doucet_)

Maxime Boudreau (MxBoud)

Externé zdroje [herný engine Unity] (https://unity3d.com)

Tento projekt sa začal potom, ako sme si prečítali návod od Allana Zucconiho „Ako integrovať Arduino s jednotou“(https://www.alanzucconi.com/2015/10/07/how-to-int…)

Žiadosť od Arduina sa spracúva pomocou knižnice SerialCommand (https://github.com/kroimon/Arduino-SerialCommand)

Odporúča: