Forum LUGPOL Strona Główna Forum LUGPOL
www.lugpol.pl

FAQFAQ  SzukajSzukaj  UżytkownicyUżytkownicy  GrupyGrupy
RejestracjaRejestracja  ZalogujZaloguj

Poprzedni temat «» Następny temat
[MOC] Automatyczna 4-biegowa skrzynia biegów NXT
Autor Wiadomość
Sariel 
VIP
p.o. majstra


Wiek: 36
Dołączył: 28 Mar 2007
Wpisy: 5090
Skąd: Warszawa
Wysłany: 2012-02-25, 15:42   [MOC] Automatyczna 4-biegowa skrzynia biegów NXT



Język: ROBOTC
Kostka: 1
Silniki: 3 x NXT
Sensory: żadnych

Moja pierwsza nieśmiała wyprawa w świat NXT. Szukałem okazji żeby poćwiczyć trochę ROBOTC, które jest dla mnie kompletną nowością, i przyszedł mi do głowy pomysł na skrzynię biegów która zmienia przełożenie sama, w oparciu o zmiany prędkości silnika który ją napędza. Prosty układ: kostka, 3 silniki, żadnych sensorów, więc nie mogłem tego za bardzo spaprać :)

Jako podstawa konstrukcji użyta jest ta skrzynia: http://sariel.pl/2008/12/...ompact-gearbox/
Dodałem do niej dwa silniki NXT które zmieniają biegi, oraz trzeci który ją napędza.

Program kontrolujący skrzynię - mój pierwszy w ROBOTC, proszę się nie śmiać - składa się z prostego wątku głównego z dwoma podwątkami, z których jeden monitoruje napięcie w baterii kostki (bo zainteresowało mnie jak potrafi ono skakać w zależności od obciążenia silników), a drugi przejmuje obsługę przycisków na kostce. Wątek główny kontroluje wszystkie silniki. Po uruchomieniu silnika napędowego, jego prędkość jest mierzona w stopniach obrotu na 0.1 sekundy. Pomiar jest banalnie prosty i odbywa się poprzez pętlę która co 0.1 sekund odczytuje licznik obrotu w silniku i go resetuje. Zależnie od stanu baterii i biegu wybranego w skrzyni, silnik wyciąga w przedziale 70-80 stopni na 0.1 sekundy. Kiedy prędkość silnika przekroczy górną lub dolną wartość skrajną, następuje zmiana biegu odpowiednio na wyższy lub niższy. Po zmianie program odczekuje chwilę żeby silnik zdążył "zaskoczyć" z nowym przełożeniem, a potem wraca do monitorowania. Trzy zmienne: obie wartości skrajne prędkości oraz okres oczekiwania po zmianie biegu - są deklarowane zaraz na początku programu, dla jego wygodnej konfiguracji.

Sama skrzynia jest zsynchronizowana i nieliniowa, da się ją więc przełączyć w dowolny sposób. Żeby nie przesadzić z ilością możliwych kombinacji, program ma przełączać tylko między najbliższymi biegami - więc z trójki może przejść na dwójkę albo czwórkę, ale nie na jedynkę. Wyjątkiem jest sytuacja kiedy program się wyłącza. Po naciśnięciu ciemnoszarego przycisku na kostce następuje zamknięcie programu, ale najpierw skrzynia jest przestawiana na jedynkę. Żeby to było możliwe, program musi cały czas śledzić aktualnie wybrany bieg - odpowiada za to zmienna gear, aktualizowana przy każdej zmianie biegu. W filmie widać jak skrzynia schodzi na jedynkę z czwórki, trójki i dwójki.

Jak wspomniałem, jest to mój pierwszy kontakt z ROBOTC i jestem zielony w temacie, program pewnie dałoby się napisać inaczej i krócej. Co mnie zdziwiło, to że kontrolowanie silników zmieniających biegi okazało się dokładniejsze przy użyciu funkcji czasowej niż przy obracaniu o zadany kąt. Silniki łatwo się "rozjeżdżały" i blokowały skrzynię kiedy ich pozycja była zmieniana w oparciu o kąt, natomiast przy dokładnym ustawieniu czasu w jakim mają pracować udało się uzyskać znacznie większą precyzję ruchów. To ważne, bo silniki NXT mają ogromny moment i potrafią wcisnąć driving ringa w zębatkę tak mocno że tarcie prawie zatrzymuje skrzynię.

