Мазмуну:

Infinity Bike - Indoors Bike Training Video Game: 5 кадам
Infinity Bike - Indoors Bike Training Video Game: 5 кадам

Video: Infinity Bike - Indoors Bike Training Video Game: 5 кадам

Video: Infinity Bike - Indoors Bike Training Video Game: 5 кадам
Video: I Became A PRO BIKE RIDER In Ultra Realistic Game! 2024, Июнь
Anonim
Image
Image
Материалдар
Материалдар

Кыш мезгилдеринде, суук күндөрдө жана аба ырайынын начардыгында велосипед ышкыбоздорунун сүйүктүү спорту менен машыгуу үчүн бир нече варианттары бар. Биз велосипед/машыктыруучу менен жабык машыгууларды өткөрүүнүн жолун издеп жүрдүк, бирок көпчүлүк продуктылар кымбат же жөнөкөй эле кызыксыз. Мына ошондуктан биз Infinity Bikeти Open Source тренинг видео оюну катары өнүктүрө баштадык. Infinity велосипеди велосипедиңиздин ылдамдыгын жана багытын окуйт жана велосипед тренерлери менен оңой табылбай турган интерактивдүүлүктүн деңгээлин сунуштайт.

Биз Arduino микроконтроллеринин жеткиликтүүлүгүн жана 3D басылган бир нече бөлүктөрүн тренерге орнотулган велосипедге арзан датчиктерди камсыз кылуу үчүн колдонобуз. Маалымат популярдуу оюн жаратуучу кыймылдаткыч Unity менен жасалган видео оюнга жеткирилет. Бул көрсөтмө аяктагандан кийин, сиз велосипедге өзүңүздүн сенсорлоруңузду орнотуп, сенсорлоруңуздун маалыматын Биримдикке өткөрүп берүүңүз керек. Биз атүгүл тректи коштук, анда сиз өзүңүз минип, жаңы түзүмүңүздү сынап көрө аласыз. Эгерде сиз салым кошууну кааласаңыз, биздин GitHubдан чыксаңыз болот.

1 -кадам: материалдар

Материалдар
Материалдар

Сизге керектүү материалдык тизме бир аз айырмаланышы мүмкүн; үчүн

Мисалы, велосипеддин көлөмү сизге керектүү секирүүчү кабелдердин узундугун чечет, бирок бул жерде сизге керектүү болгон негизги тетиктер. Сиз, балким, AliExpress сыяктуу веб -сайтта ар бир бөлүккө арзаныраак бааларды таба алмаксыз, бирок жеткирүүнү 6 ай күтүү дайыма эле мүмкүн эмес, андыктан бир аз кымбатыраак бөлүктөрдү колдонуп, баа бурмаланбайт.

1 x Arduino наносу ($ 22.00)

1 x Mini Breadboard ($ 1.33/бирдик)

1 х 220 Ом каршылыгы ($ 1.00/комплект)

1 x 10K потенциометр ($ 1.80/бирдик)

1 х Hall сенсор ($ 0.96)

20 см х 6 мм 3D принтердин убакыт белбоосу ($ 3.33)

1 комплект x Various Lenght M3 бурамалары менен болттору ($ 6.82)

1 велосипед спидометринин магнити ($ 0.98)

Биз жогорудагы материалды 3D басылган бөлүктөрү менен орноттук. Биз колдонгон файлдар төмөндө тизмеленген жана алар ушул бөлүмдүн башындагы сүрөттөгүдөй конвенция менен номерленген. Бардык файлдарды 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 -кадам: Окуу жана Биримдикке маалыматтарды берүү

Берилиштерди окуу жана Биримдикке өткөрүү
Берилиштерди окуу жана Биримдикке өткөрүү

Arduino жана Unity коду чогуу иштешет, велосипеддеги сенсорлордон маалыматтарды өткөрүп берүү жана иштетүү. Биримдик Ардуинодон маанини сериал аркылуу сап жөнөтүп сурайт жана Arduino суралган баалуулуктарга жооп берүүсүн күтөт.

Биринчиден, биз Arduino программасын китепкана менен даярдайбыз, ал Unityден келген сурамдарды функция менен жупташтыруу аркылуу башкарылат. Бул китепкана үчүн негизги орнотуу төмөнкүчө жасалышы мүмкүн;

#"SerialCommand.h" кошуу

