Driving Straight for X Distance question (Please Help)

Okay so I am trying to write a function that makes my robot drive perfectly straight for a set distance using two quad encoders in EasyC V4. (one on each side of the drive) I have a Proportional Loop for driving the specified distance and a PID Loop for driving perfectly straight. I cannot test this code right now and I am not sure this code will work. I have provided pictures of the entire function and I am hoping someone could look it over and tell me what I need/should do to adjust it to make it work. (This is the first PID Loop I have ever attempted. I understand the math but I do not understand how to use the output.)

Edit: In the beginning of the code, the absolute value function has been put before the IF statement which makes sure the Max Drive Speed is within the motor’s limit

Please help me with my code.

I can answer any questions you may have or even take new pictures of the code if need be.

Thanks very much!
PID Question 1.pdf (133 KB)
PID Question 2.pdf (124 KB)

So I can at least let you know it won’t work as is. Here are the issues I see, it is always hard with EasyC code to work with the screenshots, would be far easier to open the C source and cut and paste the C code directly, however…

  1. Termination is when both left and right errors are zero, you need some tolerance on this (perhaps 20 counts) or test for going negative or something. You will almost certainly not hit exactly zero error.

So then you create left and right drive by multiplying error by a constant, I assume the constant is a float, so far so good.

Next calculate the differential error.

  1. The Diff_Deriv should be Diff_Error - Prev-Diff_Error

  2. You should probably limit Diff_Integral so it does not get too large.

Next calculate a differential drive signal, Diff_Output, lets say Diff_Output is positive, say 10. When you first try this out set Diff_I and Diff_D to zero, you may not even need them.

  1. You add the differential output to both left and right drive, all this does is increase speed, you need to subtract it from one of them
    right = right + diff_output
    left = left - diff_output

you should probably also limit Diff_Output so some sensible value, perhaps say 32

So there is my first pass comments, hope it helps.

Tomorrow, when I can access the program, I will make the changes stated above and then post my actual code. I fully understand P Loops and I want to further my knowledge about PID so I can create a more accurate and quicker autonomous. Thank you so much for the help. (I may have more questions down the road as I am still learning PID. Another Note, Programming, at my school at least, is all self taught so this is why I come to the forum for help.)

something like this

while( Drive_Straight_Timer < Max_Time && ( Abs( Left_Dist_Error ) > 20 && Abs( Right_Dist_Error ) > 20 ) )

You also need to calculate the left and right errors before starting the while loop, they are undefined the first time through. You may need to aim for a target slightly short of your desired value, there will be some deceleration to deal with. You may also find that a minimum value of drive is needed, the motors won’t turn if you send them small values.

Yes, but one way of tuning a PID loop is to start by optimizing P then add I and D as necessary.

You want one side to turn faster than the other, you could just adjust one side but if both motors are at their maximum speed the only choice would be to slow the other side.

You will get excellent help on the forums, some of the best programmers in the world hang out here :slight_smile: Start testing slowly, get the distance code working first and then work on the differential drive. Be aware that EasyC has the horrible habit of adding large delays when you use the LCD display or print to screen functions, this will affect how your PID works as delta T (which is assumed to be constant with the way your code is written) will be variable as you add and delete debugging statements.

Yes I have noticed that a handful of people on the forum have a far greater knowledge of programming then I do so coming here for help is smart.
The only reason I had/us print to screen functions is for debugging. (the function I forgot to delete was when I was attempting to debug the code myself.)

There is no easy answer to this, there are many physical things that make every PID loop work slightly differently. One of my favorite articles on PID was by Tim Wescott and published a few years back.

http://igor.chudov.com/manuals/Servo-Tuning/PID-without-a-PhD.pdf

Using the print functions is unavoidable with EasyC as there really is no other way of debugging, I’m not saying don’t use them, just be aware that they will add delay to the loop.

Ok, well I am going to make the changes we talked about then try testing my code on a base bot tomorrow. I’ll post the results.