### Author Topic: Line follower  (Read 2065 times)

0 Members and 1 Guest are viewing this topic.

#### pranavm1502

• Beginner
• Posts: 4
##### 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.

#### waltr

• Supreme Robot
• Posts: 1,944
##### 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.

#### pranavm1502

• Beginner
• Posts: 4
##### 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 Functionint 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;}`

#### waltr

• Supreme Robot
• Posts: 1,944
##### 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.

#### pranavm1502

• Beginner
• Posts: 4
##### 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.

#### pranavm1502

• Beginner
• Posts: 4
`//Main Functionint 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;}`