Modeling a linear system with Python

Question:

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?

Asked By: benpro

||

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.

Answered By: Matt

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]).

Answered By: Scott

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()
Answered By: scls

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

Answered By: alainsanguinetti
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.