I need to program PID control for two motors. But I got a problem, for function motor] in RobotC, someone told me that the number put after is in units of feet/s. Is that true? If that is not true, how do we convert the power of a standard 393 motor to degree/s or rpm(for example, if I write motor[port5] = 90, how do I know how fast the motor should turn ideally?) Thanks
I got this from the vex store website. However, the ideal speed is prob not too useful. You should try to use integrated encoders to measure the speed your motors turn at.
Using the internal PID or you own algorithm?
My own algorithm. My problem is when I try to calculate the error value using ideal speed minus actually speed which is measured by optical shaft encoder therefore in degrees/s, I do not know what is ideal motor speed. In other words, I initially use number I put in motor] as ideal speed, but later I found out it won’t work because it is power level output to a motor but not actually speed of motor. What I am confused about is if I put motor] = 90 in code for a 393 motor, how fast it will turn ideally?
i believe you are looking for the wrong solution to the problem, im assuming what you want is a standby motor speed (im taking a wild guess and also assuming your own algorithm is simply error*kP + a idle speed constant) the better solution to the problem is using PI, where I is what is dynamically adjusting the idle speed, you could also use TBH which a lot of people are talking about lately
it is the best solution because there is no “ideal speed” of a specific motor power, the motor power you supply is simply what percentage of the time the motor is turned on, you can easialy measure the “ideal” free spinning speed of a specific motor power but in the real world you have to deal with friction and changes in battery voltage
What you mean by PI?
I believe he is referring to part of a PID loop which can be used to control velocity. To further clarify, PID stands for:
P - Proportional
I - Integral
D - Derivative
@PixelToast thought that you were using only a proportional controller and recommended that you look into making your proportional controller into a proportional-integral controller. (Which you should probably do.)
OK, I got your point. But I am still confused – without knowing the desired speed, how could I calculate the error value? (I know what PID stands for and I do use PI in my algorithm) Like in my code, the error is in degree/s or I can convert it to rom. But in the end, I need to use motor] function to adjust motor speed – how is errorKi + errorKp be the power level of motor?
Part of my code:
errorL = 5714 - vL; // vL and vR are calculated by optical shaft encoder //use degree pass in 1/20 s / (1/20)s errorR = 5714 - vR; propertionL = errorL*kp; propertionR = errorR*kp; integralL = errorL*ki; integralR = errorR*ki; motor[port5] = currentL; motor[port6] = currentR; waitInMilliseconds(20);
Well…that isn’t quite how Integral works, but you’re almost there.
I recommend taking a look at this PID Guide:
Basically, you have the right idea for calculating the error for your P controller. You’re going to have to work out on your own what your ideal target value is.
However, in order for the integral to work, you’ll need to use this piece of code:
integral = integral + lastError; lastError = error;
The guide explains much better than I do, but the Integral is basically the running sum of all your past errors. This helps the program to accelerate towards the target value more gently than only a proportional controller. In your final output equation, you’ll still want to multiply your integral value by a constant. Like so:
speed = kp * error + ki * integral;
Then you’ll output the final “speed” variable to your motors with the motor] function:
motor[port1] = speed;
I do recommend reading over the ** *entire * ** PID guide I linked. It explains the entire PID function very well and covers the Derivative function that I haven’t covered in this post. Remember to spend some time with your robot and debugger to tune your PI controller constants. Start low and increase in small increments.(By low, I mean like really low. Like 0.01.)
Hope this helps! Eat your sandwich.
Thanks a lot. But I still have one question though – if we only use P controller and we set motor]=error*Kp, when the error gets smaller, won’t motor slow down so it won’t be at our desired speed value?
That is what the I value will accomplish. The P in this case is just to make sure there is no lag when you accelerate your motors and to help shove energy into the system quickly.
With only P controller, I got a velocity graph like in the attach file – is this the way graph should look like with only P or I should adjust my Kp?
So that graph looks like a P controller if you said
motor] += kp*error;
This is the equivalent of an entirely I based velocity control loop.