Program - w czytelniejszej wersji, z tabulacją i kolorowanie składni do obejrzenia tutaj: http://sariel.pl/2012/02/nxt-automated-gearbox/

Kod:
// config start
int mspeed_high = 78;
int mspeed_low = 75;
int shift_time = 3000;
// config end
 
int gear = 1;
 
task Buttons()
{
  while(true)
  {
    nNxtButtonTask  = -2;
    nNxtExitClicks = 2;
 
    if(nNxtButtonPressed == 0)
    {
      eraseDisplay();
      motor[motorA] = 0;
 
            switch(gear)
            {
              case 1:
                break;
 
              case 2:
                motor[motorB] = -100;
                wait1Msec(120);
                motor[motorC] = 0;
                break;
 
              case 3:
                motor[motorC] = 100;
                wait1Msec(60);
                motor[motorC] = 0;
                wait1Msec(500);
                motor[motorB] = -100;
                wait1Msec(70);
                motor[motorB] = 0;
                break;
 
              case 4:
                motor[motorC] = -100;
                wait1Msec(60);
                motor[motorC] = 0;
                wait1Msec(500);
                motor[motorB] = -100;
                wait1Msec(70);
                motor[motorB] = 0;
                break;
            }
 
      StopAllTasks();
    }
  }
  return;
}
 
task BatLev()
{
  while(true)
  {
    nxtDisplayCenteredTextLine(0, "Brick up @ %3.1fV", nImmediateBatteryLevel / (float) 1000);
    wait1Msec(50);
  }
  return;
}
 
task main ()
{
  StartTask(Buttons);
  StartTask(BatLev);
 
  motor[motorA] = 0;
  bool mstatus = false;
  nMotorEncoder[motorB] = 0;
  nMotorEncoder[motorC] = 0;
  nxtDisplayCenteredTextLine(2, "MOTOR A OFF");
  nxtDisplayCenteredTextLine(4, "GEAR 1");
  wait1Msec(50);
 
  while(true)
  {
    if(nNxtButtonPressed == 3)
    {
      if (mstatus == true)
      {
        PlaySound(soundBlip);
        motor[motorA] = 0;
        mstatus = false;
        nxtDisplayCenteredTextLine(2, "MOTOR A OFF");
        nxtDisplayClearTextLine(5);
        nxtDisplayClearTextLine(7);
        wait1Msec(500);
      }
      else
      {
        motor[motorA] = 100;
        mstatus = true;
        nxtDisplayCenteredTextLine(2, "MOTOR A ON");
        wait1Msec(500);
        int mspeed = nMotorEncoder[motorA];
 
        while(nNxtButtonPressed != 3)
        {
          nMotorEncoder[motorA] = 0;
          wait1Msec(100);
          mspeed = nMotorEncoder[motorA];
          nxtDisplayCenteredTextLine(5, "Speed: %d", mspeed);
 
          if (mspeed > mspeed_high) // gearing up
          {
            nxtDisplayCenteredTextLine(7, "Gearing up...");
            switch(gear)
            {
              case 1:
                motor[motorB] = 100;
                wait1Msec(110);
                motor[motorB] = 0;
                gear = 2;
                nxtDisplayCenteredTextLine(4, "GEAR 2");
                wait1Msec(shift_time);
                break;
 
              case 2:
                gear = 3;
                motor[motorB] = -100;
                wait1Msec(60);
                motor[motorB] = 0;
                wait1Msec(300);
                motor[motorC] = -100;
                wait1Msec(60);
                motor[motorC] = 0;
                nxtDisplayCenteredTextLine(4, "GEAR 3");
                wait1Msec(shift_time);
                break;
 
              case 3:
                motor[motorC] = 100;
                wait1Msec(110);
                motor[motorC] = 0;
                gear = 4;
                nxtDisplayCenteredTextLine(4, "GEAR 4");
                wait1Msec(shift_time);
                break;
 
              case 4:
                nxtDisplayClearTextLine(7);
                break;
            }
          }
          else if (mspeed < mspeed_low) // gearing down
          {
            nxtDisplayCenteredTextLine(7, "Gearing down...");
            switch(gear)
            {
              case 4:
                motor[motorC] = -100;
                wait1Msec(110);
                motor[motorC] = 0;
                gear = 3;
                nxtDisplayCenteredTextLine(4, "GEAR 3");
                wait1Msec(shift_time);
                break;
 
              case 3:
                motor[motorC] = 100;
                wait1Msec(60);
                motor[motorC] = 0;
                wait1Msec(300);
                motor[motorB] = 100;
                wait1Msec(60);
                motor[motorB] = 0;
                gear = 2;
                nxtDisplayCenteredTextLine(4, "GEAR 2");
                wait1Msec(shift_time);
                break;
 
              case 2:
                motor[motorB] = -100;
                wait1Msec(110);
                motor[motorB] = 0;
                gear = 1;
                nxtDisplayCenteredTextLine(4, "GEAR 1");
                wait1Msec(shift_time);
                break;
 
              case 1:
                nxtDisplayClearTextLine(7);
                break;
            }
          }
        }
      }
    }
  }
}


