# How to check for a sharp angle with a line follower?

I have the mBot robot and I want to program it to follow the line. So far it can pass any kind of line that is >90°.

I want it to be able to pass 90°-ish angles as well. Like this one:

The problem is that my mBot robot has only 2 line following sensors (they are 5 mm apart and the line is 2 cm wide) so I can't use just the sensors.

Most of the times it just goes to the line and when it's supposed to turn it just misses the line (goes on the white) and goes back to get back on track. Once it's back on the black line it once again tries to go forward but goes on the white instead of taking a turn. This happens endlessly.

Sometimes it passes the angle by going back and forth and accidentally turning, but that's not even a workaround, let alone a solution.

Here's a test course of the first round of the competition.

My robot can pass this without a problem, but it gets stuck on this (poorly edited, sorry) course:

It can't pass the 20 block if the robot enters it from a 15 or 20 block (so basically it gets stuck if it's coming from an angle and hits a 90 degree turn).

The sensor value could be read as either 0, 1, 2 or 3 depending on what the robot currently sees:

0 - on the line
1 - on the right of the line
2 - on the left of the line
3 - not on the line

Pseudo code of my current program:

loop forever:
if (on the right of the line):
turn_left()
if (on the left of the line):
turn_right()
if (on the line):
go_forward()
if (not on the line):
go_backwards()


So how would I go about taking such sharp turns?

• Its hard to tell from the images are the two sensors mounted to the left and right of a centre line or are they mounted one forward of the other? – Code Gorilla Apr 29 '16 at 12:23
• Great edit! Is it true that your robot can pass the tile 20 once, but not twice in a row? – Bending Unit 22 May 4 '16 at 21:07
• @BendingUnit22 Ah, forgot to mention it (now edited). It can't pass the 20 block twice in a row, but the problem is that it can only pass the 20 block if the robot is entering it from a relatively straight line (5 or 10). It gets stuck if it enters from an angle (15 or 20). – Ciprum May 4 '16 at 21:24
• @Janekmuric - Great edit, full of detail. I can now see exactly what the problem is, unfortunately I still can't fix it :( – Code Gorilla May 5 '16 at 10:21
• @Personia You should ask a new question! Just make sure to follow the question asking guidelines. – Ciprum May 23 '17 at 21:13

It can't pass the 20 block if the robot enters it from a 15 or 20 block (so basically it gets stuck if it's coming from an angle and hits a 90 degree turn).

Somehow coming from an angled line makes it more likely that your robot moves orthogonal to the 90°-ish turn, so that it gets stuck in the back-and-forth loop. Maybe if it moved very slowly backwards it could detect the moment when only one sensor goes on, which would lead to a turn. But it's a competition after all, so let's not move backwards, especially not very slowly.

I'm not sure if the image of the different sensor values is accurate in terms of scale. It looks like the line is not much thicker than the two sensors are apart. Now imagine the edge case that both distances were the same: the sensors are as far apart as the line is thick. In this case, the robot can only really move in the exact direction of the line. This is very bad for a 90°-ish turn for the reason mentioned above. The ratio between sensor distance and line thickness seems to play a role in how the robot behaves. You cannot change anything about the thickness of the line or the distance of the sensors, but I think it's important to think about what impact those values have or at least could have.

What you can change though is what you consider to be the line. You can follow a line by following its edge, too. The code could look like this:

loop forever:
if (on the right of the line):
turn_left()
if (on the left of the line):
go_forward()
if (on the line):
turn_left()
if (not on the line):
turn_right()


As the edge is only a line, the behaviour depends more or less only on the distance of the sensors, not the ratio between the distance of the sensors and the thickness of the line. I'd give it a go and see how the behaviour changes.

A ratio that you can change more continuously is that of the velocities. How many degrees is turn_left() and how many millimetres is go_forward()? Playing around with those values will lead to different, possibly more preferable behaviour of the robot.

theory interlude

In a nutshell, you want to control a system with two inputs: angular and radial velocity. Setting either one will influence the other. In your case, the radial velocity control loop freaked out and became unstable: back-and-forth motion forever. The important thing is that the system should have reacted with a large increase in angular velocity (to do the hard 90°-ish turn), but instead the radial velocity went mad.

This is a sign that the interaction between the two is not well controlled and requires further investigation.

Changing the ratio between both velocities essentially modifies the gains of the controllers. Lowering both velocities means more sensor readings per travelled distance and thus a higher sampling rate, which in general leads to more stable systems.

tl,dr;

Things to try

