How to transform transfer functions into differential equations?

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.


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