In Python control module, you can get step response of system. I have feedback PID controlled system whose step response is to be determined and to do that I find closed loop transfer function and get the step response. However the control inputs (the output of PID controller) is lost inside, and to get that I can find the transfer function from reference input to control input, however it is not proper (numerator degree is one larger then den) and I cant get input values just by step response. So what do you suggest, or how can we find also control inputs in this case?
Get control input values in Python Control module
control theorypython
Related Solutions
The plant is a model of the dynamics of the system you are trying to control. The system is described by a number of states, usually denoted by a vector $x_{[k]}$, and the dynamic model describes how these states change in time, so in discrete time domain this would be:
$x_{[k+1]} = f(x_{[k]},u_{[k]})$
where $u_{[k]}$ is your control input. Note that $x_{[k]}$ is the state vector describing the plant, whereas $y_{[k]}$ is the plant output, i.e. something that you measure about the plant. This usually is a certain state or combination of states, but you often can't measure all states directly. This is the reason that usually your control input and the plant output do not have the same unit of measurement: the control input is not necessarily directly affecting the state that you are measuring, but some other state, which indirectly affects the plant output!
Going to your example, let's identify the various vectors:
$u_{[k]} \text{: Requests you send to the server, requests/s} \\ y_{[k]} \text{: CPU load, in.... sorry not my field, what unit is this?} \\ x_{[k]}\text{: ?? Here it depends on your model, how detailed you want to make it. For the sake of example, I'll make up some dynamics (it's not my field, so sorry if the dynamics don't make a lot of sense... I hope it's clarifying though).} $
Let's define the state vector as:
$x_{1[k]}: \text{CPU load} \\ x_{2[k]}: \text{Queue of tasks}$
This implies that $y_{[k]} = x_{1[k]}$. Let's model the dynamics as:
$x_{1[k+1]} = \frac{x_{2[k]}}{P_{[k]}} \\ x_{2[k+1]} = max[(x_{2[k])}+u_{[k]})-P_{[k]},0] \\$
Where $P_{[k]}$ is the processing power (I'm making this up...), or amount of tasks processed at step k. For $x_2$, the tasks left in the cue at step $k+1$ will be the number of tasks at $k$ plus the number of new tasks delivered by the control input $u_{[k]}$, minus the amount of tasks that have been processed ($P_{[k]}$). So you see, since the control input affects only the dynamics of $x_2$, but we are measuring $x_1$, the plant output $y$ has a different unit than control output $u$.
Here we described everything in discrete time, so the dynamics were defined as $x_{[k+1]} = f(x,u)$. In continuous time, this would be described as in your example as $\dot{x}_{(t)} = f(x,u)$. I chose to write it all in discrete time since for a digital system it makes more sense.
However note that the dynamics of a state variable (i.e. it's time-derivative) in anycase has a different measurement unit than the the state itself. This is particularly evident in continuous time: The position $[m]$ state has as a dynamic a velocity $\frac{m}{s}$. Since the control input affects the dynamics, and we usually measure the state, even in a straight-forward case with only 1 state, the units would be different. Hope that clears it up a bit.
Given a state space model of the following form,
$$ \dot{x} = A\,x + B\,u, \tag{1} $$
$$ y = C\,x + D\,u. \tag{2} $$
The openloop transfer function of this system can be found by taking the Laplace transform and assuming all initial conditions to be zero (such that $\mathcal{L}\{\dot{x}(t)\}$ can just be written as $s\,X(s)$). Doing this for equation $(1)$ yields,
$$ s\,X(s) = A\,X(s) + B\,U(s), \tag{3} $$
which can be rewritten as,
$$ X(s) = (s\,I - A)^{-1} B\,U(s). \tag{4} $$
Substituting this into equation $(2)$ and defining the openloop transfer function $G(s)$ as the ratio between output ($Y(s)$) and input ($U(s)$) yields,
$$ G(s) = C\,(s\,I - A)^{-1} B + D. \tag{5} $$
In a normal block diagram representation the controller has as an input $r-y$, with $r$ the reference value you would like to have for $y$, and an output $u$, which would be the input to $G(s)$. For now $r$ can be set to zero, so the controller can be defined as the transfer function from $-y$ to $u$.
For an observer based controller ($L$ and $K$ such that $A-B\,K$ and $A-L\,C$ are Hurwitz) for a state space model we can write the following dynamics,
$$ u = -K\,\hat{x}, \tag{6} $$
$$ \dot{x} = A\,x - B\,K\,\hat{x}, \tag{7} $$
$$ \dot{\hat{x}} = A\,\hat{x} + B\,u + L(y - C\,\hat{x} - D\,u) = (A - B\,K - L\,C + L\,D\,K) \hat{x} + L\,y. \tag{8} $$
Similar to equations $(1)$, $(2)$ and $(5)$, the transfer function of the controller $C(s)$, defined as the ratio of $U(s)$ and $-Y(s)$, can be found to be,
$$ C(s) = K\,(s\,I - A + B\,K + L\,C - L\,D\,K)^{-1} L. \tag{9} $$
If you want to find the total openloop transfer function from "$-y$" to "$y$" you have to keep in mind that in general $G(s)$ and $C(s)$ are matrices of transfer functions, so the order of multiplication matters. Namely you first multiply the error ($r-y$) with the controller and then the plant, the openloop transfer function can be written as $G(s)\,C(s)$. The closedloop transfer function can then be found with,
$$ \frac{Y(s)}{R(s)} = (I + G(s)\,C(s))^{-1} G(s)\,C(s). \tag{10} $$
It can also be found directly using equations $(2)$ and $(6)$, and the closedloop state space model dynamics,
$$ \begin{bmatrix} \dot{x} \\ \dot{\hat{x}} \end{bmatrix} = \begin{bmatrix} A & -B\,K \\ L\,C & A - B\,K - L\,C \end{bmatrix} \begin{bmatrix} x \\ \hat{x} \end{bmatrix} + \begin{bmatrix} 0 \\ -L \end{bmatrix} r, \tag{11} $$
$$ \frac{Y(s)}{R(s)} = \begin{bmatrix} C & -D\,K \end{bmatrix} \begin{bmatrix} s\,I - A & B\,K \\ -L\,C & s\,I - A + B\,K + L\,C \end{bmatrix}^{-1} \begin{bmatrix} 0 \\ -L \end{bmatrix}. \tag{12} $$
Best Answer
Probably the reason is that your PID implementation is not propper. Then you have either to find the derivative of the error signal or to replace your PID with the proper approximation: $$U(s) = \left(K_p+K_i\frac{1}{s} + K_ds\right)E(s) \approx \left(K_p+K_i\frac{1}{s} + K_d\frac{s}{\tau_d s +1 }\right)E(s),$$ where $e(t)$ is the error signal and $\tau_d$ is sufficiently small.