1. Change both angular and radial velocities, but keep their ratio the same and see if that changes anything
2. Change the ratio between the two and see if that changes the behaviour of the robot. Especially on different types of tiles. What ratio works best on straight tiles, what works better on curvy tiles. Is there some setting that works for both?
3. Try both 1. and 2. for the on-the-line approach and the on-the-edge-of-the-line approach and see if you get to different results.
• This could actually work. I don't have my robot at home right now, but I will test it in school. Now that the first round of the competition is over, I can tell that many people went for the speed, rather than precision or efficiency. Their robot would just go crazy fast and they would hope that is passes, and since there are 400+ participants, statistically, at least one of them will be in the top three. The only way to beat their luck is to make a robot that can pass the entire stage and get all the points regardless of the time. (I got 270/275 points and I'm not in the top 3 :p) – Ciprum May 5 '16 at 8:17
• My approach was to detect if it's stuck by adding one to a variable every time it goes back and forth. Once the limit is exceeded it takes a sharp turn. The problem is that when it gets stuck, sometimes it goes back and forth and it works, but sometimes it goes in random directions including left and right so it's impossible to detect if it's stuck. Another interesting idea is that the robot enters a block, and using some algorithm determines on what kind of a block is it (there are 5 kinds of blocks), and just moves with a pre-programmed set of rules to pass the block. – Ciprum May 5 '16 at 8:25
• I could finally try your answer and I am very surprised by the results. This is a lot better that my approach! – Ciprum May 24 '16 at 12:07

Sorry I have no experience of line following robots, I use ultrasonic sensors, so this answer may be a bit naïve and there allsorts of reasons why you can't do this.

Your bot travels forwards and realises it has lost the line. Assuming that the distance travelled is not "very far", less than 1/2 the length of the bot, you should be able to do a complete 360 and find two lines. One of those lines will be at about 180 degrees from where you started turning (this should be measurable by the number of turns of the motor, if its a stepper), this is not the line you are looking for, you need to follow the other one.

Does that help?

