Мазмұны:

Infinity Bike - Үйде велосипедке арналған бейне ойын: 5 қадам
Infinity Bike - Үйде велосипедке арналған бейне ойын: 5 қадам

Бейне: Infinity Bike - Үйде велосипедке арналған бейне ойын: 5 қадам

Бейне: Infinity Bike - Үйде велосипедке арналған бейне ойын: 5 қадам
Бейне: 1700 жылдардағы тасталған ертегі сарайы ~ иесі көлік апатынан қайтыс болды! 2024, Маусым
Anonim
Image
Image
Материалдар
Материалдар

Қыс мезгілінде, суық күндерде және ауа райының қолайсыздығында велосипедті ұнататындар өздерінің сүйікті спорт түрлерімен шұғылдануға бірнеше мүмкіндіктері бар. Біз велосипед/жаттықтырушы қондырғысы бар үйдегі жаттығуларды біршама қызықты етіп өткізудің жолын іздедік, бірақ қол жетімді өнімдердің көпшілігі не қымбат, не қарапайым скучно. Сондықтан біз Infinity Bike -ді ашық бастапқы коды бар бейне ойын ретінде дамыта бастадық. Infinity велосипед велосипедтің жылдамдығы мен бағытын оқиды және велотренерлермен оңай табылмайтын интерактивтілік деңгейін ұсынады.

Біз Arduino микроконтроллерінің қарапайымдылығын және бірнеше 3D басып шығарылған бөлшектерді тренажерге орнатылған велосипедке арзан датчиктерді бекіту үшін қолданамыз. Ақпарат танымал Unity қозғалтқышымен жасалған бейне ойынға қатысты. Бұл нұсқаулықтың соңында сіз велосипедке өзіңіздің датчиктеріңізді орнатып, сенсорларыңыз туралы ақпаратты Unity-ге жібере аласыз. Біз тіпті сіз жүре алатын және жаңа қондырғыңызды тексере алатын тректі қостық. Егер сіз өз үлесіңізді қосқыңыз келсе, біздің GitHub -ты тексере аласыз.

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

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

Сізге қажет материалдар тізімі сәл өзгеше болуы мүмкін; үшін

Мысалы, велосипедтің өлшемі сізге қажетті кабельдердің ұзындығын анықтайды, бірақ сізге қажет негізгі бөлшектер. Сіз AliExpress сияқты веб -сайтта әр бөлшектің арзан бағасын таба аласыз, бірақ жеткізу үшін 6 ай күту әрдайым мүмкін емес, сондықтан сәл қымбатырақ бөлшектерді пайдалану мүмкін емес, сондықтан бағалау бұрмаланбайды.

1 x Arduino нано ($ 22.00)

1 x шағын тақта ($ 1,33/бірлік)

1 x 220 Ом резисторы (жиынтық $ 1,00)

1 x 10K потенциометр (бірлік $ 1,80)

1 x Холл сенсоры ($ 0.96)

20 см x 6 мм 3D принтерінің уақыт белбеуі ($ 3,33)

1 жиынтық x Әр түрлі ұзындықтағы M3 бұрандалар мен болттар ($ 6.82)

1 x велосипед спидометрінің магниті ($ 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 сұралған мәндерге жауап беруін күтеді.

Біріншіден, біз Arduino -ны сұраныс жолын функциямен жұптастыру арқылы Unity -ден сұраныстарды басқаруға арналған Serial Command кітапханасымен дайындаймыз. Бұл кітапхана үшін негізгі қондырғы келесі түрде жасалуы мүмкін;

#«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 функциясы орындалады.

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

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

/*Потенциометрдің мәнін оқу*/ Serial.println (analogRead (ANALOGPIN)); }

Пайдалы өлшеулерге дейін Холл сенсоры сәл реттелген. Потенциометрден айырмашылығы, холл сенсорының жылдам мәні аса пайдалы емес. Дөңгелектің жылдамдығын өлшеуге тырысқандықтан, триггерлер арасындағы уақыт қызықтырды.

Arduino кодында қолданылатын әрбір функция уақытты қажет етеді, ал егер магнит Холл сенсорымен дұрыс емес уақытта орналасса, өлшеуді кешіктіруге немесе ең нашар жағдайда мүлде өткізіп жіберуге болады. Бұл нашар, себебі Arduino доңғалақтың нақты жылдамдығынан өзгеше жылдамдық туралы хабарлауы мүмкін.

Бұған жол бермеу үшін біз Arduinos -тың бекітілген үзіліс деп аталатын функциясын қолданамыз, ол сигналдың жоғарылауымен белгіленген цифрлық түйреуіш іске қосылған кезде функцияны іске қосуға мүмкіндік береді. Rpm_fun функциясы орнату кодына қосылған кодтың бір жолымен үзіліске қосылады.

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

sCmd.addCommand («TRIGG», TriggHanlder); attachInterrupt (0, rpm_fun, RISING); Serial.begin (9600); } // rpm_fun функциясы жылдамдықты есептеу үшін қолданылады және келесідей анықталады; белгісіз ұзақ 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 кодын құру үшін қолдануға болатын барлық құрылыс блоктары бар, олар Unity сұрау салған кезде деректерді серия арқылы тасымалдайды. Егер сіз толық кодтың көшірмесін алғыңыз келсе, оны біздің GitHub сайтынан жүктей аласыз. Кодтың дұрыс орнатылғанын тексеру үшін сериялық мониторды TRIGG жіберуге болады; жолды арбаға қайтару жолын орнатқаныңызға көз жеткізіңіз. Келесі бөлім біздің Unity сценарийлерінің Arduino -дан ақпаратты қалай сұрауға және алуға болатынына арналады.

3 -қадам: Деректерді қабылдау және өңдеу

Деректерді қабылдау және өңдеу
Деректерді қабылдау және өңдеу

Unity - бұл әуесқойлар үшін ақысыз қол жетімді тамаша бағдарлама

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

Бұл нұсқаулықтың мақсаты-Unity мен Arduino арасындағы байланысты орнатуға көмектесу, сондықтан біз Unity-мен қол жетімді мүмкіндіктердің көпшілігіне терең енбейміз. Бірлік пен керемет қауымдастыққа арналған көптеген керемет оқулықтар бар, олар Unity қалай жұмыс істейтінін түсіндіретін жақсы жұмыс жасай алады. Алайда, бұл нұсқаулық арқылы өз жолымен жұмыс істей алатындар үшін арнайы сыйлық бар, ол не істеуге болатынын көрсетеді. Сіз біздің Github -та шынайы велосипед физикасымен трек жасауға тырысатын алғашқы әрекетті жүктей аласыз.

Алдымен, Arduino -мен сериал арқылы байланысу үшін жасалуы керек ең төменгі деңгейден өтейік. Бұл код ойынға жарамсыз екені тез түсінікті болады, бірақ әр қадамнан өтіп, шектеулердің не екенін білу жақсы.

Unity -де ArduinoReceive атты жалғыз бос GameObject көмегімен жаңа сахна жасаңыз, C# сценарийін ArduinoReceive деп атаңыз. Бұл сценарийде біз Arduino -мен байланыс орнататын барлық кодты қосамыз.

Біз компьютердің сериялық порттарымен байланыс орнатпас бұрын кіруге болатын кітапхана бар; Белгілі бір кітапханаларды пайдалануға рұқсат ету үшін бірлікті орнату қажет. Өңдеу-> ProjectSerring-> ойнатқышқа өтіңіз және Api үйлесімділік деңгейінің жанындағы конфигурация қосқышы астында. NET 2.0 ішкі жиынтығы. NET 2.0. Енді сценарийдің жоғарғы жағына келесі кодты қосыңыз;

System. IO. Ports пайдалану;

Бұл сізге ArduinoReceive класының объектісі ретінде анықтай алатын SerialPort сыныбына кіруге мүмкіндік береді. Басқа сценарийдің араласуын болдырмау үшін оны құпия етіңіз.

жеке SerialPort arduinoPort;

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 жеке жарамсыздығы (жол хабарламасы)

{хабарлама = хабарлама + «\ r / n»; arduinoPort. Write (хабар); arduinoPort. BaseStream. Flush (); }

Бұл функцияны Жаңарту циклінде шақыруға болады.

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

{WriteToArduino («TRIGG»); Debug. Log («Бірінші мән:» + arduinoPort. ReadLine ()); Debug. Log («Екінші мән:» + arduinoPort. ReadLine ()); }

Жоғарыдағы код - бұл Arduino -дан деректерді оқу үшін қажет ең аз мөлшер. Егер сіз бірлік берген FPS -ге мұқият назар аударсаңыз, өнімділіктің айтарлықтай төмендеуін көруіңіз керек. Менің жағдайда, бұл 90 FPS -тен 20 FPS -ке дейін оқымай -ақ жазылады. Егер сіздің жобаңыз жиі жаңартуларды қажет етпесе, бұл жеткілікті болуы мүмкін, бірақ бейне ойын үшін 20 FPS тым төмен. Келесі бөлімде бірнеше ағынды пайдалану арқылы өнімділікті қалай жақсартуға болатыны қарастырылады.

4 -қадам: деректерді беруді оңтайландыру

Алдыңғы бөлімде негізгі параметрлерді орнату туралы айтылады

Arduino және Unity бағдарламасы арасындағы байланыс. Бұл кодтың негізгі проблемасы - бұл өнімділік. Ағымдағы іске асыруда Unity Arduino сұранысты қабылдауын, өңделуін және жауап беруін күтуі керек. Осы уақыт ішінде Unity коды сұраныстың орындалуын күтуі керек және басқа ештеңе жасамайды. Біз бұл мәселені сұраныстарды өңдейтін және айнымалы мәнді негізгі ағынға сақтайтын ағын құру арқылы шештік.

Бастау үшін біз қосу арқылы ағындық кітапхананы қосуымыз керек;

System. Threading қолдану;

Содан кейін біз ағындарда бастайтын функцияны орнатамыз. AsynchronousReadFromArduino WrtieToArduino функциясымен Arduino сұранысын жазудан басталады. Оқу блок-блокқа салынған, егер оқудың күту уақыты аяқталса, айнымалылар нөл болып қалады және OnArduinoInfoReceive орнына 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)

Ұсынылған: