Skocz do zawartości

Oscylacja Robota Line Follower


piotr3332

Pomocna odpowiedź

Witam

Mam kłopoty ze sterowaniem mojego robota line follower.

Problem występuje gdy robot śledzi linię prostą przy wyższych prędkościach. W linii prostej robot naprawia blad i skreca trochę w lewo i wystepuje male przeregulowanie, następnie koryguje w prawo i

przeregulowanie jest nieco większe, potem w lewo, potem w prawo, itp. za każdym razem

przeregulowanie wzrasta a aż traci linię.

Nie moge zbytnio zrozumiec dlaczego tak sie dzieje.

Używam algorytm PID i używam 5 czujników. 2 z lewej, 2 z prawej i 1 w środku.

Probowalem zmieniac wartosci dla PID ale bez skutku. Przy wiekszej predkosci moj robot nie podarza lini prostej w wlasciwy sposob. Czy ktos moglby mi pomoc jak ten problem naprawic?

Dziekuje

Link do komentarza
Share on other sites

Zmniejsz odrobinę prędkość i spróbuj najpierw na samym P, kombinuj wagami czujników i jak bedzie już ładnie to zwiększ prędkość i ewentualnie znowu skoryguj nastawy i wagi czujników. Jak będzie w miarę podążał za linię to potem kombinuj już z resztą 😋

  • Lubię! 1
Link do komentarza
Share on other sites

Juz siedze nad tym dosyc sporo. Przy jednej predkosci wszystko jest ok. Gdy zwiekszam chociaz troche wiecej. Robot traci kontrole. Nie rozumiem tylko dlaczego na poczatku blad jest dobrze korygowany a po jakims czasie przeregulowania wzrastaja. Czy to wina D?

Link do komentarza
Share on other sites

1. W jakiej odległości są czujniki i jaka jest szerokość linii?

2. Skoro robot się daje rozbujać tzn., że ma za dużą wartość P w stosunku do D. Zwiększ wartość D i to tak solidnie (x10)

Grabki:

Współczynnik D jest właśnie od tego, żeby robot nie "przekraczał" zadanej wartości. Eliminacja współczynnika D jest kontrowersyjnym pomysłem...

  • Lubię! 1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

piotr3332, to nie jest wina D. Jeśli oscylacje rosną to jednym z powodów może być zbyt wysokie wzmocnienie P. Problemem może być rozstawienie czujników i zastosowany algorytm. Prawda jest taka, że im się chce osiągnąć wyższą prędkość tym czujników musi być więcej i muszą być one oddalone od siebie o taką odległość, aby nie było pomiędzy czujnikami stref takich, że żaden z czujników nie widzi linii.

  • Lubię! 1
Link do komentarza
Share on other sites

Niestety zwiekszylem D i jest troche roznicy ale dalej sa spore przesterowania . Gdy probwalem zwiekszyc D do sporych wartosci, robot tracil kontrole i wypadal z trasy.

Dla predkosci 10000

P mam 70

D mam 3000

I mam 0

wagi to -50, -40, -30 , -20, 0, 20, 30, 40, 50

Czy solucja rowniez moze byc zwiekszenie badz zmniejszenie wag dla sensorow?

Link do komentarza
Share on other sites

No wlasnie juz pisze. Algorytm odczytuje najpierw dane z czujnika, potem przypisuje pozycje sensora w kodzie jest to np. centre, hard left. odczyt dla danego czujnika jest w przedziale od wartosci 5 do 15 gdzie 5 to linia jest centralnie pod czujnikiem i 15 linia jest kompletnie poza czujnikiem. Nastepnie obliczane sa wagi na podstawie wlasnie pozycji. Czyli np. dla centre i small right, bedzie to waga -20 itd.

Potem jest juz funkcja dla PID i kontrolowanie motorow poprzez dodawanie i odejmowanie wartosci od PWM.

