Skip to content

Commit bd14729

Browse files
author
camilo
committed
Small fixes and addons. Bump to 1.3.6
1 parent 521fa8a commit bd14729

File tree

9 files changed

+233
-26
lines changed

9 files changed

+233
-26
lines changed

check/qlibs_cpp_test.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,12 @@ void test_ltisys( void )
277277
t += dt;
278278
}
279279

280+
pidController controller;
281+
auto othergains = 1.5_kc + 0.1_ki;
282+
controller.setup(1.5_kc + 0.1_ki, dt);
283+
auto gains = controller.getGains();
284+
285+
cout << "kc = "<< gains.Kc << " ki = "<< gains.Ki << endl;
280286
cout << "discreteSystem"<< endl;
281287
//discreteTF<3,3> dtf= {
282288
// { 0.1f, 0.2f, 0.3f },

library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"maintainer": true
1717
}
1818
],
19-
"version": "1.3.5",
19+
"version": "1.3.6",
2020
"license": "MIT",
2121
"frameworks": "arduino",
2222
"platforms": "*"

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=qlibs
2-
version=1.3.5
2+
version=1.3.6
33
license=MIT
44
author=J. Camilo Gomez C. <[email protected]>
55
maintainer=J. Camilo Gomez C. <[email protected]>

src/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cmake_minimum_required( VERSION 3.2 )
22
project( qlibs-cpp
3-
VERSION 1.3.5
3+
VERSION 1.3.6
44
DESCRIPTION "A collection of useful C++ libraries for embedded systems"
55
LANGUAGES CXX )
66