SerialCommand sCmd; жараксыз орнотуу () {sCmd.addCommand ("TRIGG", TriggHanlder); Serial.begin (9600); } void loop () {while (Serial.available ()> 0) {sCmd.readSerial (); }} void TriggHandler () { /*Бул жерден сенсорлорду окуп, өткөрүп бериңиз* /}

TriggHandler функциясы SCmd объектине тиркелет. Эгерде серия тиркелген буйрукка дал келген сапты алса (бул учурда TRIGG), TriggHandler функциясы аткарылат.

Биз потенциометрди рулдун багытын өлчөө үчүн жана велосипеддин бир мүнөтүнө айланууну өлчөө үчүн холл сенсорун колдонобуз. Потенциометрдин көрсөткүчтөрүн Arduinoдон орнотулган функцияларды колдонуу менен оңой эле жасаса болот. TriggHandler функциясы андан кийин маанини сериалга төмөнкү өзгөртүү менен басып чыгара алат.

жараксыз TriggHandler () {

/*Потенциометрдин маанисин окуу*/ Serial.println (analogRead (ANALOGPIN)); }

Биз пайдалуу өлчөөлөргө ээ боло электе Hall сенсорунда бир аз көбүрөөк орнотуу бар. Потенциометрден айырмаланып, холл сенсорунун заматта мааниси анча деле пайдалуу эмес. Дөңгөлөктүн ылдамдыгын өлчөөгө аракет кылып жаткандыктан, триггерлердин ортосундагы убакыт кызыктырды.

Arduino кодунда колдонулган ар бир функция убакытты талап кылат жана эгер магнит Холл сенсору менен туура эмес убакта биригип калса, анда өлчөө эң жакшы кечиктирилиши же эң начар учурда толугу менен өткөрүлүп жиберилиши мүмкүн. Бул, албетте, жаман, анткени Arduino дөңгөлөктүн чыныгы ылдамдыгынан бир топ айырмаланат.

Мунун алдын алуу үчүн, биз Arduinosтун тиркөө үзгүлтүк деп аталган өзгөчөлүгүн колдонобуз, ал бизге белгиленген санариптик пин жогорулап турган сигнал менен иштей баштаганда функцияны иштетүүгө мүмкүндүк берет. Rpm_fun функциясы орнотуу кодуна кошулган коддун бир сабы менен үзгүлтүккө тиркелет.

жараксыз орнотуу () {

sCmd.addCommand ("TRIGG", TriggHanlder); attachInterrupt (0, rpm_fun, RISING); Serial.begin (9600); } // Функция rpm_fun ылдамдыкты эсептөө үчүн колдонулат жана төмөнкүдөй аныкталат; unsigned long lastRevolTime = 0; белгисиз узак revolSpeed = 0; void rpm_fun () {unsigned long revolTime = millis (); белгисиз узак deltaTime = revolTime - lastRevolTime; /*revolSpeed - бул Arduino кодуна өткөрүлгөн маани* / revolSpeed = 20000 / deltaTime; lastRevolTime = revolTime; } TriggHandler андан кийин калган маалыматты керектүү учурда өткөрүп бере алат. void TriggHanlder () { /*Потенциометрдин маанисин окуу* / Serial.println (analogRead (ANALOGPIN)); Serial.println (revolSpeed); }

Азыр бизде биримдик тарабынан суроо -талап түшкөндө маалыматтарды сериал аркылуу өткөрүп бере турган Arduino кодун куруу үчүн колдонула турган бардык курулуш блоктору бар. Эгерде сиз толук коддун көчүрмөсүн алууну кааласаңыз, аны биздин GitHubдан жүктөп алсаңыз болот. Код туура орнотулганын текшерүү үчүн, TRIGG жөнөтүү үчүн сериялык мониторду колдонсоңуз болот; сызыктын аяктаганын Араба кайтарууга койгонуңузга ишениңиз. Кийинки бөлүм биздин Unity сценарийлери Arduinoдон маалыматты кантип сурап жана ала алары жөнүндө болмокчу.

3 -кадам: маалыматтарды алуу жана иштетүү

Маалыматтарды кабыл алуу жана иштетүү
Маалыматтарды кабыл алуу жана иштетүү

Биримдик - бул бекер хоббистер үчүн жеткиликтүү болгон сонун программа

оюн жасоого кызыкдар; ал C# сценарийлери менен эмне кылууну чектебестен, жип салуу же GPU программалоо (AKA көлөкөлөштүрүү) сыяктуу кээ бир нерселерди орнотуу убактысын чындап кыскартууга мүмкүн болгон көптөгөн функциялар менен келет. Unity жана Arduino микроконтроллерлери салыштырмалуу аз бюджет менен уникалдуу интерактивдүү тажрыйбаларды түзүү үчүн бирге колдонулушу мүмкүн.

Бул нускаманын максаты-Unity менен Arduino ортосундагы байланышты түзүүгө жардам берүү, ошондуктан биз Unity менен жеткиликтүү болгон көптөгөн мүмкүнчүлүктөргө өтө терең кирбейбиз. Биримдиктин жана укмуштуудай коомчулуктун Улуу Окутуулары көп, алар Юнитеттин кантип иштээрин түшүндүрүү иштерин жакшыраак аткара алышат. Бирок, эмне кылса болорун кичинекей көргөзмө катары кызмат кылган бул көрсөтмө аркылуу өз жолун башкара алгандар үчүн атайын сыйлык бар. Сиз биздин Githubдан реалдуу велосипед физикасы менен тректи биринчи жолу жүктөп алсаңыз болот.

Биринчиден, Arduino менен сериал аркылуу байланышуу үчүн эмне кылыш керек экенин карап көрөлү. Бул код ойноо үчүн ылайыктуу эмес экени тез эле билинет, бирок ар бир кадамды басып өтүп, чектөөлөр эмне экенин билүү жакшы.

Биримдикте, ArduinoReceive аттуу бош бош GameObject менен жаңы көрүнүштү түзүңүз, C# сценарийи ArduinoReceive деп атташет. Бул скрипт биз Arduino менен байланышты башкарган бардык кодду кошобуз.

Компьютериңиздин сериялык порттору менен байланышуу үчүн, кире турган китепкана бар; Кээ бир китепканаларды колдонууга уруксат берүү үчүн биримдикти орнотуу керек. Edit-> ProjectSerring-> Playerге барып, конфигурация которгучунун астындагы Api шайкештик деңгээлинин жанына барыңыз. NET 2.0. NET 2.0ге топтому. Эми скрипттин жогору жагына төмөнкү кодду кошуңуз;

System. IO. Ports колдонуу;

Бул сизге ArduinoReceive классына объект катары аныктоого мүмкүн болгон SerialPort классына кирүүгө мүмкүнчүлүк берет. Башка скрипттин кийлигишүүсүнө жол бербөө үчүн аны купуя кылыңыз.

жеке SerialPort arduinoPort;

АрдуиноПорт объектиси туура портту (мисалы, USB Arduino туташкан) жана берилүү ылдамдыгын (б.а. маалымат жөнөтүү ылдамдыгын) тандоо менен ачылышы мүмкүн. Эгерде сиз Arduino кайсы портко туташтырылганын билбесеңиз, аны түзмөк менеджеринен же Arduino IDE ачуу менен биле аласыз. Байдын ылдамдыгы үчүн, көпчүлүк түзмөктөрдүн демейки мааниси 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 -бөлүмдүн коду Arduinoго жүктөлгөнүн жана сериялык монитор ушул бөлүмдүн калган бөлүгүндө жабылганын жана бул коддун көйгөйсүз түрдө түзүлгөнүн текшериңиз.

Эми ар бир кадрга Arduinoго суроо жөнөтүп, жыйынтыгын консоль терезесине жазалы. WriteToArduino функциясын ArduinoReceive классына кошуңуз. Арбанын кайтып келиши жана жаңы линия Arduino коду келген инструкцияны туура талдоо үчүн керек.

жеке боштук WriteToArduino (сап билдирүүсү)

{message = message + "\ r / n"; arduinoPort. Write (билдирүү); arduinoPort. BaseStream. Flush (); }

Бул функцияны Update циклинде чакырса болот.

жараксыз жаңыртуу ()

{WriteToArduino ("TRIGG"); Debug. Log ("Биринчи маани:" + arduinoPort. ReadLine ()); Debug. Log ("Экинчи Мааниси:" + arduinoPort. ReadLine ()); }

