Satura rādītājs:

Bezgalības velosipēds - velosipēdu apmācības videospēle: 5 soļi
Bezgalības velosipēds - velosipēdu apmācības videospēle: 5 soļi

Video: Bezgalības velosipēds - velosipēdu apmācības videospēle: 5 soļi

Video: Bezgalības velosipēds - velosipēdu apmācības videospēle: 5 soļi
Video: Tiešsaistes seminārs "Darbs ar jauniešiem Covid 19 pandēmijas laikā" 2024, Novembris
Anonim
Image
Image
Materiāli
Materiāli

Ziemas sezonās, aukstās dienās un sliktos laika apstākļos velosipēdistu entuziastiem ir tikai dažas iespējas, kā nodarboties ar savu iecienītāko sporta veidu. Mēs meklējām veidu, kā padarīt treniņu iekštelpās ar velosipēdu/trenažieri nedaudz izklaidējošāku, taču lielākā daļa pieejamo produktu ir dārgi vai vienkārši garlaicīgi. Tāpēc mēs sākām attīstīt Infinity Bike kā atvērtā koda mācību videospēli. Bezgalības velosipēds nolasa ātrumu un virzienu no jūsu velosipēda un piedāvā interaktivitātes līmeni, ko nevar viegli atrast ar velosipēdu trenažieriem.

Mēs izmantojam vienkāršību, kas pieejama no Arduino mikrokontrollera, un dažas 3D drukātas detaļas, lai nodrošinātu lētus sensorus velosipēdam, kas uzstādīts uz trenažiera. Informācija tiek nodota videospēlei, kas veidota, izmantojot populāro spēļu veidošanas dzinēju Unity. Līdz šīs pamācības beigām jums vajadzētu būt iespējai uzstādīt savus sensorus uz sava velosipēda un pārsūtīt savu sensoru informāciju Unity. Mēs pat iekļāvām trasi, pa kuru varat braukt un pārbaudīt savu jauno iestatījumu. Ja jūs interesē ieguldījums, varat pārbaudīt mūsu GitHub.

1. solis: materiāli

Materiāli
Materiāli

Nepieciešamais materiālu saraksts var nedaudz atšķirties; priekš

Piemēram, jūsu velosipēda izmērs noteiks vajadzīgo džemperu kabeļu garumu, taču šeit ir galvenās detaļas, kas jums būs nepieciešamas. Jūs, iespējams, varētu atrast lētākas cenas par katru gabalu vietnē, piemēram, AliExpress, taču 6 mēnešu gaidīšana piegādei ne vienmēr ir risinājums, tāpēc izmantojāt nedaudz dārgākas detaļas, tāpēc aprēķins nav sagrozīts.

1 x Arduino nano (22,00 ASV dolāri)

1 x mini maizes dēlis (1,33 ASV dolāri par vienību)

1 x 220 omu rezistors (1,00 ASV dolāri/komplekts)

1 x 10K potenciometrs (1,80 ASV dolāri par vienību)

1 x zāles sensors (0,96 ASV dolāri)

20 cm x 6 mm 3D printera zobsiksna (3,33 ASV dolāri)

1 komplekts x dažāda garuma M3 skrūves un skrūves (6,82 ASV dolāri)

1 x velosipēda spidometra magnēts (0,98 ASV dolāri)

Mēs montējām iepriekš minēto materiālu ar 3D drukātajām detaļām. Mūsu izmantotie faili ir uzskaitīti zemāk, un tie ir numurēti ar tādu pašu paraugu kā šīs sadaļas sākumā esošais attēls. Visus failus var atrast vietnē Thingiverse. Jūs varat tos izmantot tādus, kādi tie ir, bet pārliecinieties, vai izmantotie izmēri atbilst jūsu velosipēdam.

1. FrameConnection_PotentiometerHolder_U_Holder.stl

2. FrameConnection_Spacer.stl

3. BreadboardFrameHolder.stl

4. Skriemelis_PotentiometerSide.stl

5. Pot_PulleyConnection.stl

6. FrameConnection.stl

7. Skriemelis_HandleBarSide_Print2.stl

8. FrameToHallSensorConnector.stl

9. PotHolder.stl

10. HallSensorAttach.stl

2. darbība: datu lasīšana un pārsūtīšana uz Unity

Datu lasīšana un pārsūtīšana Unity
Datu lasīšana un pārsūtīšana Unity

Arduino un Unity kods strādās kopā, lai savāktu, pārsūtīt un apstrādāt datus no velosipēda sensoriem. Unity pieprasīs vērtību no Arduino, nosūtot virkni caur sēriju, un gaidīs, kamēr Arduino atbildēs ar pieprasītajām vērtībām.

