RobotC and PID

Can anyone recommend some good resources for learning PID in robot C. I understand the concept of it, but I have no idea how to do it. Last year, I didn’t use PID or shaft encoders on my robot, and if definitely made driving and autonomous more difficult. This year, I hope to change that because of how precise robots need to be when picking up cones.

Also, what is the difference between using PID to correct motors vs using a shaft encoder (if its possible)?

I think you are under a misconception as to what PID does. PID is a control loop for reducing distance from desired location(error). It can only do this with the ability to sense its current location. A shaft encoder is an example of a sensor you can use, but a gyro, potentiometer, ultrasonic range finder all also are examples.

tldr; PID takes in position estimates and computes motor outputs

error = distance from where I am from where i want to be, goalLocation - currentLocation

This is my favorite PID guide
http://georgegillard.com/documents/2-introduction-to-pid-controllers

Thanks!!

In the guide referenced by tabor, they confuse speed and power. All RobotC does is allow you to change power to the motor, they call the variable “speed” which is incorrect, so don’t let that confuse you.

Yes, this is correct, although in the 5-6 years since I originally created this document I’ve never had anyone make this comment to me before. I know that plenty of new programmers in VEX use “speed” as a variable to represent the power for a motor, so I think it hasn’t confused too many people (certainly I hope not). Obviously this document was never intended to be academic, it’s very much only an introduction for students.

As always, I’ll update the document when I have a few minutes. Right now, I’m in the middle of my university exams so it doesn’t sit as a high priority, but I’ll do it when I find the time. Of course if people see errors/spot things that might confuse people, feel free to send me a PM and I’ll do my best :slight_smile: I’ve had heaps of comments supportive of the document which has been lovely, but obviously I want this to be the best it can be (while not roaming outside the intended scope) so any suggestions for improvement are always welcome.

Yep, i’ve seen people use “speed” a lot, never said much. The only reason I mention it now is with the smart motors “speed” will become a real command to motors if they are anything like IQ. So, just time to clarify a bit.

If you really want to get super picky about it, you really aren’t controlling speed or power directly. The PID control loop in the VEX IQ motors (and, similarly in the V5 motors when they are released) actually controls duty cycle so, in essence, we are really only controlling voltage.

Again, the end results are both a specific motor speed and motor power, but the independent variable is really PWM duty cycle, which is directly controlling motor input voltage.

Agreed, it is technically duty cycle which is what we have our kids name the variables. My point is to get them to separate the incorrect thought of calculating speed in the above example and placing that in the motor array expecting a certain speed to come from the motor. Because, speed will actually mean speed in the new V5. Of course, the root of this issue is most likely RobotC and it’s help file since it defines the motor command presently as :

“This command is used to set the speed (-127 to 127) for a motor.”

Which isn’t the case and will be even more confusing if it stays that way when the V5 commands really do mean speed.

In IQ, which I assume (big assumption) will be similar to V5, the motor speed is a % of max/min, whatever that is?

In the VEX IQ motor, there is a lot going on. We have both speed control and position control. In position control we are actually controlling speed while tracking to a position. We do this with motion planning before entering the PID control loop.

Basically, at each motor loop (independent of the main loop in the brain) we tell the motor where it should be (in encoder ticks) and how fast it should be going (in motor ticks per cycle). We then pass both the velocity error and the position error into the control loop (since the derivative of position error is velocity error and the integral of velocity error is position error).

Doing this allowed for us to have very large Kp, Kd, and Ki gains since the error is so small as it is looking at the error every loop (approx 16ms) instead of the total error for the end point.

For pure speed control without position control it is a traditional PIDF with the feedforward gain doing most of the work.

In the V5 motor we are going to give the user the ability to control PIDF and the motion profile parameters, but will have 2 default sets of gains: one for non gravity loaded applications and one for gravity loaded applications.

I expect we may also have different gain sets for the different gear ratio motors (yes, there will be three output speed versions of the motor with a MUCH more user friendly way to swap gear ratios).

One last thing on the VEX IQ motor. While we give the user the ability to describe the speed in RPM and %, the actual limits and control are all in encoder counts per cycle. All of the math is integer math on the motor processor so the brain does the conversion from % or RPM to encoder counts per cycle and the motor controls the raw integer data.;

