[MOC] Maszyna do gry w łapki

Mindstorms, WeDo, Lego Digital Desinger, Stud.io

Moderatorzy: Mod Team, Mod Team

Autor
Wiadomość
aro_kal
Posty: 436
Rejestracja: 2006-02-07, 14:34
Lokalizacja: Warszawa
brickshelf: aro-kal

 

[MOC] Maszyna do gry w łapki

#1 Post autor: aro_kal »

Co mi przyświecało by zrobić coś takiego? Nie wiadomo. Pewnie chciałem dla siostry zrobić zabawkę. Muszę przyznać, że jej się podoba. Ha, nie tylko jej. Sam jestem zachwycony tym co mi wyszło. Moi koledzy z pracy (dużo ode mnie starsi) przyzwyczajeniu do mojego hobby też się tym bawią, bo w ramach mojej próżności, przyniosłem toto do pracy.

A wygląda to tak:
Obrazek

Krótki opis działania
Jest to zabawka sterowana RCX 2.0 z podłączonymi doń dwoma silnikami, czujnikiem dotyku i czujnikiem światła. Zabawa polega na tym by napędzana dwoma silnikami łapka, trafiła gracza w dłoń. Na początku uruchamiamy program. Łapka wędruje do góry i w tej pozycji zostaje do momentu aż gracz umieści swoją dłoń obok fotokomórki, umieszczonej na prostopadłym wysięgniku. W pomieszczeniach z dość "zdradliwym" oświetleniem stosuje się też drugi wysięgnik z czarną płytką, tak by fotokomórka widziała wciąż ciemne tło, jeśli nie ma obok niej dłoni. Umieszczenie kończyny obok fotokomórki sygnalizowane jest dźwiękiem. Wykorzystałem tu fakt, że ręka jest sporo jaśniejsza niż tło i z bliskiej odległości daje duże odbicie, co jest wykrywane przez czujnik. Od tej pory czekamy od 0 do 5 sekund. Czas ten generowany jest losowo. Bez ostrzeżenie łapka spada. Gdy trafi nas w dłoń, umieszczony na niej czujnik dotyku zostaje zwolniony i wyczuwany jest kontakt z przeszkodą, co sygnalizuje dźwięk. Zabawka zyskuje punkt. Jeśli unikniemy zderzenia, to my ten punkt zdobędziemy, a na tę okazję przygotowałem inny sygnał dźwiękowy. Jeśli w czasie, od umieszczenie dłoni w pobliżu fotokomórki do opuszczenia ramienia, usuniemy rękę z pola widzenia czujnika, zabawka uznaje, że tę rundę wygrała, ponieważ gracz pozwolił sobie na falstart. Opuszcza wtedy powoli ramię po czym podnosi je znów gotowa do kolejnej rundy. Gra się do 5 punktów, a wynik wyświetlany jest na wyświetlaczu w postaci wartość z kropką, np: 3.2, co oznacza 3 do 2. Jak wiemy RCX umie wyświetlać tylko liczby naturalne i to był jedyny sposób na pokazanie punktacji obu rywali. Pierwsza wartość oznacza punkty gracza.

Gra, jak już wcześniej wspomniałem kończy się wraz ze zgromadzeniem, bądź to przez gracza, lub zabawkę, pięciu punktów. Rozgrywkę kończy smutna, w przypadku wygranej "bijki", lub wesoła melodia, jeśli wygra gracz.

Model budowałem jakieś 6 godzin. Dziwne że aż tak długo. Chciałem jednak by był bardzo mocny. Ramię napędzają dwa silniki z przełożeniem 1:1, czyli przez dwa średnie koła zębate co widać tutaj. Może niektórzy uznają, że przełożenie 1:3 byłoby jeszcze szybsze. Nic z tych rzeczy - wtedy mamy bardzo wolny start, a poza tym silniki nie mają siły podnieść ramię.

Łapka ma wbudowany czujnik dotyku, co widać tutaj. Guzik jest wciśnięty przez mały klocek dociskany gumką. Gdy łapka trafi w dłoń guzik jest zwalniany a dotknięcie to jest wyczuwane. Guzik nie pracuje w trybie 0,1. Podczas gwałtownego startu bardzo często wyczuwane byłoby jego zwolnienie, zatem zastosowałem tu tryb pracy "ciągłej", czyli w zakresie od 0 do 1024 (teoretycznie). A tak wygląda całe ramię.

