-
Notifications
You must be signed in to change notification settings - Fork 134
PID Tuning
The firmware uses two PID controllers for each axis in an arrangement often called a Cascade Control Loop. The internet is full of articles describing what a PID controller is, Wikipedia - PID Controller, so we will not go into great detail here. Instead, the purpose of this page is to document the functions built into the Maslow that allow you to test different settings for the PID controllers and some general guidance about specific PID tuning on the Maslow.
GroundControl allows the user to tweak three values for each controller so that it is tuned properly for the user's setup. Users of a stock MaslowCNC shouldn't need to tune their PID controllers, the default settings were selected using the stock machine. However, stock users may still want to tune their PID controllers to see if they can get better results than the stock version. If you do get better results, please share them in the forum. Finally, users with different motors or setups will likely benefit from some customization of the settings to their setup.
As mentioned the firmware uses two PID controllers in series for each axis. A positional controller and a velocity controller. The positional controller attempts to move the router to the desired position by outputting a desired movement speed. The velocity controller attempts to achieve the speed demanded by the positional controller by outputting a motor voltage.
Because the velocity controller is last in the stack, you want to tune it first. The B13 command will attempt to move an axis at a requested RPM for 2 seconds while dumping the velocity error to the log.
B13 R<1,0> L<1,0> Z<0,1> S<##> F<##> I<#>
R,L,Z - Select Right, Left, or zAxis using a 1. Only one axis can be enabled. S - The starting RPM +,- F - The finishing RPM +,- I - The number of steps to take between the starting and finishing RPM 1 means only starting, 2 start and finish, and any higher number adds additional steps between the start and finish. Each step will run for 2 seconds.
The log output will contain the something like the following (only much longer):
You can excerpt out the relevant data using the following sed command:
The data can then be pasted into a spreadsheet (I used google sheets) to visualize the error graph like this:
You graphs may look very different.
I would recommend starting with the stock settings and running a test that has steps from 10RPM to -10RPM in 1RPM increments. I would graph this result and then make small changes and repeat this test comparing the graphed results. Because of the Minimum Velocity Resolution discussed below, I don't believe you can get rid of the +-.5RPM oscillations that you see in the graph.
Also because of the Non-Linearity of the motors, also discussed below, you may not be able to get each RPM to average zero error. In my experience, it isn't essential to get an average of zero errors, instead the more important aspect is to have as few oscillations as possible in the velocity output. The positional controller is able to compensate for the non-zero error, but has a harder time compensating for random oscillations.
My belief is that you shouldn't try and chase perfection in the velocity controller. I spent a lot of time on this and it is elusive and maybe unobtainable. Plus, I am not sure that improvements in the velocity controller achieve much in the way of accuracy. It seems like the positional controller is able to compensate for much of the error in velocity just fine.
But, if you have the desire, the following are some of my thoughts on the issue.
The encoders on the Maslow have 8148 steps per revolution and the PID compute process runs every 10 milliseconds (or 100 times per second). This means at 1RPM each computation of the PID expects to see 1.358 steps (8148/6000). As a result, the best velocity resolution you can achieve is between .25 RPM and .5 RPM. This obviously makes hitting the low RPMs accurately very difficult.
To hide this problem the code doesn't even try and turn the motors at extremely low RPMs ~1RPM. So you may see very flat error lines around 0RPM. This decreases the likelihood of integrator windup occurring at low RPMs. But it does mean that the positional controller may settle out not exactly at zero, but in my testing this seems to be less than .1mm, well below our desired error.
The old code used to use a running average of 10 readings as the input to the velocity controller. This caused the controller to react very slowly at low RPMs and often times introduced oscillations. I don't think that averaging is a good idea.
I tried decreasing the frequency at which the controller operates with little success, it didn't seem to harm anything, but I also didn't see any benefits.
Bar did a good job characterizing the motor's velocity response profile, this profile is not constant and changes under tension:
Using a velocity PID controller simplifies this somewhat, but is not a complete solution. In my experience, you can't get all RPM ranges to hover around zero error. The best you can achieve is to get low oscillations. This is largely because using a PID to control a non-linear process is not ideal. To solve this issue, articles and comments online suggest solutions which include Gain Scheduling and Linearizing the Output.
I will caution that both of these solutions add a lot of complexity to the system. Plus, the non-linearity of the response changes based on tension, so it is difficult or impossible to linearize the response without knowledge of the tension on the motors.
Best I can understand, Gain Scheduling is comprised of breaking up the operating range into a series of discrete segments and applying different tuning values to each segment. In our case, we could break up the tunings based on the input RPM, different settings for low RPM and high RPM. I briefly tried this, and was generally unimpressed with the results, plus it clearly adds a layer of complexity.
Alternatively, it sounds like some people attempt to linearize the output. This sounds like it would work well for systems where the non-linearity can be easily quantified. Although, I see a number of mentions that such linearity systems don't have to be perfect they just have to nudge things in the right direction. I also briefly tried this, I applied a formula to the voltage output before it was written to the motor. For example, increasing the voltage at the higher ends. This was inconsistent and had issues dealing with high tension vs low tension situations and it added complexity as well.