Im working on a two wheeled robot and im trying to implement a pid control for the motors. But i have a problem, all sources i found online said i have to calculate the error with my encoder values. For the robot im programming i got 2 functions. One that gets the absolute encoder values and one that gets the speed in ticks/s. The sources i found didnt spezify if i use absolute encoder values or the speed encoder values. I tried both already but it didnt work out too well, so i would like to know if some already have some experience with a motor pid control using the encoders.


e_func_r = v_des-v_act_r;

r_mot_r = r_old_r
    + (1/K_P)*(e_func_r-e_old_r) 
    + K_I*(e_func_r+e_old_r)/2
    + K_D*(e_func_r-2*e_old_r+e_old2_r);

if(r_mot_r >= 100)
    r_mot_r = 100;
if(r_mot_r <= -100)
    r_mot_r = 100;

r_old_r  = r_mot_r;
e_old2_r = e_old_r;
e_old_r  = e_func_r;

This is my pid code i wanted to use

  • $\begingroup$ HI Qilos and welcome, you need to provide more info to get some help. Do you want to control the position or the speed of the wheel? What is the error you see that tells you that it doesn't "work out to well"? What are the coefficients you used in your PID, maybe they are poorly tunned ? $\endgroup$ – N. Staub Dec 14 '18 at 13:54

In your question you are talking about two different kind of controls, one is controlling the position of the encoder (absolute value), and the second one is control on the velocity ticks/s. I don't know what exactly you want to do and what kind of mistakes you get, it would be better to upload your PID code in order to see it. The controller that I made was for velocity but I was actually doing it for the amount of current that I was sending to the motors (PWM).

More specific I had a function that calculated the angular velocity of the motor from the PWM that I sent and on that value I controlled the robot.

  • $\begingroup$ I added my code for the PID control. How did you calculate the angular velocity? $\endgroup$ – Qilos Dec 14 '18 at 10:04
  • $\begingroup$ You have to provide some information about the values that you send, receive. Are the v_des / v_act_r measured in the same measurement unit? I mean are both in rpms / ticks/s etc. $\endgroup$ – nionios Dec 14 '18 at 11:07

The "PID code" you have is not a PID controller. At all. You should have error terms defined as:

error = setpoint - feedback; // Setpoint and feedback should be in the same units.
deltaTime = TimeSinceLastCall(); // Platform/language specific. 

proportionalError = error;
integralError = integralError + error*deltaTime;
derivativeError = (error-prevError)/deltaTime;
prevError = error;

controlSignal = (kP*proportionalError) + (kI*integralError) + (kD*derivativeError);

That's a PID controller. I'm not going to go through the code that you posted point-by-point because it's very wrong, to the point that I can't understand how you arrived at it so I don't really have a rebuttal or explanation to try to help point out where you went wrong. Use the error terms as I provided above. Also, your motor control signal is always accumulating. It shouldn't do this, it should instead just be the output of the PID controller. You have:

r_mot_r = r_old_r + <controller output>

when it should just be

r_mot_r = <controller output>

as in:

r_mot_r = controlSignal

where controlSignal is the term I defined in the block of code at the top of this post.

I'll point out that two-wheeled vehicles are non-holonomic platforms, which means you can't just position the actuators (wheels) independently and arrive at a given position and orientation. Going forward 10 blocks and then turning left is not the same as turning left and then going forward 10 blocks! You are going to find that your robot will never go straight without having some kind of absolute position feedback. Wheel encoder feedback is okay for (very) short term, but you will experience drift.

  • $\begingroup$ The error value in the example can only be a numerical value, for example “4”. The amount of information which can be stored in numbers is low. There is not enough entropy in it. As a result, the pid controller on top of such input parameter won't be able to bring the system into a stable state. It's similar to drive a car without observing the street. $\endgroup$ – Manuel Rodriguez Jan 2 at 7:54
  • $\begingroup$ @ManuelRodriguez - What are you going on about?? The error value in the example can only be a numerical value - Yes of course; this is code intended for use in an actual control system. Please post your own answer and show us how you solve the problem without numbers. Also, the statement the pid controller on top of [a numerical] input parameter won't be able to bring the system into a stable state is completely false. If you're going to make statements like that, please cite some facts. $\endgroup$ – Chuck Jan 2 at 14:35
  • $\begingroup$ It seems that we have both the opinion that the error value in the sourcecode needs to be a numerical one. That's a good starting point. This restriction is a result from the posted equation. I think, the transformation from a wheeled robot problem into a mathematical equation wasn't handled optimal here. $\endgroup$ – Manuel Rodriguez Jan 2 at 16:33
  • $\begingroup$ @ManuelRodriguez - Please post the optimal formulation or transformation. $\endgroup$ – Chuck Jan 2 at 16:36
  • $\begingroup$ @Chuck Thanks for your answer but i dont know if you really can call my controller code wrong, i got it from a book about robotics and it worked finally. The response of the controller is quite fast but one motor gets faster to the desired speed than the other why the robot goes straight after approximatly 1 second but before that it has a little curve. How can i eliminate that error between the motors so that the curve disappears? $\endgroup$ – Qilos Jan 8 at 15:31

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

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