Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modeling a linear system with Python

I would like to simulate/model a closed-loop, linear, time-invariant system (specifically a locked PLL approximation) with python.

Each sub-block within the model has a known transfer function which is given in terms of complex frequency H(s) = K / ( s * tau + 1 ). Using the model, I would like to see how the system response as well as the noise response is affected as parameters (e.g. the VCO gain) are changed. This would involve using Bode plots and root-locus plots.

What Python modules should I seek out to get the job done?

like image 619
benpro Avatar asked Nov 15 '11 22:11

benpro


4 Answers

I know this is a bit old, but a search brought me to this question. I put this together when I couldn't find a good module for it. It's not much, but it's a good start if somebody else finds themselves here.

import matplotlib.pylab as plt
import numpy as np
import scipy.signal

def bode(G,f=np.arange(.01,100,.01)):
    plt.figure()
    jw = 2*np.pi*f*1j
    y = np.polyval(G.num, jw) / np.polyval(G.den, jw)
    mag = 20.0*np.log10(abs(y))
    phase = np.arctan2(y.imag, y.real)*180.0/np.pi % 360

    plt.subplot(211)
    #plt.semilogx(jw.imag, mag)
    plt.semilogx(f,mag)
    plt.grid()
    plt.gca().xaxis.grid(True, which='minor')

    plt.ylabel(r'Magnitude (db)')

    plt.subplot(212)
    #plt.semilogx(jw.imag, phase)
    plt.semilogx(f,phase)
    plt.grid()
    plt.gca().xaxis.grid(True, which='minor')
    plt.ylabel(r'Phase (deg)')
    plt.yticks(np.arange(0, phase.min()-30, -30))

    return mag, phase

f=scipy.signal.lti([1],[1,1])
bode(f)

Edit: I am back here because somebody upvoted this answer, you should try Control Systems Library. They have implemented the bulk of the Matlab control systems toolbox with matching syntax and everything.

like image 50
Matt Avatar answered Oct 02 '22 16:10

Matt


According to http://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.bode.html you can now use this:

from scipy import signal
import matplotlib.pyplot as plt

s1 = signal.lti([1], [1, 1])
w, mag, phase = signal.bode(s1)

plt.figure()
plt.semilogx(w, mag)    # bode magnitude plot
plt.figure()
plt.semilogx(w, phase)  # bode phase plot
plt.show()
like image 25
scls Avatar answered Oct 02 '22 15:10

scls


As @Matt said, I know this is old. But this came up as my first google hit, so I wanted to edit it.

You can use scipy.signal.lti to model linear, time invariant systems. That gives you lti.bode.

For an impulse response in the form of H(s) = (As^2 + Bs + C)/(Ds^2 + Es + F), you would enter h = scipy.signal.lti([A,B,C],[D,E,F]). To get the bode plot, you would do plot(*h.bode()[:2]).

like image 39
Scott Avatar answered Oct 02 '22 16:10

Scott


I got Bode plots working out this way, using python-control.

from matplotlib.pyplot import * # Grab MATLAB plotting functions
from control.matlab import *    # MATLAB-like functions


# Transfer functions for dynamics
G_modele = tf([1], [13500, 345, 1]);

# Use state space versions
G_modele = tf2ss(G_modele);

figure(1); 
bode(G_modele, dB=1);
show();

The code was mainly taken from this example which is very extensive

http://www.cds.caltech.edu/~murray/wiki/index.php/Python-control/Example:_Vertical_takeoff_and_landing_aircraft

like image 41
alainsanguinetti Avatar answered Oct 02 '22 17:10

alainsanguinetti