Pololu Robotics & Electronics
My account Comments or questions? About Pololu Contact Ordering information Distributors

Tackling line breaks in line following arenas



I’ve been building a robot that follows a black line on a white surface for a line following competition. One of its challenges is that the robot should also tackle line breaks.

My robot utilizes the Arduino Uno, a Pololu QTR-8RC, a TB6612FNG motor driver and 30:1 HP micrometal gearmotors.

My code uses a PD algorithm, and I’ve been able to tune my robot to follow an arena including right angles at around 400 rpm.

The line is 2.5 cm thick and both sensors 4 and 5 of the array are located above the line in a zero error condition (the error is calculated by subtracting 3500 from the value obtained using the ‘readLine’ method of the QTRSensors library).

I was trying to write code that makes it handle line breaks according to the following logic:
If no sensors are on the line and the absolute value of the error is 3500 then continue straight (because when the robot arrives on white, the error is either 3500 or -3500).

However, I noticed during turns that the robot overshoots a bit and the loop for a line break starts executing.

I would like to know how I can solve this problem.

I would also appreciate advice on how to tune my robot to speeds around 800 rpm.

An early response would be appreciated.

Anmol Singh


Hello, Anmol.

There are probably a few ways to handle those kinds of obstacles. It sounds like right now you are using the position reading to determine if the line was lost, which is causing the incorrect behavior on overshoots during turns. Instead of just sensing that your robot lost the line, you might consider trying to determine how the line was lost (e.g. to the left of the sensor, to the right of the sensor, or if it was centered when it disappeared). If the robot was centered when the line disappeared, this would indicate a line break (and not an overshoot), so you can program your robot to go straight until it senses the line again. To do this, you can keep track of the previous line position and as soon as the robot senses that it lost the line, check that previous position to determine if it ran into a dashed segment. This method should stop the robot from seeing overshoots as line breaks.

Alternatively, if you can stop your robot from overshooting the turns that could help as well. If the overshoot occurs on the right angle turns, you might consider trying to sense the turn (e.g. if the center and far-right or far-left sensors both see the line) and doing a hard-coded turn or entering a while loop that turns until the line is found again. If the overshoot is on smooth turns, you could try tuning your P and D coefficients better to eliminate the overshoot.

If you still have problems with these suggestions, can you post some pictures of your course and preferably a video of your robot attempting it?

As far as tuning your robot to work at twice the speed, I recommend getting it to work reliably at lower speeds first, then slowly increasing the speed and tweaking the tuning as you go. If you need help tuning your PID coefficients, this post by ben has some useful tips and suggestions. Additionally, when you get up to faster speeds, you might find that keeping your wheels clean can significantly help with retaining traction.



Hello, Brandon.

Thank you for your reply! Your suggestions and the link recommended by you were fantastic.

However, I’m having some problems trying to implement the algorithms suggested by you.

Currently, my robot is following a complex arena (including right angular turns) at 400 rpm.

Relating to this suggestion, I tried tracking three values - the error before the previous error, the previous error and the current error, calculated using ‘readLine’ values from the QTR array, since I found that using only two values was not reliable. I couldn’t get the error before the previous error part working. Could you please provide the details on how to accomplish this?

I attempted to implement this; however, many times the robot didn’t begin execution of the loop despite correct outcomes on the Serial Monitor, and there was almost always an overshoot due to the while loop. The performance of the robot on curves declined as well. The condition for the while loop was - turning in the appropriate direction while the error was less than or greater than zero, respectively. How can I avoid this overshoot?

Lastly, I have also noticed that tuning the P and D coefficients of my robot is dependent on the voltage of my 3S 1500 mAh Lithium Polymer battery (which is powering the TB6612FNG motor shield directly). Should I use a power module to regulate the voltage to 11V before supplying into the VMOT pin of the motor shield, or is there a better way of solving this? For information, the Vcc of the QTR array and the Arduino is provided using a Step-Down module LM2596, connected to the battery, adjusted to provide 5V.




