[IDEA] Wirtualny Subtraktor

Mindstorms, WeDo, Lego Digital Desinger, Stud.io

Moderatorzy: Mod Team, Mod Team

Autor
Wiadomość
Awatar użytkownika
Sariel
VIP
Posty: 5418
Rejestracja: 2007-03-28, 08:16
Lokalizacja: Warszawa
brickshelf: Sariel
Kontakt:

 

[IDEA] Wirtualny Subtraktor

#1 Post autor: Sariel »

Obrazek

Nie wiem czy to się kwalifikuje jako pełnoprawny MOC, bo chodzi o ledwie parę linijek kodu, ale będę tego intensywnie używał więc może jeszcze komuś się przyda. Męczyło mnie zagadnienie jak prosto sterować dwoma silnikami napędowymi w układzie lewy/prawy kiedy na subtraktor nie ma miejsca albo obciążenie jest za duże żeby wytrzymał. Napisałem więc prosty programik, który pozwala sterować nimi jedną gałką standardowego pada, z kontrolą prędkości, tak jakby były połączone subtraktorem. Co ważne, kontrola prędkości działa we wszystkich kombinacjach - również przód/lewa, tył/prawa itd.

Kod:

Kod: Zaznacz cały

#include "JoystickDriver.c"

task main()
{
  bMotorReflected[motorA] = false;
  bMotorReflected[motorB] = false;
  while(true)
  {
    getJoystickSettings(joystick);
    motor[motorA] = 0;
    motor[motorB] = 0;
    if (joystick.joy1_y1 != -6)
    {
      motor[motorA] = joystick.joy1_y1 / 1.28;
      motor[motorB] = joystick.joy1_y1 / 1.28;

      if (joystick.joy1_x1 != -5)
      {
        motor[motorA] = (joystick.joy1_y1 + joystick.joy1_x1) / 2.56;
        motor[motorB] = (joystick.joy1_y1 - joystick.joy1_x1) / 2.56;
      }
    }
    else if (joystick.joy1_x1 != -5)
    {
      motor[motorA] = joystick.joy1_x1 / 1.28;
      motor[motorB] = joystick.joy1_x1 / -1.28;
    }

    nxtDisplayCenteredTextLine(0, "BATTERY: %3.1fV", nImmediateBatteryLevel / (float) 1000);
    nxtDisplayTextLine(2, "Y1: %d", joystick.joy1_y1);
    nxtDisplayTextLine(3, "X1: %d", joystick.joy1_x1);
  }
}
I film pokazujący to w akcji:

[youtube]http://www.youtube.com/watch?v=CAq6RBeseac[/youtube]
Ostatnio zmieniony 2012-10-29, 11:26 przez Sariel, łącznie zmieniany 2 razy.

Awatar użytkownika
piotrek839
Posty: 459
Rejestracja: 2011-10-05, 18:37
Lokalizacja: Jastrzębie-Zdrój
brickshelf: piotrek839

 

#2 Post autor: piotrek839 »

Kompletnie się na tym nie znam więc śledzę uważnie Twoje prace z NXT. Mam jeden zestaw NXT 1,0 i zupełnie nie mam inspiracji by coś z nim zrobić. Dlatego iż uważam Cię za jednego z ekspertów mam takie pytanie.

W jaki prosty sposób połączyć silnik NXT z padem od konsoli PS3? (Zakładając że jestem laikiem)?
Dodam że kod który podajesz jest dla mnie nie zrozumiały. Wersja obrazkowa byłaby dla mnie czytelniejsza. Z góry dziękuję.

Awatar użytkownika
Sariel
VIP
Posty: 5418
Rejestracja: 2007-03-28, 08:16
Lokalizacja: Warszawa
brickshelf: Sariel
Kontakt:

 

#3 Post autor: Sariel »