Pirmkārt, mēs sagatavojam Arduino ar bibliotēkas sērijas komandu, kas tiek izmantota, lai pārvaldītu Unity pieprasījumus, savienojot pārī pieprasījuma virkni ar funkciju. Šīs bibliotēkas pamata iestatījumus var veikt šādi;

#include "SerialCommand.h"

SerialCommand sCmd; void setup () {sCmd.addCommand ("TRIGG", TriggHanlder); Sērijas sākums (9600); } void loop () {while (Serial.available ()> 0) {sCmd.readSerial (); }} void TriggHandler () { /*Lasiet un pārsūtiet sensorus šeit* /}

Funkcija TriggHandler ir pievienota objektam SCmd. Ja seriāls saņem virkni, kas atbilst pievienotajai komandai (šajā gadījumā TRIGG), tiek izpildīta funkcija TriggHandler.

Mēs izmantojam potenciometru stūres virziena mērīšanai un zāles sensoru, lai izmērītu velosipēda rotāciju minūtē. Potenciometra rādījumus var viegli izdarīt, izmantojot Arduino iebūvētās funkcijas. Funkcija TriggHandler pēc tam var izdrukāt sērijas vērtību, veicot šādas izmaiņas.

void TriggHandler () {

/*Potenciometra vērtības nolasīšana*/ Serial.println (analogRead (ANALOGPIN)); }

Halles sensoram ir nedaudz vairāk iestatījumu, pirms varam veikt noderīgus mērījumus. Pretēji potenciometram halles sensora tūlītējā vērtība nav īpaši noderīga. Tā kā mēģināja izmērīt riteņa ātrumu, interesēja laiks starp aktivizētājiem.

Katrai funkcijai, kas izmantota Arduino kodā, ir vajadzīgs laiks, un, ja magnēts nepareizā laikā sakrīt ar Halles sensoru, mērījumu labākajā gadījumā var aizkavēt vai sliktākajā gadījumā pilnībā izlaist. Tas acīmredzami ir slikti, jo Arduino varētu ziņot par ātrumu, kas DAUDZ atšķiras no faktiskā riteņa ātruma.

Lai no tā izvairītos, mēs izmantojam Arduinos funkciju, ko sauc par pievienošanas pārtraukšanu, kas ļauj mums aktivizēt funkciju ikreiz, kad tiek aktivizēta norādītā digitālā tapa ar pieaugošu signālu. Funkcija rpm_fun ir pievienota pārtraukumam, iestatīšanas kodam pievienojot vienu koda rindu.

void setup () {

sCmd.addCommand ("TRIGG", TriggHanlder); attachInterrupt (0, rpm_fun, RISING); Sērijas sākums (9600); } // Ātruma aprēķināšanai tiek izmantota funkcija rpm_fun, un tā tiek definēta kā; neparakstīts ilgi lastRevolTime = 0; neparakstīts garš apgriezienu ātrums = 0; void rpm_fun () {unsigned long revolTime = millis (); neparakstīts garš deltaTime = revolTime - lastRevolTime; /*revolSpeed ir vērtība, kas tiek pārsūtīta uz Arduino kodu* / revolSpeed = 20000 / deltaTime; lastRevolTime = revolTime; } Pēc tam TriggHandler pēc pieprasījuma var pārsūtīt pārējo informāciju. void TriggHanlder () { /*Potenciometra vērtības nolasīšana* / Serial.println (analogRead (ANALOGPIN)); Serial.println (revolSpeed); }

Tagad mums ir visi celtniecības bloki, kurus var izmantot, lai izveidotu Arduino kodu, kas pārsūtīs datus, izmantojot sēriju, līdz Unity pieprasījuma iesniegšanai. Ja vēlaties iegūt pilna koda kopiju, varat to lejupielādēt mūsu vietnē GitHub. Lai pārbaudītu, vai kods ir pareizi iestatīts, varat izmantot seriālo monitoru, lai nosūtītu TRIGG; pārliecinieties, ka rindas beigas ir iestatītas uz Carriage return. Nākamajā sadaļā uzmanība tiks pievērsta tam, kā mūsu Unity skripti var pieprasīt un saņemt informāciju no Arduino.

3. darbība: datu saņemšana un apstrāde

Datu saņemšana un apstrāde
Datu saņemšana un apstrāde

Unity ir lieliska programmatūra, kas bez maksas pieejama hobijam

