pythondifferential-equationstransfer-functionpython-control

How to simulate the time response of a system transfer function with python-control (IVP problem)?


I'm trying to demonstrate how to "solve" (simulate the solution) of differential equation initial value problems (IVP) using both the definition of the system transfer function and the python-control module. The fact is I'm really a newbie regarding control.

I have this simple differential as an example: y'' - 4y' + 13y = 0, with these initial conditions: y(0) = 1 and y'(0) = 0.

I achieve this transfer function by hand: Y(s) = (s - 4)/(s^2 - 4*s + 13).

So, in Python, I'm writing this little piece of code (note that y_ans is the answer of this differential IVP as seen here):

import numpy as np
import control as ctl
import matplotlib.pyplot as plt

t = np.linspace(0., 1.5, 100)
sys = ctl.tf([1.,-4.],[1.,-4.,13.])
T, yout, _ = ctl.forced_response(sys, T=t, X0=[1, 0])

y_ans = lambda x: 1/3*np.exp(2*x)*(3*np.cos(3*x) - 2*np.sin(3*x))

plt.plot(t, y_ans(t), '-.', color='gray', alpha=0.5, linewidth=3, label='correct answer')
plt.plot(T, yout, 'r', label='simulated')
plt.legend()

This code gets me this graph:

original plots

But when I insert a negative sign in front of yout, I got a match as I'd like it to be:

plt.plot(T, -yout, 'r', label='simulated') ### yout with negative sign

fliped simulation plot

What am I doing wrong? Python-control documentation is not very clear to me. Also, I don't know if my interpretation of X0 parameter for control.forced_response is correct. Is it possible to do this as I'm intended of doing?

Anyone who can shed a light on this subject is welcome to contribute.

EDIT

Setting X0 = [0,0] gives me this graph:

enter image description here


Solution

  • Thanks to the comment of @LutzLehmann, I've being thinking on the meaning of "encode twice" some stuff. So, back to square one, I realized that this transfer function incorporates both input (time or ramp) and initial conditions. It is actually an output. I need some sort of inverse laplace transform or, as I start to think, I'd need only to simulate it as it is, without further information.

    Therefore, I managed to use an impulse input (which laplace transform is equal to 1) and I was able to get an output that was exactly my tf simulated in time.

    import numpy as np
    import control as ctl
    import matplotlib.pyplot as plt
    
    t = np.linspace(0., 1.5, 100)
    sys = ctl.tf([1.,-4.],[1.,-4.,13.])
    T, yout = ctl.impulse_response(sys, T=t) # HERE is what I wanted
    
    y_ans = lambda x: 1/3*np.exp(2*x)*(3*np.cos(3*x) - 2*np.sin(3*x))
    
    plt.plot(t, y_ans(t), '-.', color='gray', alpha=0.5, linewidth=3, label='correct answer')
    plt.plot(T, yout, 'r', label='simulated')
    plt.legend()
    

    enter image description here

    Now I think I can show how to use python-control to indirectly simulate answers for differential equations. :-D