Nie mam zbytnio doswiadczenia w programowaniu, dlatego moj kod napewno jest zle zoptymalizowany. Wszystko dzieje sie w jednym while loop.

Rozwniez. Po zmianie wartosci PWM dla danego silnika nie ma u mnie zadnej metody ktora dawala by jaka jest predkosc motorow po korygacji PID.

Staralem sie mniej wiecej w skrocie wytlumaczyc.


//***********PID INIT*******************

 int err;

 int error,error_old=0,zero=0,temp,error_diff;
 int integral = 0;
 int turn;  
 int position;
 int target_position = 0;


 while(true)
 {

   bool centre = false;
   bool small_left = false;
   bool small_right = false;
   bool right = false;
   bool left = false;



   ir_rx0.output();
   ir_rx1.output();
   ir_rx2.output();
   ir_rx3.output(); 
   ir_rx4.output();
   ir_rx5.output();
   ir_rx6.output();
   ir_rx7.output(); 

   ir_rx0 = 1;
   ir_rx1 = 1;
   ir_rx2 = 1;
   ir_rx3 = 1;
   ir_rx4 = 1;
   ir_rx5 = 1;
   ir_rx6 = 1;
   ir_rx7 = 1; 

   for(i=0; i<8; i++)
   {
     ir_set[i]=true;
     ir_value[i]=0;
   }

   wait_us(50);

   ir_rx0.input(); 
   ir_rx1.input();  
   ir_rx2.input(); 
   ir_rx3.input(); 
   ir_rx4.input(); 
   ir_rx5.input();  
   ir_rx6.input(); 
   ir_rx7.input(); 

   test = 1;

   for(i=0; i<20; i++)
   {
     wait_us(50);

     if ((ir_buffer && 0x01) == 0)
       test = 0;

     if((ir_rx0==0) & ir_set[0])
     {
       ir_set[0]=false; ir_value[0]=i; 
     }  
     if((ir_rx1==0) & ir_set[1])
     {
       ir_set[1]=false; ir_value[1]=i; 
     }  
     if((ir_rx2==0) & ir_set[2])
     {
       ir_set[2]=false; ir_value[2]=i; 
     }  
     if((ir_rx3==0) & ir_set[3])
     {
       ir_set[3]=false; ir_value[3]=i; 
     }  
     if((ir_rx4==0) & ir_set[4])
     {
       ir_set[4]=false; ir_value[4]=i; 
     }  
     if((ir_rx5==0) & ir_set[5])
     {
       ir_set[5]=false; ir_value[5]=i; 
     }  
     if((ir_rx6==0) & ir_set[6])
     {
       ir_set[6]=false; ir_value[6]=i; 
     }  
     if((ir_rx7==0) & ir_set[7])
     {
       ir_set[7]=false; ir_value[7]=i; 
     }  

   }

   if(ir_value[3] == 5 || ir_value[3] == 6 || ir_value[3] == 6 || ir_value[3] == 7 || ir_value[3] == 8 || ir_value[3] == 9 || ir_value[3] == 10 || ir_value[3] == 11 || ir_value[3] == 12 || ir_value[3] == 13)
   {   

       centre = true;

       //perfectly straight
   }

   if(ir_value[2] == 5 || ir_value[2] == 6 || ir_value[2] == 6 || ir_value[2] == 7 || ir_value[2] == 8 || ir_value[2] == 9 || ir_value[2] == 10 || ir_value[2] == 11 || ir_value[2] == 12 || ir_value[2] == 13)
   {   
       //slighltly left
       small_right = true;

   }

  if(ir_value[5] == 5 || ir_value[5] == 6 || ir_value[5] == 6 || ir_value[5] == 7 || ir_value[5] == 8 || ir_value[5] == 9 || ir_value[5] == 10 || ir_value[5] == 11 || ir_value[5] == 12)
   {
       //left
       small_left = true;
       //more left

   }    

   if(ir_value[7] == 5 || ir_value[7] == 6 || ir_value[7] == 6 || ir_value[7] == 7 || ir_value[7] == 8 || ir_value[7] == 9 || ir_value[7] == 10 || ir_value[7] == 11 || ir_value[7] == 12 || ir_value[7] == 13)
   {
       //hard left
       left = true;

   }    
   if(ir_value[1] == 5 || ir_value[1] == 6 || ir_value[1] == 6 || ir_value[1] == 7 || ir_value[1] == 8 || ir_value[1] == 9 || ir_value[1] == 10 || ir_value[1] == 11 || ir_value[1] == 12 || ir_value[1] == 13)
   {
       //hard right
       right = true;

   }


   if(centre == true && small_left == false && small_right == false && right == false && left == false)
   {
   error = 0;
   centre = false;
   }
   else if(centre == true && small_left == true && small_right == false && right == false && left == false)
   {
   error = 20;
   centre = false;
   small_left = false;
   }
   else if(centre == false && small_left == true && small_right == false && right == false && left == false)
   {
   error = 30;
   small_left = false;
   }
   else if(centre == false && small_left == true && left == true && small_right == false && right == false)
   {
   error = 40;
   small_left = false;
   left = false;
   }
   else if(centre == false && small_left == false && left == true && small_right == false && right == false)
   {
   error = 50;
   left = false;
   }

   else if(centre == true && small_left == false && small_right == true && right == false && left == false)
   {
   error = -20;
    centre = false;
   small_right = false;
   }
   else if(centre == false && small_left == false && small_right == true && right == false && left == false)
   {
   error = -30;
   small_right = false;
   }
   else if(centre == false && small_left == false && left == false && small_right == true && right == true)
   {
   error = -40;
   small_right =false;
   right = false;
   }
   else if(centre == false && small_left == false && left == false && small_right == false && right == true)
   {
   error = -50;
   right = false;
   }


   //****************PID control*****************************//

   err = target_position - error;


   err = err * -1;

   error_diff = err - error_old;

   integral = integral + err; 

   turn = err*kp +error_diff*kd + integral*ki; 

   error_old=err;

   if((superslow + turn) > superslow) 
   {
   motorLeft = superslow;
   }
   else 
   {
   motorLeft = (superslow + turn);
   }
   if((superslow + turn) <1500)
   {
   motorLeft = 1500;
   }

   if((superslow - turn) > superslow)
   {
   motorRight = superslow ;
   }
   else
   {
   motorRight = (superslow - turn);  
   }
   if((superslow - turn) <1500)
   {
   motorRight = 1500;
   }

   pwm0.pulsewidth_us(motorLeft);

   pwm1.pulsewidth_us(motorRight); 

   DIRECTION = FORWARD;

   cmd[0] = DIRECTION;           
   cmd[1] = 0x00;           
   i2c.write(addr, cmd, 1); 

}
Link do komentarza
Share on other sites