interesē spēļu veidošana; tam ir liels skaits funkciju, kas var patiešām samazināt laiku, iestatot noteiktas lietas, piemēram, pavedienus vai GPU programmēšanu (AKA ēnojums), neierobežojot to, ko var izdarīt ar C# skriptiem. Unity un Arduino mikrokontrolleri var izmantot kopā, lai radītu unikālu interaktīvu pieredzi ar salīdzinoši nelielu budžetu.

Šīs pamācības mērķis ir palīdzēt izveidot saziņu starp Unity un Arduino, lai mēs pārāk dziļi neiedziļinātos lielākajā daļā ar Unity pieejamo funkciju. Ir daudz LIELU pamācību vienotībai un neticamai kopienai, kas varētu paveikt daudz labāku darbu, izskaidrojot, kā darbojas Vienotība. Tomēr tiem, kuriem izdodas tikt galā ar šo pamācību, ir īpaša balva, kas kalpo kā neliels paraugs tam, ko varētu darīt. Jūs varat lejupielādēt mūsu Github mūsu pirmo mēģinājumu izveidot trasi ar reālistisku velosipēdu fiziku.

Pirmkārt, iziesim minimumu, kas jādara, lai sazinātos ar Arduino, izmantojot sēriju. Būs ātri redzams, ka šis kods nav piemērots spēlei, taču ir labi iziet katru soli un uzzināt, kādi ir ierobežojumi.

Vienotībā izveidojiet jaunu ainu ar vienu tukšu GameObject ar nosaukumu ArduinoRecept, pievienojot C# skriptu, kas nosaukts arī ArduinoRecept. Šajā skriptā mēs pievienosim visu kodu, kas apstrādā saziņu ar Arduino.

Ir bibliotēka, kurai jābūt pieejamai, lai mēs varētu sazināties ar jūsu datora sērijas portiem; Ir jāiestata Unity, lai varētu izmantot noteiktas bibliotēkas. Dodieties uz Rediģēt-> ProjectSerring-> Player un blakus konfigurācijas slēdža Api saderības līmenim. NET 2.0 apakškopa uz. NET 2.0. Tagad pievienojiet šādu kodu skripta augšpusē;

izmantojot System. IO. Ports;

Tas ļaus jums piekļūt SerialPort klasei, kuru jūs varētu definēt kā ArduinoRecept klases objektu. Padariet to privātu, lai izvairītos no cita skripta iejaukšanās.

privāts SerialPort arduinoPort;

Objektu arduinoPort var atvērt, izvēloties pareizo portu (piemēram, kurā USB ir pievienots Arduino) un bodu ātrumu (t.i., informācijas nosūtīšanas ātrumu). Ja neesat pārliecināts, kurā portā Arduino ir pievienots, varat to uzzināt vai nu ierīces pārvaldniekā, vai atverot Arduino IDE. Bodu ātrumam lielākajā daļā ierīču noklusējuma vērtība ir 9600, vienkārši pārliecinieties, vai šī vērtība ir jūsu Arduino kodā, un tai vajadzētu darboties.

Kodam tagad vajadzētu izskatīties šādi;

izmantojot System. Collections;

