विषयसूची:

इन्फिनिटी बाइक - घर के अंदर बाइक प्रशिक्षण वीडियो गेम: 5 कदम
इन्फिनिटी बाइक - घर के अंदर बाइक प्रशिक्षण वीडियो गेम: 5 कदम

वीडियो: इन्फिनिटी बाइक - घर के अंदर बाइक प्रशिक्षण वीडियो गेम: 5 कदम

वीडियो: इन्फिनिटी बाइक - घर के अंदर बाइक प्रशिक्षण वीडियो गेम: 5 कदम
वीडियो: Wheelie Feel Machine 😅 #shorts #wheelie #machine #crazy 2024, नवंबर
Anonim
Image
Image
सामग्री
सामग्री

सर्दियों के मौसम, ठंड के दिनों और खराब मौसम के दौरान, साइकिल चलाने वालों के पास अपने पसंदीदा खेल में व्यायाम करने के लिए कुछ ही विकल्प होते हैं। हम एक बाइक/ट्रेनर सेटअप के साथ इनडोर प्रशिक्षण को और अधिक मनोरंजक बनाने का एक तरीका ढूंढ रहे थे लेकिन उपलब्ध अधिकांश उत्पाद या तो महंगे हैं या उपयोग करने के लिए सिर्फ सादा उबाऊ हैं। यही कारण है कि हमने इन्फिनिटी बाइक को एक ओपन सोर्स प्रशिक्षण वीडियो गेम के रूप में विकसित करना शुरू किया। इन्फिनिटी बाइक आपकी साइकिल से गति और दिशा को पढ़ती है और एक ऐसी अन्तरक्रियाशीलता प्रदान करती है जो बाइक प्रशिक्षकों के साथ आसानी से नहीं पाई जा सकती है।

हम Arduino माइक्रोकंट्रोलर और कुछ 3D प्रिंटेड भागों से उपलब्ध सरलता का लाभ उठाते हैं ताकि सस्ते सेंसर को ट्रेनर पर लगे साइकिल पर सुरक्षित किया जा सके। जानकारी लोकप्रिय गेम बनाने वाले इंजन, यूनिटी के साथ बनाए गए वीडियो गेम से संबंधित है। इस निर्देश के अंत तक, आप अपनी बाइक पर अपने स्वयं के सेंसर सेट करने और अपने सेंसर की जानकारी को एकता में स्थानांतरित करने में सक्षम होना चाहिए। हमने एक ट्रैक भी शामिल किया है जिस पर आप सवारी कर सकते हैं और अपने नए सेट-अप का परीक्षण कर सकते हैं। यदि आप योगदान करने में रुचि रखते हैं तो आप हमारे GitHub को चेकआउट कर सकते हैं।

चरण 1: सामग्री

सामग्री
सामग्री

आपको जिस सामग्री सूची की आवश्यकता होगी वह थोड़ी भिन्न हो सकती है; के लिये

उदाहरण के लिए, आपकी बाइक का आकार आपको आवश्यक जम्पर केबल्स की लंबाई निर्धारित करेगा लेकिन यहां मुख्य भाग हैं जिनकी आपको आवश्यकता होगी। आप शायद अलीएक्सप्रेस जैसी वेबसाइट पर प्रत्येक टुकड़े के लिए सस्ती कीमत पा सकते हैं, लेकिन शिपिंग के लिए 6 महीने का इंतजार करना हमेशा एक विकल्प नहीं होता है, इसलिए थोड़ा अधिक महंगे भागों का उपयोग कर रहे थे ताकि अनुमान तिरछा न हो।

1 एक्स अरुडिनो नैनो ($ 22.00)

1 एक्स मिनी ब्रेडबोर्ड ($ 1.33 / यूनिट)

1 x 220 ओम रोकनेवाला ($1.00/किट)

1 x 10K पोटेंशियोमीटर ($1.80/इकाई)

1 एक्स हॉल सेंसर ($ 0.96)

