7
$\begingroup$

is there a way with Mathematica to transform transferfunctions (Laplace) into differential equations?

Let's say I have the transfer function $\frac{Y(s)}{U(s)}=\text{Kp} \left(\frac{1}{s \text{Tn}}+1\right)$. What I want to get is $\dot{y}(t)\text{Tn}=\text{Kp}(\dot{u}(t)\text{Tn}+u(t))$.

On (I think) Nasser's page I found something I adapted:

sys = Kp (1 + 1/(Tn s))
sys = Together[sys]
rhs = Numerator[sys]
lhs = Denominator[sys]
rhs = rhs /. m_. s^n_. -> m Derivative[n][u[t]]
lhs = lhs /. m_. s^n_. -> m Derivative[n][y[t]]

eq = lhs == rhs

But this gives a wrong output for factors with $s^0$:

Input: eq

Output: Tn y[t]'==Kp (1+Tn u[t]')
$\endgroup$
5
$\begingroup$

Using Control`DEqns`ioEqnsForm

tfm = TransferFunctionModel[
  Array[(s + Subscript[a, ##])/(s + Subscript[b, ##]) &, {3, 2}], s]

enter image description here

res = Control`DEqns`ioEqnsForm[tfm];

The first argument has the differential equations

res[[1, 1]]

enter image description here

and the output equations

res[[1, 2]]

enter image description here

The second argument has the state variables

res[[2]]

enter image description here

The third the input variables

res[[3]]

enter image description here

The fourth the output variables

res[[4]]

enter image description here

And the fifth the time variable

res[[5]]

enter image description here

The function also works for delay systems

Control`DEqns`ioEqnsForm[TransferFunctionModel[(Exp[-s T] s)/(s + 1), s]]

enter image description here

Control`DEqns`ioEqnsForm[
 TransferFunctionModel[{{{Subscript[\[SystemsModelDelay], 3] - 1}}, s + 3}, s]]

enter image description here

For discrete-time systems it returns difference equations

Control`DEqns`ioEqnsForm[
TransferFunctionModel[(z - 0.1)/(z + 0.6), z, SamplingPeriod -> 1]]

enter image description here

Legacy answer

A solution for scalar transfer functions with delays.

The main function accepts the numerator and denominator of the transfer function.

tfmToTimeDomain[{num_, den_}, ipvar_, opvar_, s_, t_] := 
    Catch[polyToTimeDomain[den, opvar, s, t] == polyToTimeDomain[num, ipvar, s, t]]

A function to extract the numerator and denominator:

tfmToTimeDomain[tf_, rest__] := With[{tf1 = Together@tf}, 
    tfmToTimeDomain[Switch[Head@tf1, Times, {DeleteCases[tf1, Power[_, _?Negative]], 
    1/DeleteCases[tf1, Except[Power[_, _?Negative]]]} // Expand, 
    _, {Numerator@tf1, Denominator@tf1}], rest]]

Supporting functions:

polyToTimeDomain[poly_, var_, s_, t_] := With[{cl = CoefficientList[poly, s]},
    Plus @@ MapIndexed[coeffToTimeDomain[##, var, s, t] &, cl]]

coeffToTimeDomain[coeff_, {i_}, var_, s_, t_] /; FreeQ[coeff, Exp[__]] := 
    coeff Derivative[i-1][var][t]
coeffToTimeDomain[coeff_, {i_}, var_, s_, t_] := 
    coeff /. Exp[expr_] :> expToTimeDomain[expr, {i}, var, s, t]

expToTimeDomain[expr_, {i_}, var_, s_, t_] := Block[{cl}, 
     Switch[Length[cl = CoefficientList[expr, s]], 
        1, Exp[cl[[1]]] var[t], 
        2, Exp[cl[[1]]] Derivative[i - 1][var][t + cl[[2]]], 
        _, Throw[$Failed]
     ]
 ]

Examples:

tfmToTimeDomain[{Kp (s Tn + 1), s Tn}, u, y, s, t]

enter image description here

tfmToTimeDomain[{Kp Exp[-s T1], s }, u, y, s, t]

enter image description here

tfmToTimeDomain[{Kp Exp[-s T1] (s Tn + 1), s Tn}, u, y, s, t]

enter image description here

The function should work for any continuous-time scalar transfer function with or without delays.

$\endgroup$
13
  • $\begingroup$ Wow, with Together[] this seems to be a very short and elegant way. I'll try it with some other transfer functions. $\endgroup$
    – Phab
    Mar 20 '14 at 8:03
  • 1
    $\begingroup$ What about transfer functions with a time delay? Like $tf=\frac {\text {Kp}~e^{-s\text {T1}}} {s}$. Any idea how to handle these? $\endgroup$
    – Phab
    Mar 20 '14 at 10:16
  • $\begingroup$ I have updated the function to handle delays as well. The cases I have not considered are discrete-time systems and multivariable systems. $\endgroup$ Mar 20 '14 at 15:18
  • 2
    $\begingroup$ Phab, I have now added the function to extract numerators and denominators as well. Am I hand-holding too much. Hope you can take it from here. $\endgroup$ Mar 21 '14 at 15:33
  • 1
    $\begingroup$ @dtn you can use this code in your work. System` functions have a 'Cite this as' feature at the very end (example). Since this is kind of an internal feature so far, just point to this post. $\endgroup$ May 25 '21 at 1:33
4
$\begingroup$

Here's a step-by-step albeit long-winded approach to deconstructing and reconstructing your differential equation. While not elegant, perhaps it provides alternatives or ideas for further development.

sys = Kp (1 + 1/(Tn s))
tfm = TransferFunctionModel[{{sys}}, s]
ssm = StateSpaceModel[tfm]

Extract the elements of the StateSpaceModel (the a, b, c, and d matrices):

sseqn = Take[Flatten[ssm[[1]], 2], 2]    (*  {0, 1}  *)
outputeqn = Drop[Flatten[ssm[[1]], 2], 2]    (*  {Kp/Tn, Kp}  *)

Construct the state-space equation:

xaccent = sseqn.{x[t], u[t]}    (*  u[t]  *)

and the output equation:

yaccent = outputeqn.{x[t], u[t]}    (*  Kp u[t] + (Kp x[t])/Tn  *)

Now in the output equation, substitute for the x[t] with the integral of the state-space equation:

yaccent /. x[t] -> Integrate[xaccent, t]

Then differentiate that w.r.t. t and set it equal to y'[t]:

D[%, t]
eqFinal = % == y'[t]

which gives:

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.