Wybacz, ale Twój kod ma tyle wspólnego z PID co...

1. Na wejściu masz tylko kilka stanów, które nawet nie za bardzo wiem czy są poprawnie ustawiane z powodu całej gamy ifów.

PID do poprawnego działania musi dostać coś sensownego na wejście. np. liczbę zmieniającą się od -127 do 127 - patrz swój drugi temat gdzie opisałem jak bym ją uzyskał.

Inna sprawa jest taka, że rozmieszczenie czujników wydaje mi się mało sensowne. Przynajmniej na początku ograniczyłbym się do 5 w "jednej" linii (1,4,5,6,3). Szkoda, że czujników nie ma więcej / na większej szerokości, bo w tym momencie robot łatwo będzie wypadał czujnikami poza linię i przy krętym torze zawsze będzie lipa.

2. Na wyjściu masz coś.. co to jest superslow?

Jak ma się wielkość superslow do turn?

Dlaczego zamiast ustawiać coś w stylu:

if (turn < 0 ) pwmsilnikalewo = max;

else pwmsilnikalewo = max-turn;

if (turn > 0 ) pwmsilnikaprawo = max;

else pwmsilnikaprawo = max-turn

Ty masz wiele ifów?

3. Przynajmniej część kodu z deklaracjami zmiennych brakuje.

Plan naprawczy:

1. Fajnie gdybyś miał możliwość wyrzucania danych do PCta żeby analizować co się dzieje na mikrokontrolerze

2. Przygotuj prawidłowy kod obliczający pozycję linii pod czujnikami - patrz drugi temat, gdzie to dosyć dokładnie opisałem. Bez poprawnej pozycji wejściowej PID nigdy nie będzie dobrze działał

3. Jak będzie poprawna pozycja wejściowa dopisz kod PID, sprawdź co z niego wychodzi w różnych sytuacjach i uprość zamianę wyjścia PID (zmienna turn) na wartości PWM silników.

4. Zakładam, że w tym momencie wszystko zacznie jakoś działać i będzie trzeba poprawnie ustawić wartości ki,kd,kp , ale jak cały algorytm będzie działać to dasz sobie radę.

Ten kod co masz niestety nadaje się w większości do kosza...

Link do komentarza
Share on other sites

superslow jest to wartosc dla pulsewidth w microsekundach. W tym wypadku do superslow jest przypisane 8000 ktore wyznacza predkosc. Ify mam dlatego ze aby nie uszkodzic motorow, nie przypisuje wartosci 0 do jednego z motorow, zamiast tego mam limit w postaci 1500.

Jesli chodzi o prawidlowy kod obliczajacy lini na ta chwile nie do konca rozumiem jak to poprawnie zaprogramowac. Ale bardzo dziekuje za rade w tej sprawie.

podaje caly kod

#include "mbed.h"


//**********LINE SENSORS*************
DigitalOut   led(LED1);                                  // status LED
DigitalOut   test(p27);                                  // test pin

DigitalInOut ir_rx0(p11);  // IR recieves
DigitalInOut ir_rx1(p12);  // IR recieves
DigitalInOut ir_rx2(p15);  // IR recieves
DigitalInOut ir_rx3(p16);  // IR recieves
DigitalInOut ir_rx4(p17);  // IR recieves
DigitalInOut ir_rx5(p18);  // IR recieves
DigitalInOut ir_rx6(p25);  // IR recieves
DigitalInOut ir_rx7(p26);  // IR recieves

PwmOut ir_tx(p24);                                       // IR transmitter
Timer t;
Serial pc(USBTX, USBRX);                                 // USB serial port


//**********MOTOR********************
I2C i2c(p9, p10);        // sda, scl

PwmOut pwm0(p22);
PwmOut pwm1(p23);

const int addr = 0x40; // define the I2C Address

//**********PID CONSTANTS******
int kp = 82;; 
int kd = 69;
int ki = 6; 
#define FORWARD 0x66
#define RIGHT 0x55
#define LEFT  0xAA
#define RIGHT_STOP  0x77
#define LEFT_STOP  0xEE
#define STOP 0xFF
#define PI 3.14

//PWM
int superslow = 9000;


// Black  : 4.2x200us   = 840us
// White  : 2 x 100us   = 200us
// Silver : 1.2 x 100us = 120us

int main() {

 //************MOTOR INIT******************
 char cmd[2];
 pwm0.period_us(20);          
 pwm1.period_ms(20);   


 int DIRECTION = FORWARD;

 int motorLeft;
 int motorRight;


  //*************SENSOR INIT******************

 bool ir_set[8];
 int  ir_value[8];

 int  ir_buffer;
 int  i, j, k;

  ir_tx.period_ms(20);       // a 20ms period
 ir_tx.pulsewidth_ms(20);

 led  = 1;   
 test = 0;

 //***********PID INIT*******************

 int err;


 int error,error_old=0,zero=0,temp,error_diff;

 int integral = 0;

 int turn;  
 int position;
 int target_position = 0;


 while(true)
 {


   bool centre = false;
   bool small_left = false;
   bool small_right = false;
   bool right = false;
   bool left = false;


   ir_rx0.output();
   ir_rx1.output();
   ir_rx2.output();
   ir_rx3.output(); 
   ir_rx4.output();
   ir_rx5.output();
   ir_rx6.output();
   ir_rx7.output(); 

   ir_rx0 = 1;
   ir_rx1 = 1;
   ir_rx2 = 1;
   ir_rx3 = 1;
   ir_rx4 = 1;
   ir_rx5 = 1;
   ir_rx6 = 1;
   ir_rx7 = 1; 

   for(i=0; i<8; i++)
   {
     ir_set[i]=true;
     ir_value[i]=0;
   }

   wait_us(50);

   ir_rx0.input(); 
   ir_rx1.input();  
   ir_rx2.input(); 
   ir_rx3.input(); 
   ir_rx4.input(); 
   ir_rx5.input();  
   ir_rx6.input(); 
   ir_rx7.input(); 

   test = 1;

   for(i=0; i<20; i++)
   {
     wait_us(50);

     if ((ir_buffer && 0x01) == 0)
       test = 0;

     if((ir_rx0==0) & ir_set[0])
     {
       ir_set[0]=false; ir_value[0]=i; 
     }  
     if((ir_rx1==0) & ir_set[1])
     {
       ir_set[1]=false; ir_value[1]=i; 
     }  
     if((ir_rx2==0) & ir_set[2])
     {
       ir_set[2]=false; ir_value[2]=i; 
     }  
     if((ir_rx3==0) & ir_set[3])
     {
       ir_set[3]=false; ir_value[3]=i; 
     }  
     if((ir_rx4==0) & ir_set[4])
     {
       ir_set[4]=false; ir_value[4]=i; 
     }  
     if((ir_rx5==0) & ir_set[5])
     {
       ir_set[5]=false; ir_value[5]=i; 
     }  
     if((ir_rx6==0) & ir_set[6])
     {
       ir_set[6]=false; ir_value[6]=i; 
     }  
     if((ir_rx7==0) & ir_set[7])
     {
       ir_set[7]=false; ir_value[7]=i; 
     }  

   }

   if(ir_value[3] == 5 || ir_value[3] == 6 || ir_value[3] == 6 || ir_value[3] == 7 || ir_value[3] == 8 || ir_value[3] == 9 || ir_value[3] == 10 || ir_value[3] == 11 || ir_value[3] == 12 || ir_value[3] == 13)
   {   

       centre = true;


       //perfectly straight
   }

   if(ir_value[2] == 5 || ir_value[2] == 6 || ir_value[2] == 6 || ir_value[2] == 7 || ir_value[2] == 8 || ir_value[2] == 9 || ir_value[2] == 10 || ir_value[2] == 11 || ir_value[2] == 12 || ir_value[2] == 13)
   {   
       //slighltly left
       small_right = true;

   }

  if(ir_value[5] == 5 || ir_value[5] == 6 || ir_value[5] == 6 || ir_value[5] == 7 || ir_value[5] == 8 || ir_value[5] == 9 || ir_value[5] == 10 || ir_value[5] == 11 || ir_value[5] == 12)
   {
       //left
       small_left = true;
       //more left


   }    


   if(ir_value[7] == 5 || ir_value[7] == 6 || ir_value[7] == 6 || ir_value[7] == 7 || ir_value[7] == 8 || ir_value[7] == 9 || ir_value[7] == 10 || ir_value[7] == 11 || ir_value[7] == 12 || ir_value[7] == 13)
   {
       //hard left
       left = true;

   }    
   if(ir_value[1] == 5 || ir_value[1] == 6 || ir_value[1] == 6 || ir_value[1] == 7 || ir_value[1] == 8 || ir_value[1] == 9 || ir_value[1] == 10 || ir_value[1] == 11 || ir_value[1] == 12 || ir_value[1] == 13)
   {
       //hard right
       right = true;

   }

   //printf( "position =  %d\n", pos);  


   if(centre == true && small_left == false && small_right == false && right == false && left == false)
   {
   error = 0;
   centre = false;
   }
   else if(centre == true && small_left == true && small_right == false && right == false && left == false)
   {
   error = 15;
   centre = false;
   small_left = false;
   }
   else if(centre == false && small_left == true && small_right == false && right == false && left == false)
   {
   error = 25;
   small_left = false;
   }
   else if(centre == false && small_left == true && left == true && small_right == false && right == false)
   {
   error = 35;
   small_left = false;
   left = false;
   }
   else if(centre == false && small_left == false && left == true && small_right == false && right == false)
   {
   error = 45;
   left = false;
   }

   else if(centre == true && small_left == false && small_right == true && right == false && left == false)
   {
   error = -15;
    centre = false;
   small_right = false;
   }
   else if(centre == false && small_left == false && small_right == true && right == false && left == false)
   {
   error = -25;
   small_right = false;
   }
   else if(centre == false && small_left == false && left == false && small_right == true && right == true)
   {
   error = -35;
   small_right =false;
   right = false;
   }
   else if(centre == false && small_left == false && left == false && small_right == false && right == true)
   {
   error = -45;
   right = false;
   }

   //****************PID*****************************//

   err = target_position - error;

   err = err * -1;

   error_diff = err - error_old;

   integral = integral + err; 
   turn = err*kp +error_diff*kd + integral*ki; 

   error_old=err;

   if((superslow + turn) > superslow) 
   {
   motorLeft = superslow;
   }
   else 
   {
   motorLeft = (superslow + turn);
   }
   if((superslow + turn) <1500)
   {
   motorLeft = 1500;
   }

   if((superslow - turn) > superslow)
   {
   motorRight = superslow ;
   }
   else
   {
   motorRight = (superslow - turn);  
   }
   if((superslow - turn) <1500)
   {
   motorRight = 1500;
   }



   pwm0.pulsewidth_us(motorLeft);
   pwm1.pulsewidth_us(motorRight); 


   DIRECTION = FORWARD;

   cmd[0] = DIRECTION;           
   cmd[1] = 0x00;           
   i2c.write(addr, cmd, 1); 


 }


}
Link do komentarza
Share on other sites

superslow jest to wartosc dla pulsewidth w microsekundach. W tym wypadku do superslow jest przypisane 8000 ktore wyznacza predkosc. Ify mam dlatego ze aby nie uszkodzic motorow, nie przypisuje wartosci 0 do jednego z motorow, zamiast tego mam limit w postaci 1500.
if((superslow + turn) > superslow) 
   { 
   motorLeft = superslow; 
   } 
   else 
   { 
   motorLeft = (superslow + turn); 
   } 
   if((superslow + turn) <1500) 
   { 
   motorLeft = 1500; 
   } 

   if((superslow - turn) > superslow) 
   { 
   motorRight = superslow ; 
   } 
   else 
   { 
   motorRight = (superslow - turn);  
   } 
   if((superslow - turn) <1500) 
   { 
   motorRight = 1500; 
   } 

W takim razie masz na końcu to co sugerowałem.. tylko dlaczego tak zapisane? Trzeba się domyślać o co chodzi.. warunki powinny być czytelne, a zmienne sensownie nazwane.

Przykładowa zmiana tego kodu na coś bardziej czytelnego:

superslow -> maxspeed

1500 -> minspeed

if (turn>0)
{ // skret w prawo
   motorLeft = maxspeed;
   motorRight = maxspeed - turn;
   if (motorRight < minspeed) motorRight = minspeed;
}
else // turn <= 0
{ // skret w lewo
   motorLeft = maxspeed - turn;
   motorRight = maxspeed;
   if (motorLeft < minspeed) motorLeft = minspeed;
}

Jak widać mniej kodu i przejrzyściej napisany.

  • Lubię! 1
Link do komentarza
Share on other sites

Czujniki masz podpięte pod ADC? Jeśli tak, to możesz sprytnie zwiększyć rozdzielczość w taki sposób:


poz = (W1*CZ1+W2*CZ2+...+Wn*CZn)/(CZ1+CZ2+...+CZn);

Czyli po prostu średnia ważona. Wn to waga n-tego czujnika, CZn to wartość pomiaru n-tego czujnika. Jest to rozwiązanie duużo czytelniejsze od miliona ifów, i ma jeszcze zaletę w postaci programowego zwiększenia rozdzielczości.

Zerknij na 1:30 - tak by to działało.

  • Lubię! 1
Link do komentarza
Share on other sites

Zaimplementowalem metode obliczania sredniej z sensorow.

Niestety minimalne i maksymalne wartosci dla ktorych dany sensor widzi albo nie widzi lini co jakis czas sie zmieniaja. I np. wartosci kiedy sensor nie widzi lini zmieniaja sie z 13 do 14 albo odwrotnie podczas jazdy. rowniez wartosci maksymalne kiedy dany sensor widzi linie nie sa takie same dla wszystkich sensorow. Np.

Sensor 1 = 8;

Sensor 2 = 6;

Sensor 3 = 8;

Sensor 4 = 6;

Sensor 5 = 7;

int minlimit = 0; //wartosc minimalna dla sensora
int maxlimit = 100; //wartosc maksymalna dla sensora
int weights[5] = {-30, -15, 0, 15, 30}; //wagi
int Sensor_Value[8]; //tablica z wartosciami po przeliczniku dla kazdego z sensorow


//14 albo 13 to wartosci dla ktorych sensor kompletnie nie widzi lini
//wartosc dla danego sensora jest obliczana tak aby zakres byl pomiedzy 0 a 100

Sensor_Value[1] = ((14 - ir_value[1])*16.666666667);
   if(Sensor_Value[1] < minlimit)
   {
   Sensor_Value[1] = minlimit;  
   }
   else if(Sensor_Value[1] > maxlimit)
   {
   Sensor_Value[1] = 100; 
   }

   Sensor_Value[2] = ((14 - ir_value[2])*16.666666667);
   if(Sensor_Value[2] < minlimit)
   {
   Sensor_Value[2] = minlimit; 
   }
   else if(Sensor_Value[2] > maxlimit)
   {
   Sensor_Value[2] = maxlimit; 

   }

   Sensor_Value[4]= (14 - ir_value[4])*16.6;   
   if(Sensor_Value[4] > maxlimit)
   {
   Sensor_Value[4] = maxlimit;
   }    
   Sensor_Value[5] = (13 - ir_value[5])*15;

   if(Sensor_Value[5] < minlimit)
   {
   Sensor_Value[5] = minlimit; 
   }
   else if(Sensor_Value[5] > maxlimit)
   {
   Sensor_Value[5] = maxlimit; 
   }
   Sensor_Value[7] = (13 - ir_value[7])*15;

   if(Sensor_Value[7] < minlimit)
   {
   Sensor_Value[7] = minlimit; 
   }
   else if(Sensor_Value[7] > maxlimit)
   {
   Sensor_Value[7] = maxlimit; 
   }


   //liczenie bledu
   error = (((weights[0] * Sensor_Value[1]) + (weights[1] * Sensor_Value[2]) + (weights[2] * Sensor_Value[4]) + (weights[3] * Sensor_Value[5]) + (weights[4] * Sensor_Value[7]))/(Sensor_Value[1]+ Sensor_Value[2] + Sensor_Value[4] + Sensor_Value[5] + Sensor_Value[7]));

Podsumowując. Jestem w stanie zwiekszyc predkosc i moj robot sledzi linie dosyc dobrze. Sporo pomoglo zwiekszenie I.

W tej chwili bede chcial zamplementowac algorytm wykorzystujacy logike rozmyta.

Dziekuje bardzo za pomoc bardzo sie przydala.

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.