src/include/ltisys.hpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,10 @@ namespace qlibs {
8888
constexpr explicit timeDelay(real_t v) : value(v) {}
8989
/** @cond **/
9090
constexpr size_t operator()(const real_t dt) const {
91-
return static_cast<size_t>((value / dt) + 0.5f);
91+
return static_cast<size_t>( ( value/dt ) + 0.5_re);
9292
}
9393
constexpr size_t operator[](const real_t dt) const {
94-
return static_cast<size_t>((value / dt) + 0.5f);
94+
return static_cast<size_t>( ( value/dt ) + 0.5_re);
9595
}
9696
/** @endcond **/
9797
};
@@ -234,8 +234,8 @@ namespace qlibs {
234234
size_t na{ 0U };
235235
size_t nb{ 0U };
236236
real_t b0{ 0.0_re };
237-
real_t min{ REAL_MIN };
238-
real_t max{ REAL_MAX };
237+
real_t min{ -REAL_MAX };
238+
real_t max{ +REAL_MAX };
239239
void normalizeTransferFunction( real_t *num,
240240
real_t *den,
241241
size_t n_num,
@@ -257,8 +257,32 @@ namespace qlibs {
257257
* @param[in] u A sample of the input signal that excites the system
258258
* @return The system response.
259259
*/
260+
261+
/**
262+
* @brief Drives the LTI system recursively using the provided input
263+
* sample.
264+
* @details This function evaluates the system response based on the
265+
* given input signal and the internal state of the system. It must
266+
* be called periodically with a fixed time step to maintain correct
267+
* system behavior.
268+
*
269+
* @pre The instance must be properly initialized before calling this method.
270+
*
271+
* @note The user is responsible for ensuring that this function is invoked at consistent
272+
* intervals equal to the system's time step @a dt. This timing should
273+
* be enforced using a hardware timer, software timer, real-time task,
274+
* or another reliable timing mechanism.
275+
*
276+
* @param[in] u A new input sample that excites (drives) the system.
277+
* @return The system's output (response) at the current time step.
278+
*/
260279
real_t excite( real_t u );
261280

281+
/// @copydoc excite(real_t)
282+
real_t operator()( const real_t u ) {
283+
return excite( u );
284+
}
285+
262286
/**
263287
* @brief Check if the LTI system is initialized.
264288
* @return @c true if the system has been initialized, otherwise

src/include/numa.hpp

Lines changed: 107 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ namespace qlibs {
8686
const real_t sn_2 = 0.0_re ) noexcept;
8787

8888
/**
89-
* @brief Perform a numerical integration step.
89+
* @brief Perform a numerical integration step by using the specified
90+
* integration method.
9091
* @param[in] s The input signal
9192
* @param[in] dt The time-step given in seconds.
9293
* @param[in] bUpdate Flag to update the states ( @c true by default).
@@ -97,7 +98,8 @@ namespace qlibs {
9798
const bool bUpdate = true ) noexcept;
9899

99100
/**
100-
* @brief Perform a numerical derivation step by using the delta rule.
101+
* @brief Perform a numerical derivation step by using the specified
102+
* derivation method.
101103
* @param[in] s The input signal
102104
* @param[in] dt The time-step given in seconds.
103105
* @param[in] bUpdate Flag to update the states ( @c true by default).
@@ -108,8 +110,11 @@ namespace qlibs {
108110
const bool bUpdate = true ) noexcept;
109111

110112
/**
111-
* @brief Set integration method .
112-
* @param[in] m The desired integration method. Use one of the following:
113+
* @brief Sets the numerical integration method.
114+
* @details Configures the method used to approximate the integral of
115+
* input values. This allows the user to select from several common
116+
* numerical integration techniques.
117+
* @param[in] m The desired integration method. Supported options:
113118
*
114119
* @c ::INTEGRATION_RECTANGULAR : Integrate using the Rectangular rule.
115120
*
@@ -119,24 +124,35 @@ namespace qlibs {
119124
*
120125
* @c ::INTEGRATION_QUADRATIC : Integrate using a parabola fit to three points.
121126
*
122-
* @return @c true on success, otherwise return @c false.
127+
* @note The effectiveness and accuracy of each method depend on the
128+
* signal characteristics and time step.
129+
*
130+
* @return @c true if the method was successfully set; @c false otherwise.
123131
*/
124132
inline void setIntegrationMethod( integrationMethod m ) noexcept
125133
{
126134
iMethod = m;
127135
}
128136

129137
/**
130-
* @brief Set derivation method.
131-
* @param[in] m The desired derivation method. Use one of the following:
138+
* @brief Sets the numerical derivation method.
139+
* @details Configures the method used to compute the numerical
140+
* derivative of input values. Different methods offer varying accuracy
141+
* and responsiveness depending on signal characteristics.
142+
*
143+
* @param[in] m The desired derivation method. Supported options:
132144
*
133-
* @c ::DERIVATION_2POINTS : (default) Derivative using two points.
145+
* @c ::DERIVATION_2POINTS : (default) Uses a simple two-point
146+
* (first-order backward) difference.
134147
*
135148
* @c ::DERIVATION_BACKWARD : Derivative using the three-point backward-difference.
136149
*
137150
* @c ::DERIVATION_FORWARD : Derivative using the three-point forward-difference.
138151
*
139-
* @return @c true on success, otherwise return @c false.
152+
* @note Choose the method based on the required balance between
153+
* accuracy and latency.
154+
*
155+
* @return @c true if the method was successfully set; @c false otherwise.
140156
*/
141157
inline void setDerivationMethod( derivationMethod m ) noexcept
142158
{
@@ -203,6 +219,88 @@ namespace qlibs {
203219
}
204220
/*! @endcond */
205221

222+
/**
223+
* @brief A numerical integration class.
224+
* @details A numerical integration class that can be used to compute
225+
* in real-time the numerical approximation of an integral for data values
226+
* sampled periodically. It supports optional output saturation limits.
227+
*/
228+
class integrator : public nState, private nonCopyable {
229+
private:
230+
real_t dt;
231+
real_t min{ -REAL_MAX };
232+
real_t max{ +REAL_MAX };
233+
public:
234+
virtual ~integrator() {}
235+
236+
/**
237+
* @brief Constructs an integrator block with a given @a timeStep time
238+
* and optional initial condition.
239+
* @param[in] timeStep The fixed time step (dt) used to compute the
240+
* integration.
241+
* @param[in] initialCondition The initial output value of the
242+
* integrator. Default is 0.0.
243+
* @note It is assumed that input samples will be provided at regular
244+
* intervals of timeStep.
245+
*/
246+
integrator( const real_t timeStep,
247+
const real_t initialCondition = 0.0_re );
248+
249+
/**
250+
* @brief Sets the saturation limits for the integrator output.
251+
* @param[in] minV The minimum value the output can reach.
252+
* @param[in] maxV The maximum value the output can reach.
253+
* @return @c true if the limits are valid and applied; @c false
254+
* otherwise (e.g., minV > maxV).
255+
* @note If not set, the output is unbounded.
256+
*/
257+
bool setSaturation( const real_t minV, const real_t maxV ) noexcept;
258+
259+
/**
260+
* @brief Performs one step of numerical integration.
261+
* @param[in] xDot The input value to be integrated
262+
* @return The integrated value (i.e., the output of the integrator)
263+
* after applying saturation.
264+
* @note This should be called at intervals equal to the time step provided in the constructor.
265+
*/
266+
real_t operator()( const real_t xDot );
267+
};
268+
269+
/**
270+
* @brief A numerical derivative class.
271+
* @details A numerical derivative class that can be used to compute
272+
* in real-time the numerical approximations of derivatives for data values
273+
* sampled periodically.
274+
*/
275+
class derivative : public nState, private nonCopyable {
276+
private:
277+
real_t dt;
278+
public:
279+
virtual ~derivative() {}
280+
281+
/**
282+
* @brief Constructs a derivative block with a given @a timeStep and
283+
* optional initial condition.
284+
* @param[in] timeStep The fixed time step (dt) used to compute the
285+
* derivative.
286+
* @param[in] initialCondition The initial input value. Default is @c 0.0
287+
* @note It is assumed that input samples will be provided at regular
288+
* intervals of timeStep.
289+
*/
290+
derivative( const real_t timeStep,
291+
const real_t initialCondition = 0.0_re );
292+
293+
/**
294+
* @brief Computes the numerical derivative based on the current
295+
* input value.
296+
* @param[in] xt The current input value.
297+
* @return The estimated derivative of the input signal.
298+
* @note This should be called at intervals equal to the time step
299+
* provided in the constructor.
300+
*/
301+
real_t operator()( const real_t xt );
302+
};
303+
206304
/** @}*/
207305
}
208306

src/include/pid.hpp

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,37 @@ namespace qlibs {
5656
* @brief PID Gains structure
5757
*/
5858
struct pidGains {
59-
real_t Kc; /*!< Proportional gain */
60-
real_t Ki; /*!< Integral gain */
61-
real_t Kd; /*!< Derivative gain */
59+
real_t Kc{ 0.0_re }; /*!< Proportional gain */
60+
real_t Ki{ 0.0_re }; /*!< Integral gain */
61+
real_t Kd{ 0.0_re }; /*!< Derivative gain */
62+
63+
/*! @cond */
64+
constexpr pidGains() = default;
65+
constexpr pidGains(real_t kc, real_t ki, real_t kd)
66+
: Kc(kc), Ki(ki), Kd(kd) {}
67+
68+
constexpr pidGains operator+(const pidGains& other) const {
69+
return pidGains{
70+
this->Kc + other.Kc,
71+
this->Ki + other.Ki,
72+
this->Kd + other.Kd
73+
};
74+
}
75+
/*! @endcond */
6276
};
6377

78+
/*! @cond */
79+
constexpr pidGains operator"" _kc(long double v) {
80+
return {static_cast<real_t>(v), 0.0_re, 0.0_re};
81+
}
82+
constexpr pidGains operator"" _ki(long double v) {
83+
return {0.0_re, static_cast<real_t>(v), 0.0_re};
84+
}
85+
constexpr pidGains operator"" _kd(long double v) {
86+
return {0.0_re, 0.0_re, static_cast<real_t>(v)};
87+
}
88+
/*! @endcond */
89+
6490
/**
6591
* @brief A PID Auto-tuning object
6692
* @details The instance should be bound to a configured PID controller by
@@ -333,6 +359,14 @@ namespace qlibs {
333359
real_t control( const real_t w,
334360
const real_t y ) noexcept;
335361

362+
363+
/// @copydoc control(const real_t, const real_t)
364+
real_t operator()( const real_t w,
365+
const real_t y )
366+
{
367+
return control( w, y );
368+
}
369+
336370
/**
337371
* @brief Binds the specified instance to enable the PID controller auto
338372
* tuning algorithm.

src/numa.cpp

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,49 @@ real_t nState::derive( const real_t s,
6464

6565
return ds;
6666
}
67-
/*===========================================================================*/
67+
/*===========================================================================*/
68+
integrator::integrator(const real_t timeStep, const real_t initialCondition )
69+
: dt( timeStep )
70+
{
71+
init( initialCondition, initialCondition, initialCondition );
72+
}
73+
/*===========================================================================*/
74+
bool integrator::setSaturation( const real_t minV,
75+
const real_t maxV ) noexcept
76+
{
77+
bool retValue = false;
78+
79+
if ( maxV > minV ) {
80+
min = minV;
81+
max = maxV;
82+
retValue = true;
83+
}
84+
return retValue;
85+
}
86+
/*===========================================================================*/
87+
real_t integrator::operator()( const real_t xDot ) {
88+
real_t xt;
89+
90+
xt = integrate( xDot, dt );
91+
if ( xt > max ) {
92+
xt = max;
93+
}
94+
else if ( xt < min ) {
95+
xt = min;
96+
}
97+
else {
98+
/*nothing to do*/
99+
}
100+
101+
return xt;
102+
}
103+
/*===========================================================================*/
104+
derivative::derivative(const real_t timeStep, const real_t initialCondition )
105+
: dt( timeStep )
106+
{
107+
init( initialCondition, initialCondition, initialCondition );
108+
}
109+
/*===========================================================================*/
110+
real_t derivative::operator()( const real_t xt ) {
111+
return derive( xt, dt );
112+
}

0 commit comments

Comments
 (0)