فهرست مطالب:

دوچرخه بی نهایت - بازی دوچرخه سواری داخل سالن: 5 مرحله
دوچرخه بی نهایت - بازی دوچرخه سواری داخل سالن: 5 مرحله

تصویری: دوچرخه بی نهایت - بازی دوچرخه سواری داخل سالن: 5 مرحله

تصویری: دوچرخه بی نهایت - بازی دوچرخه سواری داخل سالن: 5 مرحله
تصویری: دوچرخه پنومات🤙😅 | ماشین بازی باید تو خونت باشه !! 2024, سپتامبر
Anonim
Image
Image
مواد
مواد

در فصول زمستان ، روزهای سرد و هوای بد ، علاقه مندان به دوچرخه سواری تنها چند گزینه برای انجام ورزش مورد علاقه خود دارند. ما به دنبال راهی بودیم که تمرینات داخل سالن را با نصب دوچرخه/مربی کمی سرگرم کننده تر کنیم ، اما اکثر محصولات موجود هزینه بر هستند یا استفاده از آنها خسته کننده است. به همین دلیل است که ما توسعه Infinity Bike را به عنوان یک بازی ویدیویی آموزشی منبع باز آغاز کردیم. دوچرخه Infinity سرعت و جهت دوچرخه شما را می خواند و سطحی از تعامل را ارائه می دهد که به راحتی با مربیان دوچرخه پیدا نمی شود.

ما از سادگی موجود در میکروکنترلر آردوینو و چند قطعه پرینت سه بعدی استفاده می کنیم تا حسگرهای ارزان قیمت را روی دوچرخه ای که روی مربی نصب شده ایمن کنیم. این اطلاعات به یک بازی ویدئویی منتقل می شود که با موتور بازی سازی محبوب Unity ساخته شده است. در پایان این دستورالعمل ، شما باید بتوانید سنسورهای خود را روی دوچرخه خود نصب کرده و اطلاعات سنسورهای خود را به یونیتی منتقل کنید. ما حتی یک پیست را شامل می شود که می توانید در آن سوار شوید و تنظیمات جدید خود را آزمایش کنید. اگر علاقه مند به مشارکت هستید می توانید GitHub ما را بررسی کنید.

مرحله 1: مواد

مواد
مواد

فهرست مواد مورد نیاز شما ممکن است کمی متفاوت باشد. برای

به عنوان مثال ، اندازه دوچرخه شما طول کابل های بلوز مورد نیاز شما را تعیین می کند ، اما در اینجا قطعات اصلی مورد نیاز شما آمده است. احتمالاً برای هر قطعه در وب سایت مانند AliExpress می توانید قیمت های ارزان تری پیدا کنید ، اما انتظار 6 ماه برای حمل و نقل همیشه یک گزینه نیست ، بنابراین از قطعات کمی گران تر استفاده کنید تا برآورد آن اشتباه نباشد.

1 عدد آردوینو نانو (22.00 دلار)

1 x Mini Breadboard (1.33 دلار/واحد)

1 مقاومت 220 اهم (1.00 دلار/کیت)

پتانسیومتر 1 x 10K (1.80 دلار/واحد)

1 عدد سنسور هال (0.96 دلار)

کمربند زمان بندی چاپگر سه بعدی 20 سانتی متر در 6 میلی متر (3.33 دلار)

1 کیت x پیچ و مهره مختلف طول M3 (6.82 دلار)

1 عدد آهنربای سرعت سنج دوچرخه (0.98 دلار)

ما مواد بالا را با قطعات چاپ سه بعدی نصب کردیم. فایلهای مورد استفاده ما در زیر لیست شده اند و شماره آنها با همان تصویر در ابتدای این بخش شماره گذاری شده است. همه فایل ها را می توانید در Thingiverse پیدا کنید. می توانید از آنها به صورت واقعی استفاده کنید اما مطمئن شوید که ابعادی که استفاده کردیم با دوچرخه شما مطابقت داشته باشد.

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

مرحله 2: خواندن و انتقال داده ها به وحدت

خواندن و انتقال داده ها به وحدت
خواندن و انتقال داده ها به وحدت

کد آردوینو و یونیتی با هم کار خواهند کرد تا

انتقال و پردازش داده ها از سنسورهای روی دوچرخه. Unity با ارسال یک رشته از طریق سریال ، مقدار را از آردوینو درخواست می کند و منتظر می ماند تا آردوینو با مقادیر درخواست شده پاسخ دهد.

ابتدا ، Arduino را با دستور سریال کتابخانه آماده می کنیم که برای مدیریت درخواست های Unity با جفت کردن یک رشته درخواست با یک تابع استفاده می شود. راه اندازی اولیه این کتابخانه را می توان به شرح زیر انجام داد:

#شامل "SerialCommand.h"