Na wysięgniku jest fotokomórka. Podczas uruchamiania programu bada "siłę" światła w pomieszczeniu i traktuje ją jako wzorcową do tej potyczki. Gdy zbliżymy rękę porówna aktualny odczyt z wzorcowym i jeśli różnica będzie większa niż 35 jednostek wtedy zacznie rundę. Po cofnięciu ręki przez gracza, sprawdza czy przypadkiem odczyt nie jest większy niż wzorcowy i uznaje, że gracz zrobił falstart. Działa to w 95% przypadków. Czasami kanciarzom udaje się nie dostać kary. Podczas jednej gry nie wolno przestawiać zabawki, bo odczyty światła będą inne.

Po co dałem te zwinięte kable u góry? Po to, by ramię na nich hamowało i nie burzyło konstrukcji. Po spadku łapka łapana jest przez gumkę.

I to chyba tyle. Tu są pozostałe zdjęcia:
1, 2, 3, 4.

A TU JEST FILM. Grał mój kolega z pracy. Przegrał 3:5. Proszę wybaczyć to, że obraz jest obrócony. Plik ma ok. 9 mb.

Smacznego.

PS. Może komuś się przyda. Zamieszczam tu kod.

Kod: Zaznacz cały

///// Autor - Arkadiusz Kalecinski /////
////////////////////////////////////////
int czekanie, punkt_komp, punkt_gracz, wynik, naturalny_poziom_swiatla;
#define NOTETIME   10
#define WAITTIME   10
task podnies()     // podnoszenie ramienia
{
     PlaySound(SOUND_LOW_BEEP);
     Wait(150);
     ClearTimer(0);
     while &#40;Timer&#40;0&#41;<10&#41;    // podnosci powoli, tak by nie odbiło na końcu i z powrotem spadło
     &#123;
           OnRev&#40;OUT_A+OUT_C&#41;;
           Wait&#40;2&#41;;
           Off&#40;OUT_A+OUT_C&#41;;
           Wait&#40;1&#41;;
     &#125;
     Off&#40;OUT_A+OUT_C&#41;;
     start opusc;
&#125;

task opusc&#40;&#41;
&#123;
     while &#40;true&#41;
     &#123;
           if &#40;SENSOR_2 <naturalny_poziom_swiatla-35&#41;               // zacznie działać dopiero gdy czujnik swiatła wyczuje rękę &#40;czyli jasniejsze tło&#41;
           &#123;
              czekanie = Random&#40;500&#41;;           // czeka od 0 s do 5 s &#41;
              PlayTone&#40;240, 5&#41;;
              Wait&#40;10&#41;;
              PlayTone&#40;340, 5&#41;;
              start sprawdz;                       // sprawdza czy ręka nie została cofnięta przed czasem
              Wait&#40;czekanie&#41;;
              start dotyk;                         // sprawdza czy nie dotnieto czujnika dotyku podczas opuszcza ramienia
              stop sprawdz;
              OnFwd&#40;OUT_A+OUT_C&#41;;
              Wait&#40;30&#41;;
              stop dotyk;
              Off&#40;OUT_A+OUT_C&#41;;
              punkt_gracz = punkt_gracz+1;

              PlayTone&#40;175,NOTETIME&#41;;              // jeśli gracz cofnał rękę w porę zagra mu melodyjkę
              Wait&#40;WAITTIME&#41;;
              PlayTone&#40;220,NOTETIME&#41;;
              Wait&#40;WAITTIME&#41;;
              PlayTone&#40;262,NOTETIME&#41;;
              Wait&#40;WAITTIME&#41;;

              start punkty;
              stop opusc;
              &#125;
     &#125;
&#125;

task dotyk&#40;&#41;             // sprawdza czy podczas opadania ramienia ramię nie uderzyło w dłoń gracza
&#123;
     while &#40;true&#41;
     &#123;
           if &#40;SENSOR_1>700&#41;
           &#123;
              PlaySound&#40;SOUND_DOUBLE_BEEP&#41;;
              punkt_komp = punkt_komp+1;
              Float&#40;OUT_A+OUT_C&#41;;
              stop opusc;
              start punkty;
              stop dotyk;
           &#125;
     &#125;
&#125;

task sprawdz&#40;&#41; // sprawdza czy reka wciaz jest trzymana przy sensorze
&#123;
     while &#40;true&#41;
     &#123;
           if &#40;SENSOR_2>=naturalny_poziom_swiatla&#41;
           &#123;
              stop opusc;
              stop dotyk;
              punkt_komp = punkt_komp+1;
              PlaySound&#40;SOUND_DOUBLE_BEEP&#41;;
              PlaySound&#40;SOUND_DOUBLE_BEEP&#41;;
              Wait&#40;200&#41;;
              OnFwd&#40;OUT_A+OUT_C&#41;;        // opuszcza powoli ramię
              Wait&#40;5&#41;;
              Off&#40;OUT_A+OUT_C&#41;;
              start punkty;
              stop sprawdz;
           &#125;
     &#125;
&#125;

task punkty&#40;&#41; // sprawdza ile jest zdobytych punktow i przerywa gre jesli ktos zgromadzil 5
&#123;
     if &#40;&#40;punkt_gracz==5&#41; || &#40;punkt_komp==5&#41;&#41;
     &#123;
        wynik = punkt_gracz*10 + punkt_komp;
        Wait&#40;50&#41;;
        if &#40;punkt_gracz==5&#41;           // gracz wygrał
              &#123;
              PlayTone&#40;175,NOTETIME&#41;;
              Wait&#40;WAITTIME&#41;;
              PlayTone&#40;220,NOTETIME&#41;;
              Wait&#40;WAITTIME&#41;;
              PlayTone&#40;262,NOTETIME&#41;;
              Wait&#40;WAITTIME&#41;;
              PlayTone&#40;330,NOTETIME&#41;;
              Wait&#40;WAITTIME&#41;;
              PlayTone&#40;392,NOTETIME&#41;;
              Wait&#40;WAITTIME&#41;;
              PlayTone&#40;494,NOTETIME&#41;;
              Wait&#40;WAITTIME&#41;;
              PlayTone&#40;587,NOTETIME&#41;;
              Wait&#40;WAITTIME&#41;;
              PlayTone&#40;523,NOTETIME&#41;;
              Wait&#40;WAITTIME&#41;;
              PlayTone&#40;659,NOTETIME&#41;;
              Wait&#40;WAITTIME&#41;;
              PlayTone&#40;659,NOTETIME&#41;;
              Wait&#40;WAITTIME&#41;;
             &#125;
             else                           // komputer wygrał
             &#123;
              PlayTone&#40;123,4*NOTETIME&#41;;
              Wait&#40;4*WAITTIME&#41;;
              PlayTone&#40;49,4*NOTETIME&#41;;
              Wait&#40;4*WAITTIME&#41;;
              PlayTone&#40;65,4*NOTETIME&#41;;
              Wait&#40;4*WAITTIME&#41;;
              &#125;
           StopAllTasks&#40;&#41;;
           &#125;
           else
           &#123;
              wynik = punkt_gracz*10 + punkt_komp;
              Wait&#40;200&#41;;
              start podnies;
              stop punkty;
           &#125;

&#125;

task wyswietl_punkty&#40;&#41;   // co 1/10 s wyswietla na wyswietlaczu aktualny wynik &#40;liczba dwucyfrowa z przecinkiem&#41;
&#123;
    while &#40;true&#41;
    &#123;
         SetUserDisplay&#40;wynik,1&#41;;
         Wait&#40;10&#41;;
    &#125;
&#125;

task main&#40;&#41;
&#123;
    punkt_komp = 0;
    punkt_gracz = 0;
    wynik=0;
    naturalny_poziom_swiatla = SENSOR_2;
    start wyswietl_punkty;
    SetSensorType&#40;SENSOR_1, SENSOR_TYPE_TOUCH&#41;;
    SetSensorMode&#40;SENSOR_1, SENSOR_MODE_RAW&#41;;
    SetSensorType&#40;SENSOR_2, SENSOR_TYPE_LIGHT&#41;;
    SetSensorMode&#40;SENSOR_2, SENSOR_MODE_RAW&#41;;
    start podnies;
&#125;
Ostatnio zmieniony 2007-12-30, 01:18 przez aro_kal, łącznie zmieniany 5 razy.

pawelec
Posty: 107
Rejestracja: 2006-12-28, 10:21
Lokalizacja: Gdynia

#2 Post autor: pawelec »

Dla mnie extra !!
Nie spodziewałem się takiej szybkości.

Gdyby dociążyć trochę zakończenie ramienia, szybkość była by jeszcze większa, tylko może wtedy przegrana byłaby zbyt bolesna ;)
Zresztą patrząc na ten film już teraz sprawia to wrażenie trochę sadystyczne ;]