Foty:


Film:
_________________
Kalkulator przełożeń | Generator miniaturek z BSa/Majhosta
Ostatnio zmieniony przez Sariel 2012-02-25, 16:29, w całości zmieniany 1 raz  
 
 
 
Mrosik 
VIP


Wiek: 34
Dołączył: 05 Maj 2009
Wpisy: 276
Skąd: Poznań
Wysłany: 2012-02-25, 16:19   

A jakby działała w praktyce? Możesz ją zamontować na jakimś prymitywnym podwoziu i pokazać jej działanie/skuteczność?
 
 
 
Jetboy
[Usunięty]

Wysłany: 2012-02-25, 16:27   

Fajne!
Jedno co można poprawić to wcięcia w kodzie, byłby dzięki emu znacznie bardziej czytelny.
Ostatnio zmieniony przez Jetboy 2012-02-25, 16:37, w całości zmieniany 1 raz  
 
 
 
Sariel 
VIP
p.o. majstra


Wiek: 36
Dołączył: 28 Mar 2007
Wpisy: 5090
Skąd: Warszawa
Wysłany: 2012-02-25, 16:30   

Jetboy, zapomniałem użyć code zamiast quote, dzięki :P
Mrosik, w praktyce działałaby tak samo jak na filmie - widzisz co się dzieje jak generuję opór na wyjściu ręką. Tylko na filmowanie na podwoziu byłoby trudniejsze.
_________________
Kalkulator przełożeń | Generator miniaturek z BSa/Majhosta
 
 
 
TT 
VIP


Wiek: 30
Dołączył: 27 Maj 2004
Wpisy: 1181
Skąd: Kraków i Bytom
Wysłany: 2012-02-25, 17:33   

Paweł gratuluje debiutu w NXT ! :-)
Skrzynia działa bardzo dobrze. Trudno sobie wyobrazić tak sprawną skrzynię automatyczną LEGO bez udziału Mindstorms.

Jeśli chodzi o precyzję silników przy wykorzystaniu ich enkoderów do pozycjonowania to polecam Ci zainteresować się funkcją: nMotorEncoderTarget[]

U początku mojej kariery zmontowałem skrzynię automatyczną - zasada działania taka sama jak u Sariela. Dla zainteresowanych odsyłam do archaicznego filmu: http://www.youtube.com/wa...23&feature=plcp (początek to pokaz działa trybu sekwencyjnego, potem załączam automat).
_________________
Pozdrawiam,
Tomek
Ostatnio zmieniony przez TT 2012-02-25, 17:34, w całości zmieniany 1 raz  
 
 
 
 
Emilus 
Adminus Emeritus


Wiek: 39
Dołączył: 26 Sie 2007
Wpisy: 1460
Skąd: Polska
Wysłany: 2012-02-25, 17:36   

