[1]:
import sympy
import matplotlib.pyplot as plt
import numpy
sympy.init_printing()
%matplotlib inline
[2]:
tau, zeta, t, w, K = sympy.symbols('tau, zeta, t, w, K', real=True, positive=True)
s = sympy.Symbol('s')
[3]:
def L(f):
    return sympy.laplace_transform(f, t, s, noconds=True)
def invL(F):
    return sympy.inverse_laplace_transform(F, s, t)

This is the standard form for the second order system transfer function

[4]:
G = K/(tau**2*s**2 + 2*tau*zeta*s + 1)
G
[4]:
$$\frac{K}{s^{2} \tau^{2} + 2 s \tau \zeta + 1}$$

In recent versions of Sympy, we can solve for the step response directly.

[5]:
sympy.__version__
[5]:
'1.1.1'
[6]:
invL(G/s)
[6]:
$$\frac{K e^{- \frac{t \zeta}{\tau}}}{2 \left(- \zeta + \sqrt{\zeta - 1} \sqrt{\zeta + 1}\right)^{2} \left(\zeta + \sqrt{\zeta - 1} \sqrt{\zeta + 1}\right)^{2} \sqrt{\zeta^{2} - 1}} \left(- i \zeta e^{\frac{t}{\tau} \sqrt{\zeta + 1} \cos{\left (\frac{1}{2} \operatorname{atan_{2}}{\left (0,\zeta - 1 \right )} \right )} \sqrt{\left|{\zeta - 1}\right|}} \sin{\left (\frac{t}{\tau} \sqrt{\zeta + 1} \sin{\left (\frac{1}{2} \operatorname{atan_{2}}{\left (0,\zeta - 1 \right )} \right )} \sqrt{\left|{\zeta - 1}\right|} \right )} - \zeta e^{\frac{t}{\tau} \sqrt{\zeta + 1} \cos{\left (\frac{1}{2} \operatorname{atan_{2}}{\left (0,\zeta - 1 \right )} \right )} \sqrt{\left|{\zeta - 1}\right|}} \cos{\left (\frac{t}{\tau} \sqrt{\zeta + 1} \sin{\left (\frac{1}{2} \operatorname{atan_{2}}{\left (0,\zeta - 1 \right )} \right )} \sqrt{\left|{\zeta - 1}\right|} \right )} - i \zeta e^{- \frac{t}{\tau} \sqrt{\zeta + 1} \cos{\left (\frac{1}{2} \operatorname{atan_{2}}{\left (0,\zeta - 1 \right )} \right )} \sqrt{\left|{\zeta - 1}\right|}} \sin{\left (\frac{t}{\tau} \sqrt{\zeta + 1} \sin{\left (\frac{1}{2} \operatorname{atan_{2}}{\left (0,\zeta - 1 \right )} \right )} \sqrt{\left|{\zeta - 1}\right|} \right )} + \zeta e^{- \frac{t}{\tau} \sqrt{\zeta + 1} \cos{\left (\frac{1}{2} \operatorname{atan_{2}}{\left (0,\zeta - 1 \right )} \right )} \sqrt{\left|{\zeta - 1}\right|}} \cos{\left (\frac{t}{\tau} \sqrt{\zeta + 1} \sin{\left (\frac{1}{2} \operatorname{atan_{2}}{\left (0,\zeta - 1 \right )} \right )} \sqrt{\left|{\zeta - 1}\right|} \right )} - i \sqrt{\zeta - 1} \sqrt{\zeta + 1} e^{\frac{t}{\tau} \sqrt{\zeta + 1} \cos{\left (\frac{1}{2} \operatorname{atan_{2}}{\left (0,\zeta - 1 \right )} \right )} \sqrt{\left|{\zeta - 1}\right|}} \sin{\left (\frac{t}{\tau} \sqrt{\zeta + 1} \sin{\left (\frac{1}{2} \operatorname{atan_{2}}{\left (0,\zeta - 1 \right )} \right )} \sqrt{\left|{\zeta - 1}\right|} \right )} + i \sqrt{\zeta - 1} \sqrt{\zeta + 1} e^{- \frac{t}{\tau} \sqrt{\zeta + 1} \cos{\left (\frac{1}{2} \operatorname{atan_{2}}{\left (0,\zeta - 1 \right )} \right )} \sqrt{\left|{\zeta - 1}\right|}} \sin{\left (\frac{t}{\tau} \sqrt{\zeta + 1} \sin{\left (\frac{1}{2} \operatorname{atan_{2}}{\left (0,\zeta - 1 \right )} \right )} \sqrt{\left|{\zeta - 1}\right|} \right )} + 2 \sqrt{\zeta^{2} - 1} e^{\frac{t \zeta}{\tau}} - \sqrt{\zeta^{2} - 1} e^{\frac{t}{\tau} \sqrt{\zeta + 1} \cos{\left (\frac{1}{2} \operatorname{atan_{2}}{\left (0,\zeta - 1 \right )} \right )} \sqrt{\left|{\zeta - 1}\right|}} \cos{\left (\frac{t}{\tau} \sqrt{\zeta + 1} \sin{\left (\frac{1}{2} \operatorname{atan_{2}}{\left (0,\zeta - 1 \right )} \right )} \sqrt{\left|{\zeta - 1}\right|} \right )} - \sqrt{\zeta^{2} - 1} e^{- \frac{t}{\tau} \sqrt{\zeta + 1} \cos{\left (\frac{1}{2} \operatorname{atan_{2}}{\left (0,\zeta - 1 \right )} \right )} \sqrt{\left|{\zeta - 1}\right|}} \cos{\left (\frac{t}{\tau} \sqrt{\zeta + 1} \sin{\left (\frac{1}{2} \operatorname{atan_{2}}{\left (0,\zeta - 1 \right )} \right )} \sqrt{\left|{\zeta - 1}\right|} \right )}\right)$$