piotrek839 pisze:W jaki prosty sposób połączyć silnik NXT z padem od konsoli PS3?
Dwa tematy wcześniej: http://www.00453005_0000002.pl/forum/viewtopic.php?t=17358
piotrek839 pisze:Dodam że kod który podajesz jest dla mnie nie zrozumiały. Wersja obrazkowa byłaby dla mnie czytelniejsza. Z góry dziękuję.
Kod w wersji obrazkowej? Raczej nieprędko :)
A speców od NXT na forum jest kilku, ale mnie do nich nie wliczaj.

staak
Posty: 53
Rejestracja: 2008-10-07, 19:05
Lokalizacja: Warszawa
brickshelf: staak

 

#4 Post autor: staak »

Jako, że dawno nic nie pisałem w RobotC to się odniosę....
Do momentu getJoystickSettings(joystick); wszystko jes OK :)
Potem bezwarunkowo (niezależnie od wychylenia joysticka) oba silniki są zatrzymywane - w jakim celu?
Dla "higieny pisania" (dotyczy tego programu) w pętli while podstawienia motor[motorA]= wartość; powinny być używane tylko raz.
Najpierw wyliczasz "moc silnika" a potem na końcu pętli przepisujesz "moc silnika" na motor[motorA].
Bo jeżeli każdorazowo po wywołaniu funkcji motor[motorA] = wartość; jest to ustawiane na wyjściu (a tak jest) to w Twoim przypadku silnik niepotrzebnie szarpie (i nie musi być tego widać).
Ponieważ jest to krótki programik określenie położenia "0x" i "0y" joysticka jako =! w if-ach nie sprawia trudności.
Zawsze jednak lepiej zdefiniować te "zera" jako dwie niezależne zmienne (kwestia typu danych int, short int czy jeszcze coś innego) . Przy zmianie np typu pada (który ma 0x=+2 i 0y=-3 zmieniasz tylko wartości tych zmiennych w jednym miejscu a nie szukasz po całym programie.
Poza tym osoba postronna nie musi kombinować co to za -5 i -6.
Należało również wyjaśnić skąd te "magiczne " 1.28
-100 <= motor[motorABC] <=100
-128 <= joystick.joy1_X1Y1 <=127

Moja propozycja (oczywiście gwarancji nie daję)

Kod: Zaznacz cały

#include "JoystickDriver.c" 

task main&#40;&#41; 
&#123; 
  bMotorReflected&#91;motorA&#93; = false; 
  bMotorReflected&#91;motorB&#93; = false; 

  int joy1_x1_0pos = -5; //wskazanie manetki lewej, oś x &#40;lewo prawo&#41;w pozycji 0
  int joy1_y1_0pos = -6; //wskazanie manetki lewej, os y &#40;góra dół&#41; w pozycji 0

    
  while&#40;true&#41; 
  &#123; 
    getJoystickSettings&#40;joystick&#41;; 
    motor&#91;motorA&#93; = &#40;joystick.joy1_y1 - joy1_y1_0pos &#41;/1.28 + &#40;joystick.joy1_x1 - joy1_x1_0pos&#41; /1.28; 
    motor&#91;motorB&#93; = &#40;joystick.joy1_y1 - joy1_y1_0pos &#41;/1.28 - &#40;joystick.joy1_x1 - joy1_x1_0pos&#41; /1.28;
  
    nxtDisplayCenteredTextLine&#40;0, "BATTERY&#58; %3.1fV", nImmediateBatteryLevel / &#40;float&#41; 1000&#41;; 
    nxtDisplayTextLine&#40;2, "Y1&#58; %d", joystick.joy1_y1&#41;; 
    nxtDisplayTextLine&#40;3, "X1&#58; %d", joystick.joy1_x1&#41;; 
  &#125; 
&#125;
Sariel pisze:...bo chodzi o ledwie parę linijek kodu...
:)
Myślenie ma kolosalną przyszłość.

Awatar użytkownika
Sariel
VIP
Posty: 5418
Rejestracja: 2007-03-28, 08:16
Lokalizacja: Warszawa
brickshelf: Sariel
Kontakt:

 

#5 Post autor: Sariel »