izmantojot System. Collections. Generic; izmantojot UnityEngine; izmantojot System. IO. Ports; publiskā klase ArduinoRecept: MonoBehaviour {private SerialPort arduinoPort; // Izmantojiet to inicializēšanai void Start () {arduinoPort = new SerialPort ("COM5", 9600); arduinoPort. Open (); WriteToArduino ("TRIGG"); }}

Jūsu COM numurs, visticamāk, būs atšķirīgs. Ja izmantojat MAC, jūsu COM nosaukumam varētu būt šāds nosaukums /dev/cu.wchusbserial1420. Pārliecinieties, vai kods no 4. sadaļas ir augšupielādēts Arduino un sērijas monitors ir aizvērts pārējā šīs sadaļas daļā un ka šis kods tiek apkopots bez problēmām.

Tagad nosūtīsim pieprasījumu Arduino katram kadram un ierakstīsim rezultātus konsoles logā. Pievienojiet funkciju WriteToArduino klasei ArduinoRecept. Ratu atgriešana un jauna rinda ir nepieciešama, lai Arduino kods pareizi parsētu ienākošo instrukciju.

private void WriteToArduino (virknes ziņojums)

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

Šo funkciju var izsaukt atjaunināšanas ciklā.

spēkā neesošs atjauninājums ()

{WriteToArduino ("TRIGG"); Debug. Log ("Pirmā vērtība:" + arduinoPort. ReadLine ()); Debug. Log ("Otrā vērtība:" + arduinoPort. ReadLine ()); }

Iepriekš minētais kods ir minimums, kas nepieciešams, lai nolasītu Arduino datus. Ja jūs pievēršat lielu uzmanību vienotības sniegtajam FPS, jums vajadzētu redzēt ievērojamu veiktspējas kritumu. Manā gadījumā tas iet no aptuveni 90 FPS bez lasīšanas/rakstīšanas līdz 20 FPS. Ja jūsu projektam nav nepieciešami bieži atjauninājumi, tas varētu būt pietiekami, bet videospēlei 20 kadri sekundē ir pārāk zemi. Nākamajā sadaļā tiks apskatīts, kā uzlabot veiktspēju, izmantojot vairāku pavedienu pavedienus.

4. darbība: optimizējiet datu pārsūtīšanu

Iepriekšējā sadaļā tika apskatīts, kā iestatīt pamata

komunikācija starp programmu Arduino un Unity. Šī koda galvenā problēma ir veiktspēja. Pašreizējā ieviešanā Unity jāgaida, kamēr Arduino saņems, apstrādās un atbildēs uz pieprasījumu. Šajā laikā Vienotības kodam ir jāgaida, kad pieprasījums tiks izpildīts, un neko citu nedara. Mēs atrisinājām šo problēmu, izveidojot pavedienu, kas apstrādās pieprasījumus un saglabās mainīgo galvenajā pavedienā.

Lai sāktu, mums ir jāiekļauj pavedienu bibliotēka, pievienojot;

izmantojot System. Threading;

Tālāk mēs iestatām funkciju, kuru mēs sākam pavedienos. AsynchronousReadFromArduino sākas, rakstot pieprasījumu Arduino, izmantojot funkciju WrtieToArduino. Lasījums ir iekļauts mēģinājuma noķeršanas blokā, ja nolasīšanas noildze, mainīgie paliek nulle un OnArduinoInfoFail funkcija tiek izsaukta OnArduinoInfoRecept vietā.

Tālāk mēs definējam OnArduinoInfoFail un OnArduinoInfoRecept funkcijas. Lai to izdarītu, mēs izdrukājam rezultātus konsolē, bet jūs varat saglabāt rezultātus projektam nepieciešamajos mainīgajos.

private void OnArduinoInfoFail ()

{Debug. Log ("Lasīšana neizdevās"); } private void OnArduinoInfoReceived (virkņu rotācija, virknes ātrums) {Debug. Log ("Readin Successfull"); Debug. Log ("Pirmā vērtība:" + rotācija); Debug. Log ("Otrā vērtība:" + ātrums); }

Pēdējais solis ir sākt un pārtraukt pavedienus, kas pieprasīs vērtības no Arduino. Mums ir jāpārliecinās, ka pēdējā pavediens ir pabeigts ar pēdējo uzdevumu, pirms sākat jaunu. Pretējā gadījumā Arduino varētu vienlaikus iesniegt vairākus pieprasījumus, kas varētu sajaukt Arduino/Unity un dot neparedzamus rezultātus.

privāts pavediens activeThread = null;

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

Ja jūs salīdzināt koda veiktspēju ar to, ko mēs rakstījām 5. sadaļā, veiktspēja ir ievērojami jāuzlabo.

private void OnArduinoInfoFail ()

{Debug. Log ("Lasīšana neizdevās"); }

5. solis: kur tālāk?

Kur tālāk?
Kur tālāk?

Mēs sagatavojām demonstrāciju, kuru varat lejupielādēt mūsu vietnē Github (https://github.com/AlexandreDoucet/InfinityBike), lejupielādēt kodu un spēli un braukt pa mūsu trasi. Tas viss ir paredzēts ātram treniņam, un mēs ceram, ka tas ļaus jums izbaudīt to, ko jūs varētu veidot, ja izmantosit to, ko mēs jums mācījām, izmantojot šo pamācību.

Kredīti

Projekta līdzstrādnieki

Aleksandrs Duets (_Doucet_)

Maksims Budo (MxBoud)

Ārējie resursi [The Unity spēļu dzinējs] (https://unity3d.com)

Šis projekts sākās pēc tam, kad mēs izlasījām Allan Zucconi apmācību "kā integrēt Arduino ar Vienotību" (https://www.alanzucconi.com/2015/10/07/how-to-int…)

Arduino pieprasījums tiek apstrādāts, izmantojot SerialCommand bibliotēku (https://github.com/kroimon/Arduino-SerialCommand)

Ieteicams: