AM243x Motor Control SDK  09.02.00
dcl_df22.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
3  *
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the
15  * distribution.
16  *
17  * * Neither the name of Texas Instruments Incorporated nor the names of
18  * its contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #ifndef _DCL_DF22_H_
35 #define _DCL_DF22_H_
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
50 #include "../dcl_common.h"
51 
52 //--- Direct Form 2 - 2nd order ----------------------------------------------
53 
57 typedef struct dcl_df22_sps
58 {
64 } DCL_DF22_SPS;
65 
66 #define DF22_SPS_DEFAULTS { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f }
67 
70 typedef _DCL_VOLATILE struct dcl_df22
71 {
72  /* compensator parameter */
78 
79  /* internal storage */
82 
83  /* miscellaneous */
87 
90 #define DF22_DEFAULTS { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, \
91  &(DCL_DF22_SPS)DF22_SPS_DEFAULTS, &(DCL_CSS)DCL_CSS_DEFAULTS }
92 
101 #define DF22_INT_DEFAULTS .x1=0.0f, .x2=0.0f, .sps=&(DCL_DF22_SPS)DF22_SPS_DEFAULTS, \
102  .css=&(DCL_CSS)DCL_CSS_DEFAULTS
103 
109 #define DCL_initDF22() &(DCL_DF22)DF22_DEFAULTS
110 
117 #define DCL_initDF22asParam(_b0,_b1,_b2,_a1,_a2) &(DCL_DF22){ .b0=_b0, .b1=_b1, \
118  .b2=_b2, .a1=_a1, .a2=_a2, .a3=_a3, DF22_INT_DEFAULTS }
119 
130 #define DCL_initDF22asSPS(df_ptr,sps_ptr) \
131 ({ \
132  DCL_DF22* new_df = (df_ptr) ? df_ptr : DCL_initDF22(); \
133  DCL_DF22_SPS* new_sps = (sps_ptr) ? sps_ptr : &(DCL_DF22_SPS)DF22_SPS_DEFAULTS; \
134  if(sps_ptr) \
135  { \
136  *new_df = (DCL_DF22){ (new_sps)->b0, (new_sps)->b1, (new_sps)->b2, (new_sps)->a1,\
137  (new_sps)->a2, 0.0f, 0.0f, (DCL_DF22_SPS*)new_sps, &(DCL_CSS)DCL_CSS_DEFAULTS }; \
138  } \
139  new_df; \
140 })
141 
148 {
149  dcl_interrupt_t ints;
150  ints = DCL_disableInts();
151  df->x1 = df->x2 = 0.0f;
152  DCL_restoreInts(ints);
153 }
154 
161 {
162  df->b0 = df->sps->b0;
163  df->b1 = df->sps->b1;
164  df->b2 = df->sps->b2;
165  df->a1 = df->sps->a1;
166  df->a2 = df->sps->a2;
167 }
168 
175 {
176  dcl_interrupt_t ints;
177  ints = DCL_disableInts();
178  df->b0 = df->sps->b0;
179  df->b1 = df->sps->b1;
180  df->b2 = df->sps->b2;
181  df->a1 = df->sps->a1;
182  df->a2 = df->sps->a2;
183  DCL_restoreInts(ints);
184 }
185 
196 {
197  if (DCL_setUpdateStatus(df))
198  {
201  return true;
202  }
203  return false;
204 }
205 
213 {
214  return(DCL_isStablePn2(1.0f, df->sps->a1, df->sps->a2));
215 }
216 
227 {
228 
229 #ifdef DCL_ERROR_HANDLING_ENABLED
230  uint32_t err_code = dcl_none;
231  err_code |= DCL_isZero(cimagf(zpk->z1) + cimagf(zpk->z2)) ? dcl_none : dcl_param_invalid_err;
232  err_code |= DCL_isZero(cimagf(zpk->p1) + cimagf(zpk->p2)) ? dcl_none : dcl_param_invalid_err;
233  if (err_code)
234  {
235  DCL_setError(df,err_code);
236  DCL_getErrorInfo(df);
238  }
239 #endif
240 
241  float32_t beta1 = -(float32_t) crealf(zpk->z1 + zpk->z2);
242  float32_t beta0 = (float32_t) crealf(zpk->z1 * zpk->z2);
243  float32_t alpha1 = -(float32_t) crealf(zpk->p1 + zpk->p2);
244  float32_t alpha0 = (float32_t) crealf(zpk->p1 * zpk->p2);
245 
246  float32_t T = df->css->T;
247  float32_t a0p = 4.0f + (alpha1 * 2.0f * T) + (alpha0 * T * T);
248 
249  df->sps->b0 = zpk->K * (4.0f + (beta1 * 2.0f * T) + (beta0 * T * T)) / a0p;
250  df->sps->b1 = zpk->K * (-8.0f + (2.0f * beta0 * T * T)) / a0p;
251  df->sps->b2 = zpk->K * (4.0f - (beta1 * 2.0f * T) + (beta0 * T * T)) / a0p;
252  df->sps->a1 = (-8.0f + (2.0f * alpha0 * T * T)) / a0p;
253  df->sps->a2 = (4.0f - (alpha1 * 2.0f * T) + (alpha0 * T * T)) / a0p;
254 }
255 
267 {
268 
269 #ifdef DCL_ERROR_HANDLING_ENABLED
270  uint32_t err_code = dcl_none;
271  err_code |= (z >= 0.0f) ? dcl_none : dcl_param_invalid_err;
272  err_code |= (wn >= 0.0f) ? dcl_none : dcl_param_invalid_err;
273  if (err_code)
274  {
275  DCL_setError(df,err_code);
276  DCL_getErrorInfo(df);
278  }
279 #endif
280 
281  float32_t T = df->css->T;
282  float32_t v1 = wn * wn * T * T;
283  float32_t a2p = 1.0f / (4.0f + (4.0f * z * wn * T) + v1);
284  df->sps->b0 = v1 * a2p;
285  df->sps->b1 = 2.0f * df->sps->b0;
286  df->sps->b2 = df->sps->b0;
287  df->sps->a1 = ((2.0f * v1) - 8.0f) * a2p;
288  df->sps->a2 = (4.0f - (4.0f * z * wn * T) + v1) * a2p;
289 }
290 
303 {
304 
305 #ifdef DCL_ERROR_HANDLING_ENABLED
306  uint32_t err_code = dcl_none;
307  err_code |= (Kp < 0.0f) ? dcl_param_range_err : dcl_none;
308  err_code |= (Ki < 0.0f) ? dcl_param_range_err : dcl_none;
309  err_code |= (Kd < 0.0f) ? dcl_param_range_err : dcl_none;
310  err_code |= ((fc < 0.0f) || (fc > (1.0f / (2.0f * df->css->T)))) ? dcl_param_range_err : dcl_none;
311  if (err_code)
312  {
313  DCL_setError(df,err_code);
314  DCL_getErrorInfo(df);
316  }
317 #endif
318 
319  float32_t T = df->css->T;
320  float32_t tau = 1 / (2.0f * CONST_PI * fc);
321  float32_t c1 = 2.0f / (T + (2.0f * tau));
322  float32_t c2 = c1 * (T - (2.0f * tau)) / 2.0f;
323  float32_t Kdp = Kd * c1;
324  df->sps->b0 = Kp * (1 + Ki + Kdp);
325  df->sps->b1 = Kp * (c2 - 1 + Ki*c2 - 2*Kdp);
326  df->sps->b2 = Kp * (-c2 + Kdp);
327  df->sps->a1 = c2 - 1;
328  df->sps->a2 = -c2;
329 }
330 
343 {
344 
345 #ifdef DCL_ERROR_HANDLING_ENABLED
346  uint32_t err_code = dcl_none;
347  err_code |= (Kp < 0.0f) ? dcl_param_range_err : dcl_none;
348  err_code |= (Ki < 0.0f) ? dcl_param_range_err : dcl_none;
349  err_code |= (Kd < 0.0f) ? dcl_param_range_err : dcl_none;
350  err_code |= (fc < 0.0f) ? dcl_param_range_err : dcl_none;
351  err_code |= (fc > (1.0f / (2.0f * df->css->T))) ? dcl_param_warn_err : dcl_none;
352  if (err_code)
353  {
354  DCL_setError(df,err_code);
355  DCL_getErrorInfo(df);
357  }
358 #endif
359 
360  float32_t T = df->css->T;
361  float32_t tau = 1.0f / (2.0f * CONST_PI * fc);
362  float32_t c1 = 2.0f / (T + (2.0f * tau));
363  float32_t c2 = c1 * (T - (2.0f * tau)) / 2.0f;
364  float32_t Kdp = Kd * c1;
365  df->sps->b0 = Kp + Ki + Kdp;
366  df->sps->b1 = (Kp * (c2 - 1)) + (Ki * c2) - (2.0f * Kdp);
367  df->sps->b2 = (-c2 * Kp) + Kdp;
368  df->sps->a1 = c2 - 1;
369  df->sps->a2 = -c2;
370 }
371 
380 {
381  float32_t v7 = (ek * df->b0) + df->x1;
382  df->x1 = (ek * df->b1) + df->x2 - (v7 * df->a1);
383  df->x2 = (ek * df->b2) - (v7 * df->a2);
384 
385  return(v7);
386 }
387 
397 {
398  return((ek * df->b0) + df->x1);
399 }
400 
409 {
410  df->x1 = (ek * df->b1) + df->x2 - (uk * df->a1);
411  df->x2 = (ek * df->b2) - (uk * df->a2);
412 }
413 
424 {
426  bool is_clamped = DCL_runClamp(&uk, Umax, Umin);
427  if(!is_clamped) DCL_runDF22PartialUpdate(df, ek, uk);
428  return(uk);
429 }
430 
433 #ifdef __cplusplus
434 }
435 #endif // extern "C"
436 
437 #endif // _DCL_DF22_H_
DCL_DF22_SPS::b2
float32_t b2
pos. coefficient to e(k-2)
Definition: dcl_df22.h:61
CONST_PI
#define CONST_PI
Local definitions of the mathematical constant pi.
Definition: dcl_macro.h:55
DCL_runDF22PartialCompute
_DCL_CRIT_ACCESS float32_t DCL_runDF22PartialCompute(DCL_DF22 *df, float32_t ek)
Immediate computation to obtain DF22 servo error without updating the controller.
Definition: dcl_df22.h:396
DCL_ZPK3::K
float32_t K
Real gain.
Definition: dcl_zpk3.h:69
DCL_isStableDF22
_DCL_CODE_ACCESS bool DCL_isStableDF22(DCL_DF22 *df)
Determines stability of the shadow compensator.
Definition: dcl_df22.h:212
dcl_df22::b2
float32_t b2
pos. coefficient to e(k-2)
Definition: dcl_df22.h:75
DCL_isStablePn2
_DCL_CODE_ACCESS bool DCL_isStablePn2(float32_t a0, float32_t a1, float32_t a2)
Determines stability of a second order polynomial with real coefficients P(z) = a0 z^2 + a1 z + a2.
Definition: dcl_stability.h:72
DCL_ZPK3::z2
float complex z2
Complex zeros 2.
Definition: dcl_zpk3.h:64
DCL_ZPK3::p2
float complex p2
Complex poles 2.
Definition: dcl_zpk3.h:67
DCL_setUpdateStatus
#define DCL_setUpdateStatus(p)
Macros to set and clear the update-in-progress flag.
Definition: dcl_css.h:115
dcl_none
@ dcl_none
No error.
Definition: dcl_error.h:57
dcl_df22::b1
float32_t b1
pos. coefficient to e(k-1)
Definition: dcl_df22.h:74
DCL_updateDF22NoCheck
_DCL_CODE_ACCESS void DCL_updateDF22NoCheck(DCL_DF22 *df)
Loads DF22 tuning parameter from its SPS parameter with interrupt protection.
Definition: dcl_df22.h:174
DCL_loadDF22asParallelPID
_DCL_CODE_ACCESS void DCL_loadDF22asParallelPID(DCL_DF22 *df, float32_t Kp, float32_t Ki, float32_t Kd, float32_t fc)
Loads the shadow DF22 compensator coefficients to emulate a parallel form PID.
Definition: dcl_df22.h:342
DCL_runErrorHandler
#define DCL_runErrorHandler(ptr)
Prototype for basic error handler.
Definition: dcl_error.h:108
DCL_clearUpdateStatus
#define DCL_clearUpdateStatus(p)
Definition: dcl_css.h:116
DCL_DF22
_DCL_VOLATILE struct dcl_df22 DCL_DF22
DCL_updateDF22
_DCL_CODE_ACCESS bool DCL_updateDF22(DCL_DF22 *df)
A conditional update based on the update flag. If the update status is set, the function will update ...
Definition: dcl_df22.h:195
DCL_forceUpdateDF22
_DCL_CODE_ACCESS void DCL_forceUpdateDF22(DCL_DF22 *df)
Loads DF22 tuning parameter from its SPS parameter without interrupt protection.
Definition: dcl_df22.h:160
_DCL_CODE_ACCESS
#define _DCL_CODE_ACCESS
Defines the scope of dcl functions.
Definition: dcl_common.h:63
DCL_loadDF22asZPK
_DCL_CODE_ACCESS void DCL_loadDF22asZPK(DCL_DF22 *df, DCL_ZPK3 *zpk)
Loads the DF22 shadow coefficients from a ZPK3 description.
Definition: dcl_df22.h:226
DCL_loadDF22asSeriesPID
_DCL_CODE_ACCESS void DCL_loadDF22asSeriesPID(DCL_DF22 *df, float32_t Kp, float32_t Ki, float32_t Kd, float32_t fc)
Loads the shadow DF22 compensator coefficients to emulate a series form PID.
Definition: dcl_df22.h:302
DCL_ZPK3::p1
float complex p1
Complex poles 1.
Definition: dcl_zpk3.h:66
DCL_runDF22Clamp
_DCL_CRIT_ACCESS float32_t DCL_runDF22Clamp(DCL_DF22 *df, float32_t ek, float32_t Umax, float32_t Umin)
Executes a 2nd order Direct Form 2 controller with clamp.
Definition: dcl_df22.h:423
DCL_resetDF22
_DCL_CODE_ACCESS void DCL_resetDF22(DCL_DF22 *df)
Resets DF22 internal storage data with interrupt protection.
Definition: dcl_df22.h:147
dcl_interrupt_t
uint32_t dcl_interrupt_t
Definition: dcl_common.h:107
DCL_runDF22PartialUpdate
_DCL_CRIT_ACCESS void DCL_runDF22PartialUpdate(DCL_DF22 *df, float32_t ek, float32_t uk)
Update DF22 controller based on pre-computed control effort.
Definition: dcl_df22.h:408
dcl_df22
DCL_DF22 object for storing df22 specific parameters.
Definition: dcl_df22.h:71
DCL_DF22_SPS::a2
float32_t a2
neg. coefficient to u(k-2)
Definition: dcl_df22.h:63
DCL_isZero
#define DCL_isZero(x)
Determines floating point numerical proximity to zero.
Definition: dcl_macro.h:77
dcl_param_range_err
@ dcl_param_range_err
Parameter range exceeded.
Definition: dcl_error.h:58
dcl_df22::a1
float32_t a1
neg. coefficient to u(k-1)
Definition: dcl_df22.h:76
dcl_df22::css
DCL_CSS * css
configuration & debugging
Definition: dcl_df22.h:85
dcl_df22::b0
float32_t b0
pos. coefficient to e(k)
Definition: dcl_df22.h:73
dcl_df22::a2
float32_t a2
neg. coefficient to u(k-2)
Definition: dcl_df22.h:77
DCL_DF22_SPS
Defines DCL_DF22 shadow parameter set used for updating compensator parameter.
Definition: dcl_df22.h:58
dcl_df22::sps
DCL_DF22_SPS * sps
updates compensator parameter
Definition: dcl_df22.h:84
dcl_param_warn_err
@ dcl_param_warn_err
Parameter warning.
Definition: dcl_error.h:60
DCL_loadDF22asZwn
_DCL_CODE_ACCESS void DCL_loadDF22asZwn(DCL_DF22 *df, float32_t z, float32_t wn)
Loads the DF22 shadow coefficients from damping ratio and un-damped natural frequency using sample ra...
Definition: dcl_df22.h:266
DCL_DF22_SPS::b1
float32_t b1
pos. coefficient to e(k-1)
Definition: dcl_df22.h:60
DCL_CSS
Defines the controller common support structure.
Definition: dcl_css.h:57
DCL_restoreInts
#define DCL_restoreInts(v)
Definition: dcl_common.h:106
dcl_param_invalid_err
@ dcl_param_invalid_err
Parameter not valid.
Definition: dcl_error.h:59
DCL_runClamp
_DCL_CODE_ACCESS bool DCL_runClamp(float32_t *data, float32_t Umax, float32_t Umin)
Saturates a control variable and returns true if either limit is exceeded.
Definition: dcl_clamp.h:59
DCL_ZPK3
Defines the DCL_ZPK3 structure.
Definition: dcl_zpk3.h:62
DCL_runDF22
_DCL_CRIT_ACCESS float32_t DCL_runDF22(DCL_DF22 *df, float32_t ek)
Executes a 2nd order Direct Form 2 controller.
Definition: dcl_df22.h:379
_DCL_VOLATILE
#define _DCL_VOLATILE
Defines volatile for DCL strctures.
Definition: dcl_common.h:79
dcl_df22::x2
float32_t x2
x2 = b2*e(k-2) - a2*u(k-2)
Definition: dcl_df22.h:81
DCL_DF22_SPS::a1
float32_t a1
neg. coefficient to u(k-1)
Definition: dcl_df22.h:62
DCL_getErrorInfo
#define DCL_getErrorInfo(ptr)
Macro to store error info in CSS.
Definition: dcl_error.h:98
DCL_setError
#define DCL_setError(ptr, code)
Macro to set error code in CSS.
Definition: dcl_error.h:80
_DCL_CRIT_ACCESS
#define _DCL_CRIT_ACCESS
Defines the scope of critical dcl functions.
Definition: dcl_common.h:70
dcl_df22::x1
float32_t x1
x1 = b1*e(k-1) - a1*u(k-1) + x2
Definition: dcl_df22.h:80
float32_t
float float32_t
Definition: dcl_common.h:58
DCL_DF22_SPS::b0
float32_t b0
pos. coefficient to e(k)
Definition: dcl_df22.h:59
DCL_ZPK3::z1
float complex z1
Complex zeros 1.
Definition: dcl_zpk3.h:63
DCL_disableInts
#define DCL_disableInts()
Define enable and disable interrupt operations.
Definition: dcl_common.h:105