Great info, I’d like to ask another IQ question since they seem relevant. Our kids use Graphical C since they are 9-11 yo, but I’ve looked through the regular IQ RobotC commands and it seems all the speed commands are -100% to 100% of min/max, but I see no definition of what that speed actually is? We can’t request a move to target with a known speed in RPM, just %. Also, is 95% speed on one motor the same as 95% on another (I assume so for IQ)?

One of the issues the kids run into each year is acceleration. It seems you may have this accounted for in V5 with motion profiles. However, presently the kids can request a move to a target value with a max speed, but not with a profile. So, for instance, if they want to move 1400 counts as fast as possible they must use the max speed in the command which may jerk or cause the robot to veer at first. They have worked on this by having a loop that increments the max speed of the set motor target command every 20ms to get up to full speed over a 0.5 sec period, but wouldn’t this reset at least the accumulated integral information each time the command is sent?

Is there another method to allow a gradual (.25 - 1sec) access/decel to target on the IQ for the kids without asking them to write the low level stuff themselves?

I’ll have to ask the ROBOTC folks if they are using the low level APIs we gave them for the motors but the motion profile for IQ is in the motor firmware if they are using the profile position command. If I remember correctly the accel time is around 300 ms.

As far as only percent in ROBOTC, that is a decision they made. Th motor has a max speed that we control in the motor of 120 rpm. 100% is 120 rpm no matter what.

Currently, in IQ we do not give the user access to accel time.

Excellent, great info, thank you.

Is there a decel built into these discussions(profiles) as well, V5 and IQ?

Yes. It is a symmetric accel and decel cycle. Here is a link to a post several years ago to explain it to the FRC community. https://www.chiefdelphi.com/forums/showpost.php?p=1204121&postcount=20

If you also read the thread from my post, there is a ton of additional information about the motion profiling.

In V5 we plan on giving users control of almost everything related to motion planning and PIDF, but will have a safety net to return to the default values that we tuned at design time.

Additionally, we will have pure PWM open loop mode in case people want to write their own control algorithms and motion planning. In either case, the max voltage sent to the motor will be limited in a similar way we do in VEX IQ.

We have found that using a battery larger than we need and reducing it’s max voltage in SW and using a motor capable of faster free speed and reducing its max in SW creates a better user experience in autonomous consistency. We have taken what we learned in VEX IQ and applied it to V5.

Any guess on an date when we will be getting some more official information?

Great, thanks. I would like to use the smart motor side to teach the kids about control coefficients, but then move to what we have now, which is our own PID code. This is very helpful, I was concerned they wouldn’t have this capability.

Will the V5 motors be waterproof?

What will the motor controller update rate be on the new V5 stuff. The current 50Hz* ish timing is way to slow for real control loops, I was hoping for something like 1kHz.

I would imagine the built in PID control rate and the manual control rate are different but would expect them both to be a big step up from the current system.

*15 ms really is 66 Hz but I rounded

I’m obviously new to programming, but does a faster refresh rate mean that the programming and pid can be more precise, because there is more data?

No, it can actually mean the opposite sometimes. Generally, you can update the P for for a PID loop as fast as you want. However, the D (derivative) needs information to work with and this information comes from taking the difference between the sensor values between PID updates. Normally this data is coming from a sensor, or encoder in this case. So, for worse case operation, if you run too fast you will only ever have values of 0 or 1 (or very small) so you can do one of two things, decrease the PID update speed or increase the resolution of your sensor (encoder). It’s all a systems level design balance.

Just for some comparison, the VEX Cortex updates its analog values at 16 kHz. This means currently control loops with a pot run ever 250 times the pot values updates, which is ridiculous. So the current sensors and current ADC can already handle a real 1 control loop at 1kHz.

Also VEX seems to think 1 kHz is a reasonable update rate because supposedly that’s what the 2 wire ports on the cortex have.

(2) 2-wire Motor Outputs
Usage: For 2-wire VEX motors
Type: H-Bridge
Refresh: Every 1 mSec