staak pisze:Potem bezwarunkowo (niezależnie od wychylenia joysticka) oba silniki są zatrzymywane - w jakim celu?
Bo w pozycji neutralnej ROBOTC odczytuje pozycje gałek pada nie jako 0 ale jako wartości rzędu -5, -6, co powoduje uruchomienie silników w momencie startu programu. Zdefiniowanie ich prędkości jako 0 na początku rozwiązuje ten problem.
staak pisze:Poza tym osoba postronna nie musi kombinować co to za -5 i -6.
Jak wyżej - to są rzeczywiste odczyty gałek w pozycji neutralnej.
staak pisze:Należało również wyjaśnić skąd te "magiczne " 1.28
Chodzi oczywiście o wyrównanie zakresów. Odczyt z gałek mieści się w zakresie od -128 do 128, prędkość silników to od -100 do 100. Stąd dzielenie przez 1.28 nie jest konieczne, ale zwiększa precyzję sterowania i pozwala pełniej wykorzystać zakres ruchu gałek.

Awatar użytkownika
Atros
VIP
Posty: 803
Rejestracja: 2009-04-08, 19:03
Lokalizacja: Warszawa
brickshelf: Atrx
Kontakt:

 

#6 Post autor: Atros »

Hmm, myślę, że MOC to trochę za dużo powiedziane na tą konstrukcyjkę, szczególnie jeśli chodzi o Ciebie Sariel.

Skąd RobotC wie, że "joystick" to jest to urządzenie którym sterujesz (mógłbyś mieć 2 joysticki), jest to zdefiniowane gdzieś indziej?

Awatar użytkownika
Sariel
VIP
Posty: 5418
Rejestracja: 2007-03-28, 08:16
Lokalizacja: Warszawa
brickshelf: Sariel
Kontakt:

 

#7 Post autor: Sariel »

W sterowniku zapewne.

Kod: Zaznacz cały

#include "JoystickDriver.c" 

staak
Posty: 53
Rejestracja: 2008-10-07, 19:05
Lokalizacja: Warszawa
brickshelf: staak

 

#8 Post autor: staak »

Sariel pisze:Zdefiniowanie ich prędkości jako 0 na początku rozwiązuje ten problem.
i stwarza następny, bo
staak pisze:niezależnie od wychylenia joysticka oba silniki są zatrzymywane
Więc należy to traktować jako błąd w programie... i podziękować za skorygowanie :)

Tak na marginesie, czytasz posty na które odpowiadasz? :p
staak pisze:

Kod: Zaznacz cały

short joy1_x1_0pos = -5; //wskazanie manetki lewej, oś x &#40;lewo prawo&#41;w pozycji 0 
short joy1_y1_0pos = -6; //wskazanie manetki lewej, os y &#40;góra dół&#41; w pozycji 0
staak pisze:-100 <= motor[motorABC] <=100
-128 <= joystick.joy1_X1Y1 <=127
Mogłeś napisać :
Ponieważ joystick.joy1_x1y1 jest zmienną typu short tak więc zmienne joy1_x1_0pos i joy1_y1_0pos muszą być typu short a nie int.
....ale nie napisałeś.
Atr pisze:Skąd RobotC wie, że "joystick" to jest to urządzenie którym sterujesz (mógłbyś mieć 2 joysticki), jest to zdefiniowane gdzieś indziej?
W RobotC przyporządkowujesz (ręcznie) określone urządzenie wskazujące (które jest predefiniowane w RobotC) do określonego NXT (choć do tego wrócimy w kolejnym temacie Sariela pt [IDEA] Sterowanie wieloma kostkami jednym padem) . Urządzeniem wskazującym może być pad, joystick itp. Soft RobotC jedynie "konwertuje" wskazania (położenia manetek i przycisków) wybranego urządzenia do odpowiednio sformatowanej "ramki danych" i wysyła po USB lub BT do wybranego NXT.
Biblioteka JoystickDriver.c "jedynie" odbiera dane z bufora NXT i umożliwia wyciągnięcie z odpowiednio sformatowanej "ramki danych" poszczególnych elementów.
Taka jest teoria...
Myślenie ma kolosalną przyszłość.

ODPOWIEDZ