[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));

[ ]:



[ ]: