
Subha Thomas walks through modeling, analyzing, and designing control systems in Wolfram tools, from first principles to deployment. The talk covers state-space representations, controllability tests, PID tuning, model predictive control, and code generation to microcontrollers, with a live demo on an Arduino quarter-car suspension.
Chapters
So, hello and welcome to this talk. I'm Subha Thomas, the developer of the control systems functionality in the Wolfram language. My plan is to give an overview of, of the control system functionality to this. What I'm trying to get across is how natural and straightforward it is to use this functionality and how streamlined the workflow is. Let me, let me start by going over what a control system is, why we need one, and how to obtain a controller. You can think of control systems as a systematic way to change the behavior of a system. So why would we need to change the behavior of a system? The system could have undecidable characteristics. For example, it could be unstable or the, or the response could be sluggish, or it could be oscillatory, things like that. Another main reason is that we would like to achieve a higher level of automation. For example, in cruise control we can control the speed manually using the pedal and that indirectly controls the position of the throttle plate or the voltage to the motor. But using cruise control, we set the speed we need and the controller takes care of what setting the throttle plate or the voltage to the motor should be. So to obtain a controller, we typically start with a model of the system and then we analyze the system based on that model and design the controller and then analyze again the performance of the system with the controller. And once we are satisfied, we deploy the controller to the real world. This whole process is iterative. So the starting point typically is to get the model. So there are various ways in which we can get the models. So there is, we can get a model through system identification, or we can get it from first principles, or we can get it through component based modeling using system modeler. So in this talk I'm not going to focus on this, but I'll focus on the modeling aspect itself, but on what we can do with those models. The end result of these models usually odes and differential equations and difference equations. So here I have an example of a car model. It's a very simple model and we'll immediately see that this is simply Newton's law, which says that the rate of change of momentum is the force acting on the car subtracted. And from that we subtract any of the drag forces acting, acting on the vehicle. So, and that's just a first order ode. So here is the model for a boat. This is also based on Newton's laws, but you can see it can get complicated really fast where the input forces become non linear functions of the inputs to the, to the boat. I have a Third example here of the model for a mixing tank. It describes how the concentrations of two chemicals change in response to the flow rates of two input reactants. And this is a difference equation. So when we have models like this, we can put it into a canonical form, the state space, the, the canonical state space representation. So if I take the CAR model and try to convert it into a state space model. So I give, you see if this evaluates. No, I did not evaluate the previous input. Okay, So I give the, the equation which I have, denoted by the variable car and then what is the input to the model? And then all the other time dependent variables. I give as, as the other variables, which is the second argument. And these are the output variables. And they are, they are some combination of the state of these variables and the input variables. And for the car, it's a, it's a very, it's a fairly simple. It's already a first order system. And so this is the generic state space representation. It's a first order vector matrix differential equation all. And we have the model represented using three matrices. The state matrix A, the input matrix B, the output matrix C and the feed through matrix B. So for a model, if you have these four matrices, then we can also specify this model manually using state space model. So here is a second example using Euler's equations of motion. And now when we try to get the state space representation of this model. So the inputs are the three torques and the angular velocities I have used as both the states and the outputs, we can see that all these nonlinear terms do not appear in the resulting state space model. This is because state space model is a linear model and if it sees any nonlinear terms like these, it just throws them away. So to handle such models, we have a more general model which is the affine state space model. Again, the arguments to this model are exactly the same as state space model. The only thing we changed is the head. And when we try to put it in an affine form, then none of the terms are thrown out. There is no approximation happening. So the affine model is called the affine model because this is its general form. It's affine in the input variables, but the state variables themselves can be nonlinear. So for our model, if you already have the A, in this case it's a vector A, B, C and D, then we can specify A, B, C and D and specify the model in that manner as well. So there is an even more general model which is a nonlinear model. So for the, for the Euler equations of motions. If I compute the nonlinear state space model, this is what I will get. It is expressed in terms of two vectors where F is just any nonlinear combination of the states and the input variables, where this is useful. And output too is a linear combination of the state and input variables. Where this is useful is when the inputs appear nonlinearly. So here the F and delta are the inputs and they are non linear. And if you, if you try to represent them using affine state space model, they will get approximated. And again, if I have the F and G vector for any model, then I can specify them manually specify them manually into nonlinear state space model. So one thing I'd like to point out is all these models also approximate all these more. I don't know why that went up. Yeah, all these models also approximate the highest order derivative. So here I have a nonlinear ode and the non linearity appears in the highest order derivative. And now if I convert it into states, a nonlinear state space model, you see that tan term is gone. It's because linearizes the highest order derivative. So this is something that we need to be aware of. So nonlinear state space model can handle all nonlinear models, but not non linearities in the highest order derivative. And we can have the same kind of models for this for discrete time systems. So these are all odes. This comes from difference equations. I have a difference equation and I specify the states, the input and the output just like before. And I can get the state space representation. And again, if I have the ABC and D matrices, I can specify the state space model like that way as well. Now there is another canonical representation which is transfer function representation. So I have the ODE describing the model. And one way you can see the transfer function model is starts from the impulse response of the system with all initial conditions. So I set the input to an impulse response and this is the impulse response of this ode. So this impulse response contains all the information we need about that system. And that's why this is very important. And the Laplace transform of this impulse response is what's called the transfer function model. So we can also get this transfer function by taking the Laplace transform of the, of the equation. So to get rid of these, these Laplace transform expressions, I just want to say that lowercase x of t is uppercase x of S. I want to, that's what I'm doing here. And then I'm sending all initial conditions to zero. And then I solve for the ratio x of S over U of S. And that will also give Me the, give me the transfer function. So once we. So this is one way to obtain the transfer function model. But sometimes we all already have the transfer function model and then we can directly specify it, as I'm doing here. So this is a multiple, so transfer function in general is a matrix. So this is a multiple input system which has three inputs and one output. Now, similar analysis holds for discrete time systems. We start from difference equations in this case, and instead of the Laplace transform, we take the z transform and as before, I repress, I convert all the z transform of the lowercase x of k to x uppercase x of z and lowercase u of k to uppercase u of z and set all initial conditions to zero and then solve for the for output which is x of z over U of z. And that will give me the transfer function for the discrete time system. And then I can also get the. If I already have the expression for the transfer function, I can again enter it directly. The difference from continuous time is you'll be specifying what the sampling period of the system is. And now here I have two output and one input system. And here I can specify a transfer function using the delay operator, a discrete time transfer function. Okay, so these kinds of modeling work for small systems and when we start from first principles, but if we are dealing with large systems and, and systems which span multiple domains, then it's better to use system modeler and create the model from there. Okay, so here I'm not, I'm not. I just call a model that was already created. But once we have that model, then we can linearize it and bring it into Mathematica to do the controller design and other analysis. You don't have to actually do this step for most of our, for all our control design functions, you can directly specify this model and it will automatically handle the linearization and other tasks to compute the controller for the model. That's taking some time for some reason. But anyway, so once we have these models, we can convert from one model to the other. Okay, just hold on, let me see. Okay, finally evaluated it. So this is a state space representation of that model. Okay, I'm going to unset these variables because I used it. Okay, I can take any model and convert it into any other model. So this was a, the CARS model was a linear model. So we have no problem converting it into. It was a linear state space model. We have no problem converting it into any other model representation. So if you take the Euler equations of motion, they were linear only in the Inputs, but in general they were non linear. So if you converted into a transfer function or a state space model, it will approximate to throw away the nonlinear terms. But the affine and nonlinear systems have no problem handling that model. If you take a completely nonlinear model, only the nonlinear state space model will be able to handle it. You'll see all these nonlinear terms get approximated in the other models. And then if you have one of these models. So this was the way to go come from system modeler models to into the Wolfram language to go the other way. We create a system model. And once we create this model, this model will then show up in the model center in in system modeler. Another way we could model systems is to assemble it from smaller subsystems. Here we have a large system with five small smaller subsystems. And the function we use to assemble these models is systems connections model. We specify the models, the models, the connections between them, the inputs and the outputs in, in our workflows. You'll rarely do this when you're doing control design and you want to do these connections. These connections are automated for you. So when typically you will not do this, but in case you need to actually assemble a system from subsystems manually. So this is, this is the function to do it and it will give a connections model object. And so in, in this example, I can actually simplify it to one object. I can reduce it and, and so I can bring it down to one state space model. If we cannot, then it will try to simplify it as much as possible. So once we have models, then one thing we can do with them is analyze them. So one of the things we would we will be interested in is in the controllability of the model. That is the property of the model that sees whether we can reach every final state from, from an initial state. And there are various ways to test it. Or we test whether the controllability matrix has full rank. Okay, it's got. It's computed from the A and B matrices. Or we test whether this, this expression which is called the Gramian is positive definite and that is computed by solving a Lyapunov equation. So for this to work because of this integral and this matrix exponential, this technique will only work if the system is stable or this will blow up. Then there is the PBH test which tests using the eigenvalues of the system. And this is useful to see if whether we can test whether individual modes are controllable or not. And then for nonlinear systems we have, we test controllability using a Distribution A distribution which spans these vectors and it is invariant with respect with respect to these these vectors. So all these computations are already implemented. You, you only have to call the top level function controllable model Q. So here I have the model for the for parking a vehicle. And when we do controllable model Q for the nonlinear system, when you have a non linear model, it is controllable. But if you linearize it, you've thrown off too much information and we'll actually get the get the result that the system is not controllable when reality it is. Here's another example. I took the Euler equations of motion and and I'm testing whether you can control all the angular rates using the the three torques. You see, we cannot control the entire system using just one input. We need at least two to be able to control the system. If I do the same analysis based on the linear model, linearize the model. So with the linear model we see that it requires all three inputs to be controllable for the system to be controllable. A related property, it comes as the dual is observability. This analyzes whether different initial conditions or distinct initial conditions will result in distinct output trajectories from the system. So I'll explain that with an example. But the tests are like especially for the linear case are duals of what the tests are for controllability. We test the controllability matrix. We test whether the controllability. I'm sorry, we test the observability matrix. We test with the observability. Gramian is positive definite. We have a dual PBH test and also a co distribution rank test. So here I have a mechanical system with three masses and springs and we and the output is just the first, the position of the first state. We say observable model Q. It says true. What it means is that given a distinct initial states initial conditions for the system, it will produce distinct values for x1. So the implication of this is from the trajectory of X1 and the model of the system, we can reconstruct the trajectories of all the of the three positions and velocities of the masses. So that's where observability the property is useful and it's used in assembling computing estimators for the system. So here's a nonlinear model which is also observable. But if I linearize it and then test if it's observable, we see that it's not true. So a system, so, so what I'm trying to say is that when we model, we need to be careful what terms we throw out. Sometimes if you throw out terms that are relevant, the analysis, we may get spurious results. So another thing we can do is actually simulate the models we do both symbolic and numeric. So this is the output response of standard second order system. The Omega N is the natural frequency and this is the damping in the system. And then we see that for various damping values, when the damping is slow, system is very oscillatory. And as the damping increases the system then the oscillations are reduced. So this is the output response of that car. Okay, I'm, I'm setting an input, a ramp input for about 1 second and then shutting it and then turning it off. That's the force and we get a piecewise result. See, if the, if the drag forces are really small and after that time this system takes, it continues like that for a very long time. But if the drag forces are really large and once that input force is taken off, this is the expected is what we would expect from that model. And then we can also do numeric simulation. So I get that Euler equations of motion. I set three values for the, for the moments of inertia. And then when I simulate it, I'm simulating it from initial conditions. So I just set the angular, initial angular velocity in one of the axes to be large and the other small. And you see that the system continues like that. And I can also do it that the last one to be the most prominent one and the other small. And again we see that the system continues to have the maximum angular velocity along that axis. But if I set the maximum angular velocity along the intermediate axis, you see the system has this interesting behavior where actually flips around and then keeps flipping, flipping to its original direction. And it. So this is a very interesting phenomena. It's called the intermediate axis theorem or the tennis racket theorem. It's also called Hani Peckoff. I don't know that I'm pronouncing it right effect. And then we can also simulate discrete time systems. This is the symbolic simulation of a discrete time system. So this is. Yeah, this is the numeric simulator simulation. We have discrete time system. We are giving a sequence, an input sequence. And this is the, the result of that. Then this system has two inputs. So when there are two inputs, we can give two input sequences and two outputs. So we'll get two output sequences as the results. So we have all we can actually compute and also plot the results. But we also have a very useful function to actually quantify what these values are. So if we can compute the response, we can see it visually, but we can also get what those actual values are. What's the rise time? What's the settling of the rise time is? Rest time is I think the system where it reaches one the first time and that. But we can get, and the maximum overshoot percent, which is how much percentage it has overshot over the final value of the final settling value. Okay. Now so so far we've been looking at modeling and analysis. So let's look at some, now some design functions. So we have, so this is the summary of, of how a PID controller will work. So we have the system and we just, it's highly automated. So if you just give PID tune of that system, it will compute this controller gf the feedback controller and it will return that. Okay. And you can also specify, so it automatically shows what kind of controller and what tuning rule to use, but you can specify what architecture you need and what tuning rules to choose. So here I asked specifically for PID and choose one of those methods and I can get the controller computed as a PID controller using that method. So, so in, so this is just a one off where you just get that controller, but typically you want to get the controller and then see its performance. Right. So. Well, I'll have an example here showing how the workflow is. So this, this is a two tank system. Let me unset these variables. These are the equations governing the height of the fluid in, in these two tanks. Yeah, I've, I want to find what, what an equilibrium position is for this system. So I set all derivatives to zero and I assume a constant flow rate coming into the upper tank. Okay. And then if I solve this for the, these two equations for the two heights, I get that at that constant flow rate, this will be the heights of the liquid in the two tanks. Yeah. Substitute some parameter values. And now I define the model as a nonlinear state space model. Okay. So I specify that this is the operating point for the input variable and these are the operating point for the state variables. Once I have the model, then it's just one, one line where we say PID tune. We automatically choose the tuning rule and the architecture. And this time I'm asking for a data object. So you'll see in the subsequent designs too that this data object is the hub around which the entire controller design, the controller design is based. Because why it's useful is once we have, once we Have a controller, we need to assemble it back like this. And to do that you'll have to use the systems connections model or there are other connections models like systems model, feedback connect and so on. That can be quite cumbersome. So once we have this object we just have to ask what is the, what is the model? By putting that controller together with the plant. So this reference output will give me the con, the model of the system from the reference to the output with the controller in feedback. So that is the useful, usefulness of this, of this object. And so now I have the closed loop system and now I can simulate it. I give some reference values and I simulate it and I can see the result. Let's look at another design technique. Okay, this is an LQ technique. So the LQ technique, okay, it starts from a linear model. So even if we give a non linear model, it will first linearize this model and then base the design on this model. And what this controller does is it's called a linear quadratic. So it's because it's based on the linear model and it's minimizing this quadratic cost. And by driving these states to zero and at the same time minimizing the control effort, then result is it will stabilize the system. Not only stabilize, it will also regulate the system to zero. Let's look at this example. So here I have a helicopter model and I do an initial analysis. I see all the poles are in the. There are not all the poles. Three of them are in the right half plane. So the system is unstable. So I design a regulator. So these are my weighting matrices, these are the Q and R matrices to penalize the states and the inputs. So I specify a high weight on the, on the two states X and theta and some weight on the input so it doesn't get quite out of hand. And again I get this data object and just like before, I don't have to assemble that system. I just asked for the closed loop system. And it's not, not just there are a whole bunch of properties you can get from that. So again here I'm getting the closed loop poles. And now there are no poles in the right half plane. So system is stable. And I have the closed loop system so I can simulate it and plot the result. Now we would like to know what was the control effort that was expended again from that data object. We can ask for the controller model and specify the inputs going into the controller model. And then we can see what the control effort was that the controller was using. And you'll see this, this workflow again and again in all, in all the designs. So this is the MPC design. So the MPC design is based on this linear discrete time model and it's similar to the LQ control except that over here the main difference is it, it takes constraints into account a priori. In the LQ design you, we do not specifically cannot specify the constraints a priori. We simulate it and then if the system violates the constraints, we tweak the weights. But over here we can specify the constraints a priori. We can minimize three different costs. By default it chooses this quadratic cost. But we can also give a one norm or an infinite norm problem. And the outline and the layout of this controller is similar to the LQ controller. So let's look at an example. So this is what I want. This, what I'm trying to do with this controller is to automate the administration of anesthesia. So we have a model, we have a model of how the drug interacts with, with the body. One is the PK model which says, which, which gives the effect of the drug on different components in the body. And then the PD model which, which gives its effect on the actual, on the actual site. And then the effectiveness of the drug is measured by this index. So we want the effectiveness to be somewhere around here. Over here it's actually harmful to the patient. And over here the patient is awake. So the drug is not that effective. Okay, so we create that model and then we discretize it because it only accepts a discrete time model. And, and then we are ready to do the control design. We say for, for the, for the MPC design we need to specify a horizon. So I give the horizon and the different weights and I'm going to specify a constraint. So I don't want the, the index, the BIS index value to go really low. Okay, so I'm, so I, I don't want it to go lower than 40. And so that gives me a constraint on that CE variable. So I specify the constraint and now I can, so once I have the system, the cost and the constraints, I can compute the constraint controller. Okay, so again, as before, I don't have to assemble the system. I can just ask for the closed loop system. And it's going to assemble the closed loop system. Okay? And I'm going to compute what the reference value should be to achieve an index of the index of 50. And I see the controller actually brings that C value to that. And now I can compute the, I can see what the actual index value is. And you see, the patient starts from here and eventually reaches this moderately hypnotic state in about a minute. Okay. Okay. This is. Okay, I think this, this is the last design technique. This is for non linear systems of. It's called feedback linearization. So we can. So there's a. By this technique of feedback linearization, we can take an affine system and transform it to a linear system. The advantage of this is that once we get the linear system, then we can do so this transformation happens by transforming the input variables and the state variables. So once we have this linear system, then we can use all the linear techniques that are available and compute a controller and then transform that controller back into the original, to the original variables and assemble it. Yeah. So again, because we have this process automated, transforming these variables and assembling the controller is all, is all taken care of. You just have to give the top level command. So the linear system itself comprises of a completely linear system and a residual system. In general, you will not be able to completely linearize the system. And if there are residual dynamics, there are ways to. If it's stable, then it's fine. But if there are residual dynamics, then we need this and we need to be aware of about it or handle it in another way. And this is the way we put it together. And as I just mentioned, we don't have to manually do it. The whole process is automated. So let me show that with an example. So here I have the model of a compressor. I think this is the mass, flow, plenum pressure. And if you look at the response, you see that the system is highly oscillatory. So we feedback linearize it. That means we do a transformation to make it a linear system. So I can see what the linear system is. I'm basing my design on that. So it's a completely. So there was no residual dynamics. And I can base my design on this linear system. I'm using pole placement here. And I get, and I get these feedback gains. Now these feedback gains are for the linear system, the new variables. I need to put it back in the original states and assemble it together with the original, original model. So again, we don't have, we just have to ask for the closed loop system with that controller and we get the closed loop system in just that one line of code. And then now we can simulate it and we see that the oscillations have been eliminated. Okay, so there's one more thing I'd like to present and that is the deployment of these controllers. So once we have these controllers, these controllers just don't live just with the simulation. We want to deploy it to the, to the plant we are actually trying to control. So the process is, excuse me for the process is we take that controller model and then we have to generate the source code typically in C C and then we have to invoke a compiler and a programmer to deploy it onto the microcontroller. So this process is also automated. So once we have the, the controller we, we have to specify the configuration of the mind, what microcontroller and the configuration and we'd be able to, to deploy it with, with again with that top level command. This is very useful because control design is, is always an iterative process. So we design the controller, we test it and then we need to tweak it. So each time we generate a new controller, we should be able to quickly deploy it onto the microcontroller board. So we can deploy any of these models that I have shown. And there are various reasons why we would deploy it. One, one, an obvious one is that we have a controller or it could be a filter that we would like to deploy or an estimator. Now the thing that I'm going to show here is what's called hardware in the loop simulation. We want to deploy the actual model itself. So when we deploy the actual model then we have a simulation of the model in real time running on a microcontroller and we can test that model in real time against a controller that we have designed. So for this illustrate, for this example I choose the model for a quarter car suspension system. So to deploy it we of course have to discretize it. So I'm going to deploy this onto the microcontroller and I'm going to, and the three states are the, are the road or the road profile, the displacement of the road, the displacement of the unsprung mass and the displacement of the sprung mass. And the way I'm going to simulate the road is using a joystick. And this joystick, I have it right here, you can see I have this joystick connected to the Arduino. Hope you can see it. Okay, so this is my system. I have, it's a very simple system. I have this joystick connected to this Arduino. So when it's it, it's in its neutral state. It gives me a voltage of 2.44 volts and that I want to set to zero. And the highest voltage I can read from that is 4.85 and that I want to set from, set to 1. So I take the raw voltages from the, from that potentiometer and rescale it to a value between minus one and one. And that is going to be the model through which I'm going to get the road profile. Okay. And I'm going to cut, converted it into a nonlinear state space model. So the input for the road is coming through the, through the joystick and it's going to take that voltage, convert it to a value between -1 and 1 and that I'm going to feed it into the, the car model. So I'm going to just. Yeah, I'm going to connect these two. Okay, so that's my system and then I'm going to specify the microcontroller configuration. So I have an Arduino Uno. The input is going to come into channel A3 and the three outputs the road profile, the displacement of the sprung mass and the unsprung mass. I'm going to output it into, through the, through the serial channel and I'm going to use the device framework to read it. And I need this package. And then. Okay, so let me connect mine. So now what's happened is that this, that this Arduino has a model of the quarter car system. I can unplug, I can unplug it. As long as it's forward, it's going to be running that model. If I design any controller, I can test it against this model in real time. But what I've deployed here is to read these values back. So let me, let me set up the device. So I'm going to open a connection now to this device where the device is coming, the data is coming, it has a start byte. And so all this is the device framework. I query what those values are. Again, when the microcontroller code was embedded, I know what these values based on what the code is running, I can query what those values are. And here is some code to actually parse that data. Now I'm going to create a task that is going to read it and plot it. Okay, so here is, okay, so that's, that's my car. It's just sitting still. I'm going to. So as I move this joystick, you can see the system responding in, in real time. Okay, so then I'm going to remove the task and close the connection to the device. Okay, so that's all that I wanted to present, but I omitted several things. We, we have support for delay systems, descriptor systems, and I've omitted this whole area of system models. It's very vital for control design. And you have especially large systems. That's where you would model the systems and then bring it into Mathematica for analysis and control design. Then there's a whole suite of tools for classical analysis. Bode Nyquist, how to get the stability margins, the circle criteria. And we also have functionality to compute minimum various decomposition based on various basically states based transform. We can compute decompositions and minimal models linearizations. And in the design too, I briefly did pole placement, but you have pole placement, tracking, estimated design. And we also have various other control design techniques like full information output regulator and track and other tracking techniques. So with that I will conclude my presentation from the slide. Let me see if there are any questions at this point. Yeah, so the question is to what degree is ND Solve's delayed differential equation solvers used? I assume it is possible to run it all in system modeler. Yeah, so this whenever we call simulation functions, the numeric simulation functions for continuous time systems all go to ND Solve. We do not. We are not set up to for these models to hook up directly to system modeler. The way you would get to use system modeler solvers is to create system model. Create a system model object and then you can use system model of solvers to solve it. I hope that answered the question. So if there are no more questions, that should conclude my talk. I thank you all for watching and bye for now.
More from Guy

Cheryl Strauss Einhorn | The Human Edge: Smarter Decisions in the Age of AI | Talks at Google

Rachel Glennerster | Innovation and the Center for Global Development | Talks at Google

Rebecca Winthrop | Rethinking the Purpose of Education in the Age of AI | Talks at Google

Dr. Robert Wachter | A Giant Leap: How AI Is Transforming Healthcare... | Talks at Google






