Documentation
Tools for embedded systems
Loading...
Searching...
No Matches
Recursive LTI Systems Evaluation by transfer functions.

qLTISys is a class that evaluates single-input, single-output (SISO) transfer function models in real-valued systems. A transfer function is a model that describes the frequency-dependent response of a linear time-invariant system, and this class can handle both continuous-time and discrete-time systems. qLTISys can be used for simulating dynamic systems and implementing filters, compensators, or controllers.

Continous-time transfer functions

Here, the transfer function \( G(s) \) is the linear mapping of the Laplace transform of the input, \( U(s)= \mathcal{L}[u(t)]\), to the Laplace transform of the output \( Y(s)= \mathcal{L}[y(t)]\).

\( G(s) = \frac{N(s)}{D(s)} = \frac{ b_{0}s^{n} + b_{1}s^{n-1} + b_{2}s^{n-2} + ... + b_{n} }{ s^{n} + a_{1}s^{n-1} + a_{2}s^{n-2} + ... + a_{n} } \)

\( N(s) \) and \( D(s) \) are the numerator and denominator polynomials in descending powers of \(s\), respectively.

To instantiate a continuous transfer function, you should define a variable of type qLTISys_t, two arrays of N+1 elements with the coefficients of the polynomials for both, the numerator and denominator, and finally, an array of type qLTISys_ContinuosX_t to hold the N states of the system. Then, you can call qLTISys_Setup() to construct the system and set initial conditions. Subsequently, you can evaluate the system with a given input-signal by just calling qLTISys_Excite().

Attention
The user must ensure that the evaluation of the system is executed periodically at the required time step.

Example: Evaluate the given continuous transfer function

\( G(s) = \frac{ 2s^{2} + 3s + 6 }{ s^{3} + 6s^{2} + 11s + 16 } \)

#include <stdio.h>
#include <stdlib.h>
#include "bsp.h"
#include "qltisys.h"
#define SYS_ORDER ( 3 )
const TickType_t dt = 50; /*50mS time-step*/
qLTISys_t system;
float num[ SYS_ORDER+1 ] = { 0.0f, 2.0f, 3.0f, 6.0f };
float den[ SYS_ORDER+1 ] = { 1.0f, 6.0f, 11.0f, 16.0f };
qLTISys_ContinuosX_t x[ SYS_ORDER ];
void xTaskSystemSimulate( void *arg )
{
qLTISys_Setup( &system, num, den, x, 0, SYS_ORDER+1, (float)dt/1000.0f ) );
float ut, yt;
for( ;; ) {
ut = BSP_InputGet();
yt = qLTISys_Excite( &system, ut );
vTaskDelay( dt / portTICK_RATE_MS) ;
printf( "u(t) = %0.2f y(t) = %0.2f \r\n", ut, yt );
}
}
float qLTISys_Excite(qLTISys_t *const sys, float u)
Drives the LTI system recursively using the input signal provided.
Definition qltisys.c:61
int qLTISys_Setup(qLTISys_t *const sys, float *num, float *den, void *x, const size_t nb, const size_t na, const float dt)
Setup and initialize an instance of a LTI system.
Definition qltisys.c:155
A LTI system object.
Definition qltisys.h:52
Definition qnuma.h:19

Discrete-time transfer functions

The z-transform is used in discrete-time systems to deal with the relationship between an input signal \( u(t) \) and an output signal \( y(t) \) , so the transfer function is similarly written as \( G(z^{-1}) \) and is often referred to as the pulse-transfer function.

\( G(z^{-1}) = \frac{N(z^{-1})}{D(z^{-1})} = \frac{ b_{0} + b_{1}z^{-1} + b_{2}z^{-2} + ... + b_{m}z^{-m} }{ 1 + a_{1}z^{-1} + a_{2}z^{-2} + ... + a_{n}z^{-n} } \)

Discrete systems are instantiated in a similar way to continuous systems, but there are some differences. States are should be stored in an array of type qLTISys_DiscreteX_t. The size of polynomials can vary according to their order, and you should pass the QLTISYS_DISCRETE directive on qLTISys_Setup() in order to differentiate the system when it is being evaluated. Please take a look at the following example:

Example: Evaluate the given discrete transfer function

\( G(z^{-1}) = \frac{ 0.1 + 0.2z^{-1} + 0.3z^{-2} }{ 1 - 0.85z^{-1} + 0.02z^{-2} } \)

#include <stdio.h>
#include <stdlib.h>
#include "bsp.h"
#include "qltisys.h"
#define NB ( 3 )
#define NA ( 2 )
const TickType_t Ts = 100; /*100mS sample time*/
qLTISys_t system;
float num[ NB ] = { 0.1f, 0.2f, 0.3f };
float den[ NA+1 ] = { 1.0f, -0.85f, 0.02f };
void xTaskSystemSimulate( void *arg )
{
qLTISys_Setup( &system, num, den, xk, NB, NA, QLTISYS_DISCRETE );
float uk, yk;
for( ;; ) {
uk = BSP_InputGet();
yk = qLTISys_Excite( &system, uk );
vTaskDelay( Ts / portTICK_RATE_MS) ;
printf( "u(k) = %0.2f y(k) = %0.2f \r\n", uk, yk );
}
}
#define QLTISYS_DISCRETE
Macro to specify that the system is time-discrete.
Definition qltisys.h:30
float qLTISys_DiscreteX_t
Type to specify continuos states.
Definition qltisys.h:42