That’s a really hairy expression, so let’s try to simplify.

The characteristic equation is the denominator of the transfer function

[7]:
ce = sympy.Eq(sympy.denom(G), 0)
ce
[7]:
$$s^{2} \tau^{2} + 2 s \tau \zeta + 1 = 0$$
[8]:
roots = sympy.roots(ce, s)
roots
[8]:
$$\left \{ \frac{1}{\tau} \left(- \zeta - \sqrt{\zeta - 1} \sqrt{\zeta + 1}\right) : 1, \quad \frac{1}{\tau} \left(- \zeta + \sqrt{\zeta - 1} \sqrt{\zeta + 1}\right) : 1\right \}$$

The shape of the inverse Laplace depends on the nature of the roots, which depends on the value of \(\zeta\)

Overdamped: \(\zeta>1\). Two distinct real roots

[9]:
invL(G.subs({zeta: 7})).simplify().expand()
[9]:
$$\frac{\sqrt{3} K}{24 \tau} e^{- \frac{7 t}{\tau}} e^{\frac{4 t}{\tau} \sqrt{3}} - \frac{\sqrt{3} K}{24 \tau} e^{- \frac{7 t}{\tau}} e^{- \frac{4 t}{\tau} \sqrt{3}}$$

Critically damped: \(\zeta=1\). Repeated roots.

[10]:
invL(G.subs({zeta: 1}))
[10]:
$$\frac{K t}{\tau^{2}} e^{- \frac{t}{\tau}}$$

Underdamped: \(0<\zeta<1\): a complex conjugate pair of roots

[11]:
r = invL(G.subs({zeta: 0.7}))
r
[11]:
$$\frac{1.40028008402801 K}{\tau} e^{- \frac{0.7 t}{\tau}} \sin{\left (\frac{0.714142842854285 t}{\tau} \right )}$$

We can get prettier results if we use Rationals instead of floats

[12]:
r = invL(G.subs({zeta: sympy.Rational(1, 2)}))
r
[12]:
$$\frac{2 \sqrt{3} K}{3 \tau} e^{- \frac{t}{2 \tau}} \sin{\left (\frac{\sqrt{3} t}{2 \tau} \right )}$$
[13]:
from ipywidgets import interact
[14]:
def secondorder(K_in, tau_in, zeta_in, tmax):
    values = {K: sympy.nsimplify(K_in), tau: sympy.nsimplify(tau_in), zeta: sympy.nsimplify(zeta_in)}
    stepresponse = sympy.re(invL(G.subs(values)/s))

    sympy.plot(stepresponse, (t, 0, tmax), ylim = [0, 10])
[15]:
interact(secondorder, K_in=(0, 10.), tau_in=(0., 10.), zeta_in=(0., 2), tmax=(30., 100));
[ ]:

[ ]: