PID simulator and a real adaptive smith predictor for PID-SP - #244
Open
dberlin wants to merge 4 commits into
Open
PID simulator and a real adaptive smith predictor for PID-SP#244dberlin wants to merge 4 commits into
dberlin wants to merge 4 commits into
Conversation
dberlin
force-pushed
the
pid-simulator-fixes
branch
from
July 27, 2026 03:39
55fdf04 to
9515164
Compare
Owner
|
Would you be able to raise this PR against the development branch? |
Author
|
Done |
# Conflicts: # controller/pid_sp.py # Conflicts: # controller/pid_sp.py
dberlin
force-pushed
the
pid-simulator-fixes
branch
from
July 27, 2026 16:39
9515164 to
c3d5f9d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I included the docs/plans used to make it in the commits. The commits have their own comments/docs, but they exist so you can see how it was designed/implemented/progressed at the time. I'm happy to remove them.
This PR consists of 3 things, and similar to above, happy to split it further (IE 1 PR per thing here, or whatever)
A simulator for the PIDs, used to do the testing for the rest of the changes in this set of commits. Any simulator is somewhat grill specific, so i had it try to simulate a small smoker, a medium smoker, and a large smoker. It is not a perfect simulations, this one uses a fairly simple model.
A real smith predictor for PID-SP. The existing "smith predictor" is not one. Smith predictors normally are things that try to figure out what the dead-time is (in our case, deadtime is basically time from auger start moving to when the pellets burn), so they can avoid large overshoot. The current predictor just tries to extrapolate rate of change, which is somewhat related but not really. This patch adds a real smith predictor, and tests for it. The smith predictor recovers 3 variables through its predictions - tau (how fast the process reacts and reaches a new state after change), theta (dead time until response), and K (temperature gain per cycle time). These are used to make the PID more correct over time. The tests verify not just the actual settling/etc times are okay, but that the predictor actually recovers the model parameters we are trying to predict (to within reasonable bounds for a unit test)
A way to store the smith predictor calculations over time. For a given grill, the static variables we are recovering should converge over time with a very small set of error. The more observations we have, the better we are. We store both the number observations, and the static variable states (no variables that are dynamic to the cook are stored) This enables PID-SP to simply get better the more you use it. The number of observations are stored because of how the variable recovery works. Because we are recovering three variables, and are trying to do it with a first order model, we directly recover two of them (tau and gain) and then see if changing the dead time (theta) better explains the observations for the current tau and gain. We don't want to randomly flip back and forth, so we require this be true over a significant time window/number of observations before allowing the new prediction to take effect. To avoid having to wait the entire time/observation window again (currently 60 minutes/240 observations), we track it. That way, if you do a bunch of short cooks, it will still eventually trust the predicted variables.
We assume dead time is somewhere between 0 and 120 seconds. You would either need a remarkably large smoker or a very slow auger, or both, for it to take longer than 120 seconds for a pellet to reach the firebox from the point the auger turns on. The number can be increased, it just costs extra CPU.
Right now we calculate a result for each candidate dead time individually, so there is a total of (120/5 + 1 = 25)33 calculations involved. This is a totally immaterial cost right now, so we don't do it in array form, because it would be harder to understand.
All 25 candidates could be calculated at once as a numpy array, and it would be 25-75x faster, but it is harder to understand how it works when it's written like this, so i wouldn't bother unless something changes.
I would not bother unless we want better-than-5-second accuracy deadtime