qlibs::ltisys 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. qlibs::ltisys 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 qlibs::continuousSystem, two arrays of N+1
elements with the coefficients of the polynomials for both, the numerator and denominator, and finally, an array of type qlibs::continuousStates to hold the N
states of the system. Then, you can call qlibs::continuousSystem::setup() to construct the system and set initial conditions. Subsequently, you can evaluate the system with a given input-signal by just calling qlibs::continuousSystem::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 <iostream>
#include <chrono>
#include <thread>
#include <qlibs.h>
void xTaskSystemSimulate( void )
{
std::chrono::milliseconds delay(static_cast<long long>( dt*1000 ) );
real_t num[] = { 0.0f, 2.0f, 3.0f, 6.0f };
real_t den[] = { 1.0f, 6.0f, 11.0f, 16.0f };
for( ;; ) {
ut = BSP_InputGet();
yt = gc.excite( ut );
std::this_thread::sleep_for(delay);
std::cout << "u(t) = " << ut << " y(t) = " << yt << std::endl;
}
}
A LTI continuous system object.
Definition ltisys.hpp:466
nState[order] continuousStates
Type to specify continuous states.
Definition ltisys.hpp:47
The qLibs++ library namespace.
Definition fp16.cpp:4
float real_t
A type to instantiate a real variable double-precision of 64-bits IEEE 754.
Definition qlibs_types.hpp:43
Alternatively, you can also use a simpler definition by employing the qlibs::continuousTF structure as follows:
#include <iostream>
#include <chrono>
#include <thread>
#include <qlibs.h>
void xTaskSystemSimulate( void )
{
std::chrono::milliseconds delay(static_cast<long long>( dt*1000 ) );
{ 0.0f, 2.0f, 3.0f, 6.0f },
{ 1.0f, 6.0f, 11.0f, 16.0f },
};
for( ;; ) {
ut = BSP_InputGet();
yt = gc.excite( ut );
std::this_thread::sleep_for(delay);
std::cout << "u(t) = " << ut << " y(t) = " << yt << std::endl;
}
}
Continuous transfer function for easy LTI system definition.
Definition ltisys.hpp:61
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 should be stored in an array of type qlibs::discreteStates. The size of polynomials can vary according to their order. 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 <iostream>
#include <chrono>
#include <thread>
#include <qlibs.h>
void xTaskSystemSimulate( void )
{
real_t num[] = { 0.1f 0.2f, 0.3f };
real_t den[] = { 1.0f, -0.85f, 0.02f };
for( ;; ) {
uk = BSP_InputGet();
yk = gc.exite( uk );
std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) );
std::cout << "u(k) = " << uk << " y(k) = " << yk << std::endl;
}
}
A LTI discrete system object.
Definition ltisys.hpp:271
real_t[order] discreteStates
Type to specify discrete states.
Definition ltisys.hpp:53
Alternatively, you can also use a simpler definition by employing the qlibs::discreteTF structure as follows:
#include <iostream>
#include <chrono>
#include <thread>
#include <qlibs.h>
void xTaskSystemSimulate( void )
{
{ 0.1f, 0.2f, 0.3f },
{ 1.0f, -0.85f, 0.02f },
};
for( ;; ) {
uk = BSP_InputGet();
yk = gc.excite( ut );
std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) );
std::cout << "u(k) = " << uk << " y(k) = " << yk << std::endl;
}
}
Discrete transfer function for easy LTI system definition.
Definition ltisys.hpp:155