Our local robotics club recently held a line following competition that included an advanced course with obstacles like dashed lines and right-angle turns. For the dashed lines, I had my robot use essentially the logic I described in my previous post (keeping track of the last position to detect the dashed line). I found only two values were needed. Essentially, before I updated the position reading I saved the current position to another variable. Then, after updating the position reading, I checked if the current reading was not detecting the line and if the last position was within some threshold of the center. For example:

if( lineLost() && (prevPos > -1000) && (prevPos < 1000)){
  dashFound = true;

If the dashFound value is true, I had the robot enter a loop that just goes straight and updates the sensor readings to see if it finds the line again. When it does, it goes back to following the line.

It sounds like you might be doing some serial communication for debugging right now; you might get better performance by removing that since it could be slowing down your loop. Other than that, it is hard to give specific advice for tuning the PD coefficients for better performance without seeing the behavior. If you can post a video of your robot’s performance, I might be able to offer some more recommendations.

Battery drain can certainly cause inconsistencies and make it harder to tune your robot. Regulating your motor voltage is one way to fix this problem. If you want to do this, you should be sure to use a regulator that can handle the combined current draw of your motors. It sounds like you are using the 30:1 Micro Metal Gearmotor HP 6V and running them from a 3S LiPo. Please note that at 11V, those motors could pull upwards of 3.1A each. However, it also sounds like you are using them at a duty cycle well below 100%, so you might be able to use something like our 7.5V, 2.4A Step-Down Voltage Regulator D24V22F7. It sounds like running the motors at 7.5V might still be faster than you want to go, and having a wider range of duty cycles available will probably help with control also.


Related to Micrometal Gearmotors

Hello, Brandon.

Thank you for your suggestions!

My TB6612FNG burnt due to mishandling by one of my teammates. I’ve ordered another TB6612FNG and a DRV8833. As soon as my robot’s operational, I’ll update about the progress and send the video.

Also, is it acceptable if I use a 2S LiPo (1000 or 2200 mAh) or a 3S LiPo, along with a LM2596 (giving a constant current ouptut of 3A)? I do not want to compromise on the RPM, and intend to operate my robot at around 700-800 RPM.



I noticed Grant is already helping you with a similar question about selecting a power source and regulator in this thread. To keep things organized, we can continue helping you with that there.

When your robot is operational again, you can post the progress and video here and I’d be glad to offer any suggestions I can.



Hello, Brandon.

My robot is now operational. I’m running the PD algorithm which is given as an example towards the end of the Arduino library documentation of the QTR sensors here. The only differences in the code are the following:

  • All of the 8 sensors of the QTR-8RC are being used and 3500 is being subtracted from the value obtained using the ‘readLine’ method to calculate the error after appropriate data-type conversions.

  • I’m also defining a MAX_SPEED value (equal to +900 RPM) and a MIN_SPEED value (equal to 900 RPM in the counterclockwise direction i.e -900 RPM). The output motor speed for each motor is therefore appropriately modified if it is greater than the MAX_SPEED or less than the MIN_SPEED.

There have been three major modifications to the robot, as follows:

  1. I’m now using an XL4015 regulator, adjusted to 7.5V, in between the battery and the VMOT pin of the TB6612FNG, as approved by Grant.

  2. I’ve added a counterweight on top of my 3S LiPo battery, since I noticed that the robot was facing stability problems as it turned sharp angles <= 90 degrees, due to the fact that the circuitry of the robot is mounted near the sensor in front.

  3. Finally, I’ve also pasted black electrical tape on the QTR array to prevent false readings due to ambient lighting. However, I am also calibrating the sensors before each run.

The robot has now become much more stable; the motors don’t overheat, as was happening previously, and the performance is much better.

But, I’m observing strange behavior. Initially, the robot follows the line flawlessly, but there is an occasional, completely random, overshoot. The robot deviates from the line, only at the right angular turns, and rotates in the oppposite direction before resuming following in the correct direction. I’ve attached two videos as well - one showing accurate line following at 300 RPM, and the other one depicting this random, strange behaviour during line following at 400 RPM.

I would appreciate suggestions on how to solve this problem, since I also plan to increase the speed to around 600 RPM.


https://forum.pololu.com/uploads/default/original/2X/e/e99315795aaa64d855c2341d188c8ccc8e1b0fed.mp4 https://forum.pololu.com/uploads/default/original/2X/6/6da6031fbba39d289ad43bc25dc7b31ac35164f8.mp4


Hello, Anmol.

It sounds like the behavior you are getting might be a result of false readings from your robot noticing the darker parts of the tile that your line following course is built upon. Do you get the same behavior if you switch over to running on a course that is made of electrical tape and a more homogeneous white surface (like poster or dry-erase board)?



Hello, Jon.

Thank you for your reply.

I had a look at calculated error values and motor speeds on the serial monitor, and noticed that there was nothing wrong with them on the surface shown in the video. The robot performed similarly on a homogeneous white surface (a white table) as well; it missed sharp turns occasionally and rotated the wrong way before coming back onto the line during the same.

I feel that the sensor needs to be extended out a bit more in front to give the robot some more time to react to changes in sensor readings, since I tjink that the momentum of the robot results in the overshoot.

I’m planning to modify the hardware slightly before resuming testing. I’ll let you know what’s going on as soon as it’s done.

Additionally, I would appreciate if you could please help me with hard coding sharp turns. Specifically, I’m trying to write while loops that start execution when the robot detects a sharp turn, and terminate as soon as the robot gets back on the line. My code always results in an overshoot before the loop is terminated. I’m using the error value as a condition for the loop.



Can you post a snippet of the code you are using that handles sharp turns, along with a video that shows your robot executing that code? (It would also help to know the base speed of your robot going into the turn.)



Hello, Jon.

Apologies for the delay; I had a competition yesterday.

I’ve extended out the sensors in front of the robot. The line following performance, specially at the right angular turns, has become much better.

However, I observed that line following with just PD control was better than line following with PD + hard coding turns. Please note that I tested with the same KP and KD constants.

I’m using all 8 sensors of the QTR-8RC. Therefore, the robot is centered over sensors 4 & 5. But to decrease execution time, the control structure only uses the states of sensor 4 and each extreme sensor.

The code which is part of the loop of my Arduino code is as follows:

if(sensorVals[3] > 500 && sensorVals[7] > 500){
else if(sensorVals[3] > 500 && sensorVals[0] > 500){
// follow the line using PD control

The codes for the functions ‘turnLeft()’ and ‘turnRight()’ are the following:

void turnLeft(){
  while(error > 1000 || error < -1000){
  error = ((int) qtr.readLine(sensorVals)) - 3500;
void turnRight(){
  while(error > 1000 || error < -1000){
  error = ((int) qtr.readLine(sensorVals)) - 3500;

BASE_SPEED is the minimum speed for both motors during line following (presently, around 400 RPM).

I’m attaching two videos showing the performance of the robot without and with the while loops. It did deviate once during the only PD control test, but the overall performance was very good. It oscillated a lot during the PD + hard coded turns test, and overshot occasionally (I wasn’t able to film that since it was very random).

I would appreciate if you could suggest a better way to code the loops, if any. I do suspect that an additional control structure at the end of the loop changes loop time, but does that mean that I’ll have to re-tune the constants every time?


https://forum.pololu.com/uploads/default/original/2X/a/afc5c4eef727af9d5efac3e4e446343aa966a72a.mp4 https://forum.pololu.com/uploads/default/original/2X/8/8f1e406ae685ec006562ac88f2653a0140c3d60f.mp4


Are you sure the P and D coefficients are tuned the same in those two tests? If they are, you might be triggering your turnLeft() and turnRight() functions during the smooth portions of the line. Ideally, they would only be triggered during the sharp turns, which shouldn’t affect the performance during the other parts of the course. You might try putting in some kind of indicator (like an LED or buzzer) when the turn functions are triggered to see if they are working correctly.

As far as the turning functions, since your line sensors are out in front of your drive wheels and the robot is essentially doing a zero point turn, you could try going straight for some small amount of time before going into your loop to get your turning point closer to the sharp corner on the course before turning.



Hello, Brandon.

Apologies for the delayed reply!

Thank you very much for your suggestions.

I’ll try them out and get back to you.