Fajnie Paweł, super że startujesz w mindstorms.

Skrzynia działa, super. Szkoda tylko, że aby mogła pracować w trybie automatycznym, do napędu konieczny jest motor NXT. Ale rozumiem, nie używałeś czujników dlatego tak jest.
_________________
legotrucktrial.boo.pl | Regulamin LTTC 2012 | Terminarz LTTC i CC 2012
 
 
 
Atros 
VIP
Kuba


Wiek: 32
Dołączył: 08 Kwi 2009
Wpisy: 727
Skąd: Warszawa
Wysłany: 2012-02-25, 18:30   Re: Automatyczna 4-biegowa skrzynia biegów NXT

Witamy w świecie NXT :)

Skrzynia i idea działania bardzo prosta, też kiedyś testowałem coś takiego. Na stołku działa to fajnie ale po włożeniu do samochodu trudno jest dopasować momenty w którym biegi powinny być zmieniane.

Sariel napisał/a:
Co mnie zdziwiło, to że kontrolowanie silników zmieniających biegi okazało się dokładniejsze przy użyciu funkcji czasowej niż przy obracaniu o zadany kąt. Silniki łatwo się "rozjeżdżały" i blokowały skrzynię kiedy ich pozycja była zmieniana w oparciu o kąt, natomiast przy dokładnym ustawieniu czasu w jakim mają pracować udało się uzyskać znacznie większą precyzję ruchów.


Takie działanie jest dziwne i niepokojące, obracanie silnika o kąt powinno być idealnie dokładne, czasowe ustawianie nigdy nie będzie tak dokładne ponieważ występują wahania napięcia i zmiany tarcia co ma wpływ na wynikową wartość obrotu.
W leJOSie działa to tak jak należy, w robotc też zapewne działa to poprawnie tylko coś skopałeś ;)
 
 
 
Emilus 
Adminus Emeritus


Wiek: 39
Dołączył: 26 Sie 2007
Wpisy: 1460
Skąd: Polska
Wysłany: 2012-02-25, 19:03   

Cytat:
Takie działanie jest dziwne i niepokojące, obracanie silnika o kąt powinno być idealnie dokładne, czasowe ustawianie nigdy nie będzie tak dokładne ponieważ występują wahania napięcia i zmiany tarcia co ma wpływ na wynikową wartość obrotu.
W leJOSie działa to tak jak należy, w robotc też zapewne działa to poprawnie tylko coś skopałeś ;)


Nigdy nie będzie idealnie dokładne, gdyż encoder w silniku NXT nie znajduje się przy wyjściu na ośkę a ileś zębatek wcześniej i niestety ustawianie silnika na kąt ma sporą bezwładność.
Ratunek to albo formuła "motortarget" ale ona hamuje na końcu silnik w określonej pozycji (więc zużywa cały czas prąd) albo finezja programisty :) Ja to robię na przedziałach z wykorzystaniem encodera w silniku i z płynnym zmniejszaniem prędkości silnika przy dochodzeniu do punktu "stop", aby zminimalizować bezwładność.
_________________
legotrucktrial.boo.pl | Regulamin LTTC 2012 | Terminarz LTTC i CC 2012
 
 
 
ontek 
VIP


Wiek: 34
Dołączył: 30 Maj 2011
Wpisy: 178
Skąd: Rzeszów
Wysłany: 2012-02-25, 20:31   

Ostatnio w moich badaniach zajmowałem się sensoryką Lego. Jeżeli chodzi o te serwomechanizmy to jest to koszmar, przede wszystkim z bezwładnością oraz precyzją. Miałem też do czynienia z żyroskopem i akcelerometrem produkcji Hitechnic i też wygląda to tragicznie. Żeby skalibrować sensory aby poprawnie działały, to należy poświęcić kilka dni z życia. Sensory dają różne wskazania w zależności od temperatury, poziomu baterii, ciśnienia atmosferycznego, a nawet wilgotności powietrza, nie wspominając o czasie próbkowania.
Ostatnio zmieniony przez ontek 2012-02-26, 10:44, w całości zmieniany 2 razy  
 
 
 
 
Atros 
VIP
Kuba


