I am currently building a line-following mobile robot. I've done all my image processing work in C#, and now I am in the control phase. I am looking for a PD controller program written in C# to start with. I've searched a lot but without success. My robot is not an Arduino based, it has a motherboard with a Core i3 CPU, and I am using a Camera not an LDR sensor.

  • $\begingroup$ At the risk of sounding pedantic, did you try looking for a "PD controller algorithm"? $\endgroup$ – Ian Jul 19 '14 at 17:44

Your problem is not the P[I]D controller, but extracting control parameters from your system. A PID controller by itself is something like this (assuming a periodic control task):

/* 1. get current position */
cur_position = get_current_position();

/* 2. calculate error */
err = goal_position - cur_position;

/* 3. calculate the output */
proportional = Kp * err;
derivative = Kd * (err - last_err);
integral = Ki * (last_sum + err);
output = proportional + derivative + integral;

/* 4. keep history */
last_sum += err;
last_err = err;

/* 5. apply control output */

where last_sum and last_err are persistent (they are defined outside the scope of the control loop, e.g. they are global or are a class member or on stack of caller who's calling the control task in a loop). In a PD controller, Ki is zero.

Now steps 2 through 4 are very simple and probably that code runs on any C-derived language without modification. Needless to say, the control parameters Kp, Kd and Ki need to be tuned to your application (which is a problem of its own, but in this case you can just fiddle with it to get a good idea (hint: Ki is really small)). The problem is thus steps 1 and 5. Step 1 depends on your input and step 5 depends on your output.

In step 1, you need to get an image from your camera, process it and understand how far off you are from the line. That would be your position. Note that you may also like to extract the direction of the line, in which case steps 2 through 4 could be done on 2D data! But PID rather sucks anyway and a line-following robot is not a serious application either, so you may not want to bother with that.

Let's take an example. Imagine you see the following image on your camera:

enter image description here

One simple way to calculate your position with respect to the line would be to take the distance d from the center of the image to the line that needs to be followed (or to its tangent if its curved):

enter image description here

In this case, your cur_position would be d (which would be negative if it's on the other side of the line) and your goal_position would be 0.

This is a very simplistic solution and likely the robot may move in a weird way, since it doesn't take direction into account. If you think of the robot position as the pair of data containing distance from line and direction of line (its angle with respect to a vertical line), your goal would also be to make that (0, 0). This still doesn't take non-smooth lines in consideration.

That done, step 5 remains. Step 5 takes the output of the controller and makes the robot follow it. This of course depends on how the robot acts. For example, if your robot has two speed-controllable wheels in the front and a passive omnidirectional one in the back for balance, then you need to tell the motors turning the wheels to maintain what speed.

For example, if the output parameter is positive, it may mean that you are on the right side of the line. What you need would be then to turn left. To do that, you can set a higher speed for the right wheel and a lower speed. The higher the output, the higher the ratio of speed between the two wheels.

  • $\begingroup$ thanks for clarifying the approach, but i have a question, what are the techniques to obtain the center of the black line ? $\endgroup$ – Bouzenzel Jul 17 '14 at 18:08
  • $\begingroup$ I thought "you've done your image processing" already? I'm not an expert in image processing. Feel free to ask another question specifically on that! $\endgroup$ – Shahbaz Jul 17 '14 at 22:33
  • $\begingroup$ Yes i've done the most part but i still sicked with this question, i will post it as a separate one ... $\endgroup$ – Bouzenzel Jul 18 '14 at 18:15

You may take a look at this library running on Arduino in 'standard' C. The author has a line by line explanation on his blog. Hence, easy to change to other system as needed. See the blog for the autotune utility too.

PID http://playground.arduino.cc/Code/PIDLibrary

Full description by author http://brettbeauregard.com/blog/2011/04/improving-the-beginners-pid-introduction/

By the way, you need analogue reading (no just on and off) on the line. That is, analogue of 512 out of 1023 menas the sensor is at 50% edge of the line.

Advanced use can detect the analogue signal from the sensor diode, giving an continuous reading on the "percentage of hitting the white/black line". (says, n% of voltage is, as tested by experiment, is 60% on line and 40% outside the line). This analogue input can use PID control to provide smooth and continuous (no just on and off) and provide best optimal drive speed as in the enclosed video.

This is 3PI, showing the analogue reading from 5 sensors, note the initial spinning for the robot to calibrate through n% of crossing the line and analogue reading from sensors. If 2 sensors reading 50%, the line is at the middle between the 2 sensors. https://www.youtube.com/watch?v=ylyRi1Qlbl0&feature=player_embedded

See page 18 pf 3pi manual http://www.pololu.com/docs/pdf/0J21/3pi.pdf for a very clever use of IO pins.

The sensor can be read WITHOUT ADC converter. This method is widely used in mass produced consumer electronic, as i worked for factory, where high resolution (16 bits) is needed and the reading speed is ms range or slower (1 to 10ms or slower). MCU only has 10 to 12 bits high speed ADC and this circuit give higher resolution.

Fast example

Product https://www.youtube.com/watch?v=6ENIiMv7LvM

Hope this helps

  • $\begingroup$ Thanks for the help i appreciate it, but i missed to clarify that am not working in an Arduino based robot, but am working on a computer motherboard based robot, with Core I3 CPU, plus am not using a LDR sensors but am using a camera ... $\endgroup$ – Bouzenzel Jul 16 '14 at 17:34
  • $\begingroup$ Thanks for clarification. You may consider using webcam, within budget, choose one with highest frame rate at says, 640 X 480 resolution, no need for too high res as slower frame rate. Consider software library like OpenCV. My posting 2 weeks ago on another topic has opencv learning information, etc. The sensing part is functionally 'same' as above and gives an analogue percentage value relative to line position. The PID part is same for PC or Arduino as in C language. $\endgroup$ – EEd Jul 17 '14 at 6:18
  • $\begingroup$ By the way, for information, LDR (CdS) is a bit slow (ms to tens of ms). Photo diode is popular choice as fast, wide variety of well controller beam acceptance angle (with/without build-in lens) and widely available due to mass manufactured for appliance remote control, etc. For information, camera is good as easily start and widely available. For best performance (may be phase 2 after camera), consider TSL1401 which give 10,000 update per second, but, needs IC chip level hardware interfacing. There are many open source web example using Arduino and similar MCU for those need extreme speed $\endgroup$ – EEd Jul 17 '14 at 7:58
  • $\begingroup$ thanks for the infos, in fact i am using a Full HD Logitech camera with 30 FPS with pan and tilt capabilities, am using EmguCV rather than OpenCV, but they are the same one with C++ the other with C# ... $\endgroup$ – Bouzenzel Jul 17 '14 at 18:17

Not the answer you're looking for? Browse other questions tagged or ask your own question.