Powiedz mi jeszcze jaki cel mają te gumki umieszczone na ramieniu?

Pozdrawiam
Paweł
Ostatnio zmieniony 2007-02-05, 21:32 przez pawelec, łącznie zmieniany 1 raz.

aro_kal
Posty: 436
Rejestracja: 2006-02-07, 14:34
Lokalizacja: Warszawa
brickshelf: aro-kal

 

#3 Post autor: aro_kal »

Gumka na środku ramienia naciąga mechanizm spustowy. Tak jak pisałem czujnik dotyku jest ciągle wciśnięty, dopiero uderzenie w dłoń go zwalnia. Działa to na zasadzie takiej zwykłej belki podpartej pośrodku, z tym, że jeden koniec jest ciągnięty na siłę. Gdy drugi koniec uderzy w dłoń to odciąga ten pierwszy ciągnięty gumką. Zwalnia to przycisk.

Druga gumka jedynie trzyma kabel.

Obciążenie końca mogłoby sprawić (i sprawiało), że silniki nie podciągnęły ramienia do góry. Poza tym prawdopodobnie starty ramienia podczas opadania byłby wolny.

PS. A uderzenie nic a nic nie boli. Gumka doskonale amortyzuje cios. Poza tym z reguły dostaje się w opuszki palców.
Ostatnio zmieniony 2007-02-05, 22:06 przez aro_kal, łącznie zmieniany 1 raz.

