Mündəricat:

Infinity Bike - İçəridə Velosiped Təlimi Video Oyunu: 5 Addım
Infinity Bike - İçəridə Velosiped Təlimi Video Oyunu: 5 Addım

Video: Infinity Bike - İçəridə Velosiped Təlimi Video Oyunu: 5 Addım

Video: Infinity Bike - İçəridə Velosiped Təlimi Video Oyunu: 5 Addım
Video: Выбираем лучшую колоду игральных карт для фокусов, кардистри и шулеров 2024, Iyun
Anonim
Image
Image
Materiallar
Materiallar

Qış mövsümlərində, soyuq günlərdə və pis hava şəraitində velosiped sürməyi sevənlərin ən çox sevdikləri idmanla məşğul olmaq üçün yalnız bir neçə variantları var. Velosiped/məşqçi qurmaqla qapalı təhsili bir az daha əyləncəli etmək üçün bir yol axtarırdıq, lakin mövcud olan məhsulların əksəriyyəti ya baha başa gəlir, ya da istifadəsi sadəcə darıxdırıcıdır. Bu səbəbdən Infinity Bike -ı Açıq Mənbə təlim video oyunu olaraq inkişaf etdirməyə başladıq. Infinity velosipedi velosipedinizin sürətini və istiqamətini oxuyur və velosiped təlimçiləri ilə asanlıqla tapıla bilməyən bir interaktivlik səviyyəsi təqdim edir.

Arduino mikrokontrolörünün sadəliyindən və bir neçə 3D çaplı hissədən istifadə edərək, ucuz sensorları məşqçiyə quraşdırılmış velosipedə bağlayırıq. Məlumat, məşhur oyun qurma mühərriki Unity ilə hazırlanmış bir video oyuna ötürülür. Bu təlimatın sonunda, velosipedinizdə öz sensorlarınızı qura və sensorlarınızın məlumatlarını Birliyə ötürə bilməlisiniz. Hətta gəzə biləcəyiniz və yeni quruluşunuzu sınaya biləcəyiniz bir parça da daxil etdik. Töhfə vermək istəyirsinizsə, GitHub -dan istifadə edə bilərsiniz.

Addım 1: Materiallar

Materiallar
Materiallar

Ehtiyac duyacağınız material siyahısı bir qədər dəyişə bilər; üçün

Məsələn, velosipedinizin ölçüsü sizə lazım olan tullanan kabellərin uzunluğunu diktə edəcək, ancaq burada sizə lazım olacaq əsas hissələr var. AliExpress kimi veb saytlarda hər bir parça üçün daha ucuz qiymətlər tapa bilərsiniz, ancaq göndərmə üçün 6 ay gözləmək həmişə bir seçim deyil, buna görə də bir az daha bahalı hissələrdən istifadə etməklə qiymətləndirmə yalnış deyil.

1 x Arduino nano (22.00 dollar)

1 x Mini Çörək Paneli (1.33 dollar/ədəd)

1 x 220 Ohm müqavimət (dəsti 1.00 dollar)

1 x 10K Potansiyometr (vahid 1.80 dollar)

1 x Hall sensoru (0.96 dollar)

20 sm x 6 mm ölçülü 3D printer zamanlama kəməri (3.33 dollar)

1 dəst x Müxtəlif Uzunluq M3 vintlər və boltlar (6.82 dollar)

1 x Velosiped sürətölçən maqnit (0.98 dollar)

Yuxarıdakı materialı 3D çaplı hissələrlə quraşdırdıq. İstifadə etdiyimiz fayllar aşağıda verilmişdir və bu bölmənin əvvəlindəki şəkil ilə eyni qaydada nömrələnmişdir. Bütün faylları Thingiverse -də tapa bilərsiniz. Onları olduğu kimi istifadə edə bilərsiniz, ancaq istifadə etdiyimiz ölçülərin velosipedinizə uyğun olduğundan əmin olun.

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

Addım 2: Məlumatları Oxumaq və Birliyə köçürmək

Məlumatların oxunması və Birliyə köçürülməsi
Məlumatların oxunması və Birliyə köçürülməsi

Arduino və Unity kodu toplamaq üçün birlikdə işləyəcək.

velosipeddəki sensorlardakı məlumatları köçürün və emal edin. Birlik, serial vasitəsilə bir sim göndərərək Arduinodan dəyər tələb edəcək və Arduinonun tələb olunan dəyərlərlə cavab verməsini gözləyəcək.

Birincisi, Arduino -nu bir funksiya ilə bir sorğu sətrini birləşdirərək Unity -dən gələn istəkləri idarə etmək üçün istifadə olunan kitabxana Serial Command ilə hazırlayırıq. Bu kitabxana üçün əsas qurulma aşağıdakı kimi edilə bilər;

