# Experimental PID improvement changes

**URL:** <https://klipper.discourse.group/t/experimental-pid-improvement-changes/3604>\
**Category:** Developers\
**Created:** [July 28, 2022, 2:31am UTC](https://klipper.discourse.group/t/experimental-pid-improvement-changes/3604 "2022-07-28T02:31:40Z")\
**Posts on this page:** 13\
**Page:** 4

<div class="post-metadata">

**Author:** ![DanS](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/dans/32/746_2.png) [@DanS](https://klipper.discourse.group/u/DanS)\
**Post date:** [October 3, 2022, 4:46pm UTC](https://klipper.discourse.group/t/experimental-pid-improvement-changes/3604/61 "2022-10-03T16:46:29Z")

</div>

@ReXT3D could you perhaps run a pid tune on your bed and send me the output file?

I’ve had a minor breakthrough, with regards to getting the velocity form to work. Beds such as are simply work better when cohen-coon based parameters are used, and after a little digging i’ve found that cohen coon parameters can be generated via the relay test klipper already uses.

I obviously can’t change the pid parameters outputted during calibration, but i can dump them to the log like Ku & Tu already are.

If you send me a pid calibration output file I manually go through it and send you back some pid parameters to test and tell me what you think.

---

<div class="post-metadata">

**Author:** ![ReXT3D](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/rext3d/32/200_2.png) [@ReXT3D](https://klipper.discourse.group/u/ReXT3D)\
**Post date:** [October 4, 2022, 9:18pm UTC](https://klipper.discourse.group/t/experimental-pid-improvement-changes/3604/62 "2022-10-04T21:18:51Z")

</div>

> [@DanS](#):
>
> If you send me a pid calibration output file I manually go through it and send you back some pid parameters to test and tell me what you think.

`heattest.csv` sent through Discord…

---

<div class="post-metadata">

**Author:** ![DanS](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/dans/32/746_2.png) [@DanS](https://klipper.discourse.group/u/DanS)\
**Post date:** [October 14, 2022, 8:17pm UTC](https://klipper.discourse.group/t/experimental-pid-improvement-changes/3604/63 "2022-10-14T20:17:19Z")

</div>

I’ve finally got the last round of development ready for everyone to test. It took far longer than I thought it would to complete, but that’s mainly because I stubbornly went down the path of continuously trying to shove a square peg into a round hole. Add to that distractions of everyday life.

No matter what I tried, I could not get classic Ziegler-Nichols parameters to work well for my bed while using the velocity algorithm, regardless of what temperature I calibrated for or what smoothing algorithm I used. The primary reason for this seems to be the huge lag/dead time associated with thick aluminum beds! The fact that my bed sensor is noisy only exacerbated the issue.

@ReXT3D inspired me to try Cohen-Coon parameters, and to my joy, they worked far better regardless of what control algorithm I used. After reviewing my notes and the various papers I’ve collected, I noticed that Cohen-Coon parameters can be calculated using a relay test.

see equations 5 & 6.

> **[Adaptive relay autotuning under static and non-static disturbances with...](https://www.osti.gov/biblio/1646635)**
>
> The U.S. Department of Energy's Office of Scientific and Technical Information

Thus I updated the pid calibration class to also calculate Cohen-Coon calibration constants. If you check the klipper log after a calibration run you will see something like this.

> Ziegler-Nichols constants: Ku=0.103092 Tu=41.800000  
> Cohen-Coon constants: Km=-17.734845 Theta=6.600000 Tau=-10.182680  
> Autotune: final: Kp=15.773129 Ki=0.754695 Kd=82.414600  
> PID parameters: pid\_Kp=15.773 pid\_Ki=0.755 pid\_Kd=82.415  
> The SAVE\_CONFIG command will update the printer config file  
> with these parameters and restart the printer.  
> save\_config: set [extruder] control = pid  
> save\_config: set [extruder] pid\_Kp = 15.773  
> save\_config: set [extruder] pid\_Ki = 0.755  
> save\_config: set [extruder] pid\_Kd = 82.415

You can take the constants from the log and drop them into the attached spreadsheet (can be opened with almost any spreadsheet application, including several free ones), and try out the various pid parameters.  
[pid\_params.zip](https://klipper.discourse.group/uploads/short-url/oR6MJ0s0I07T2LIXvgZB6iql5DY.zip) (5.3 KB)

As a refresher you can run pid calibration with the following command.

> PID\_CALIBRATE HEATER=heater\_bed TARGET=70 TOLERANCE=0.03 WRITE\_FILE=1

1. WRITE\_FILE is not needed unless you want to look at the output directly.
2. TOLERANCE defaults to 0.02 if not passed in. The tighter the tolerance the better, but how tight you can achieve depends on how clean your sensor readings are.

The following graphs show comparisons between Ziegler-Nichols classic & Cohen-Coon parameters generated from the same calibration run.

**The plot shorthand is as follows:**  
positional - the current control algorithm used by klipper  
velocity - the new velocity control algorithm  
zn - Ziegler-Nichols  
cc - Cohen-Coon  
calibraded - pid parameters generated directly from a calibration run.  
manual - pid parameters generated from a calibration run that have been manually tweaked to yield better performance.

**75C bed**

 ![75_position_zn](https://global.discourse-cdn.com/free1/uploads/klipper/original/2X/6/6c1680532fc0f406b56d1021917409118179b915.png)

 ![75_position_cc](https://global.discourse-cdn.com/free1/uploads/klipper/original/2X/0/06587ea082ba5a4a9bb51700e9982126f90fcd39.png)

 ![75_velocity_cc](https://global.discourse-cdn.com/free1/uploads/klipper/original/2X/8/87927ed8db58529cd88cd97f4e7c8349ceb4673d.png)

 ![75_full](https://global.discourse-cdn.com/free1/uploads/klipper/original/2X/6/6362a582678c5dc64b14160bf2bdf032ee748be0.png)

 ![75_over](https://global.discourse-cdn.com/free1/uploads/klipper/original/2X/9/929e3aece3dbae012a06e41f23f347085e7db595.png)

 ![75_deviance](https://global.discourse-cdn.com/free1/uploads/klipper/original/2X/5/5fa41324670bd597f11ba649f3c2aff30a195bd0.png)

**55C bed**

 ![55_full](https://global.discourse-cdn.com/free1/uploads/klipper/original/2X/9/9b47f92deaa70432c22482da06fda6b91a510395.png)

 ![55_over](https://global.discourse-cdn.com/free1/uploads/klipper/original/2X/f/f609b08aecd6c4cbf8c430b15d1dfa55ba0e010d.png)

 ![55_deviance](https://global.discourse-cdn.com/free1/uploads/klipper/original/2X/2/278ca98d45e63740f5353723d8906da1a9954d17.png)

**40C bed**  
40C is by far the hardest scenario to control on my printer. it’s within 20C of ambient and only requires 4 to 6% of the heaters capacity to maintain temperature.

 ![40_full](https://global.discourse-cdn.com/free1/uploads/klipper/original/2X/9/9419aaf713a74f92772eddac9b37a552aa90ab30.png)

 ![40_over](https://global.discourse-cdn.com/free1/uploads/klipper/original/2X/a/ade348ce438110381ec31fc0bc566e5ce25d545b.png)

 ![40_deviance](https://global.discourse-cdn.com/free1/uploads/klipper/original/2X/3/37f3237b2d895dedb5fe578be7a60dc15925032c.png)

If you want to try the velocity algorithm, just change the Control algorithm from “pid” to “pid\_v” in your config. Be sure to monitor the first run, because if you have bad pid parameters, or a particularly noisy system the velocity algorithm might not work for you without manual tuning.

the code can be found here.  
[https://github.com/dans98/klipper/tree/PID-Improvements](https://github.com/dans98/klipper/tree/PID-Improvements)

---

<div class="post-metadata">

**Author:** ![DanS](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/dans/32/746_2.png) [@DanS](https://klipper.discourse.group/u/DanS)\
**Post date:** [December 24, 2022, 8:23pm UTC](https://klipper.discourse.group/t/experimental-pid-improvement-changes/3604/64 "2022-12-24T20:23:59Z")

</div>

I’ve heard no negative feedback since the last update so I submitted a PR.

> <https://github.com/Klipper3d/klipper/pull/5955>
>
> This PR is related to improving PID control within the constraints Klipper
> curr…ently operates under. I've made changes to the calibration algorithm as 
> well standard positional form algorithm. Additionally I've added a standard 
> velocity form algorithm, that eliminates to potential for integral windup.     
> 
> 
> Please see one of the 2 commit messages for greater details, test results, and 
> links to relevant papers.
> 
> \-Dan S.

---

<div class="post-metadata">

**Author:** ![ReXT3D](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/rext3d/32/200_2.png) [@ReXT3D](https://klipper.discourse.group/u/ReXT3D)\
**Post date:** [December 24, 2022, 10:14pm UTC](https://klipper.discourse.group/t/experimental-pid-improvement-changes/3604/65 "2022-12-24T22:14:53Z")

</div>

My apologies, beyond the feedback that I passed on to you on Discord I’ve been busy chasing my tail on other subjects, so had no chance to experiment more…

---

<div class="post-metadata">

**Author:** ![DanS](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/dans/32/746_2.png) [@DanS](https://klipper.discourse.group/u/DanS)\
**Post date:** [December 26, 2022, 7:44am UTC](https://klipper.discourse.group/t/experimental-pid-improvement-changes/3604/66 "2022-12-26T07:44:36Z")

</div>

No worries, a lot of people had played with it and given feedback!

---

<div class="post-metadata">

**Author:** ![pki](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/pki/32/2892_2.png) [@pki](https://klipper.discourse.group/u/pki)\
**Post date:** [January 8, 2023, 3:16pm UTC](https://klipper.discourse.group/t/experimental-pid-improvement-changes/3604/67 "2023-01-08T15:16:02Z")

</div>

Hi.  
I have tried Your improovements. I am using the bambulab hotend which heats up very quickly, the PID tune finishes within a minute. I finished with takining the Ziegler-Nichols values from the log and using the Some Overshoot values. Additionally changing to pid\_v did an additionall improovement. The PWM spread was about 50% with the master branch tune, now it is about 10-15% and holding the temperature more precise. Thank You. My opinion is the pid\_v should be merged into main. Also the PID-CALIBRATE routine should return the alternative PID values for Some Overshood and No Overshoot in the terminal window.

---

<div class="post-metadata">

**Author:** ![Hundsbuah](https://avatars.discourse-cdn.com/v4/letter/h/839c29/32.png) [@Hundsbuah](https://klipper.discourse.group/u/Hundsbuah)\
**Post date:** [January 10, 2023, 8:28pm UTC](https://klipper.discourse.group/t/experimental-pid-improvement-changes/3604/68 "2023-01-10T20:28:59Z")

</div>

> [@pki](#):
>
> I finished with takining the Ziegler-Nichols values from the log

how do you mean that - edit the python file ( klippy/extras/pid\_calibrate.py ) and replace the

```auto
Ku = 4. * self.heater_max_power / (math.pi * amplitude)

```

and

```auto
Tu = time_diff

```

in the code with the values from the log ( i.e Ziegler-Nichols constants: Ku=0.090939 Tu=25.400000 ) ?

---

<div class="post-metadata">

**Author:** ![pki](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/pki/32/2892_2.png) [@pki](https://klipper.discourse.group/u/pki)\
**Post date:** [January 10, 2023, 8:44pm UTC](https://klipper.discourse.group/t/experimental-pid-improvement-changes/3604/69 "2023-01-10T20:44:43Z")

</div>

Nooooo, taking the values from the log and placing in the excel/calc sheet which is in this topic 😀

---

<div class="post-metadata">

**Author:** ![Hundsbuah](https://avatars.discourse-cdn.com/v4/letter/h/839c29/32.png) [@Hundsbuah](https://klipper.discourse.group/u/Hundsbuah)\
**Post date:** [January 10, 2023, 9:16pm UTC](https://klipper.discourse.group/t/experimental-pid-improvement-changes/3604/70 "2023-01-10T21:16:35Z")

</div>

ahh ok, havent found the excel sheet, but now found it, its in the [pid\_params.zip](https://klipper.discourse.group/uploads/short-url/oR6MJ0s0I07T2LIXvgZB6iql5DY.zip) (5.3 KB) - thanks

---

<div class="post-metadata">

**Author:** ![Hundsbuah](https://avatars.discourse-cdn.com/v4/letter/h/839c29/32.png) [@Hundsbuah](https://klipper.discourse.group/u/Hundsbuah)\
**Post date:** [January 10, 2023, 9:23pm UTC](https://klipper.discourse.group/t/experimental-pid-improvement-changes/3604/71 "2023-01-10T21:23:15Z")

</div>

may i ask why you choose the “some overshoot” values and not the “Pessen Integral Rule”?

> **[PID “Proportional, Integral, and Derivative” Control Theory](https://www.crystalinstruments.com/blog/2020/8/23/pid-control-theory)**
>
> PID control is a very simple and powerful method for controlling a variety of processes, including temperature. The acronym PID stands for “Proportional, Integral, and Derivative”.

Im refering to the section “Tuning” and the graph:

 ![image](https://global.discourse-cdn.com/free1/uploads/klipper/original/2X/d/d66708bf4d137a6153c54c6d8dc19a9c4d2af951.png)

---

<div class="post-metadata">

**Author:** ![DanS](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/dans/32/746_2.png) [@DanS](https://klipper.discourse.group/u/DanS)\
**Post date:** [January 10, 2023, 10:00pm UTC](https://klipper.discourse.group/t/experimental-pid-improvement-changes/3604/72 "2023-01-10T22:00:44Z")

</div>

@Hundsbuah keep in mind those graphs are based on a perfect simulation/model. what we have are sensor readings with noise, and then random disturbances like your hvac turning on/off, or a door opening or closing etc.

Also each tune acts differently when saturated compared to unsaturated.

---

<div class="post-metadata">

**Author:** ![pki](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/pki/32/2892_2.png) [@pki](https://klipper.discourse.group/u/pki)\
**Post date:** [January 10, 2023, 10:04pm UTC](https://klipper.discourse.group/t/experimental-pid-improvement-changes/3604/73 "2023-01-10T22:04:14Z")

</div>

Sure, i choose it because it gives me the best effect with less time spend tuning it. Of course i like it to be tuned good, but I also keep in mind how it affects the print.

Longer story:  
I am using the bambulab hotend which is heating up very quick. The master (branch) PID CALIBRATE routine takes less than a minute. I think the routine returns the Ziegler-Nichols values way off, this leads to a bad tune. Following the Classic ZN PID values results in permanent oscilation and a PWM signal range of permanently about 50%, never stabilize. The PID CALIBRATE routine from Dans returns almost same PID values. So i took the ZN values from the log, posted into this excel sheet and tried all four PID value sets. The set named “Some Overshoot” gives best results, fairly good stabilization and good reaction during print. Choosing “pid\_v” improoves it even more. That was my short trip into this tuning. If someone is interested, i can log whatever is helpfull, just tell me what You need and how to approach.

I think the PID-CALIBRATE mersurement cycle is way off in case of this hotend, may be due to measurement delay or some other effects. Maybe there is some idea to modify it so it could better approach this quick hotend.

During print this hotend stabilize at about 45% PWM.

[Previous page](https://klipper.discourse.group/t/experimental-pid-improvement-changes/3604.md?page=3)