Wiek: 32
Dołączył: 08 Kwi 2009
Wpisy: 727
Skąd: Warszawa
Wysłany: 2012-02-25, 20:51   

Emilus napisał/a:
Nigdy nie będzie idealnie dokładne, gdyż encoder w silniku NXT nie znajduje się przy wyjściu na ośkę a ileś zębatek wcześniej i niestety ustawianie silnika na kąt ma sporą bezwładność.


A to tego to wiadomo, że nie przeskoczymy.

Emilus napisał/a:
Ratunek to albo formuła "motortarget" ale ona hamuje na końcu silnik w określonej pozycji (więc zużywa cały czas prąd) albo finezja programisty :) Ja to robię na przedziałach z wykorzystaniem encodera w silniku i z płynnym zmniejszaniem prędkości silnika przy dochodzeniu do punktu "stop", aby zminimalizować bezwładność.


W takim razie jest możliwość, że lejos lepiej radzi sobie ze sterowaniem serwami.
Tu jest np. metoda rotateTo która przy max prędkości silnika gdy zadam rotację do kąta 320 stopni obraca silnik z regulacją czyli silnik obróci się do max 322-323 stopni i potem wyreguluje do dokładnie 320, regulacja ta trwa dosłownie milisekundy.

Napiszę jeszcze o zmianie biegów an driving ringach bo trochę nad tym posiedziałem w Volvo. Żeby driving ringi nie blokwały się napisałem specjalną metodę zmieniającą biegi i wykrywającą, czy driving ring nie trafił akurat na tą wypustkę w tej z16. W nowej wersji lejosa metoda sprawdzająca zablokowanie silnika jest już w standardowej bibliotece.
 
 
 
Sariel 
VIP
p.o. majstra


Wiek: 36
Dołączył: 28 Mar 2007
Wpisy: 5090
Skąd: Warszawa
Wysłany: 2012-02-25, 20:59   

Ja myślałem o metodzie zatrzymującej silnik w momencie kiedy licznik obrotów w nim się zatrzyma. Czyli jak silnik trafi na opór, to go wyłączamy. Co do wyczucia kiedy skrzynię przełączyć, przeszło mi przez myśl że możnaby napisać algorytm który odpala silnik na jedynce, daje mu chwilę pochodzić, a potem wylicza sobie średnią prędkość i procentowe progi odchyleń od niej, co przyjmuje za podstawę zmiany biegów. Ale nie chciałem przekombinować, w końcu to mój debiut i jak się jest takim leszczem to trzeba po kroczku :)
Chciałbym jeszcze podziękować TT i Emilowi za wciągnięcie w świat NXT. Mój portfel Was nienawidzi, ale tak w ogóle to dzięki chłopaki ;)
_________________
Kalkulator przełożeń | Generator miniaturek z BSa/Majhosta
 
 
 
Neo 


Wiek: 49
Dołączył: 29 Kwi 2011
Wpisy: 274
Skąd: Kraków/Rzeszów/Starachowice
Wysłany: 2012-02-25, 21:17   

Bardzo sympatyczna koncepcja. Ale nie kryguj się tak kolego - program nie jest skomplikowany, ale napewno wykracza poza słowo "prosty". Musiałeś mieć wcześniej kontakt przynajmniej z C :)
_________________
www.imperiumtechniki.pl
 
 
 
Emilus 
Adminus Emeritus


Wiek: 39
Dołączył: 26 Sie 2007
Wpisy: 1460
Skąd: Polska
Wysłany: 2012-02-25, 21:19   

ontek napisał/a:
Ostatnio w moich badaniach zajmowałem się sensoryką Lego i jeżeli chodzi o te serwomechanizmy to jest koszmar w ogóle z bezwładnością oraz precyzją.


Bez przesady. Można sobie spokojnie poradzić. Kwestia sprawności mechanika/programisty.