Awatar użytkownika
Bricksley
VIP
Posty: 2573
Rejestracja: 2005-03-29, 23:00
Lokalizacja: Stalowa Wola
brickshelf: KAROL4

 

#4 Post autor: Bricksley »

Może z wyglądu nie jest piekna, ale funkcjonuje na piątkę. Bobra robota!

PS. Sam bym sobie z nią pograł :)
Pozdrawiam :)

sives1
Posty: 153
Rejestracja: 2005-10-16, 19:12
Lokalizacja: Warszawa
brickshelf: sives1
Kontakt:

 

#5 Post autor: sives1 »

Bardzo ciekawy pomysł i wykonanie bardzo dobre! Bravo!

Awatar użytkownika
Darek Mróz
VIP
Posty: 213
Rejestracja: 2004-06-02, 14:12
Lokalizacja: Rzeszów
brickshelf: sasik

 

#6 Post autor: Darek Mróz »

Imponujące.
Można się trochę przestraszyć tej łapki, ale przegrana musi boleć :).
Dzięki za wyczerpujący opis i kod, który na pewno się przyda.
LEg GOdt Darek Mróz

Awatar użytkownika
Bricksley
VIP
Posty: 2573
Rejestracja: 2005-03-29, 23:00
Lokalizacja: Stalowa Wola
brickshelf: KAROL4

 

#7 Post autor: Bricksley »

Darek Mróz pisze:ale przegrana musi boleć
aro_kal moze bys spróbował wyliczyć siłę z jaką łakpka uderza w przeszkodę?
Pozdrawiam :)

sives1
Posty: 153
Rejestracja: 2005-10-16, 19:12
Lokalizacja: Warszawa
brickshelf: sives1
Kontakt:

 

#8 Post autor: sives1 »

W sumie też jestem ciekaw! Napisz może w skali od 1 do 10 poziom bólu :D żartuje

aro_kal
Posty: 436
Rejestracja: 2006-02-07, 14:34
Lokalizacja: Warszawa
brickshelf: aro-kal

 

#9 Post autor: aro_kal »

Tak jak napisałem wcześniej - bólu praktycznie nie ma. Gdy testowały to kobiety, coś tam jednak czuły, ale znacie ich odporność na ból. Sam czasem jak z czułością złapię za rękę to słyszę, że mam imadło a nie dłoń. :mruga: . Mnie mogłaby ta łapka trafić 100 razy pod rząd i nie czułbym bólu. Siłę ciosu od 0 do 10 oceniam na 2.
Ostatnio zmieniony 2007-02-07, 17:25 przez aro_kal, łącznie zmieniany 1 raz.

Awatar użytkownika
szarikm
Adminus Emeritus
Posty: 1312
Rejestracja: 2005-11-03, 16:43
Lokalizacja: Rzeszów
brickshelf: szarikm

 

#10 Post autor: szarikm »

ale nie łaskocze w rękę...... :(

Oryginalny pomysł :ok:

ODPOWIEDZ