lti-freq-domain-toolbox
(require lti-freq-domain-toolbox) | |
package: lti-freq-domain-toolbox |
The lti-freq-domain-toolbox is a collection of functions written in Racket, which lets Control Systems engineers study LTI (linear time-invariant) dynamical systems - from PID controllers to more complex systems.
It can perform tasks such as:
computation of the overall transfer function (tf) of a system that is modeled by interconnected tfs in the s-domain
generation of its Bode and Nyquist plots
numerical computation of its time domain response
Known issues & limitations: check the package’s README.md file.
1 Representing a dynamical system
1.1 Introduction
A linear time-invariant (LTI) dynamical system is represented as a circuit of interconnected elements: transfer functions (tfs), adders and blocks.
A block of elements is a means for achieving abstraction. Circuit elements such as transfer functions (tfs), adders and even other blocks can be "stored" inside a block, and form a whole that can be handled as an element itself.
1.2 Elements
Implementation assumption:
Each block of elements has only one input (another tf, adder or block) and multiple outputs.
Multiple inputs can be achieved by adding in front of it an adder.
A new block is defined using the block procedure. A parent block inside which the block is stored can be optionally specified.
(define new-block1 (block)) (define new-block-inside-block-a (block a))
The four blocks a, b, c, d are predefined for speed
Build new blocks only when needed and if there are elements to be stored inside
If all the elements inside a block are not connected, the value of the block’s overall tf is that of the latest tf stored
Re-run the program before defining new circuits in already used blocks
Implementation assumption:
Each tf has only one input (another tf, adder or block) and multiple outputs.
Multiple inputs can be achieved by adding in front of it an adder.
To define a transfer function, the lists of the coefficients of its nominator and denominator polynomials, as well as the block it belongs to must be specified, using the tf procedure.
(define new-tf1 (tf '(4 3 6) '(2 1) b))
Implementation assumption:
Each adder has multiple inputs and multiple outputs
An adder is an element used to add multiple input signals, and provide one or multiple outputs. It can be placed in front of a block or tf, to provide them with multiple inputs. An adder is created and placed inside a block using the adder procedure.
(define tf1 (tf '(1 0) '(2 1 0) b)) (define tf2 (tf '(5 0) '(5 1 0) b)) (define new-adder1 (adder b)) (connect tf1 new-adder1) (connect tf2 new-adder1)
1.3 Connecting elements
Elements (tfs, adders and blocks) are connected serially using the connect procedure:
(connect tf1 tf2) (connect tf2 adder1) (connect tf3 adder1) (connect a b)
The connection of two elements has no effect if they are not elements of the same block.
Complex connection designs can be achieved by defining all serial connections between elements.
2 Plot functions
All plot functions listed below take as inputs blocks, not transfer functions.
2.1 Frequency domain
procedure
(bode b1) → void?
b1 : block?
(bode (pd-controller 5 8 a))
This example works because the pd-controller function is defined so that it returns as result the block in which it is installed in.
procedure
(compare b1 b2) → void?
b1 : block? b2 : block?
(define c1 (block)) (define c2 (block)) (define tf1 (tf '(1) '(1 0 1) c1)) (define tf2 (tf '(5) '(1 0 1) c2)) (compare c1 c2) (compare (pid-controller 6 7 3 a) (pi-controller 7 8 b))
The second example works because the pid-controller and pi-controller functions return as result the block they are installed in.
procedure
(evolve b1) → void?
b1 : block?
(evolve (pid-controller 6 7 3 a)) (evolve (pid-controller 5 20 4 a))
The function prints the value of the parameter computed, and the Bode magnitude and phase plots of the system.
(tune (pi-controller 5 'y a) '(= AR 140) 0.01) (tune (pi-controller 5 'y a) '(= ph -50) 0.01)
procedure
(nyquist b1) → void?
b1 : block?
(define tf1 (tf '(1) '(1 1 1) a)) (nyquist a)
2.2 Time domain
(step (sine a) 5) (define tf2 (tf '(1) '(0.3 0.1 1) b)) (step b 5)
procedure
(impulse b1) → void?
b1 : block?
(impulse (sine a)) (define tf2 (tf '(1) '(0.3 0.1 1) b)) (impulse b)
procedure
(trajectory b1) → void?
b1 : block?
(trajectory (sine a)) (define tf2 (tf '(1) '(0.3 0.1 1) b)) (trajectory b)
3 Predefined circuits
Circuits can be defined so that they return as result the block they are stored in. Therefore, they can be used directly as inputs to functions:
All plot functions listed below take as inputs blocks, not transfer functions.
(bode (feedback-loop-test1 a))
instead of:
(feedback-loop-test1 a) (bode a)
That isn’t the case when using tfs, because a tf does not return the block in which it is installed.
3.1 Basic components
procedure
b1 : block?
(bode (integrator a))
procedure
b1 : block?
(bode (sine a))
procedure
b1 : block?
(bode (phase-delay-circuit a))
3.2 Controllers
The PI, PD and PID controllers are defined by specifying the proportional (Kp), integral (Ki) and/or derivative (Kd) gains respectively, as well as the block to be stored in.
procedure
Kp : real? Ki : real? b1 : block?
(bode (pi-controller 5 8 a))
procedure
Kp : real? Kd : real? b1 : block?
(bode (pd-controller 5 8 a))
procedure
Kp : real? Ki : real? Kd : real? b1 : block?
(bode (pid-controller 5 8 4 a))
3.3 Filters
A Chebyshev Type I filter is defined by specifying the polynomial order (n), ripple factor (e) and cutoff frequency (w0) parameters, along with the block to be stored in.
procedure
n : exact-positive-integer? e : real? w0 : positive? b1 : block?
(bode (chebyshev-type1 6 1 1 a))
3.4 Delay components
by approximating it using a Padé polynomial
by adding delay as a function f(w) of the frequency w in the overall block’s tf (only for the s-domain)
The pade-delay procedure adds a time delay component to a block, modeled by a Padé polynomial of order [6/6] approximating the function e^(-t).
procedure
t : positive? b1 : block?
(step (pade-delay 5 (sine a)) 1)
4 Circuit simplifications
In order to compute the overall transfer function (tf) of a system modeled by interconnected elements inside a block, a simplification of its structure must be performed.
This simplification is performed by running a set of algorithms inside the block. Each algorithm may run more than once. During each algorithm run, a simplification may or may not be performed.
To be able to test and review this whole process, logging checkpoints have been implemented, with respective messages available to be displayed.
4.1 Display modes
procedure
(set-logger-mode! logger-mode) → void?
logger-mode : symbol?
(set-logger-mode! 'checkpoints)
The set-logger-mode! procedure can adjust the volume of simplifications-related messages displayed, in terms of the four following levels:
’nil: no messages are displayed (default)
’algorithms: only messages regarding the algorithms run are displayed
’simplifications: only messages regarding the algorithms run and the simplifications performed are displayed
’checkpoints: all messages at all checkpoints are displayed