#"SerialCommand.h" daxil edin

SerialCommand sCmd; boş quraşdırma () {sCmd.addCommand ("TRIGG", TriggHanlder); Serial.begin (9600); } void loop () {while (Serial.available ()> 0) {sCmd.readSerial (); }} void TriggHandler () { /*Sensorları buradan oxuyun və ötürün* /}

TriggHandler funksiyası SCmd obyektinə bağlıdır. Seriya əlavə edilmiş əmrə uyğun gələn bir sim alırsa (bu halda TRIGG), TriggHandler funksiyası yerinə yetirilir.

Sükan istiqamətini ölçmək üçün potensiometrdən və velosipedin dəqiqədə fırlanmasını ölçmək üçün halllar sensorundan istifadə edirik. Potensialiometrdən oxunuşlar Arduinonun quraşdırılmış funksiyalarından istifadə etməklə asanlıqla edilə bilər. TriggHandler funksiyası sonrakı dəyişikliyi ilə dəyəri seriala yazdıra bilər.

boş TriggHandler () {

/*Potansiyometrin dəyərinin oxunması*/ Serial.println (analogRead (ANALOGPIN)); }

Faydalı ölçülər əldə etməzdən əvvəl Hall sensoru bir az daha qurulmuşdur. Potensiometrdən fərqli olaraq, halllar sensorunun ani dəyəri o qədər də faydalı deyil. Təkərin sürətini ölçməyə çalışdıqları üçün tətiklər arasındakı vaxt maraqlandı.

Arduino kodunda istifadə olunan hər bir funksiya vaxt aparır və maqnit səhv zaman Hall sensoru ilə üst -üstə düşərsə, ölçmə ən yaxşı halda gecikdirilə bilər və ya ən pis halda tamamilə atlana bilər. Bu açıq -aşkar pisdir, çünki Arduino təkərin həqiqi sürətindən çox fərqli bir sürət bildirə bilər.

Bunun qarşısını almaq üçün, təyin edilmiş bir rəqəmsal pin yüksələn bir siqnal ilə işə salındıqda bir funksiyanı işə salmağa imkan verən, əlavə kəsmə adlı Arduinos xüsusiyyətindən istifadə edirik. Rpm_fun funksiyası, quraşdırma koduna əlavə edilmiş bir kod xətti olan bir fasilə əlavə olunur.

boş quraşdırma () {

sCmd.addCommand ("TRIGG", TriggHanlder); attachInterrupt (0, rpm_fun, RISING); Serial.begin (9600); } // rpm_fun funksiyası sürəti hesablamaq üçün istifadə olunur və belə təyin olunur; imzasız uzun lastRevolTime = 0; işarəsiz uzun revolSpeed = 0; void rpm_fun () {işarəsiz uzun revolTime = millis (); imzasız uzun deltaTime = revolTime - lastRevolTime; /*revolSpeed, Arduino koduna ötürülən dəyərdir* / revolSpeed = 20000 / deltaTime; lastRevolTime = revolTime; } TriggHandler tələb edildikdə qalan məlumatları ötürə bilər. void TriggHanlder () { /*Potansiyometrenin dəyərinin oxunması* / Serial.println (analogRead (ANALOGPIN)); Serial.println (revolSpeed); }

İndi Unity tərəfindən sorğu edildikdə məlumatları serial vasitəsilə ötürəcək Arduino kodunu qurmaq üçün istifadə edilə bilən bütün tikinti bloklarına sahibik. Tam kodun bir nüsxəsinə sahib olmaq istəyirsinizsə, GitHub -dan yükləyə bilərsiniz. Kodun düzgün qurulduğunu yoxlamaq üçün TRIGG göndərmək üçün seriyalı monitordan istifadə edə bilərsiniz; Satırın qaytarılması üçün bitən xətti təyin etdiyinizə əmin olun. Növbəti hissədə Unity skriptlərimizin Arduinodan məlumatları necə istəyə və ala biləcəyi müzakirə olunacaq.

Addım 3: Məlumatların Alınması və İşlənməsi

Məlumatların qəbulu və emalı
Məlumatların qəbulu və emalı

Unity, həvəskarlar üçün pulsuz olaraq mövcud olan əla bir proqramdır

oyun qurmaqla maraqlanır; C# skriptləri ilə nə edilə biləcəyini məhdudlaşdırmadan iş parçacığı və ya GPU proqramlaşdırma (AKA gölgələmə) kimi müəyyən şeyləri qurma vaxtını həqiqətən azalda bilən çox sayda funksiya ilə gəlir. Unity və Arduino mikro nəzarətçiləri nisbətən kiçik bir büdcə ilə unikal interaktiv təcrübələr yaratmaq üçün birlikdə istifadə edilə bilər.

Bu təlimatın məqsədi Unity ilə Arduino arasında ünsiyyət qurmağa kömək etməkdir, buna görə də Unity ilə mövcud olan xüsusiyyətlərin çoxuna çox dərindən girməyəcəyik. Birlik və Unity -nin necə işlədiyini izah edən daha yaxşı bir iş edə biləcək inanılmaz bir cəmiyyət üçün çoxlu BÖYÜK dərslər var. Bununla birlikdə, edilə biləcəklərin kiçik bir vitrini olaraq xidmət edən bu təlimat yolu ilə işləməyi bacaranlar üçün xüsusi bir mükafat var. Github -da real velosiped fizikası ilə bir trek etmək üçün ilk cəhdimizi yükləyə bilərsiniz.

Birincisi, serial vasitəsilə bir Arduino ilə ünsiyyət qurmaq üçün edilməli olan minimumu keçək. Bu kodun oyuna uyğun olmadığı tezliklə aydın olacaq, amma hər addımı keçmək və məhdudiyyətlərin nə olduğunu öyrənmək yaxşıdır.

Birlikdə, ArduinoReceive adlı bir boş GameObject ilə ArduinoReceive adlı bir C# skriptində yeni bir səhnə yaradın. Bu skript, Arduino ilə ünsiyyəti idarə edən bütün kodu əlavə edəcəyimiz yerdir.

Kompüterinizin seriyalı portları ilə əlaqə qura bilməyimizdən əvvəl daxil olması lazım olan bir kitabxana var; Müəyyən kitabxanaların istifadəsinə icazə vermək üçün birlik qurulmalıdır. Edit-> ProjectSerring-> Player-ə gedin və Konfiqurasiya açarı altında Api Uyğunluq Səviyyə yanındakı. NET 2.0. NET 2.0-a daxil olun. İndi skriptin yuxarısına aşağıdakı kodu əlavə edin;

System. IO. Ports istifadə etmək;

Bu, ArduinoReceive Sinifinə obyekt olaraq təyin edə biləcəyiniz SerialPort sinifinə daxil olmağa imkan verəcəkdir. Başqa bir skriptdən hər hansı bir müdaxilənin qarşısını almaq üçün özəlləşdirin.

özəl SerialPort arduinoPort;

ArduinoPort obyekti düzgün portu (məsələn, Arduinonun USB -yə qoşulduğu) və ötürmə sürətini (yəni məlumatın göndərilmə sürətini) seçməklə açıla bilər. Arduinonun hansı porta qoşulduğundan əmin deyilsinizsə, cihaz menecerində və ya Arduino IDE -ni açaraq öyrənə bilərsiniz. Baud dərəcəsi üçün, əksər cihazlarda standart dəyər 9600 -dir, yalnız bu dəyərin Arduino kodunuzda olduğundan əmin olun və işləməlidir.

Kod indi belə görünməlidir;

System. Collections istifadə;

System. Collections. Generic istifadə edərək; UnityEngine istifadə edərək; System. IO. Ports istifadə etmək; ictimai sinif ArduinoReceive: MonoBehaviour {özəl SerialPort arduinoPort; // Başlatmaq üçün istifadə edin void Start () {arduinoPort = yeni SerialPort ("COM5", 9600); arduinoPort. Open (); WriteToArduino ("TRIGG"); }}

COM nömrəniz böyük ehtimalla fərqli olacaq. Bir MAC -da olsanız, COM adınızın /dev/cu.wchusbserial1420 kimi bir ad ola bilər. 4 -cü hissədəki kodun Arduinoya yükləndiyinə və bu hissənin qalan hissəsi üçün serial monitorun bağlı olduğuna və bu kodun problemsiz tərtib edildiyinə əmin olun.

İndi hər çərçivəyə Arduinoya bir sorğu göndərək və nəticələrini konsol pəncərəsinə yazaq. WriteToArduino funksiyasını ArduinoReceive sinifinə əlavə edin. Arduino kodunun daxil olan təlimatı düzgün təhlil etməsi üçün vaqonun geri qaytarılması və yeni xətt lazımdır.

şəxsi boşluq WriteToArduino (simli mesaj)

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

Bu funksiya sonra Yeniləmə döngəsində çağırıla bilər.

etibarsız yeniləmə ()

{WriteToArduino ("TRIGG"); Debug. Log ("İlk Dəyər:" + arduinoPort. ReadLine ()); Debug. Log ("İkinci dəyər:" + arduinoPort. ReadLine ()); }

Yuxarıdakı kod, bir Arduinodan məlumatları oxumaq üçün lazım olan minimumdur. Birliyin verdiyi FPS -ə çox diqqət yetirsəniz, performansda əhəmiyyətli bir azalma görməlisiniz. Mənim vəziyyətimdə, oxumadan/yazmadan 90 FPS -dən 20 FPS -ə qədər gedir. Layihənizin tez -tez yeniləmələrə ehtiyacı yoxdursa, bu kifayət ola bilər, ancaq bir video oyunu üçün 20 FPS çox aşağıdır. Növbəti bölmə, çox iş parçacığı istifadə edərək performansı necə artıra biləcəyinizi əhatə edəcək.

Addım 4: Məlumat ötürülməsini optimallaşdırın

Əvvəlki hissədə təməlin necə qurulacağı izah edildi

Arduino və Birlik proqramı arasında əlaqə. Bu kodun əsas problemi performansdır. Mövcud tətbiqində Birlik, Arduinonun istəyi qəbul etməsini, işlənməsini və cavab verməsini gözləməlidir. Bu müddət ərzində Birlik kodu sorğunun yerinə yetirilməsini gözləməlidir və başqa heç nə etmir. İstəkləri idarə edəcək və dəyişəni əsas mövzuda saxlayacaq bir mövzu yaratmaqla bu problemi həll etdik.

Başlamaq üçün, əlavə edərək iş parçacığı kitabxanasını daxil etməliyik;

System. Threading istifadə edərək;

Sonra, mövzularda başladığımız funksiyanı qururuq. AsynchronousReadFromArduino, WrtieToArduino funksiyası ilə Arduinoya sorğu yazmaqla başlayır. Oxumaq bir cəhd blokuna daxil edilir, əgər oxumaq zaman aşımına uğrayarsa, dəyişənlər sıfır olaraq qalır və OnArduinoInfoReceive yerinə OnArduinoInfoFail funksiyası çağırılır.

Sonra OnArduinoInfoFail və OnArduinoInfoReceive funksiyalarını təyin edirik. Bu təlimatlandırmaq üçün nəticələri konsolda çap edirik, ancaq nəticələri layihəniz üçün lazım olan dəyişənlərə saxlaya bilərsiniz.

şəxsi boşluq OnArduinoInfoFail ()

{Debug. Log ("Oxunmadı"); } şəxsi boşluq OnArduinoInfoReceived (simli fırlanma, simli sürət) {Debug. Log ("Readin Sucessfull"); Debug. Log ("İlk dəyər:" + fırlanma); Debug. Log ("İkinci dəyər:" + sürət); }

Son addım, Arduinodan dəyərlər istəyəcək mövzuları başlatmaq və dayandırmaqdır. Yeni bir işə başlamazdan əvvəl son işin son vəzifəsi ilə yerinə yetirilməsini təmin etməliyik. Əks təqdirdə, Arduino/Unity -ni qarışdıra biləcək və gözlənilməz nəticələr verə biləcək birdən çox sorğu Arduino -ya verilə bilər.

şəxsi mövzu aktivThread = null;

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

Kodun performansını 5 -ci bölmədə yazdığımızla müqayisə etsəniz, performans əhəmiyyətli dərəcədə artırılmalıdır.

şəxsi boşluq OnArduinoInfoFail ()

{Debug. Log ("Oxunmadı"); }

Addım 5: Sonrakı Harada?

Sonrakı Harada?
Sonrakı Harada?

Github -da yükləyə biləcəyiniz bir demo hazırladıq (https://github.com/AlexandreDoucet/InfinityBike), kodu və oyunu yükləyib trekimizdə gəzə bilərsiniz. Hamısı sürətli bir məşq üçün qurulmuşdur və ümid edirik ki, öyrətdiklərimizi bu təlimatla istifadə etsəniz, nələr qura biləcəyinizi dadacaqdır.

Kreditlər

Layihə iştirakçıları

Alexandre Doucet (_Doucet_)

Maxime Boudreau (MxBoud)

Xarici mənbələr [Birlik oyun motoru] (https://unity3d.com)

Bu layihə, Allan Zucconi-nin "Arduino'yu Birliyə necə inteqrasiya etmək" (https://www.alanzucconi.com/2015/10/07/how-to-int…) dərsini oxuduqdan sonra başladı.

Arduinodan gələn sorğu SerialCommand kitabxanasından istifadə olunur (https://github.com/kroimon/Arduino-SerialCommand)

Tövsiyə: