go_away

Author Topic: Line follower  (Read 872 times)

0 Members and 1 Guest are viewing this topic.

Offline pranavm1502Topic starter

  • Beginner
  • *
  • Posts: 4
  • Helpful? 0
Line follower
« on: January 25, 2013, 02:46:21 PM »
Hi,
I am programming a line follower with 7x white line sensors attached in a straight line to it. Can someone guide me on the following points?-
1. how  to detect sharp turns (more than 200 degree)?
2.How to change a white line follower to a black line follower in the same code?
3. is PID the best algorithm out there for line followers? What are different effective algorithms?
 I have attached the image of the track I am coding for.

Offline waltr

  • Supreme Robot
  • *****
  • Posts: 1,919
  • Helpful? 97
Re: Line follower
« Reply #1 on: January 25, 2013, 07:04:33 PM »
1- Think of what the line sensors 'see' when the line makes a sharp bend. Or, actually move the line sensor array over such a line.
2- If the sensor output in a logic high when it 'sees' a white line then it will output a logic low for a black line.
3- Maybe. The best is usually the simplest algorithm. Start with just a 'proportional' and experiment to see if this works well enough.

Offline pranavm1502Topic starter

  • Beginner
  • *
  • Posts: 4
  • Helpful? 0
Re: Line follower
« Reply #2 on: January 25, 2013, 11:13:56 PM »
1. The problem here is by the time it reaches the end of the sharp turn, it only center sensors detect white line and it goes straight ahead. But it goes straight ahead. To overcome this I made it remember last location but the condition just before it reaches the end of turn keeps changing as it approaches each time a little differently. What to do here?

2. My question is how would you know that you have to follow black instead of white now?

Thanks.


Code: [Select]
//Main Function
int main(void)
{
 unsigned char data;
 unsigned char data_old;
 init_devices();
 lcd_set_4bit();
 lcd_init();

 while(1)
 {
  Leftmost_white_line = 180- ADC_Conversion(3); //Getting data of Leftmost WL Sensor
      Left_white_line = 200- ADC_Conversion(2); //Getting data of left WL Sensor
  Left_center_white_line = 200- ADC_Conversion(1); //Getting data of left center WL Sensor

  Center_white_line = 256 - spi_master_tx_and_rx(0);
  Right_center_white_line = 256 - spi_master_tx_and_rx(1);
  Right_white_line = 256 - spi_master_tx_and_rx(2);
  Rightmost_white_line = 256 - spi_master_tx_and_rx(3);


  flag=0;

data_binary[0] = white_detect(Leftmost_white_line);
data_binary[1] = white_detect(Left_white_line);
data_binary[2] = white_detect(Left_center_white_line);
data_binary[3] = white_detect(Center_white_line);
data_binary[4] = white_detect(Right_center_white_line);
data_binary[5] = white_detect(Right_white_line);
data_binary[6] = white_detect(Rightmost_white_line);
data =0x0;
data|=data_binary[0];
data<<=1;
data|=data_binary[1];
data<<=1;
data|=data_binary[2];
data<<=1;
data|=data_binary[3];
data<<=1;
data|=data_binary[4];
data<<=1;
data|=data_binary[5];
data<<=1;
data|=data_binary[6];
data&=0b01111111;

_delay_ms(10); // delay to control LCD refresh rate

lcd_home();
//lcd_string("WL4 WL5 WL6 WL7");

lcd_print(1, 1, data_binary[0], 3);
lcd_print(1, 6, data_binary[1], 3);
lcd_print(1, 10, data_binary [2], 3);
lcd_print(1, 14, data_binary [3], 3);
lcd_print(2, 1, data_binary [4], 3);
lcd_print(2, 6, data_binary [5], 3);
lcd_print(2, 10, data_binary [6], 3);
lcd_print(2, 14, data, 3);

switch(data)
{
case 0b00000100:
case 0b00001000:
case 0b00010000:
case 0b00011000:
case 0b00001100:
case 0b00011100:
velocity(230,230);//straight
forward();
break;
case 0b00011110:
case 0b00011111:
case 0b00001111: //sharp right
velocity(230,0);
forward();
_delay_ms(140);
break;
case 0b00111100:
case 0b01111100:
case 0b01111000://sharp left
velocity(0,230);
forward();
_delay_ms(140);
break;
case 0b01000000:
case 0b01100000://left
case 0b01110000:
velocity(40,230);
forward();
_delay_ms(15);
break;
case 0b00100000:
case 0b00110000: //soft left
velocity(80,210);
forward();
_delay_ms(5);
break;
case 0b00000001:
case 0b00000011: //right
case 0b00000111:
velocity(230,40);
forward();
_delay_ms(15);
break;
case 0b00000010:
case 0b00000110: // soft right
velocity(210,80);
forward();
_delay_ms(5);
break;
case 0b00000000: //reverse
stop();
_delay_ms(500);
if(data_old==0b00111000||data_old==0b00110000 ||data_old==0b00011100 || data_old==0b00011000 || data_old == 0b00001100)
{
velocity(255,255);
left();
_delay_ms(700);
}
else
{
velocity(255,255);
back();
_delay_ms(500);
}
stop();
_delay_ms(500);
break;
default:// straight(slight left)
if(data >64)
{
velocity(0,230);//turn left
forward();
_delay_ms(20);
}

else if (data&0b00000001)
{
velocity(230,0);//turn right
forward();
_delay_ms(20);
}
else
{
velocity(180,150); //slight right
forward();
}
}

data_old= data;
}
return 0;
}

Offline waltr

  • Supreme Robot
  • *****
  • Posts: 1,919
  • Helpful? 97
Re: Line follower
« Reply #3 on: January 26, 2013, 08:06:11 AM »
Quote
2. My question is how would you know that you have to follow black instead of white now?

If it is centered on the White line then the inner sensors 'see' white and the outer sensors 'see' black.
If then the outer sensors 'see' white and the inner sensors 'see' black Then the line changed from White to Black and the sensor outputs need to be inverted ('complement') to use the same code.

Offline pranavm1502Topic starter

  • Beginner
  • *
  • Posts: 4
  • Helpful? 0
Re: Line follower
« Reply #4 on: January 26, 2013, 10:30:48 AM »
Quote
2. My question is how would you know that you have to follow black instead of white now?

If it is centered on the White line then the inner sensors 'see' white and the outer sensors 'see' black.
If then the outer sensors 'see' white and the inner sensors 'see' black Then the line changed from White to Black and the sensor outputs need to be inverted ('complement') to use the same code.

well as you can see in the attached photo, center black and white in the side arises in the maze also. If I do what you have said than the robot wont be able to solve maze properly.

Offline pranavm1502Topic starter

  • Beginner
  • *
  • Posts: 4
  • Helpful? 0
Re: Line follower
« Reply #5 on: January 31, 2013, 12:51:48 PM »
Hi,
I have attached my code for proportional line follower . But it is not able to turn right angle turns.
Please help.
Code: [Select]

//Main Function
int main(void)
{
 unsigned char data , i ,left_speed, right_speed;
 unsigned char data_old;
 int deviation , integration , prev_deviation , correction;
 init_devices();
 lcd_set_4bit();
 lcd_init();

 while(1)
 {
  Leftmost_white_line =  ADC_Conversion(3); //Getting data of Leftmost WL Sensor
      Left_white_line =  ADC_Conversion(2); //Getting data of left WL Sensor
  Left_center_white_line = ADC_Conversion(1); //Getting data of left center WL Sensor

  Center_white_line =  spi_master_tx_and_rx(0);
  Right_center_white_line =  spi_master_tx_and_rx(1);
  Right_white_line = spi_master_tx_and_rx(2);
  Rightmost_white_line =  spi_master_tx_and_rx(3);


  flag=0;

data_binary[0] = white_detect(Leftmost_white_line);
data_binary[1] = white_detect(Left_white_line);
data_binary[2] = white_detect(Left_center_white_line);
data_binary[3] = white_detect(Center_white_line);
data_binary[4] = white_detect(Right_center_white_line);
data_binary[5] = white_detect(Right_white_line);
data_binary[6] = white_detect(Rightmost_white_line);
/* data =0x0;
data|=data_binary[0];
data<<=1;
data|=data_binary[1];
data<<=1;
data|=data_binary[2];
data<<=1;
data|=data_binary[3];
data<<=1;
data|=data_binary[4];
data<<=1;
data|=data_binary[5];
data<<=1;
data|=data_binary[6];
data&=0b01111111;
*/
_delay_ms(10); // delay to control LCD refresh rate

lcd_home();
//lcd_string("WL4 WL5 WL6 WL7");

lcd_print(1, 1, left_speed, 3);
lcd_print(1, 6, right_speed, 3);
lcd_print(1, 10, deviation+20, 3);
//lcd_print(1, 14, data_binary [3], 3);
//lcd_print(2, 1, data_binary [4], 3);
//lcd_print(2, 6, data_binary [5], 3);
//lcd_print(2, 10, data_binary [6], 3);
//lcd_print(2, 14, data, 3);

deviation =0;
for(i=0;i<7;i++)
deviation += 5*(i+1) * data_binary[i];
deviation-=20;



correction = 2*deviation ;
left_speed = 200+ correction;
right_speed = 200 - correction;
if (correction > 55)
left_speed = 255;
if (correction <-55)
right_speed =255;
if(correction >200)
right_speed =0;
if(correction <-200)
left_speed=0;
velocity(left_speed,right_speed);
forward();

}
return 0;
}

 


Get Your Ad Here