Apart from being easier to tune, I just found a good article[2] for why this approach works better for problems such as this. For quadcopters, of course, this allows one to easily switch between rate/acro mode and angle mode.
[1] https://github.com/ThePinkScareCrow/TheScareCrow/blob/master... [2] https://www.controleng.com/single-article/fundamentals-of-ca...
Each integrator is one dimension of state.
The nice thing about linear systems is that almost every dynamical system is locally linear near some operating point.
Maybe it's explained by the state space containing more terms than PID controller, so the transfer function can be linear for each individual term?
Given a linear plant model and a PID controller, you can compute all the classic control metrics like phase and gain margins, settling time, and even how the controller would perform according to the LQR metric.
That's the theory. All linear. Theoretically it's as appropriate to apply LQR to a nonlinear plant as it is to apply PID.
If you tweak the four LQR matrices (say, for a second-order system), and couple the gain matrix with the output of a linear observer (Luenberger), that combination system should be able to generate any PID controller. It's an over-parameterization, however (which is why I think PID controllers are ubiquitous. Not many parameters). Many settings will produce the same controller.
If anyone knows a reference that discussed PID and LQR like this, I'd love to see it
But as noted in my comment above, linear controllers can be used to control nonlinear systems under certain circumstances.
p.s. btw, having more states in the model does not linearize a nonlinear system per se. Only nonlinear transformations like log-transforms are capable of linearizing a system.
In practice, PID is applied to nonlinear systems too. The catch is the nonlinear system need to either be:
1) locally linear within the region of interest (very often the case)
2) mildly nonlinear
3) linearizable (by doing a mathematical transformation)
The first time I build a fuzzy logic controller for an industrial plant optimisation I was very surprised at performance vs complexity and how imprecise the characterisations can be and still get very good results.
I suspect the difficulties you've experienced stem not from nonlinearity, but from trying to control a system poorly approximated by a second order system with a second order controller. By cascading, both PID controllers effectively "see" a plant that looks more or less second order, so the controllers are much more effective.
Solutions to linear ODEs are in general exponential or polynomial in time. The solution doesn't have to be linear for the system to be linear.
(Unless I've misunderstood and you are modeling the system as actually controlling time. But I doubt that's what you meant)
The biggest issue for me was spending a lot of time trying to achieve a better system response (fast settling time with minimal overshoot) for system that was just designed badly.
Additionally, the set value for the boiler temperature is calculated using separate model that takes the group head temperature into the account.
The end result is that the controller is able to stabilize immediately, with maximum power of the heater and with no overshoots or undershoots to a temperature that takes into the account the state of group head to provide the ideal water when brewing.
While PID is able to control the temperature very accurately I found even in best case it took additional 50% of the time to stabilize and also it was difficult to optimally use 100% power of the heater until last possible moment.
Being able to achieve stability almost immediately means I can keep lower water temperature in the boiler and bring it to temperature at the last possible moment. End result being that it is now much faster to get it ready.
From my experience it is often observed in large processing plants that the operators have learned to do this instinctively from the standard faceplate.
I have slapped together few components to create a working prototype, STM32 Nucleo board with STM32L452 MCU, Texas Instruments development board with Bluetooth 5, some RTD temperature measurement development boards from MaximIntegrated, a bunch of relays, current sensors, water flow sensor from Digmesa (actually replacement part from one of Saeco machines), etc.
I am using a test board to detect existing espresso machine operation and perform readings using multichannel laboratory thermometer that measures external boiler case temperature, group head temperature, brewing water temperature (inside portafilter), tank water temperature and external temperature along with signals (when the brewing starts, stops, etc.) to provide experimental data to build the model.
I am using Matlab and Simulink to help me generate parts of the software using gathered experimental data. This lets me play with models and observe how it could behave without actually brewing any coffee:)
Predictors are often too hard in practice, but in this case seems simple as looks like you have the parameters you need to calculate the required energy as Q=ml (+losses) and just put exactly that amount of electrical joules into the heating element.
"Tune" factors like thermal losses by hand, and/or have a simple heuristic learning algo that tunes factors for you based on previous result errors.
I am assuming you have the level in the tank as well to calculate volume, as how else do you protect the boiler element from coming on when no water in the tank?
Predictor calculates future evolution of the system based on current state and system parameters. The horizon changes dynamically and typically is about 5 seconds when in steady state and up multiple minutes when cooling from steaming to brewing temperature (depends heavily on insulation, steaming temperature, how long it was steamed, etc.)
The parameters are not directly physical values like thermal mass or energy but are related to them. For example, I am calculating the amount of energy lost based on water temperature and outside temperature (outside is inside enclosure). This is in units used to drive the heater (the unit is half-cycle of AC power). I am calculating (predicting) cooling of water when it is pumped based on amount of water pumped and temperature of water in the tank (this is also being measured).
I calculate initial values based on step responses and then use moving horizon estimator to continually test past predictions vs actual readings and adjust parameters to match.
I haven't yet analyzed which parameters are truly important and which can be easily compensated for without having to sense them.
As to the level of water in the I could not find suitable sensor so I built one. It can only give low level alarm (water falling below set level). It is a plastic pipe with floating magnet attach to the inside of the tank. On the outside, not mounted to the tank so that I can freely remove the tank, but pressed with a flat spring are two reed switches. Using those reed switches I can detect when water falls when its being used or when it rises when it is replenished.
Also sorry, I should have said Q=mcdelta(t) in my post.
My research of mods that are described on the Internet shows that most people put some kind of existing PID controller, SSR to control the heating element and a temperature probe which gets mounted on the outside of the boiler.
Minority is using Raspberry Pi, Arduino or some other kind of existing microcontroller board to allow for nice display and more functionality.
Few people are doing completely custom boards which is what I am doing for this project. I am currently learning electronics after almost 20 years in software and I find it very good exercise from design perspective.
We were given something almost identical to this, and the customer wanted a control algorithm. I had taken control theory, but there were two problems:
1. A lot of undergrad control theory assumes linear systems.
2. They almost always give you the transfer function.
Our system was likely nonlinear and we had no transfer function.
For simple physical systems, you can use basic physics to derive it. For anything else, figuring out the transfer function is a whole course in itself. I went to the control theory professor and asked for tips and he said "Forget it, it's way beyond the scope of a senior design project. I have students who do it for their MS project". Unfortunately, I couldn't convince the course's professor, and my grade suffered.
Oh well, you learn more in failure and all...
2. Yes, but the transfer function is usually only to simulate the system in Simulink or some such software. In the real-world, you never have the transfer function.
So how do people do it?
You either identify the transfer function model using step/impulse tests (covered in undergrad courses and not that hard to do -- the least sophisticated way is to just measure the response to a step and graphically estimate parameters K and tau; it gives you a good starting point), or you can tune a controller by hand starting with a tuning heuristic and then refining. https://en.wikipedia.org/wiki/PID_controller#Loop_tuning
More advanced ways of identifying the transfer function is to collect data (either using pseudorandom binary sequence, i.e. PRBS step tests, or just simple plant step tests) and then doing "system identification", that is, fitting a transfer function model via statistical methods. Matlab's System Identification toolbox is designed for this purpose.
I suspect your course professor did not specialize in control, and/or doesn't have real world experience. This is not unusual of course. Faculty are often assigned courses to teach, and some of these courses are outside their area of expertise.
This is what I tried (step, not impulse). Did not work well. The result was too dependent on the "starting position".
The course professor probably knew less about controls than I did. He was a computer engineering professor.
PID controllers always control around a nominal operating point (which you pick), which is why deviation variables are typically used in the mathematical derivation. That's just the basis of the control algorithm.
Through personal suffering while working on firmware for UAVs (PX4/Ardupilot), CNC controllers (grbl, Marlin), inverted pendulum balancing exercises, RC car control etc.
Sadly, no resources. I guess the best advice I could give on this subject is: increase the visibility of internal state of the system. I have lost track of number of times I've seen people trying to tune PID controller just by outside observation (hmm, looks a bit better than last time) instead of real-time plots of measured process error.
Add high-resolution logging, look at the plots of error and P/I/D terms, have a simulation where you can replay the sensor values and observe the system output.
Without data we're just somebody with an opinion. It should be the root of our decisions.
Real world example: imagine you have a single-axis motion stage driven by electric motor and you want to control position of a carriage. Usually your control output is motor voltage. Motor voltage approximately translates to current through motor windings, which in turn approximately translates to torque exerted by motor. Torque exerts a force (T = F * r) on carriage. Applying force to the carriage makes it accelerate (F = m * a). Acceleration linearly increases the carriage velocity (v = v0 + a * t). Carriage having some velocity finally causes the position change (s = v0 * t + a * t^2).
In the essence, the system turns out to be non-linear with the respect to parameter you are controlling.
To improve this system, one solution is to add velocity sensor (or differentiate the position sensor, if it's resolution is high enough) and introduce a cascading PID loop topology- the outer loop takes position error and outputs velocity error, which is fed to inner loop (input = velocity error, output = acceleration). The coefficients for the loops have to be tuned starting from innermost loop.
Another solution is to use different control algorithm which is suited for non-linear systems (e.g. LQR).