20 सेमी x 6 मिमी 3डी प्रिंटर टाइमिंग बेल्ट ($3.33)

1 किट x विभिन्न लंबाई M3 स्क्रू और बोल्ट ($6.82)

1 एक्स साइकिल स्पीडोमीटर चुंबक ($0.98)

हमने ऊपर की सामग्री को 3 डी प्रिंटेड भागों के साथ माउंट किया है। हमारे द्वारा उपयोग की गई फ़ाइलें नीचे सूचीबद्ध हैं और उन्हें उसी परंपरा के साथ क्रमांकित किया गया है जैसा कि इस खंड की शुरुआत में छवि है। सभी फाइलें थिंगविवर्स पर पाई जा सकती हैं। आप उनका उपयोग वैसे ही कर सकते हैं, लेकिन सुनिश्चित करें कि हमने जिन आयामों का उपयोग किया है वे आपकी बाइक से मेल खाते हैं।

1. FrameConnection_PotentiometerHolder_U_Holder.stl

2. FrameConnection_Spaceer.stl

3. BreadboardFrameHolder.stl

4. Pulley_PotentiometerSide.stl

5. Pot_PulleyConnection.stl

6. फ्रेमकनेक्शन.stl

7. Pulley_HandleBarSide_Print2.stl

8. FrameToHallSensorConnector.stl

9. पॉटहोल्डर.stl

10. हॉल सेंसरअटैच.stl

चरण 2: डेटा को एकता में पढ़ना और स्थानांतरित करना

डेटा को एकता में पढ़ना और स्थानांतरित करना
डेटा को एकता में पढ़ना और स्थानांतरित करना

Arduino और Unity कोड इकट्ठा करने के लिए मिलकर काम करेंगे, बाइक पर लगे सेंसर से डेटा ट्रांसफर और प्रोसेस करें। एकता सीरियल के माध्यम से एक स्ट्रिंग भेजकर Arduino से मूल्य का अनुरोध करेगी और Arduino के लिए अनुरोधित मूल्यों के साथ प्रतिक्रिया करने की प्रतीक्षा करेगी।

सबसे पहले, हम Arduino को लाइब्रेरी सीरियल कमांड के साथ तैयार करते हैं जिसका उपयोग एक फ़ंक्शन के साथ अनुरोध स्ट्रिंग को जोड़कर एकता से अनुरोधों को प्रबंधित करने के लिए किया जाता है। इस पुस्तकालय के लिए एक बुनियादी ढांचा निम्नानुसार बनाया जा सकता है;

#शामिल "SerialCommand.h"

सीरियल कमांड एससीएमडी; शून्य सेटअप () {sCmd.addCommand ("TRIGG", TriggHanlder); सीरियल.बेगिन (९६००); } शून्य लूप () { जबकि (सीरियल.उपलब्ध ()> 0) {sCmd.readSerial (); } } शून्य TriggHandler () {/* सेंसर यहां पढ़ें और संचारित करें*/ }

फ़ंक्शन TriggHandler ऑब्जेक्ट SCmd से जुड़ा हुआ है। यदि सीरियल को एक स्ट्रिंग प्राप्त होती है जो संलग्न कमांड (इस मामले में TRIGG) से मेल खाती है, तो फ़ंक्शन TriggHandler निष्पादित होता है।

हम स्टीयरिंग दिशा को मापने के लिए पोटेंशियोमीटर का उपयोग करते हैं और साइकिल के प्रति मिनट रोटेशन को मापने के लिए एक हॉल सेंसर का उपयोग करते हैं। पोटेंशियोमीटर से रीडिंग आसानी से Arduino के बिल्ड-इन फ़ंक्शंस का उपयोग करके की जा सकती है। फ़ंक्शन TriggHandler तब निम्न परिवर्तन के साथ सीरियल के मान को प्रिंट कर सकता है।

शून्य ट्रिगहैंडलर () {

/*पोटेंशियोमीटर का मान पढ़ना*/ Serial.println(analogRead(ANALOGPIN)); }

इससे पहले कि हम उपयोगी माप कर सकें, हॉल सेंसर की स्थापना थोड़ी अधिक है। पोटेंशियोमीटर के विपरीत, हॉल सेंसर का तत्काल मूल्य बहुत उपयोगी नहीं है। चूंकि पहिया की गति को मापने की कोशिश कर रहे थे, ट्रिगर्स के बीच का समय वह है जिसमें रुचि थी।

Arduino कोड में उपयोग किए जाने वाले प्रत्येक फ़ंक्शन में समय लगता है और यदि चुंबक गलत समय पर हॉल सेंसर के साथ जुड़ जाता है तो माप में देरी हो सकती है या पूरी तरह से खराब हो सकती है। यह स्पष्ट रूप से बुरा है क्योंकि Arduino एक गति की रिपोर्ट कर सकता है जो पहिया की वास्तविक गति से बहुत अलग है।

इससे बचने के लिए, हम अरुडिनो की एक विशेषता का उपयोग करते हैं जिसे अटैच इंटरप्ट कहा जाता है जो हमें एक फ़ंक्शन को ट्रिगर करने की अनुमति देता है जब भी एक निर्दिष्ट डिजिटल पिन बढ़ते सिग्नल के साथ ट्रिगर होता है। फ़ंक्शन rpm_fun सेटअप कोड में जोड़े गए कोड की एक पंक्ति के साथ एक बाधा से जुड़ा हुआ है।

व्यर्थ व्यवस्था(){

sCmd.addCommand("TRIGG", TriggHanlder); अटैचइंटरप्ट (0, rpm_fun, राइजिंग); सीरियल.बेगिन (९६००); } // फ़ंक्शन rpm_fun का उपयोग गति की गणना के लिए किया जाता है और इसे इस प्रकार परिभाषित किया जाता है; अहस्ताक्षरित लास्ट लास्टरिवोल्टाइम = 0; अहस्ताक्षरित लंबी क्रांति = 0; शून्य rpm_fun () { अहस्ताक्षरित लंबी क्रांति समय = मिली (); अहस्ताक्षरित लंबा डेल्टाटाइम = रिवॉलटाइम - लास्ट रेवोलटाइम; /*revolSpeed, Arduino code*/revolSpeed = 20000 / deltaTime को प्रेषित मान है; लास्ट रिवॉलटाइम = रिवॉलटाइम; } इसके बाद TriggHandler अनुरोध किए जाने पर शेष जानकारी संचारित कर सकता है। void TriggHanlder () {/*पोटेंशियोमीटर का मान पढ़ना*/ Serial.println(analogRead(ANALOGPIN)); Serial.println (revolSpeed); }

अब हमारे पास सभी बिल्डिंग ब्लॉक्स हैं जिनका उपयोग Arduino कोड बनाने के लिए किया जा सकता है जो सीरियल के माध्यम से डेटा ट्रांसफर करेगा जब यूनिटी द्वारा अनुरोध किया जाता है। यदि आप पूर्ण कोड की एक प्रति प्राप्त करना चाहते हैं, तो आप इसे हमारे GitHub पर डाउनलोड कर सकते हैं। यह जांचने के लिए कि क्या कोड ठीक से सेट-अप किया गया था, आप TRIGG भेजने के लिए सीरियल मॉनिटर का उपयोग कर सकते हैं; सुनिश्चित करें कि आपने कैरिज रिटर्न के लिए समाप्त होने वाली लाइन को सेट किया है। अगला भाग इस बात पर ध्यान केंद्रित करेगा कि हमारी एकता स्क्रिप्ट कैसे Arduino से जानकारी का अनुरोध और प्राप्त कर सकती है।

चरण 3: डेटा प्राप्त करना और संसाधित करना

डेटा प्राप्त करना और संसाधित करना
डेटा प्राप्त करना और संसाधित करना

एकता एक बेहतरीन सॉफ्टवेयर है जो हॉबीस्ट के लिए मुफ्त में उपलब्ध है

खेल बनाने में रुचि; यह बड़ी संख्या में कार्यात्मकताओं के साथ आता है जो सी # स्क्रिप्ट के साथ क्या किया जा सकता है, इसे प्रतिबंधित किए बिना थ्रेडिंग या जीपीयू प्रोग्रामिंग (एकेए छायांकन) जैसी कुछ चीजों को स्थापित करने में वास्तव में समय में कटौती कर सकता है। अपेक्षाकृत छोटे बजट के साथ अद्वितीय इंटरैक्टिव अनुभव बनाने के लिए एकता और Arduino माइक्रोकंट्रोलर का एक साथ उपयोग किया जा सकता है।

इस निर्देश का ध्यान एकता और अरुडिनो के बीच संचार को स्थापित करने में मदद करना है, इसलिए हम एकता के साथ उपलब्ध अधिकांश सुविधाओं में बहुत गहराई तक नहीं उतरेंगे। एकता और एक अविश्वसनीय समुदाय के लिए बहुत सारे महान ट्यूटोरियल हैं जो यह बताते हुए बेहतर काम कर सकते हैं कि एकता कैसे काम करती है। हालाँकि, उन लोगों के लिए एक विशेष पुरस्कार है जो इस निर्देश के माध्यम से अपने तरीके से काम करने का प्रबंधन करते हैं जो कि क्या किया जा सकता है के एक छोटे से प्रदर्शन के रूप में कार्य करता है। आप हमारे जीथब पर यथार्थवादी बाइक भौतिकी के साथ एक ट्रैक बनाने का हमारा पहला प्रयास डाउनलोड कर सकते हैं।

सबसे पहले, सीरियल के माध्यम से एक Arduino के साथ संवाद करने के लिए नंगे न्यूनतम के माध्यम से जाने दें। यह जल्दी से स्पष्ट हो जाएगा कि यह कोड गेमप्ले के लिए उपयुक्त नहीं है, लेकिन हर कदम पर जाना और यह सीखना अच्छा है कि सीमाएं क्या हैं।

एकता में, एक खाली गेमऑब्जेक्ट के साथ एक नया दृश्य बनाएं जिसका नाम ArduinoReceive है, एक C# स्क्रिप्ट जिसे ArduinoReceive भी कहा जाता है। यह स्क्रिप्ट वह जगह है जहां हम Arduino के साथ संचार को संभालने वाले सभी कोड जोड़ देंगे।

आपके कंप्यूटर के सीरियल पोर्ट के साथ संचार करने से पहले एक पुस्तकालय है जिसे एक्सेस किया जाना चाहिए; कुछ पुस्तकालयों का उपयोग करने की अनुमति देने के लिए एकता स्थापित की जानी चाहिए। एडिट->प्रोजेक्टसेरिंग->प्लेयर पर जाएं और कॉन्फ़िगरेशन स्विच के तहत एपीआई संगतता स्तर के बगल में. NET 2.0 सबसेट से. NET 2.0 पर जाएं। अब स्क्रिप्ट के शीर्ष पर निम्न कोड जोड़ें;

System. IO. Ports का उपयोग करना;

यह आपको SerialPort क्लास को एक्सेस करने देगा जिसे आप ArduinoReceive Class के ऑब्जेक्ट के रूप में परिभाषित कर सकते हैं। किसी अन्य स्क्रिप्ट के हस्तक्षेप से बचने के लिए इसे निजी बनाएं।

निजी सीरियलपोर्ट arduinoPort;

ऑब्जेक्ट arduinoPort को सही पोर्ट (जैसे जिसमें USB Arduino जुड़ा हुआ है) और एक बॉड रेट (यानी जिस गति से सूचना भेजी जाती है) का चयन करके खोला जा सकता है। यदि आप सुनिश्चित नहीं हैं कि Arduino किस पोर्ट में प्लग इन है, तो आप डिवाइस मैनेजर में या Arduino IDE खोलकर पता लगा सकते हैं। बॉड दर के लिए, अधिकांश डिवाइस पर डिफ़ॉल्ट मान 9600 है, बस सुनिश्चित करें कि आपके Arduino कोड में यह मान है और इसे काम करना चाहिए।

कोड अब इस तरह दिखना चाहिए;

सिस्टम का उपयोग करना। संग्रह;

System. Collections. Generic का उपयोग करना; यूनिटीइंजिन का उपयोग करना; System. IO. Ports का उपयोग करना; पब्लिक क्लास ArduinoReceive: MonoBehaviour {निजी सीरियलपोर्ट arduinoPort; // इसे आरंभीकरण के लिए उपयोग करें शून्य प्रारंभ () {arduinoPort = नया सीरियलपोर्ट ("COM5", 9600); arduinoPort. Open (); WriteToArduino ("TRIGG"); } }

आपका COM नंबर सबसे अलग होगा। यदि आप मैक पर हैं, तो आपका COM नाम ऐसा नाम हो सकता है जो इस तरह दिखता है /dev/cu.wchusbserial1420। सुनिश्चित करें कि सेक्शन 4 का कोड Arduino पर अपलोड किया गया है और इस सेक्शन के बाकी हिस्सों के लिए सीरियल मॉनिटर बंद है और यह कोड बिना किसी समस्या के संकलित है।

आइए अब प्रत्येक फ्रेम में Arduino को एक अनुरोध भेजें और परिणाम कंसोल विंडो पर लिखें। ArduinoReceive वर्ग में WriteToArduino फ़ंक्शन जोड़ें। आने वाले निर्देश को ठीक से पार्स करने के लिए Arduino कोड के लिए कैरिज रिटर्न और नई लाइन आवश्यक है।

निजी शून्य WriteToArduino (स्ट्रिंग संदेश)

{संदेश = संदेश + "\ r / n"; arduinoPort.लिखें (संदेश); arduinoPort. BaseStream. Flush (); }

इस फ़ंक्शन को तब अपडेट लूप में कॉल किया जा सकता है।

शून्य अद्यतन ()

{ WriteToArduino ("TRIGG"); Debug. Log ("पहला मान:" + arduinoPort. ReadLine ()); Debug. Log ("दूसरा मान:" + arduinoPort. ReadLine ()); }

उपरोक्त कोड न्यूनतम न्यूनतम है जिसे आपको Arduino से डेटा पढ़ने की आवश्यकता है। यदि आप एकता द्वारा दिए गए FPS पर पूरा ध्यान दें, तो आपको प्रदर्शन में उल्लेखनीय गिरावट दिखाई देगी। मेरे मामले में, यह लगभग 90 एफपीएस से बिना पढ़े/लिखे 20 एफपीएस हो जाता है। यदि आपके प्रोजेक्ट को लगातार अपडेट की आवश्यकता नहीं है तो यह पर्याप्त हो सकता है लेकिन वीडियो गेम के लिए, 20 एफपीएस बहुत कम है। अगला खंड कवर करेगा कि आप मल्टी थ्रेडिंग का उपयोग करके प्रदर्शन को कैसे बेहतर बना सकते हैं।

चरण 4: डेटा स्थानांतरण का अनुकूलन

पिछले अनुभाग में बताया गया है कि बुनियादी कैसे सेट अप करें

Arduino और एकता कार्यक्रम के बीच संचार। इस कोड के साथ प्रमुख समस्या प्रदर्शन है। इसके वर्तमान कार्यान्वयन में, एकता को अनुरोध प्राप्त करने, संसाधित करने और उत्तर देने के लिए Arduino की प्रतीक्षा करनी होगी। उस समय के दौरान, यूनिटी कोड को अनुरोध करने के लिए इंतजार करना पड़ता है और कुछ नहीं करता है। हमने एक थ्रेड बनाकर इस समस्या को हल किया है जो अनुरोधों को संभालेगा और चर को मुख्य थ्रेड पर संग्रहीत करेगा।

शुरू करने के लिए, हमें थ्रेडिंग लाइब्रेरी को जोड़कर शामिल करना होगा;

सिस्टम का उपयोग करना। थ्रेडिंग;

अगला, हम उस फ़ंक्शन को सेट करते हैं जिसे हम थ्रेड्स में शुरू कर रहे हैं। AsynchronousReadFromArduino WrtieToArduino फ़ंक्शन के साथ Arduino को अनुरोध लिखकर शुरू करता है। रीडिंग एक ट्राइ-कैच ब्लॉक में संलग्न है, यदि रीड टाइमआउट, वेरिएबल शून्य रहते हैं और OnArduinoInfoReceive के बजाय OnArduinoInfoFail फ़ंक्शन को कॉल किया जाता है।

आगे हम OnArduinoInfoFail और OnArduinoInfoReceive फ़ंक्शन को परिभाषित करते हैं। इस निर्देश के लिए, हम परिणामों को कंसोल पर प्रिंट करते हैं, लेकिन आप परिणामों को अपने प्रोजेक्ट के लिए आवश्यक चर में संग्रहीत कर सकते हैं।

निजी शून्य OnArduinoInfoFail ()

{डीबग। लॉग ("पढ़ना विफल"); } निजी शून्य OnArduinoInfoReceived (स्ट्रिंग रोटेशन, स्ट्रिंग स्पीड) {Debug. Log ("रीडिन सक्सेसफुल"); Debug. Log ("पहला मान:" + रोटेशन); Debug. Log ("दूसरा मान:" + गति); }

अंतिम चरण उन थ्रेड्स को शुरू और बंद करना है जो Arduino से मूल्यों का अनुरोध करेंगे। हमें यह सुनिश्चित करना चाहिए कि एक नया शुरू करने से पहले अंतिम कार्य इसके अंतिम कार्य के साथ किया गया है। अन्यथा, Arduino के लिए एक ही समय में कई अनुरोध किए जा सकते हैं जो Arduino/Unity को भ्रमित कर सकते हैं और अप्रत्याशित परिणाम प्राप्त कर सकते हैं।

निजी थ्रेड सक्रिय थ्रेड = शून्य;

शून्य अद्यतन () { अगर (activeThread == null || !activeThread. IsAlive) {activeThread = नया थ्रेड (AsynchronousReadFromArduino); सक्रिय थ्रेड। प्रारंभ (); } }

यदि आप कोड के प्रदर्शन की तुलना उस कोड से करते हैं जिसे हमने खंड 5 में लिखा था, तो प्रदर्शन में काफी सुधार होना चाहिए।

निजी शून्य OnArduinoInfoFail ()

{डीबग। लॉग ("पढ़ना विफल"); }

चरण 5: अगला कहां?

आगे कहाँ?
आगे कहाँ?

हमने एक डेमो तैयार किया है जिसे आप हमारे जीथब (https://github.com/AlexandreDoucet/InfinityBike) पर डाउनलोड कर सकते हैं, कोड और गेम डाउनलोड कर सकते हैं और हमारे ट्रैक के माध्यम से सवारी कर सकते हैं। यह एक त्वरित कसरत के लिए तैयार है और हम आशा करते हैं कि यह आपको इस बात का स्वाद दे सकता है कि आप क्या बना सकते हैं यदि आप इसका उपयोग करते हैं जो हमने आपको इस निर्देश के साथ सिखाया है।

क्रेडिट

परियोजना योगदानकर्ता

अलेक्जेंड्रे डौसेट (_Doucet_)

मैक्सिमे बौद्रेउ (एमएक्सबौड)

बाहरी संसाधन [द यूनिटी गेम इंजन](https://unity3d.com)

एलन ज़ुकोनी द्वारा "एकता के साथ Arduino को कैसे एकीकृत करें" (https://www.alanzucconi.com/2015/10/07/how-to-int…)

Arduino के अनुरोध को SerialCommand लाइब्रेरी (https://github.com/kroimon/Arduino-SerialCommand) का उपयोग करके नियंत्रित किया जाता है।

सिफारिश की: