Kazalo:
- 1. korak: Materiali
- 2. korak: branje in prenos podatkov v Unity
- 3. korak: Prejemanje in obdelava podatkov
- 4. korak: Optimiziranje prenosa podatkov
- 5. korak: Kje naprej?
Video: Infinity Bike - Video igra za usposabljanje koles v zaprtih prostorih: 5 korakov
2024 Avtor: John Day | [email protected]. Nazadnje spremenjeno: 2024-01-30 12:07
V zimskih časih, hladnih dneh in slabem vremenu imajo ljubitelji kolesarjev le nekaj možnosti za vadbo, ki se jim zdi najljubši šport. Iskali smo način, kako narediti vadbo v zaprtih prostorih s postavitvijo kolesa/trenerja nekoliko bolj zabavno, vendar je večina razpoložljivih izdelkov draga ali preprosto dolgočasna za uporabo. Zato smo začeli razvijati Infinity Bike kot odprtokodno izobraževalno video igro. Infinity bike bere hitrost in smer vašega kolesa in ponuja raven interaktivnosti, ki je pri trenerjih za kolo ni mogoče najti.
Izkoristimo preprostost, ki je na voljo pri mikrokrmilniku Arduino, in nekaj 3D tiskanih delov, da pritrdimo poceni senzorje na kolo, nameščeno na vadbeni enoti. Podatki se posredujejo videoigri, izdelani s priljubljenim motorjem za ustvarjanje iger Unity. Do konca teh navodil bi morali na svojem kolesu nastaviti lastne senzorje in podatke o svojih senzorjih prenesti v Unity. Vključili smo celo stezo, na kateri se lahko peljete in preizkusite svojo novo postavitev. Če želite prispevati, lahko preverite naš GitHub.
1. korak: Materiali
Seznam materialov, ki ga boste potrebovali, se lahko nekoliko razlikuje; za
na primer, velikost vašega kolesa bo določala dolžino skakalnih kablov, ki jih potrebujete, tukaj pa so glavni deli, ki jih boste potrebovali. Na spletnem mestu, kot je AliExpress, bi verjetno lahko našli cenejše cene za vsak kos, vendar čakanje na pošiljanje 6 mesecev ni vedno možnost, zato ste uporabili nekoliko dražje dele, tako da ocena ni napačna.
1 x Arduino nano (22,00 USD)
1 x Mini plošča (1,33 USD/enoto)
1 x 220 ohmski upor (1,00 USD/komplet)
1 x 10K potenciometer (1,80 USD/enoto)
1 x Hall senzor (0,96 USD)
Zobati jermen za 3D tiskalnik 20 cm x 6 mm (3,33 USD)
1 komplet x Vijaki in vijaki M3 različnih dolžin (6,82 USD)
1 x magnet za merilnik hitrosti kolesa (0,98 USD)
Zgornji material smo namestili s 3D tiskanimi deli. Datoteke, ki smo jih uporabili, so navedene spodaj in so oštevilčene z isto konvencijo kot slika na začetku tega razdelka. Vse datoteke najdete na Thingiverse. Uporabite jih lahko takšne, kot so, vendar pazite, da se dimenzije, ki smo jih uporabili, ujemajo z vašim kolesom.
1. FrameConnection_PotenciometerHolder_U_Holder.stl
2. FrameConnection_Spacer.stl
3. BreadboardFrameHolder.stl
4. Stranski jermen_potenciometra.stl
5. Pot_PulleyConnection.stl
6. FrameConnection.stl
7. Jermenica_Ročna ročicaSrčna_print2.stl
8. FrameToHallSensorConnector.stl
9. PotHolder.stl
10. HallSensorAttach.stl
2. korak: branje in prenos podatkov v Unity
Koda Arduino in Unity bosta skupaj zbirali, prenos in obdelava podatkov s senzorjev na kolesu. Unity bo zahteval vrednost od Arduina tako, da bo niz poslal po nizu in počakal, da se Arduino odzove z zahtevanimi vrednostmi.
Najprej pripravimo Arduino s knjižničnim zaporednim ukazom, ki se uporablja za upravljanje zahtev iz Unityja tako, da poveže niz zahtev s funkcijo. Osnovno nastavitev te knjižnice lahko naredite na naslednji način;
#include "SerialCommand.h"
SerialCommand sCmd; void setup () {sCmd.addCommand ("TRIGG", TriggHanlder); Serial.begin (9600); } void loop () {while (Serial.available ()> 0) {sCmd.readSerial (); }} void TriggHandler () { /*Tukaj preberite in prenesite senzorje* /}
Funkcija TriggHandler je pritrjena na objekt SCmd. Če serijski niz prejme niz, ki ustreza priloženemu ukazu (v tem primeru TRIGG), se izvede funkcija TriggHandler.
Za merjenje smeri krmiljenja uporabljamo potenciometer, za merjenje vrtenja kolesa na minuto pa halsov senzor. Odčitke s potenciometra je mogoče enostavno narediti z vgrajenimi funkcijami iz Arduina. Funkcija TriggHandler lahko nato natisne vrednost v serijo z naslednjo spremembo.
void TriggHandler () {
/*Odčitavanje vrednosti potenciometra*/ Serial.println (analogRead (ANALOGPIN)); }
Hallov senzor ima nekoliko več nastavitev, preden lahko uporabimo meritve. V nasprotju s potenciometrom trenutna vrednost senzorja za hodnike ni zelo uporabna. Ker so poskušali izmeriti hitrost kolesa, je čas med sprožilci tisto, kar je zanimalo.
Vsaka funkcija, uporabljena v kodi Arduino, potrebuje čas in če se magnet poravna s Hall -jevim senzorjem ob napačnem času, bi lahko meritev v najboljšem primeru zamudili ali v najslabšem primeru popolnoma preskočili. To je očitno slabo, ker bi lahko Arduino poročal o hitrosti, ki je veliko drugačna od dejanske hitrosti kolesa.
Da bi se temu izognili, uporabljamo funkcijo Arduinosa, imenovano attach prekinitev, ki nam omogoča, da sprožimo funkcijo, kadar se sproži določen digitalni pin z naraščajočim signalom. Funkcija rpm_fun je pritrjena na prekinitev z eno vrstico kode, dodano nastavitveni kodi.
void setup () {
sCmd.addCommand ("TRIGG", TriggHanlder); attachInterrupt (0, rpm_fun, RISING); Serial.begin (9600); } // Funkcija rpm_fun se uporablja za izračun hitrosti in je definirana kot; unsigned long lastRevolTime = 0; brez podpisa dolga revolSpeed = 0; void rpm_fun () {unsigned long revolTime = millis (); nepodpisano dolgo deltaTime = revolTime - lastRevolTime; /*revolSpeed je vrednost, prenesena v kodo Arduino* / revolSpeed = 20000 / deltaTime; lastRevolTime = revolTime; } TriggHandler lahko nato na zahtevo posreduje preostale podatke. void TriggHanlder () { /*Odčitavanje vrednosti potenciometra* / Serial.println (analogRead (ANALOGPIN)); Serial.println (revolSpeed); }
Zdaj imamo vse gradnike, ki jih lahko uporabimo za izdelavo kode Arduino, ki bo prenašala podatke po zaporedju, na zahtevo Unityja. Če želite imeti kopijo celotne kode, jo lahko prenesete na naš GitHub. Če želite preveriti, ali je bila koda pravilno nastavljena, lahko s serijskim monitorjem pošljete TRIGG; preverite, ali ste vrstico, ki se konča, vrnili na prevoz. Naslednji razdelek se bo osredotočil na to, kako lahko naši skripti Unity zahtevajo in prejemajo informacije od Arduina.
3. korak: Prejemanje in obdelava podatkov
Unity je odlična programska oprema, ki je na voljo brezplačno za ljubitelje
zanima ustvarjanje iger; prihaja z velikim številom funkcionalnosti, ki lahko resnično skrajšajo čas pri nastavitvi nekaterih stvari, kot so navoji niti programiranje GPU (senčenje AKA), ne da bi omejili, kaj je mogoče storiti s skripti C#. Mikrokrmilnike Unity in Arduino lahko uporabite skupaj za ustvarjanje edinstvenih interaktivnih izkušenj z relativno majhnim proračunom.
Poudarek tega navodila je pomagati vzpostaviti komunikacijo med Unityjem in Arduinom, tako da se ne bomo preveč poglabljali v večino funkcij, ki so na voljo pri Unityju. Obstaja veliko VARNIH vaj za enotnost in neverjetno skupnost, ki bi lahko veliko bolje opravila razlago delovanja Unity. Vendar pa obstaja posebna nagrada za tiste, ki se uspejo prebiti skozi to navodilo, ki služi kot majhen prikaz tega, kar je mogoče storiti. Na našem Githubu lahko prenesete naš prvi poskus ustvarjanja skladbe z realno fiziko koles.
Najprej pojdimo skozi minimalni minimum, ki ga je treba narediti za komunikacijo z Arduinom skozi serijo. Kmalu bo očitno, da ta koda ni primerna za igranje iger, vendar je dobro iti skozi vsak korak in se naučiti, kakšne so omejitve.
V Unityu ustvarite nov prizor z enim samim praznim GameObject z imenom ArduinoReceive in priložite skript C#, imenovan tudi ArduinoReceive. Ta skript bo dodal vso kodo, ki upravlja komunikacijo z Arduinom.
Preden lahko komuniciramo s serijskimi vrati vašega računalnika, je dostopna knjižnica; Unity je treba nastaviti, da se omogoči uporaba določenih knjižnic. Pojdite na Urejanje-> ProjectSerring-> Predvajalnik in zraven ravni združljivosti Api pod stikalom za konfiguracijo. Podmnožica. NET 2.0 na. NET 2.0. Zdaj dodajte naslednjo kodo na vrh skripta;
z uporabo System. IO. Ports;
To vam bo omogočilo dostop do razreda SerialPort, ki bi ga lahko opredelili kot predmet razreda ArduinoReceive. Naj bo zasebno, da se izognete morebitnim motnjam iz drugega skripta.
zasebni SerialPort arduinoPort;
Objekt arduinoPort lahko odprete tako, da izberete ustrezna vrata (na primer, v kateri USB je priključen Arduino) in hitrost prenosa (tj. Hitrost, s katero se informacije pošiljajo). Če niste prepričani, v katera vrata je priključen Arduino, lahko to ugotovite v upravitelju naprav ali tako, da odprete Arduino IDE. Za hitrost prenosa je privzeta vrednost na večini naprav 9600, samo preverite, ali imate to vrednost v kodi Arduino in bi morala delovati.
Koda bi morala izgledati takole;
z uporabo System. Collections;
z uporabo System. Collections. Generic; z uporabo UnityEngine; z uporabo System. IO. Ports; javni razred ArduinoReceive: MonoBehaviour {private SerialPort arduinoPort; // To uporabite za inicializacijo void Start () {arduinoPort = new SerialPort ("COM5", 9600); arduinoPort. Open (); WriteToArduino ("TRIGG"); }}
Vaša številka COM bo najverjetneje drugačna. Če uporabljate MAC, ima lahko ime COM ime, ki izgleda tako /dev/cu.wchusbserial1420. Prepričajte se, da je koda iz razdelka 4 naložena v Arduino, serijski monitor pa je zaprt za preostanek tega razdelka in da se ta koda brez težav sestavi.
Zdaj pošljimo zahtevo vsakemu okvirju Arduina in zapišite rezultate v okno konzole. Dodajte funkcijo WriteToArduino v razred ArduinoReceive. Vrnitev nosilca in nova vrstica sta potrebna, da koda Arduino pravilno razčleni dohodno navodilo.
zasebna praznina WriteToArduino (sporočilo niza)
{message = message + "\ r / n"; arduinoPort. Write (sporočilo); arduinoPort. BaseStream. Flush (); }
To funkcijo lahko nato pokličete v zanki za posodobitev.
void Update ()
{WriteToArduino ("TRIGG"); Debug. Log ("Prva vrednost:" + arduinoPort. ReadLine ()); Debug. Log ("Druga vrednost:" + arduinoPort. ReadLine ()); }
Zgornja koda je minimum, ki ga potrebujete za branje podatkov iz Arduina. Če pozorno spremljate FPS, ki ga daje enotnost, bi morali opaziti pomemben padec zmogljivosti. V mojem primeru gre od približno 90 FPS brez branja/pisanja do 20 FPS. Če vaš projekt ne potrebuje pogostih posodobitev, bo morda dovolj, za videoigre pa je 20 FPS premalo. Naslednji razdelek obravnava, kako lahko izboljšate zmogljivost z uporabo večkratnega navoja.
4. korak: Optimiziranje prenosa podatkov
V prejšnjem razdelku je bilo opisano, kako nastaviti osnovno
komunikacijo med programom Arduino in Unity. Glavna težava te kode je zmogljivost. V trenutni izvedbi mora Unity počakati, da Arduino prejme, obdela in odgovori na zahtevo. V tem času mora koda Unity počakati na izvedbo zahteve in ne stori nič drugega. To težavo smo rešili z ustvarjanjem niti, ki bo obravnavala zahteve in spremenljivko shranila v glavno nit.
Za začetek moramo vključiti knjižnico niti z dodajanjem;
z uporabo System. Threading;
Nato nastavimo funkcijo, ki jo zaženemo v nitih. AsynchronousReadFromArduino se začne s pisanjem zahteve v Arduino s funkcijo WrtieToArduino. Odčitavanje je zaprto v bloku try-catch. Če je časovno omejitev branja, spremenljivke ostanejo ničelne in se namesto OnArduinoInfoReceive pokliče funkcija OnArduinoInfoFail.
Nato določimo funkcije OnArduinoInfoFail in OnArduinoInfoReceive. Za to navodilo rezultate natisnemo na konzolo, rezultate pa lahko shranite v spremenljivke, ki jih potrebujete za svoj projekt.
zasebna praznina OnArduinoInfoFail ()
{Debug. Log ("Branje ni uspelo"); } private void OnArduinoInfoReceived (vrtenje niza, hitrost niza) {Debug. Log ("Readin Successfull"); Debug. Log ("Prva vrednost:" + rotacija); Debug. Log ("Druga vrednost:" + hitrost); }
Zadnji korak je zagon in ustavitev niti, ki bodo zahtevale vrednosti od Arduina. Pred začetkom nove moramo zagotoviti, da je zadnja nit opravljena s svojo zadnjo nalogo. V nasprotnem primeru bi bilo mogoče na Arduino hkrati vnesti več zahtev, kar bi lahko zmedlo Arduino/Unity in prineslo nepredvidljive rezultate.
zasebna nit activeThread = null;
void Update () {if (activeThread == null ||! activeThread. IsAlive) {activeThread = nova nit (AsynchronousReadFromArduino); activeThread. Start (); }}
Če primerjate delovanje kode s tisto, ki smo jo napisali v razdelku 5, bi bilo treba zmogljivost bistveno izboljšati.
zasebna praznina OnArduinoInfoFail ()
{Debug. Log ("Branje ni uspelo"); }
5. korak: Kje naprej?
Pripravili smo predstavitev, ki jo lahko prenesete na naš Github (https://github.com/AlexandreDoucet/InfinityBike), naložite kodo in igro ter se popeljete po naši skladbi. Vse je pripravljeno za hitro vadbo in upamo, da vam bo dalo okusiti, kaj bi lahko zgradili, če uporabite to, kar smo vas naučili s tem navodilom.
Krediti
Sodelavci projekta
Alexandre Doucet (_Doucet_)
Maxime Boudreau (MxBoud)
Zunanji viri [igralni stroj Unity] (https://unity3d.com)
Ta projekt se je začel, potem ko smo prebrali vadnico Allana Zucconija "kako integrirati Arduino z Unity" (https://www.alanzucconi.com/2015/10/07/how-to-int…)
Zahteve iz Arduina se obravnavajo s knjižnico SerialCommand (https://github.com/kroimon/Arduino-SerialCommand)
Priporočena:
Merilnik kakovosti zraka v zaprtih prostorih: 5 korakov (s slikami)
Merilnik kakovosti zraka v zaprtih prostorih: Enostaven projekt za preverjanje kakovosti zraka v vaši hiši. Ker v zadnjem času veliko ostajamo/delamo od doma, je morda dobro, da spremljate kakovost zraka in se spomnite, kdaj je čas, da odprete okno in vdihnite svež zrak
Sistem za spremljanje in nadzor podnebja v zaprtih prostorih Raspberry Pi: 6 korakov
Sistem za spremljanje in nadzor podnebja v zaprtih prostorih Raspberry Pi: Ljudje želijo biti v svoji hiši udobni. Ker nam podnebje na našem območju morda ne ustreza, za vzdrževanje zdravega notranjega okolja uporabljamo številne aparate: grelec, hladilnik zraka, vlažilec zraka, razvlaževalec zraka, čistilnik itd
Sistem za spremljanje podnebja v zaprtih prostorih na osnovi maline Pi: 6 korakov
Sistem za spremljanje podnebja v zaprtih prostorih na osnovi Raspberry Pi: preberite ta blog in sestavite svoj sistem, da boste lahko prejemali opozorila, ko je vaša soba preveč suha ali vlažna. Kaj je sistem za nadzor podnebja v zaprtih prostorih in zakaj ga potrebujemo? omogočite hiter pogled na ključne podnebne razmere
WiFi samodejni napajalnik rastlin z rezervoarjem - nastavitev gojenja v zaprtih prostorih/na prostem - samodejno vodne rastline z daljinskim nadzorom: 21 korakov
WiFi samodejni napajalnik rastlin z rezervoarjem - nastavitev gojenja v zaprtih prostorih/na prostem - samodejno vodne rastline z daljinskim nadzorom: V tej vadnici bomo pokazali, kako nastaviti prilagojen sistem za napajanje rastlin v zaprtih prostorih/na prostem, ki samodejno zaliva rastline in ga je mogoče nadzorovati na daljavo s platformo Adosia
Komunikacijsko usposabljanje, šolska dejavnost ali mladinska igra: 3 koraki
Usposabljanje za komuniciranje, šolska dejavnost ali mladinska igra: to dejavnost sem že večkrat uporabil z dijaki. To poteka kot dirka, s toliko ekipami, kot želite. Temelji na stari igri Telephone, kjer se fraza šepeta od ene osebe do druge, na splošno pa se prižge konec