SerialCommand sCmd؛ void setup () {sCmd.addCommand ("TRIGG"، TriggHanlder)؛ Serial.begin (9600)؛ } void loop () {while (Serial.available ()> 0) {sCmd.readSerial ()؛ }} void TriggHandler () { /*سنسورها را اینجا بخوانید و ارسال کنید* /}

تابع TriggHandler به شی SCmd متصل است. اگر سریال رشته ای دریافت کند که با دستور پیوست مطابقت داشته باشد (در این مورد TRIGG) ، تابع TriggHandler اجرا می شود.

ما از پتانسیومتر برای اندازه گیری جهت فرمان و سنسور سالن برای اندازه گیری چرخش در دقیقه دوچرخه استفاده می کنیم. قرائت پتانسیومتر را می توان به راحتی با استفاده از توابع داخلی آردوینو انجام داد. تابع TriggHandler سپس می تواند مقدار را در سریال با تغییرات زیر چاپ کند.

void TriggHandler () {

/*خواندن مقدار پتانسیومتر*/ Serial.println (analogRead (ANALOGPIN)) ؛ }

سنسور Hall قبل از اینکه بتوانیم اندازه گیری های مفیدی داشته باشیم ، کمی تنظیمات بیشتری دارد. برخلاف پتانسیومتر ، مقدار لحظه ای سنسور سالن چندان مفید نیست. از آنجا که در تلاش برای اندازه گیری سرعت چرخ بود ، فاصله بین محرک ها چیزی است که به آن علاقه داشت.

هر عملکردی که در کد آردوینو استفاده می شود زمان می برد و اگر مغناطیس در زمان اشتباه با سنسور Hall هماهنگ شود ، اندازه گیری در بهترین حالت به تأخیر می افتد یا در بدترین حالت به طور کامل حذف می شود. این بدیهی است که بد است زیرا آردوینو می تواند سرعتی متفاوت با سرعت واقعی چرخ گزارش دهد.

برای جلوگیری از این امر ، ما از ویژگی Arduinos به نام attach interrupt استفاده می کنیم که به ما امکان می دهد هر زمان که یک پین دیجیتالی تعیین شده با سیگنال در حال افزایش فعال می شود ، یک تابع را فعال کنیم. تابع rpm_fun به یک وقفه متصل می شود و یک خط کد به کد راه اندازی اضافه می شود.

void setup () {

sCmd.addCommand ("TRIGG" ، TriggHanlder) ؛ attachInterrupt (0 ، rpm_fun ، RISING) ؛ Serial.begin (9600)؛ } // تابع rpm_fun برای محاسبه سرعت استفاده می شود و به صورت زیر تعریف شده است: unsigned long lastRevolTime = 0؛ revols طولانی امضا نشده Speed = 0؛ void rpm_fun () {unsigned long revolTime = millis ()؛ deltaTime طولانی بدون امضا = revolTime - lastRevolTime؛ /*revolSpeed مقدار منتقل شده به کد آردوینو* / revolSpeed = 20000 / deltaTime است ؛ lastRevolTime = revolTime؛ } TriggHandler سپس می تواند بقیه اطلاعات را در صورت درخواست ارسال کند. void TriggHanlder () { /*خواندن مقدار پتانسیومتر* / Serial.println (analogRead (ANALOGPIN)) ؛ Serial.println (revolSpeed) ؛ }

ما در حال حاضر تمام اجزای سازنده ای را داریم که می توان برای ساخت کد Arduino استفاده کرد و داده ها را از طریق سریال به زمانی که درخواست توسط Unity ارسال می شود ، منتقل می کند. اگر می خواهید یک کپی از کد کامل داشته باشید ، می توانید آن را در GitHub ما بارگیری کنید. برای بررسی اینکه آیا کد به درستی تنظیم شده است ، می توانید از مانیتور سریال برای ارسال TRIGG استفاده کنید. مطمئن شوید که خط را به Carriage return ختم می کنید. بخش بعدی بر چگونگی درخواست و دریافت اطلاعات اسکریپت های Unity ما از آردوینو تمرکز خواهد کرد.

مرحله 3: دریافت و پردازش داده ها

دریافت و پردازش داده ها
دریافت و پردازش داده ها

Unity یک نرم افزار عالی است که به صورت رایگان در اختیار علاقمندان قرار می گیرد

علاقه مند به بازی سازی ؛ این نرم افزار دارای تعداد زیادی قابلیت است که می تواند به موقع تنظیم برخی موارد مانند ایجاد رشته یا برنامه نویسی GPU (سایه زنی AKA) را بدون محدود کردن آنچه می توان با اسکریپت های C# انجام داد ، به موقع کاهش دهد. از میکروکنترلرهای یونیتی و آردوینو می توان برای ایجاد تجربیات تعاملی منحصر به فرد با بودجه نسبتاً کمی استفاده کرد.

تمرکز این دستورالعمل کمک به برقراری ارتباط بین یونیتی و آردوینو است ، بنابراین ما عمیقاً در اکثر ویژگی های موجود با یونیتی غوطه ور نمی شویم. تعداد زیادی آموزش عالی برای وحدت و یک جامعه باورنکردنی وجود دارد که می تواند کار بسیار بهتری را در توضیح نحوه عملکرد یونیتی انجام دهد. با این حال ، یک جایزه ویژه برای کسانی که موفق به کار در این راه آموزنده می شوند وجود دارد که به عنوان یک ویترین کوچک از آنچه می توان انجام داد ، عمل می کند. می توانید اولین تلاش ما را برای ایجاد یک مسیر با فیزیک دوچرخه واقع بینانه در Github ما بارگیری کنید.

اول ، بیایید حداقلهایی را که باید برای برقراری ارتباط با آردوینو از طریق سریال انجام شود ، مرور کنیم. به سرعت مشخص می شود که این کد برای گیم پلی مناسب نیست ، اما خوب است که هر مرحله را طی کرده و محدودیت ها را بیاموزید.

در Unity ، یک صحنه جدید با یک GameObject خالی به نام ArduinoReceive ایجاد کنید و یک اسکریپت C# نیز با نام ArduinoReceive ضمیمه کنید. این اسکریپت جایی است که ما تمام کدهایی را که ارتباط با آردوینو را مدیریت می کند اضافه می کنیم.

قبل از اینکه بتوانیم با پورت های سریال رایانه شما ارتباط برقرار کنیم ، باید کتابخانه ای وجود داشته باشد. وحدت باید طوری تنظیم شود که بتوان از کتابخانه های خاص استفاده کرد. به Edit-> ProjectSerring-> Player و در کنار Api Compatibility Level در قسمت Configuration switch. NET 2.0 زیر مجموعه به. NET 2.0 بروید. حالا کد زیر را در بالای اسکریپت اضافه کنید ؛

با استفاده از System. IO. Ports ؛

این به شما امکان می دهد به کلاس SerialPort دسترسی داشته باشید که می توانید آن را به عنوان یک شیء در کلاس ArduinoReceive تعریف کنید. برای جلوگیری از هرگونه دخالت اسکریپت دیگر ، آن را خصوصی کنید.

SerialPort خصوصی arduinoPort؛

شیء arduinoPort را می توان با انتخاب پورت صحیح (به عنوان مثال USB که آردوینو در آن متصل است) و نرخ baud (یعنی سرعت ارسال اطلاعات) باز کرد. اگر مطمئن نیستید که آردوینو در کدام پورت متصل شده است ، می توانید از طریق مدیر دستگاه یا با باز کردن Arduino IDE به این موضوع پی ببرید. برای نرخ baud ، مقدار پیش فرض در اکثر دستگاه ها 9600 است ، فقط مطمئن شوید که این مقدار را در کد Arduino خود دارید و باید کار کند.

اکنون کد باید به این شکل باشد.

با استفاده از System. Collections ؛

