Documentation
Tools for embedded systems
Loading...
Searching...
No Matches
ltisys.hpp
1
9#ifndef QLIBS_LTISYS
10#define QLIBS_LTISYS
11
12#include <include/qlibs_types.hpp>
13#include <include/tdl.hpp>
14#include <include/numa.hpp>
15
16
20namespace qlibs {
28 /*only for continuousSystem*/
29 #if !defined( LTISYS_EVAL_MODEL_CONTROLLABLE ) || !defined( LTISYS_EVAL_MODEL_OBSERVABLE )
30 #define LTISYS_EVAL_MODEL_CONTROLLABLE
31 #endif
42
46 template<size_t order>
47 using continuousStates = nState[ order ];
48
52 template<size_t order>
53 using discreteStates = real_t[ order ];
54
60 template<size_t order>
61 struct continuousTF {
63 real_t num[ order+1 ];
64 real_t den[ order+1 ];
65 continuousStates<order> states = {};
75 continuousTF( const real_t ( &numerator )[ order + 1 ], const real_t ( &denominator )[ order + 1 ] )
76 {
77 static_assert( order >= 1 , "Order should be greater than 0" );
78 for ( size_t i = 0; i <= order; ++i ) {
79 num[ i ] = numerator[ i ];
80 den[ i ] = denominator[ i ];
81 }
82 }
83 };
84
94 constexpr size_t delayFromTime( const real_t Time, const real_t dt )
95 {
96 return static_cast<size_t>( ( Time/dt ) + 0.5_re );
97 }
98
111 template<size_t numberOfDelays>
113 private:
114 real_t buf[ numberOfDelays + 1 ];
115 tdl delay;
116 public:
122 transportDelay( const real_t initValue = 0.0_re )
123 {
124 static_assert( numberOfDelays >= 1 , "Delay taps should be greater than 0" );
125 delay.setup( buf, initValue);
126 }
132 real_t operator()( const real_t xInput ) noexcept
133 {
134 delay.insertSample( xInput );
135 return delay.getOldest();
136 }
137 };
138
144 template<size_t delay>
146
147
154 template<size_t NB, size_t NA>
155 struct discreteTF {
157 real_t num[ NB ];
158 real_t den[ NA ];
159 discreteStates<(NA>NB)? NA:NB> states = {};
169 discreteTF( const real_t ( &numerator )[ NB ], const real_t ( &denominator)[ NA ] ) {
170 for ( size_t i = 0; i < NB; ++i ) {
171 num[ i ] = numerator[ i ];
172 }
173 for ( size_t i = 0; i < NA; ++i ) {
174 den[ i ] = denominator[ i ];
175 }
176 }
177 };
178
179
183 class ltisys : public tdl {
184 protected:
186 real_t *a{ nullptr };
187 real_t *b{ nullptr };
188 size_t n{ 0U };
189 size_t na{ 0U };
190 size_t nb{ 0U };
191 real_t b0{ 0.0_re };
192 real_t min{ REAL_MIN };
193 real_t max{ REAL_MAX };
194 void normalizeTransferFunction( real_t *num,
195 real_t *den,
196 size_t n_num,
197 size_t n_den );
198 real_t saturate( real_t y );
200 virtual real_t update( const real_t u ) = 0;
202 public:
203 virtual ~ltisys() {}
204 ltisys() = default;
205
215 real_t excite( real_t u );
216
222 virtual bool isInitialized( void ) const = 0;
223
231 virtual bool setInitStates( const real_t *xi = nullptr ) = 0;
232
238 ltisysType getType( void ) const
239 {
240 return type;
241 }
242
252 bool setDelay( real_t * const w,
253 const size_t nD,
254 const real_t initVal = 0.0_re ) noexcept;
255
262 bool setSaturation( const real_t minV,
263 const real_t maxV ) noexcept;
264 };
265
271 class discreteSystem : public ltisys {
272 private:
273 real_t *xd{ nullptr };
274 real_t update( const real_t u ) override;
275 public:
276 virtual ~discreteSystem() {}
277
304 real_t *den,
305 real_t *x,
306 const size_t n_b,
307 const size_t n_a ) noexcept
308 {
309 (void)setup( num, den, x, n_b, n_a );
310 }
311
331 template<size_t NB, size_t NA>
332 discreteSystem( real_t (&num)[ NB ],
333 real_t (&den)[ NA ],
334 real_t *x ) noexcept
335 {
336 (void)setup( num, den, x, NB, NA );
337 }
338
344 template<size_t NB, size_t NA>
346 {
347 (void)setup( dtf.num, dtf.den, dtf.states, NB, NA );
348 }
349
375 bool setup( real_t *num,
376 real_t *den,
377 real_t *x,
378 const size_t n_b,
379 const size_t n_a ) noexcept;
380
400 template<size_t NB, size_t NA>
401 bool setup( real_t (&num)[ NB ],
402 real_t (&den)[ NA ],
403 real_t *x )
404 {
405 return setup( num, den, x, NB, NA );
406 }
407
414 template<size_t NB, size_t NA>
415 bool setup( discreteTF<NB, NA>& dtf ) noexcept
416 {
417 return setup( dtf.num, dtf.den, dtf.states, NB, NA );
418 }
419
425 bool isInitialized( void ) const override
426 {
427 return ( nullptr != xd ) && ( LTISYS_TYPE_DISCRETE == type );
428 }
429
438 bool setInitStates( const real_t *xi = nullptr ) override;
439
455 static real_t updateFIR( real_t *w,
456 const size_t wsize,
457 const real_t x,
458 const real_t * const c = nullptr );
459 };
460
466 class continuousSystem : public ltisys {
467 private:
468 real_t dt{ 1.0_re };
469 nState *xc{ nullptr };
470 real_t update( const real_t u ) override;
471 public:
472 virtual ~continuousSystem() {}
473
498 real_t *den,
499 nState *x,
500 const size_t nD,
501 const real_t dT ) noexcept
502 {
503 (void)setup( num, den, x, nD, dT );
504 }
505
512 template<size_t order>
514 {
515 (void)setup( ctf.num, ctf.den, ctf.states, order, dT );
516 }
517
538 template<size_t systemOrder>
539 continuousSystem( real_t (&num)[ systemOrder+1 ],
540 real_t (&den)[ systemOrder+1 ],
541 nState (&x)[ systemOrder ],
542 const real_t dT ) noexcept
543 {
544 (void)setup( num, den, x, systemOrder, dT );
545 }
546
571 bool setup( real_t *num,
572 real_t *den,
573 nState *x,
574 const size_t nD,
575 const real_t dT ) noexcept;
576
598 template<size_t systemOrder>
599 bool setup( real_t (&num)[ systemOrder+1 ],
600 real_t (&den)[ systemOrder+1 ],
601 nState (&x)[ systemOrder ],
602 const real_t dT ) noexcept
603 {
604 return setup( num, den, x, systemOrder, dT );
605 }
606
614 template<size_t order>
615 bool setup( continuousTF<order>& ctf, const real_t dT )
616 {
617 return setup( ctf.num, ctf.den, ctf.states, order, dT );
618 }
619
625 bool isInitialized( void ) const override
626 {
627 return ( nullptr != xc ) && ( LTISYS_TYPE_CONTINUOUS == type );
628 }
629
638 bool setInitStates( const real_t *xi = nullptr ) override;
639
653 };
654
656}
657
658#endif /*QLIBS_LTISYS*/
A LTI continuous system object.
Definition ltisys.hpp:466
virtual ~continuousSystem()
Definition ltisys.hpp:472
bool setInitStates(const real_t *xi=nullptr) override
Set the initial states for the continuous system.
Definition ltisys.cpp:188
continuousSystem(real_t(&num)[systemOrder+1], real_t(&den)[systemOrder+1], nState(&x)[systemOrder], const real_t dT) noexcept
Constructor for an instance of a LTI continuous system.
Definition ltisys.hpp:539
continuousSystem(real_t *num, real_t *den, nState *x, const size_t nD, const real_t dT) noexcept
Constructor for an instance of a LTI continuous system.
Definition ltisys.hpp:497
bool setup(real_t(&num)[systemOrder+1], real_t(&den)[systemOrder+1], nState(&x)[systemOrder], const real_t dT) noexcept
Setup and initialize an instance of a LTI continuous system.
Definition ltisys.hpp:599
continuousSystem(continuousTF< order > &ctf, const real_t dT)
Constructor for an instance of a LTI continuous system from a transfer function definition.
Definition ltisys.hpp:513
bool isInitialized(void) const override
Check if the LTI continuous system is initialized.
Definition ltisys.hpp:625
bool setup(real_t *num, real_t *den, nState *x, const size_t nD, const real_t dT) noexcept
Setup and initialize an instance of a LTI continuous system.
Definition ltisys.cpp:163
bool setup(continuousTF< order > &ctf, const real_t dT)
Setup and initialize an instance of a LTI continuous system from a transfer function definition.
Definition ltisys.hpp:615
bool setIntegrationMethod(integrationMethod m)
Set integration method of the continuous system.
Definition ltisys.cpp:269
A LTI discrete system object.
Definition ltisys.hpp:271
virtual ~discreteSystem()
Definition ltisys.hpp:276
bool setInitStates(const real_t *xi=nullptr) override
Set the initial states for the discrete system.
Definition ltisys.cpp:107
bool setup(real_t *num, real_t *den, real_t *x, const size_t n_b, const size_t n_a) noexcept
Setup and initialize an instance of the discrete LTI system.
Definition ltisys.cpp:128
static real_t updateFIR(real_t *w, const size_t wsize, const real_t x, const real_t *const c=nullptr)
Evaluate the discrete FIR filter by updating the delay lines of x inside the window w of size wsize w...
Definition ltisys.cpp:80
discreteSystem(discreteTF< NB, NA > &dtf) noexcept
Constructor for a the discrete LTI system from a transfer function definition.
Definition ltisys.hpp:345
bool setup(discreteTF< NB, NA > &dtf) noexcept
Setup and initialize an instance of the discrete LTI system from a transfer function definition.
Definition ltisys.hpp:415
bool setup(real_t(&num)[NB], real_t(&den)[NA], real_t *x)
Setup and initialize an instance of the discrete LTI system.
Definition ltisys.hpp:401
discreteSystem(real_t *num, real_t *den, real_t *x, const size_t n_b, const size_t n_a) noexcept
Constructor for a the discrete LTI system.
Definition ltisys.hpp:303
discreteSystem(real_t(&num)[NB], real_t(&den)[NA], real_t *x) noexcept
Constructor for a the discrete LTI system.
Definition ltisys.hpp:332
bool isInitialized(void) const override
Check if the LTI discrete system is initialized.
Definition ltisys.hpp:425
A LTI system base class.
Definition ltisys.hpp:183
virtual ~ltisys()
Definition ltisys.hpp:203
virtual bool isInitialized(void) const =0
Check if the LTI system is initialized.
ltisysType getType(void) const
Get the LTI system type.
Definition ltisys.hpp:238
virtual bool setInitStates(const real_t *xi=nullptr)=0
Set the initial states for the given system.
bool setDelay(real_t *const w, const size_t nD, const real_t initVal=0.0_re) noexcept
Set the input delay for LTI system.
Definition ltisys.cpp:37
ltisys()=default
real_t excite(real_t u)
Drives the LTI system recursively using the input signal provided.
Definition ltisys.cpp:65
bool setSaturation(const real_t minV, const real_t maxV) noexcept
Setup the output saturation for the LTI system.
Definition ltisys.cpp:51
A numerical state object.
Definition numa.hpp:50
A Tapped Delay Line (TDL) object.
Definition tdl.hpp:32
void setup(real_t *const area, const size_t n, const real_t initVal=0.0_re) noexcept
Setup and initialize a Tapped Delay Line (TDL) instance by setting the default optimal parameters.
real_t getOldest(void) const noexcept
Get the oldest sample from the TDL x(k-n)
void insertSample(const real_t sample) noexcept
Insert a new sample to the TDL removing the oldest sample.
Delays the input by a specified amount of time. You can use this class to simulate a time delay.
Definition ltisys.hpp:112
transportDelay(const real_t initValue=0.0_re)
Constructor for the transportDelay class.
Definition ltisys.hpp:122
real_t operator()(const real_t xInput) noexcept
Delays the input by a specified amount of time.
Definition ltisys.hpp:132
ltisysType
All the possible natures of a LTI system.
Definition ltisys.hpp:37
constexpr size_t delayFromTime(const real_t Time, const real_t dt)
Computes the number of discrete delays required for a specified amount of time using a defined time-s...
Definition ltisys.hpp:94
nState[order] continuousStates
Type to specify continuous states.
Definition ltisys.hpp:47
real_t[order] discreteStates
Type to specify discrete states.
Definition ltisys.hpp:53
@ LTISYS_TYPE_CONTINUOUS
Definition ltisys.hpp:39
@ LTISYS_TYPE_DISCRETE
Definition ltisys.hpp:40
@ LTISYS_TYPE_UNKNOWN
Definition ltisys.hpp:38
integrationMethod
An enum with all the available integration methods.
Definition numa.hpp:28
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
Continuous transfer function for easy LTI system definition.
Definition ltisys.hpp:61
continuousTF(const real_t(&numerator)[order+1], const real_t(&denominator)[order+1])
Constructor for the continuousTF class.
Definition ltisys.hpp:75
Discrete transfer function for easy LTI system definition.
Definition ltisys.hpp:155
discreteTF(const real_t(&numerator)[NB], const real_t(&denominator)[NA])
Constructor for the discreteTF class.
Definition ltisys.hpp:169