• The idea appears to be good, but when you take a better look, the robot "loses" the line every time it has to turn. When it "loses" the line it just goes backwards to find it, so making a 360 turn would take up a lot of time. Also if your robot tries to take a 360 degree turn in the direction opposite of the line, it would go backwads. Also I am allowed to use ultrasonic sensors (in a competition) but they would in this case be useless because everything is on a 2D platform. – Ciprum Apr 30 '16 at 7:57
• Can the robot turn on the spot? If so change the program, so when it looses then line rather than go backwards it does a 360 spin and locates the two possible lines. This may take a while, but it will take less time than loosing the path and not being able to complete the course. – Code Gorilla May 2 '16 at 20:16
• would moving the sensors further apart work? If they were 20mm apart then only one would ever read the line. When neither sensor was reading a line it could do a little wiggle and find the line again. If both sensor read the line then the line is making a turn and you need to turn in the direction of the sensor that has just started seeing the line. – Code Gorilla May 2 '16 at 20:24
• It is not possible to move the senors as they are soldered. And doing a 360 spin would not only be extremely slow, but it may sometimes detect 3 or 4 lines and only 1 is the correct way. Anyways the first round of the competition finished today and my robot passed. (There will be more rounds so this is still an open question. – Ciprum May 3 '16 at 18:55
• @Janekmuric - Congratulations, good luck with the other rounds. – Code Gorilla May 4 '16 at 12:31

I have a similar idea like @Bending Unit 22, which is not to follow the line but its edge instead. So you detect the line only with one sensor (let's say only with the left one (blue dot)).

• If the you both sensor indicates line then your robot should turn right until the right sensor (green dot) indicates white surface. This is the event circled with green in the image below.

• If both sensor are lost sight of the line, then the robot should turn left until the left sensor is back on the track. This is the event circled with blue in the image below.

Basically, there could be two states of line-following:

1. Default state when the robot has one sensor on the line while the other is off the line.
2. Turning state if one of the events occur. The robot could stop and turn until the the left sensor gets back on line or till the right leaves the line. Since we can assume that the direction is known and the robot is not moving, we could turn on maximum speed (or at least you can try and see how it works). You can test it while the robot is in motion of course.

Previously, when your robot lost the line there was no information about the direction, so it could only go backwards hoping to find the line.

It is only a theory but I think it's worth a try or just to move forward your project.

You have mentioned that your cannot use more sensors but are you allowed to modify on the current hardware?

I have checked that the sensors have digital output which means [line] - [no line], not much information. But if you could connect the IR-sensors output voltage to some analog pins, this way you could obtain higher resolution.

To explain further this part:

A basic line detecting sensor is a IR photo-diode and photo-transistor pair. Like the one on your robot only it has a little bit more on the module, a newer version from Makeblock's page:

(Module on left, actual sensor on the right) Your robot has a previous version, which probably uses an other sensor. This one in the image is a TCRT500 from Vishay.

If we have a look at the schematic level:

The output is at the red circle. Now, if there is sufficient reflected IR light the transistor will conduct and the output will be pulled down to GND. If there is not enough reflected IR light, the transistor won't conduct and the output is pulled up through the resistor to supply voltage. But it is not working like a switch, so the out can be anything between 0 - V_Supply. For a given spectral distribution (IR in our case), the photo-current is linearly proportional to the illuminance . So as I said the output voltage can vary between 0 V and VCC (5 V in common).

Your sensor module works the same way, only it has a comparator on it which makes digital output of the analog signal.

When the IR LED illuminates the edge of the line, maybe half of the light is reflected or more, so the transistor can conduct slightly. This means that the output won't be pulled down near 0 V, it will be, let's say around 2 V. But not 0 V (which is the complete white surface), and this is the important because this means that it partly detects something (the line).

Now back to the comparator, it compares the output voltage of the photo-transistor to a reference voltage. It checks if the signal is above or below the reference and sets its output to LOW or HIGH accordingly.

If this the reference is 2.5 V then your module will say that it detects line when the output voltage is above 2.5V, so that information with the 2 V signal will be considered as a white surface where as we saw the edge, thus we lose resolution.

Now, if you could read this whole analog range with an ADC your resolution would be higher and maybe a more delicate controlling algorithm could be achieved.

• I will probably test your and @Bending Unit 22's ideas tomorrow. I have 2 Computer Science classes so I will probably have enough time. +1 – Ciprum May 5 '16 at 18:19
• I guess this would work better if the sensor diodes were more apart (although it could be the exact opposite). Anyways I'm not sure what you mean by connect IR-LEDs output voltage to some analog pins. The sensors are digital (as far as I know), but even if they were analog I don't think it would make a difference since one line sensor diode could be in only two states anyways (either on the line or not). – Ciprum May 5 '16 at 18:26
• Yes, maybe the sensors are too close. Also I have edited my question and added some more details. – Bence Kaulics May 5 '16 at 19:30
• Thanks for the explanation, very good edit. I think this would be more useful if a line would be a gradient, but I'll try to do something with it as the robot would sometimes fail to detect the line in weird light conditions. – Ciprum May 6 '16 at 5:38
• Usually, there is a potentiometer at the reference pin of the comparator, to change the reference voltage. So maybe you can tune/calibrate your sensors in those wierd light conditions. – Bence Kaulics May 6 '16 at 8:16

The problem seems to be that your robot functions by moving its sensors perpendicular to the line; when the line becomes perpendicular to itself, the robot loses the assumption that lateral movement will bring the line back into the center of the sensors.

The only way to fix is this is to change the sensor configuration (adding more if necessary) to break this ambiguity.

• I'm in a competition and adding more sensors is not allowed :( – Ciprum Apr 30 '16 at 7:53
• In that case you would need to add a scripted behavior (similar to the behavior you mentioned that makes the robot back up when it loses the line, which I presume is software-based) that attempts to resolve the ambiguity. Trying to cut the corner by 45 degrees and seeing if you wind up on a line is one way to do this. – Ian Apr 30 '16 at 13:49

In my configuration I have a PID algorithm for the main following mechanism. Then I have a separate routine to move into if The car ever goes off the line and all 6 sensors are sensing white. This tells the car to turn the direction that it saw the line last. This seems to work up to 45 degree turns for me.

It seems that you can have 4 possible readings (w,w), (w,b), (b,w) and (b,b). So, the program what to decide what to do in each situation. To help figure out the next action, the past history can also be used. So, it is up to you to decide how much history is useful, or practical. I suggest some kind of state diagram, but use whatever you are already familiar with.

Now, in your pseudocode, how much do you turn left and right? How far are you moving between each reading? Can you measure how far each wheel has gone?Is it possible to go backwards until line is found? How straight are your moves forward and backward? These questions are just some of the considerations for you to think about as you refine your strategy.

The bottom line is that the dual sensor does not provide enough data from a single reading, to, for example, identify whether you've just run over the edge of a straight line, the line has bent, or (if it has bent) by how much!

The whole point of a line robot competition is to get each builder to design (and test) their strategy.