با استفاده از System. Collections. Generic؛ استفاده از UnityEngine ؛ با استفاده از System. IO. Ports ؛ کلاس عمومی ArduinoReceive: MonoBehaviour {خصوصی SerialPort arduinoPort؛ // از این برای راه اندازی اولیه استفاده کنید void Start () {arduinoPort = new SerialPort ("COM5"، 9600)؛ arduinoPort. Open ()؛ WriteToArduino ("TRIGG") ؛ }}

شماره COM شما به احتمال زیاد متفاوت خواهد بود. اگر از MAC استفاده می کنید ، ممکن است نام COM شما شبیه به این باشد /dev/cu.wchusbserial1420. اطمینان حاصل کنید که کد قسمت 4 در آردوینو بارگذاری شده و مانیتور سریال برای بقیه این بخش بسته شده است و این کد بدون مشکل کامپایل می شود.

بیایید اکنون در هر فریم یک درخواست به آردوینو ارسال کنیم و نتایج را در پنجره کنسول بنویسیم. تابع WriteToArduino را به کلاس ArduinoReceive اضافه کنید. بازگشت کالسکه و خط جدید برای کد آردوینو ضروری است تا دستورالعمل ورودی را به درستی تجزیه کند.

خلأ خصوصی WriteToArduino (پیام رشته)

{پیام = پیام + "\ r / n"؛ arduinoPort. Write (پیام) ؛ arduinoPort. BaseStream. Flush ()؛ }

سپس می توان این تابع را در حلقه Update فراخوانی کرد.

void Update ()

{WriteToArduino ("TRIGG") ؛ Debug. Log ("مقدار اول:" + arduinoPort. ReadLine ()) ؛ Debug. Log ("مقدار دوم:" + arduinoPort. ReadLine ()) ؛ }

کد بالا حداقل چیزی است که شما برای خواندن داده ها از آردوینو نیاز دارید. اگر به FPS داده شده توسط واحد توجه زیادی داشته باشید ، باید افت قابل توجهی در عملکرد مشاهده کنید. در مورد من ، از حدود 90 FPS بدون خواندن/نوشتن به 20 FPS می رسد. اگر پروژه شما نیازی به به روز رسانی مکرر ندارد ممکن است کافی باشد اما برای یک بازی ویدیویی ، 20 FPS بسیار کم است. بخش بعدی نحوه بهبود عملکرد با استفاده از چند نخ را پوشش می دهد.

مرحله 4: بهینه سازی انتقال داده

قسمت قبل نحوه تنظیمات اولیه را پوشش داد

ارتباط بین برنامه آردوینو و یونیتی. مشکل اصلی این کد عملکرد است. در اجرای فعلی ، Unity باید منتظر بماند تا Arduino درخواست را دریافت ، پردازش و پاسخ دهد. در آن مدت ، کد یونیتی باید منتظر بماند تا درخواست انجام شود و هیچ کار دیگری نمی کند. ما این مشکل را با ایجاد موضوعی که به درخواست ها رسیدگی می کند و متغیر را در نخ اصلی ذخیره می کند ، حل کردیم.

برای شروع ، باید کتابخانه threading را با افزودن؛

با استفاده از System. Threading ؛

در مرحله بعد ، عملکردی را که در نخ ها شروع می کنیم تنظیم می کنیم. AsynchronousReadFromArduino با نوشتن درخواست به Arduino با عملکرد WrtieToArduino شروع می کند. خواندن در یک بلوک try-catch محصور شده است ، اگر زمان خواندن متغیرها صفر باقی بماند و تابع OnArduinoInfoFail به جای OnArduinoInfoReceive فراخوانی شود.

سپس توابع OnArduinoInfoFail و OnArduinoInfoReceive را تعریف می کنیم. برای این دستورالعمل ، ما نتایج را روی کنسول چاپ می کنیم ، اما شما می توانید نتایج را در متغیرهای مورد نیاز برای پروژه خود ذخیره کنید.

خلأ خصوصی OnArduinoInfoFail ()

{Debug. Log ("خواندن انجام نشد") ؛ } private void OnArduinoInfoReceived (چرخش رشته ، سرعت رشته) {Debug. Log ("Readin Successfull") ؛ Debug. Log ("مقدار اول:" + چرخش) ؛ Debug. Log ("مقدار دوم:" + سرعت) ؛ }

آخرین مرحله شروع و توقف نخ هایی است که مقادیر را از آردوینو درخواست می کنند. قبل از شروع یک موضوع جدید ، باید اطمینان حاصل کنیم که آخرین موضوع با آخرین کار انجام شده است. در غیر این صورت ، چندین درخواست می تواند همزمان با Arduino انجام شود که می تواند Arduino/Unity را اشتباه گرفته و نتایج غیرقابل پیش بینی را به همراه داشته باشد.

موضوع خصوصی activeThread = null؛

void Update () {if (activeThread == null ||! activeThread. IsAlive) {activeThread = موضوع جدید (AsynchronousReadFromArduino) ؛ activeThread. Start ()؛ }}

اگر عملکرد کد را با آنچه در بخش 5 نوشتیم مقایسه کنید ، عملکرد باید به میزان قابل توجهی بهبود یابد.

خلأ خصوصی OnArduinoInfoFail ()

{Debug. Log ("خواندن انجام نشد") ؛ }

مرحله 5: بعد کجا؟

کجا بعد؟
کجا بعد؟

ما یک نسخه ی نمایشی آماده کرده ایم که می توانید در Github ما (https://github.com/AlexandreDoucet/InfinityBike) بارگیری کنید ، کد و بازی را بارگیری کرده و در مسیر ما سوار شوید. همه اینها برای یک تمرین سریع آماده شده است و ما امیدواریم که بتواند به شما طعم آنچه را که می توانید بسازید به شما ارائه دهد اگر از آنچه ما با این دستورالعمل به شما آموزش دادیم استفاده کنید.

وام

مشارکت کنندگان پروژه

Alexandre Doucet (_Doucet_)

ماکسیم بودرو (MxBoud)

منابع خارجی [موتور بازی Unity] (https://unity3d.com)

این پروژه پس از مطالعه آموزش آلن زوکنی "نحوه ادغام آردوینو با یونیتی" (https://www.alanzucconi.com/2015/10/07/how-to-int…) آغاز شد.

درخواست آردوینو با استفاده از کتابخانه SerialCommand انجام می شود (https://github.com/kroimon/Arduino-SerialCommand)

توصیه شده: