Sisällysluettelo:

Infinity Bike - Sisäpyöräharjoittelun videopeli: 5 vaihetta
Infinity Bike - Sisäpyöräharjoittelun videopeli: 5 vaihetta

Video: Infinity Bike - Sisäpyöräharjoittelun videopeli: 5 vaihetta

Video: Infinity Bike - Sisäpyöräharjoittelun videopeli: 5 vaihetta
Video: Video To Anime - Generate An EPIC Animation From Your Phone Recording By Using Stable Diffusion AI 2024, Syyskuu
Anonim
Image
Image
Materiaalit
Materiaalit

Talvikausina, kylminä päivinä ja huonolla säällä pyöräilijöillä on vain muutama vaihtoehto harrastaa suosikkiurheiluaan. Etsimme tapaa tehdä sisäharjoittelusta pyörä/kouluttaja -asennuksella hieman viihdyttävämpää, mutta useimmat saatavilla olevat tuotteet ovat joko kalliita tai yksinkertaisesti tylsää käyttää. Tästä syystä aloimme kehittää Infinity Bikeä avoimen lähdekoodin koulutusvideopeliksi. Infinity -pyörä lukee pyörän nopeuden ja suunnan ja tarjoaa vuorovaikutteisuuden tason, jota ei löydy helposti pyöräkouluttajilta.

Hyödynnämme Arduinon mikro -ohjaimen yksinkertaisuutta ja muutamia 3D -tulostettuja osia varmistaaksemme edulliset anturit polkupyörään, joka on asennettu kouluttajaan. Tiedot välitetään videopelille, joka on tehty suositulla pelinvalmistusmoottorilla Unity. Tämän ohjeen loppuun mennessä sinun pitäisi pystyä asentamaan omat anturit pyörääsi ja siirtämään anturiesi tiedot Unitylle. Mukana oli jopa raita, jolla voit ajaa pitkin ja testata uutta kokoonpanoa. Jos olet kiinnostunut osallistumaan, voit tarkistaa GitHubin.

Vaihe 1: Materiaalit

Materiaalit
Materiaalit

Tarvitsemasi materiaaliluettelo saattaa vaihdella hieman; varten

Esimerkiksi pyöräsi koko määrää tarvittavien hyppyjohtojen pituudet, mutta tässä ovat tärkeimmät osat, joita tarvitset. Saatat luultavasti löytää halvempia hintoja jokaisesta kappaleesta verkkosivustolta, kuten AliExpress, mutta 6 kuukauden toimitusaika ei ole aina vaihtoehto, joten käytit hieman kalliimpia osia, joten arvio ei ole vääristynyt.

1 x Arduino nano (22,00 dollaria)

1 x Mini Breadboard (1,33 dollaria/yksikkö)

1 x 220 ohmin vastus (1,00 dollaria/pakkaus)

1 x 10K potentiometri (1,80 dollaria/yksikkö)

1 x Hall -anturi (0,96 dollaria)

20 cm x 6 mm 3D -tulostimen jakohihna (3,33 dollaria)

1 pakkaus x eri pituiset M3 -ruuvit ja -pultit (6,82 dollaria)

1 x polkupyörän nopeusmittarin magneetti (0,98 dollaria)

Asensimme yllä olevan materiaalin 3D -painetuilla osilla. Käyttämämme tiedostot on lueteltu alla ja ne on numeroitu samalla tavalla kuin tämän jakson alussa oleva kuva. Kaikki tiedostot löytyvät Thingiversesta. Voit käyttää niitä sellaisenaan, mutta varmista, että käyttämämme mitat vastaavat pyörääsi.

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

Vaihe 2: Tietojen lukeminen ja siirtäminen Unitylle

Tietojen lukeminen ja siirtäminen Unitylle
Tietojen lukeminen ja siirtäminen Unitylle

Arduino ja Unity -koodi toimivat yhdessä kerätäkseen

siirtää ja käsitellä tietoja pyörän antureista. Unity pyytää arvon Arduinolta lähettämällä merkkijonon sarjan kautta ja odota, että Arduino vastaa pyytämillään arvoilla.

Ensin valmistamme Arduinon Serial Command -kirjaston avulla, jota käytetään Unityn pyyntöjen hallintaan yhdistämällä pyyntöjono funktion kanssa. Tämän kirjaston perusasetukset voidaan tehdä seuraavasti;

#include "SerialCommand.h"

SerialCommand sCmd; void setup () {sCmd.addCommand ("TRIGG", TriggHanlder); Sarja.alku (9600); } void loop () {while (Serial.available ()> 0) {sCmd.readSerial (); }} void TriggHandler () { /*Lue ja lähetä anturit täältä* /}

Funktio TriggHandler on liitetty objektiin SCmd. Jos sarja vastaanottaa merkkijonon, joka vastaa liitettyä komentoa (tässä tapauksessa TRIGG), toiminto TriggHandler suoritetaan.

Käytämme potentiometriä ohjaussuunnan mittaamiseen ja hallin anturia polkupyörän kierrosta minuutissa. Potentiometrin lukemat voidaan tehdä helposti Arduinon sisäänrakennettujen toimintojen avulla. Toiminto TriggHandler voi tulostaa arvon sarjaan seuraavalla muutoksella.

void TriggHandler () {

/*Potentiometrin arvon lukeminen*/ Serial.println (analogRead (ANALOGPIN)); }

Hall -anturilla on hieman enemmän asetuksia, ennen kuin voimme saada hyödyllisiä mittauksia. Toisin kuin potentiometri, Hall -anturin hetkellinen arvo ei ole kovin hyödyllinen. Koska pyrittiin mittaamaan pyörän nopeutta, laukaisimien välinen aika kiinnosti.

Jokainen Arduino -koodissa käytetty toiminto vie aikaa, ja jos magneetti asettuu Hall -anturin kanssa väärään aikaan, mittaus voi parhaimmillaan viivästyä tai pahimmassa tapauksessa ohittaa kokonaan. Tämä on tietysti huono asia, koska Arduino voi ilmoittaa nopeuden, joka on PALJAS erilainen kuin pyörän todellinen nopeus.

Tämän välttämiseksi käytämme Arduinojen ominaisuutta, jota kutsutaan liitoskatkoksi, jonka avulla voimme käynnistää toiminnon aina, kun nimetty digitaalinen tappi laukaistaan nousevalla signaalilla. Toiminto rpm_fun on liitetty keskeytykseen, ja asetuskoodiin on lisätty yksi koodirivi.

void setup () {

sCmd.addCommand ("TRIGG", TriggHanlder); attachInterrupt (0, rpm_fun, RISING); Sarja.alku (9600); } // Funktiota rpm_fun käytetään nopeuden laskemiseen ja se määritellään seuraavasti; unsigned long lastRevolTime = 0; allekirjoittamaton pitkä kierrosluku = 0; void rpm_fun () {unsigned long revolTime = millis (); unsigned long deltaTime = revolTime - lastRevolTime; /*revolSpeed on Arduino -koodiin lähetetty arvo* / revolSpeed = 20000 / deltaTime; lastRevolTime = revolTime; } TriggHandler voi sitten lähettää loput tiedot pyydettäessä. void TriggHanlder () { /*Potentiometrin arvon lukeminen* / Serial.println (analogRead (ANALOGPIN)); Sarja.println (revolSpeed); }

Meillä on nyt kaikki rakennuspalikat, joita voidaan käyttää Arduino -koodin rakentamiseen, joka siirtää tiedot sarjan kautta siihen, kun Unity pyytää. Jos haluat saada kopion koko koodista, voit ladata sen GitHub -sivustoltamme. Voit testata, onko koodi asetettu oikein, käyttämällä sarjamonitoria lähettämään TRIGG; varmista, että olet asettanut rivin päättymisen Carriage return. Seuraavassa osassa keskitytään siihen, miten Unity -skriptimme voivat pyytää ja vastaanottaa tietoja Arduinolta.

Vaihe 3: Tietojen vastaanottaminen ja käsittely

Tietojen vastaanottaminen ja käsittely
Tietojen vastaanottaminen ja käsittely

Unity on loistava ohjelmisto, joka on saatavana ilmaiseksi harrastajalle

kiinnostunut pelien tekemisestä; sen mukana tulee suuri joukko toimintoja, jotka voivat todella lyhentää tiettyjen asioiden, kuten kierteitysten tai GPU -ohjelmoinnin (AKA -varjostus), määrittämisaikaa rajoittamatta sitä, mitä voidaan tehdä C# -komentosarjoilla. Unity- ja Arduino -mikro -ohjaimia voidaan käyttää yhdessä luomaan ainutlaatuisia interaktiivisia kokemuksia suhteellisen pienellä budjetilla.

Tämän ohjeen painopiste on auttaa Unityn ja Arduinon välisen viestinnän luomisessa, jotta emme sukella liian syvälle useimpiin Unityn ominaisuuksiin. Ykseydelle ja uskomattomalle yhteisölle on paljon upeita opetusohjelmia, jotka voisivat tehdä paljon parempaa työtä selittäen, kuinka Unity toimii. On kuitenkin erityispalkinto niille, jotka onnistuvat työskentelemään läpi tämän ohjeen, joka toimii pienenä esimerkkinä siitä, mitä voitaisiin tehdä. Voit ladata Github -sivustoltamme ensimmäisen yrityksemme luoda radan realistisella pyöräfysiikalla.

Käydään ensin läpi vähimmäismäärä, joka on tehtävä kommunikoidakseen Arduinon kanssa sarjan kautta. Nopeasti käy ilmi, että tämä koodi ei sovellu pelaamiseen, mutta on hyvä käydä läpi kaikki askeleet ja oppia rajoitukset.

Luo Unityssä uusi kohtaus yhdellä tyhjällä GameObject -nimisellä ArduinoRecept -liitteellä ja liitä C# -skripti, jonka nimi on myös ArduinoRecept. Tähän skriptiin lisätään kaikki koodit, jotka käsittelevät viestintää Arduinon kanssa.

On kirjasto, jolla on oltava pääsy, ennen kuin voimme kommunikoida tietokoneesi sarjaporttien kanssa. Unity on asetettava sallimaan tiettyjen kirjastojen käyttö. Valitse Edit-> ProjectSerring-> Player ja Api-yhteensopivuustason vieressä Configuration-kytkimessä. NET 2.0 -joukko. NET 2.0. Lisää nyt seuraava koodi komentosarjan yläosaan;

käyttämällä System. IO. Portsia;

Näin pääset käyttämään SerialPort -luokkaa, jonka voit määrittää ArduinoRecept -luokan objektiksi. Määritä se yksityiseksi, jotta vältät toisen komentosarjan häiriöt.

yksityinen SerialPort arduinoPort;

ArduinoPort -objekti voidaan avata valitsemalla oikea portti (esim. Mihin USB -liitäntään Arduino on kytketty) ja baudinopeus (eli nopeus, jolla tiedot lähetetään). Jos et ole varma, mihin porttiin Arduino on kytketty, voit selvittää sen joko laitteenhallinnassa tai avaamalla Arduino IDE: n. Siirtonopeuden useimpien laitteiden oletusarvo on 9600, tarkista vain, että tämä arvo on Arduino -koodissa ja sen pitäisi toimia.

Koodin pitäisi nyt näyttää tältä;

System. Collectionsin avulla;

käyttämällä System. Collections. Generic; käyttämällä UnityEngineä; käyttämällä System. IO. Portsia; julkinen luokka ArduinoVastaanota: MonoBehaviour {private SerialPort arduinoPort; // Käytä tätä alustamiseen void Start () {arduinoPort = new SerialPort ("COM5", 9600); arduinoPort. Open (); WriteToArduino ("TRIGG"); }}

COM -numerosi on todennäköisesti erilainen. Jos käytät MAC -tietokonetta, COM -nimelläsi voi olla nimi, joka näyttää tältä /dev/cu.wchusbserial1420. Varmista, että osion 4 koodi on ladattu Arduinoon ja sarjamonitori on suljettu tämän jakson loppuun ja että tämä koodi kääntyy ongelmitta.

Lähetämme nyt pyynnön Arduinolle joka kehyksessä ja kirjoitamme tulokset konsoli -ikkunaan. Lisää WriteToArduino -funktio luokkaan ArduinoRecept. Vaunun palautus ja uusi rivi ovat välttämättömiä, jotta Arduino -koodi jäsentää saapuvan käskyn oikein.

private void WriteToArduino (merkkijono)

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

Tätä toimintoa voidaan kutsua päivityssilmukassa.

mitätön päivitys ()

{WriteToArduino ("TRIGG"); Debug. Log ("Ensimmäinen arvo:" + arduinoPort. ReadLine ()); Debug. Log ("Toinen arvo:" + arduinoPort. ReadLine ()); }

Yllä oleva koodi on vähimmäismäärä, jonka tarvitset Arduinon tietojen lukemiseen. Jos kiinnität tarkkaa huomiota ykseyden antamaan FPS: ään, suorituskyky heikkenee merkittävästi. Minun tapauksessani se menee noin 90 FPS: stä ilman lukemista/kirjoittamista 20 FPS: ään. Jos projektisi ei vaadi usein päivityksiä, se saattaa riittää, mutta videopelille 20 FPS on aivan liian alhainen. Seuraavassa osassa käsitellään, kuinka voit parantaa suorituskykyä käyttämällä monisäikeistä.

Vaihe 4: Tiedonsiirron optimointi

Edellisessä osassa käsiteltiin perusasetusten määrittämistä

viestintä Arduinon ja Unity -ohjelman välillä. Tämän koodin suurin ongelma on suorituskyky. Nykyisessä toteutuksessa Unityn on odotettava, että Arduino vastaanottaa, käsittelee ja vastaa pyyntöön. Tänä aikana Unity -koodin on odotettava pyynnön suorittamista eikä tehdä mitään muuta. Ratkaisimme tämän ongelman luomalla säikeen, joka käsittelee pyynnöt ja tallentaa muuttujan päälankaan.

Aluksi meidän on sisällytettävä viestiketju lisäämällä;

käyttämällä System. Threading;

Seuraavaksi määritämme aloittamamme toiminnon säikeissä. AsynchronousReadFromArduino aloittaa kirjoittamalla pyynnön Arduinolle WrtieToArduino -toiminnolla. Lukema on suljettu try-catch-lohkoon, jos lukun aikakatkaisu, muuttujat pysyvät tyhjinä ja OnArduinoInfoFail-toiminto kutsutaan OnArduinoInfoRecept-sijasta.

Seuraavaksi määritellään OnArduinoInfoFail- ja OnArduinoInfoRecept -toiminnot. Tämän ohjeen vuoksi tulostamme tulokset konsoliin, mutta voit tallentaa tulokset projektisi tarvitsemiin muuttujiin.

private void OnArduinoInfoFail ()

{Debug. Log ("Lukeminen epäonnistui"); } private void OnArduinoInfoReceived (merkkijonon kierto, merkkijonon nopeus) {Debug. Log ("Readin Successfull"); Debug. Log ("Ensimmäinen arvo:" + kierto); Debug. Log ("Toinen arvo:" + nopeus); }

Viimeinen vaihe on aloittaa ja lopettaa säikeet, jotka pyytävät arvoja Arduinolta. Meidän on varmistettava, että viimeinen säie on tehty viimeisen tehtävän kanssa ennen uuden aloittamista. Muussa tapauksessa Arduinolle voitaisiin tehdä useita pyyntöjä kerralla, mikä voisi hämmentää Arduinoa/Unityä ja tuottaa odottamattomia tuloksia.

yksityinen säie activeThread = null;

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

Jos vertaat koodin suorituskykyä kohtaan, jonka kirjoitimme osioon 5, suorituskykyä pitäisi parantaa merkittävästi.

private void OnArduinoInfoFail ()

{Debug. Log ("Lukeminen epäonnistui"); }

Vaihe 5: Mihin seuraavaksi?

Missä seuraavaksi?
Missä seuraavaksi?

Valmistelimme demon, jonka voit ladata Github -sivustoltamme (https://github.com/AlexandreDoucet/InfinityBike), ladata koodin ja pelin ja ajaa radamme läpi. Kaikki on suunniteltu nopeaa harjoittelua varten ja toivomme, että se antaa sinulle maun siitä, mitä voisit rakentaa, jos käytät sitä, mitä olemme opettaneet sinulle tämän ohjeen avulla.

Laajuus

Projektin avustajat

Alexandre Doucet (_Doucet_)

Maxime Boudreau (MxBoud)

Ulkoiset resurssit [Unity -pelimoottori] (https://unity3d.com)

Tämä projekti alkoi, kun luimme Allan Zucconin opetusohjelman "kuinka integroida Arduino Unityyn" (https://www.alanzucconi.com/2015/10/07/how-to-int…)

Arduinon pyyntö käsitellään SerialCommand-kirjaston avulla (https://github.com/kroimon/Arduino-SerialCommand)

Suositeltava: