7.6

## 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

### 1Representing a dynamical system

#### 1.1Introduction

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.2Elements

 procedure(block) → block? (block parent-block) → block? parent-block : block?

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

Notes:
• 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

 procedure(tf nom-coeffs denom-coeffs b1) → tf? nom-coeffs : (listof real?) denom-coeffs : (listof real?) b1 : block?

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.3Connecting elements

Elements (tfs, adders and blocks) are connected serially using the connect procedure:

 procedure(connect e1 e2) → element? e1 : element? e2 : element?
 (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.

### 2Plot functions

All plot functions listed below take as inputs blocks, not transfer functions.

#### 2.1Frequency domain

 procedure(bode b1) → void? b1 : block?
The bode function takes as input a block. It computes and prints its overall tf, Bode magnitude and phase plots, and characteristic numbers.

(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?
The compare function takes as inputs two different blocks. It computes and prints comparatively their overall tfs, Bode magnitude and phase plots.

 (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?
The evolve function takes as input a block. It computes and prints its overall tf and its Bode magnitude and phase plots, storing the results. The next time it is called, it prints the current block’s Bode plot on top of the last one stored.

 (evolve (pid-controller 6 7 3 a)) (evolve (pid-controller 5 20 4 a))

 procedure(tune b1 condition freq) → void? b1 : block? condition : list? freq : positive?
The tune function can be used in order to compute the value of a single system’s parameter, so that the system achieves a specific performance. It takes as inputs a block, an equality condition regarding the amplitude response AR or the phase shift ph, and the frequency at which this equality condition must be satisfied.

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?
The nyquist function takes as input a block. It computes and prints its overall tf, Nyquist plot, and characteristic numbers.

 (define tf1 (tf '(1) '(1 1 1) a)) (nyquist a)

#### 2.2Time domain

 procedure(step b1 gain) → void? b1 : block? gain : real?
The step function takes as inputs a block and a gain number. It computes and prints the block’s tf, the block’s tf with gain added, and the step time response of the system.

 (step (sine a) 5) (define tf2 (tf '(1) '(0.3 0.1 1) b)) (step b 5)

 procedure(impulse b1) → void? b1 : block?
The impulse function takes as input a block. It computes and prints the block’s tf, and its impulse time response.

 (impulse (sine a)) (define tf2 (tf '(1) '(0.3 0.1 1) b)) (impulse b)

 procedure(trajectory b1) → void? b1 : block?
The trajectory function takes as input a block. It computes and prints the block’s tf, and its time domain df(t)/dt - f(t) trajectory plot.

 (trajectory (sine a)) (define tf2 (tf '(1) '(0.3 0.1 1) b)) (trajectory b)

### 3Predefined 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))

 (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.1Basic components

 procedure(integrator b1) → block? b1 : block?

(bode (integrator a))

 procedure(sine b1) → block? b1 : block?

(bode (sine a))

 procedure(phase-delay-circuit b1) → block? b1 : block?

(bode (phase-delay-circuit a))

#### 3.2Controllers

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(pi-controller Kp Ki b1) → block? Kp : real? Ki : real? b1 : block?

(bode (pi-controller 5 8 a))

 procedure(pd-controller Kp Kd b1) → block? Kp : real? Kd : real? b1 : block?

(bode (pd-controller 5 8 a))

 procedure(pid-controller Kp Ki Kd b1) → block? Kp : real? Ki : real? Kd : real? b1 : block?

(bode (pid-controller 5 8 4 a))

#### 3.3Filters

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(chebyshev-type1 n e w0 b1) → block? n : exact-positive-integer? e : real? w0 : positive? b1 : block?

(bode (chebyshev-type1 6 1 1 a))

#### 3.4Delay components

Delay can be modeled in two ways:
• 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(pade-delay t b1) → block? t : positive? b1 : block?

(step (pade-delay 5 (sine a)) 1)