Co do podziękowań, to nie ma za co Paweł. Ale jestem pewien, że sam prędzej czy później byś w to się wciągnął. Ale wiadomo, lepiej prędzej :)
_________________
legotrucktrial.boo.pl | Regulamin LTTC 2012 | Terminarz LTTC i CC 2012
Ostatnio zmieniony przez Emilus 2012-02-25, 21:20, w całości zmieniany 1 raz  
 
 
 
Sariel 
VIP
p.o. majstra


Wiek: 36
Dołączył: 28 Mar 2007
Wpisy: 5090
Skąd: Warszawa
Wysłany: 2012-02-25, 21:24   

Neo napisał/a:
Musiałeś mieć wcześniej kontakt przynajmniej z C :)


Z PHP i z jQuery. Stąd pewne moje niezdecydowanie jaki język wybrać - jedno podobne do ROBOTC, drugie do leJOSa. Mam nadzieję, że leJOSem też będę miał szansę się pobawić.
_________________
Kalkulator przełożeń | Generator miniaturek z BSa/Majhosta
 
 
 
TT 
VIP


Wiek: 30
Dołączył: 27 Maj 2004
Wpisy: 1181
Skąd: Kraków i Bytom
Wysłany: 2012-02-25, 22:08   

ontek napisał/a:
Ostatnio w moich badaniach zajmowałem się sensoryką Lego i jeżeli chodzi o te serwomechanizmy to jest koszmar w ogóle z bezwładnością oraz precyzją. Miałem tez do czynienia z żyroskopem i akcelerometrem produkcji hitechnic i też tragedia, żeby to skalibrować żeby poprawnie działało to dosłownie pare dni z życia wyjętych bo są inne wskazania w zależności od temperatury, poziomu baterii, ciśnienia a nawet wilgotności powietrza, nie wspominając o czasie próbkowania.

Fakt, LEGO nie nada się do chirurgi precyzyjnej. W połączeniu z klockami, których sama mechanika powoduje "spore" luzy to i tak to wszystko nawet ładnie działa.

Atr napisał/a:
W takim razie jest możliwość, że lejos lepiej radzi sobie ze sterowaniem serwami.
Tu jest np. metoda rotateTo która przy max prędkości silnika gdy zadam rotację do kąta 320 stopni obraca silnik z regulacją czyli silnik obróci się do max 322-323 stopni i potem wyreguluje do dokładnie 320, regulacja ta trwa dosłownie milisekundy.

W RobotC jest prosta funkcja nMotorEncoderTarget[], która ma zaimplementowany regulator PID. Proporcje nastawów P,I,D można nawet podglądać w debugerze. Działa bardzo precyzyjnie, nie ma dużych przeregulowań i jest dobra dynamika. Jako, że RobotC to najszybsza platforma pod NXT to wierzę, że ta regulacja jest jedną z najlepszych osiąganych na NXT. Oczywiście można sobie samemu zaprogramować regulator i dobrać nastawy pod konkretny projekt. Wszystko się da w końcu to NXT!

Sariel napisał/a:
Chciałbym jeszcze podziękować TT i Emilowi za wciągnięcie w świat NXT. Mój portfel Was nienawidzi, ale tak w ogóle to dzięki chłopaki ;)

Paweł ja już widzę, że NXT zdominuje Twoje moce w roku kalendarzowym 2012 :-)
Mam nadzieje, że Twój portfel posiada duże zdolności regeneracyjne - pamiętaj, że przed zakupem ostrzegałem, że na jednym zestawie na pewno się nie skończy ;-)
_________________
Pozdrawiam,
Tomek
Ostatnio zmieniony przez TT 2012-02-25, 22:11, w całości zmieniany 1 raz  
 
 
 
 
Wyświetl wpisy z ostatnich:   
Odpowiedz do tematu
Nie możesz pisać nowych tematów
Nie możesz odpowiadać w tematach
Nie możesz zmieniać swoich wpisów
Nie możesz usuwać swoich wpisów
Nie możesz głosować w ankietach
Nie możesz załączać plików na tym forum
Możesz ściągać załączniki na tym forum
Dodaj temat do Ulubionych
Wersja do druku

Skocz do:  

phpBB by przemo  
Strona wygenerowana w 0,117 sekundy. Zapytań do SQL: 9