Жогорудагы код - бул Arduino маалыматын окуу үчүн керек болгон эң аз. Эгерде сиз биримдик берген FPSке абдан көңүл бурсаңыз, анда иштин олуттуу төмөндөшүн көрүшүңүз керек. Менин учурда, ал 90 FPSтен 20 FPSке чейин окубай туруп жазат. Эгерде сиздин долбоор тез -тез жаңыртууну талап кылбаса, бул жетиштүү болушу мүмкүн, бирок видео оюн үчүн 20 FPS өтө төмөн. Кийинки бөлүмдө көп жипти колдонуу менен иштөөнү кантип жакшыртууга болот.

4 -кадам: Берилиштерди оптималдаштыруу

Мурунку бөлүм негизги орнотууну кантип камтыйт

Arduino жана Unity программасынын ортосундагы байланыш. Бул коддун негизги көйгөйү - бул иштөө. Учурдагы ишке ашырууда, Биримдик Arduino сурамды кабыл алууну, иштеп чыгууну жана жооп берүүнү күтүшү керек. Бул убакыттын ичинде, Биримдик коду сурамдын аткарылышын күтүшү керек жана башка эч нерсе кылбайт. Биз бул маселени сурамдарды иштетүүчү жана өзгөрмөнү негизги жипте сактай турган жип түзүү аркылуу чечтик.

Баштоо үчүн, биз кошуу аркылуу жип ийрим китепканасын камтышыбыз керек;

System. Threading колдонуу;

Андан кийин, биз жиптерден баштап жаткан функцияны орнотобуз. AsynchronousReadFromArduino WrtieToArduino функциясы менен Arduinoго суроо жазуудан башталат. Окуу сыноо блогуна камтылган, эгерде окуу убактысы бүтсө, өзгөрмөлөр нөл бойдон калат жана OnArduinoInfoFail ордуна OnArduinoInfoFail чакырылат.

Андан кийин OnArduinoInfoFail жана OnArduinoInfoReceive функцияларын аныктайбыз. Бул көрсөтмө берүү үчүн, биз жыйынтыгын консолго басып чыгарабыз, бирок сиз жыйынтыктарды долбооруңуз үчүн керектүү өзгөрмөлөргө сактай аласыз.

купуя боштук OnArduinoInfoFail ()

{Debug. Log ("Окубай калды"); } жеке боштук OnArduinoInfoReceived (саптын айлануусу, саптын ылдамдыгы) {Debug. Log ("Readin Sucessfull"); Debug. Log ("Биринчи маани:" + айлануу); Debug. Log ("Экинчи Мааниси:" + ылдамдыгы); }

Акыркы кадам - Arduinoдон баалуулуктарды сурай турган темаларды баштоо жана токтотуу. Биз жаңы ишти баштоодон мурун акыркы жип анын акыркы тапшырмасы менен аткарылышын камсыз кылышыбыз керек. Болбосо, Arduino/Unity'ди чаташтырып, күтүлбөгөн натыйжаларга алып келиши мүмкүн болгон бир эле убакта Arduinoго бир нече өтүнүчтөрдү жасоого болот.

private Thread activeThread = null;

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

Эгерде сиз коддун иштешин 5 -бөлүмдө жазган менен салыштырсаңыз, иштөө жакшырышы керек.

купуя боштук OnArduinoInfoFail ()

{Debug. Log ("Окубай калды"); }

5 -кадам: Кийинки кайда?

Кийинки кайда?
Кийинки кайда?

Биз Githubдан (https://github.com/AlexandreDoucet/InfinityBike) жүктөп ала турган демо даярдадык, кодду жана оюнду жүктөп алып, биздин тректи басып өтүңүз. Мунун баары тез машыгуу үчүн даярдалган жана биз сизге үйрөткөн нерсебизди ушул үйрөткүч менен колдонсоңуз, ал сиз кура турган нерсенин даамын берет деп үмүттөнөбүз.

Кредиттер

Долбоордун катышуучулары

Александр Дюцет (_Doucet_)

Максим Будро (MxBoud)

Тышкы ресурстар [Unity оюн кыймылдаткычы] (https://unity3d.com)

Бул долбоор Аллан Цукконинин "Arduino-ны Биримдик менен кантип интеграциялоо керек" деген окуу куралын окугандан кийин башталган (https://www.alanzucconi.com/2015/10/07/how-to-int…)

Arduinoдон келген өтүнүч SerialCommand китепканасы аркылуу каралат (https://github.com/kroimon/Arduino-SerialCommand)

Сунушталууда: