AM263x Motor Control SDK  09.02.00
dcl_df23.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_DF23_H_
35 #define _DCL_DF23_H_
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
50 #include "../dcl_common.h"
51 
52 //--- Direct Form 2 - 3rd order ----------------------------------------------
53 
57 typedef struct dcl_df23_sps
58 {
66 } DCL_DF23_SPS;
67 
68 #define DF23_SPS_DEFAULTS { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }
69 
72 typedef _DCL_VOLATILE struct dcl_df23
73 {
74  /* compensator parameter */
82 
83  /* internal storage */
87 
88  /* miscellaneous */
92 
95 #define DF23_DEFAULTS { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, \
96  0.0f, 0.0f, 0.0f, 0.0f, 0.0f, \
97  &(DCL_DF23_SPS)DF23_SPS_DEFAULTS, &(DCL_CSS)DCL_CSS_DEFAULTS }
98 
107 #define DF23_INT_DEFAULTS .x1=0.0f, .x2=0.0f, .x3=0.0f, \
108 .sps=&(DCL_DF23_SPS)DF23_SPS_DEFAULTS, .css=&(DCL_CSS)DCL_CSS_DEFAULTS
109 
115 #define DCL_initDF23() &(DCL_DF23)DF23_DEFAULTS
116 
123 #define DCL_initDF23asParam(_b0,_b1,_b2,_b3,_a1,_a2,_a3) &(DCL_DF23){ .b0=_b0, .b1=_b1, \
124  .b2=_b2, .b3=_b3, .a1=_a1, .a2=_a2, .a3=_a3, DF23_INT_DEFAULTS }
125 
136 #define DCL_initDF23asSPS(df_ptr,sps_ptr) \
137 ({ \
138  DCL_DF23* new_df = (df_ptr) ? df_ptr : DCL_initDF23(); \
139  DCL_DF23_SPS* new_sps = (sps_ptr) ? sps_ptr : &(DCL_DF23_SPS)DF23_SPS_DEFAULTS;\
140  if(sps_ptr) \
141  { \
142  *new_df = (DCL_DF23){ (new_sps)->b0, (new_sps)->b1, (new_sps)->b2, \
143  (new_sps)->b3,(new_sps)->a1, (new_sps)->a2, (new_sps)->a3, 0.0f, \
144  0.0f, 0.0f, (DCL_DF23_SPS*)new_sps, &(DCL_CSS)DCL_CSS_DEFAULTS }; \
145  } \
146  new_df; \
147 })
148 
155 {
156  dcl_interrupt_t ints;
157  ints = DCL_disableInts();
158  df->x1 = df->x2 = df->x3 = 0.0f;
159  DCL_restoreInts(ints);
160 }
161 
168 {
169  df->b0 = df->sps->b0;
170  df->b1 = df->sps->b1;
171  df->b2 = df->sps->b2;
172  df->b3 = df->sps->b3;
173  df->a1 = df->sps->a1;
174  df->a2 = df->sps->a2;
175  df->a3 = df->sps->a3;
176 }
177 
184 {
185  dcl_interrupt_t ints;
186  ints = DCL_disableInts();
187  df->b0 = df->sps->b0;
188  df->b1 = df->sps->b1;
189  df->b2 = df->sps->b2;
190  df->b3 = df->sps->b3;
191  df->a1 = df->sps->a1;
192  df->a2 = df->sps->a2;
193  df->a3 = df->sps->a3;
194  DCL_restoreInts(ints);
195 }
196 
207 {
208  if (DCL_setUpdateStatus(df))
209  {
212  return true;
213  }
214  return false;
215 }
216 
224 {
225  return(DCL_isStablePn3(1.0f, df->sps->a1, df->sps->a2, df->sps->a3));
226 }
227 
237 {
238 #ifdef DCL_ERROR_HANDLING_ENABLED
239  uint32_t err_code = dcl_none;
240  err_code |= DCL_isZero(cimagf(zpk->z1) + cimagf(zpk->z2) + cimagf(zpk->z3)) ? dcl_none : dcl_param_invalid_err;
241  err_code |= DCL_isZero(cimagf(zpk->p1) + cimagf(zpk->p2) + cimagf(zpk->p3)) ? dcl_none : dcl_param_invalid_err;
242  if (err_code)
243  {
244  DCL_setError(df,err_code);
245  DCL_getErrorInfo(df);
247  }
248 #endif
249 
250  float32_t beta2 = -(float32_t) crealf(zpk->z1 + zpk->z2 + zpk->z3);
251  float32_t beta1 = (float32_t) crealf((zpk->z1 * zpk->z2) + (zpk->z2 * zpk->z3) + (zpk->z1 * zpk->z3));
252  float32_t beta0 = -(float32_t) crealf(zpk->z1 * zpk->z2 * zpk->z3);
253 
254  float32_t alpha2 = -(float32_t) crealf(zpk->p1 + zpk->p2 + zpk->p3);
255  float32_t alpha1 = (float32_t) crealf((zpk->p1 * zpk->p2) + (zpk->p2 * zpk->p3) + (zpk->p1 * zpk->p3));
256  float32_t alpha0 = -(float32_t) crealf(zpk->p1 * zpk->p2 * zpk->p3);
257 
258  float32_t T = df->css->T;
259  float32_t a0p = 8.0f + (alpha2 * 4.0f * T) + (alpha1 * 2.0f * T * T) + (alpha0 * T * T * T);
260 
261  df->sps->b0 = zpk->K * (8.0f + (beta2 * 4.0f * T) + (beta1 * 2.0f * T * T) + (beta0 * T * T * T)) / a0p;
262  df->sps->b1 = zpk->K * (-24.0f - (beta2 * 4.0f * T) + (beta1 * 2.0f * T * T) + (3.0f * beta0 * T * T * T)) / a0p;
263  df->sps->b2 = zpk->K * (24.0f - (beta2 * 4.0f * T) - (beta1 * 2.0f * T * T) + (3.0f * beta0 * T * T * T)) / a0p;
264  df->sps->b3 = zpk->K * (-8.0f + (beta2 * 4.0f * T) - (beta1 * 2.0f * T * T) + (beta0 * T * T * T)) / a0p;
265 
266  df->sps->a1 = (-24.0f - (alpha2 * 4.0f * T) + (alpha1 * 2.0f * T * T) + (3.0f * alpha0 * T * T * T)) / a0p;
267  df->sps->a2 = (24.0f - (alpha2 * 4.0f * T) - (alpha1 * 2.0f * T * T) + (3.0f * alpha0 * T * T * T)) / a0p;
268  df->sps->a3 = (-8.0f + (alpha2 * 4.0f * T) - (alpha1 * 2.0f * T * T) + (alpha0 * T * T * T)) / a0p;
269 }
270 
279 {
280  float32_t v7 = (ek * df->b0) + df->x1;
281  df->x1 = (ek * df->b1) + df->x2 - (v7 * df->a1);
282  df->x2 = (ek * df->b2) + df->x3 - (v7 * df->a2);
283  df->x3 = (ek * df->b3) - (v7 * df->a3);
284  return(v7);
285 }
286 
296 {
297  return((ek * df->b0) + df->x1);
298 }
299 
308 {
309  df->x1 = (ek * df->b1) + df->x2 - (uk * df->a1);
310  df->x2 = (ek * df->b2) + df->x3 - (uk * df->a2);
311  df->x3 = (ek * df->b3) - (uk * df->a3);
312 }
313 
324 {
326  bool is_clamped = DCL_runClamp(&uk, Umax, Umin);
327  if(!is_clamped) DCL_runDF23PartialUpdate(df, ek, uk);
328  return(uk);
329 }
330 
333 #ifdef __cplusplus
334 }
335 #endif // extern "C"
336 
337 #endif // _DCL_DF23_H_
DCL_isStablePn3
_DCL_CODE_ACCESS bool DCL_isStablePn3(float32_t a0, float32_t a1, float32_t a2, float32_t a3)
Determines stability of a third order polynomial with real coefficients P(z) = a0 z^3 + a1 z^2 + a2 z...
Definition: dcl_stability.h:93
DCL_runDF23PartialUpdate
_DCL_CRIT_ACCESS void DCL_runDF23PartialUpdate(DCL_DF23 *df, float32_t ek, float32_t uk)
Update DF22 controller based on pre-computed control effort.
Definition: dcl_df23.h:307
dcl_df23::x2
float32_t x2
x2 = b2*e(k-2) - a2*u(k-2) + x3
Definition: dcl_df23.h:85
DCL_ZPK3::K
float32_t K
Real gain.
Definition: dcl_zpk3.h:69
DCL_DF23_SPS::a1
float32_t a1
neg. coefficient to u(k-1)
Definition: dcl_df23.h:63
DCL_isStableDF23
_DCL_CODE_ACCESS bool DCL_isStableDF23(DCL_DF23 *df)
Determines stability of the shadow compensator.
Definition: dcl_df23.h:223
DCL_DF23_SPS::a3
float32_t a3
neg. coefficient to u(k-3)
Definition: dcl_df23.h:65
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_df23::css
DCL_CSS * css
configuration & debugging
Definition: dcl_df23.h:90
DCL_runErrorHandler
#define DCL_runErrorHandler(ptr)
Prototype for basic error handler.
Definition: dcl_error.h:108
dcl_df23::b0
float32_t b0
pos. coefficient to e(k)
Definition: dcl_df23.h:75
DCL_clearUpdateStatus
#define DCL_clearUpdateStatus(p)
Definition: dcl_css.h:116
DCL_runDF23
_DCL_CRIT_ACCESS float32_t DCL_runDF23(DCL_DF23 *df, float32_t ek)
Executes a 3rd order Direct Form 2 controller.
Definition: dcl_df23.h:278
DCL_DF23_SPS::b3
float32_t b3
pos. coefficient to e(k-3)
Definition: dcl_df23.h:62
_DCL_CODE_ACCESS
#define _DCL_CODE_ACCESS
Defines the scope of dcl functions.
Definition: dcl_common.h:63
dcl_df23::a2
float32_t a2
neg. coefficient to u(k-2)
Definition: dcl_df23.h:80
DCL_ZPK3::p1
float complex p1
Complex poles 1.
Definition: dcl_zpk3.h:66
DCL_loadDF23asZPK
_DCL_CODE_ACCESS void DCL_loadDF23asZPK(DCL_DF23 *df, DCL_ZPK3 *zpk)
Loads the DF23 shadow coefficients from a ZPK3 description.
Definition: dcl_df23.h:236
dcl_df23::x1
float32_t x1
x1 = b1*e(k-1) - a1*u(k-1) + x2
Definition: dcl_df23.h:84
dcl_interrupt_t
uint32_t dcl_interrupt_t
Definition: dcl_common.h:107
DCL_ZPK3::z3
float complex z3
Complex zeros 3.
Definition: dcl_zpk3.h:65
DCL_DF23_SPS::a2
float32_t a2
neg. coefficient to u(k-2)
Definition: dcl_df23.h:64
dcl_df23::a3
float32_t a3
neg. coefficient to u(k-3)
Definition: dcl_df23.h:81
dcl_df23::b1
float32_t b1
pos. coefficient to e(k-1)
Definition: dcl_df23.h:76
DCL_isZero
#define DCL_isZero(x)
Determines floating point numerical proximity to zero.
Definition: dcl_macro.h:77
DCL_updateDF23NoCheck
_DCL_CODE_ACCESS void DCL_updateDF23NoCheck(DCL_DF23 *df)
Updates DF23 parameter from its SPS parameter with interrupt protection.
Definition: dcl_df23.h:183
DCL_DF23_SPS::b0
float32_t b0
pos. coefficient to e(k)
Definition: dcl_df23.h:59
DCL_forceUpdateDF23
_DCL_CODE_ACCESS void DCL_forceUpdateDF23(DCL_DF23 *df)
Loads DF23 tuning parameter from its SPS parameter without interrupt protection.
Definition: dcl_df23.h:167
dcl_df23::x3
float32_t x3
x3 = b3*e(k-3) - a3*u(k-3)
Definition: dcl_df23.h:86
dcl_df23::sps
DCL_DF23_SPS * sps
updates compensator parameter
Definition: dcl_df23.h:89
DCL_DF23_SPS::b1
float32_t b1
pos. coefficient to e(k-1)
Definition: dcl_df23.h:60
DCL_DF23_SPS::b2
float32_t b2
pos. coefficient to e(k-2)
Definition: dcl_df23.h:61
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_ZPK3::p3
float complex p3
Complex poles 3.
Definition: dcl_zpk3.h:68
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_VOLATILE
#define _DCL_VOLATILE
Defines volatile for DCL strctures.
Definition: dcl_common.h:79
DCL_runDF23PartialCompute
_DCL_CRIT_ACCESS float32_t DCL_runDF23PartialCompute(DCL_DF23 *df, float32_t ek)
Immediate computation to obtain DF23 servo error without updating the controller.
Definition: dcl_df23.h:295
dcl_df23::b2
float32_t b2
pos. coefficient to e(k-2)
Definition: dcl_df23.h:77
DCL_updateDF23
_DCL_CODE_ACCESS bool DCL_updateDF23(DCL_DF23 *df)
A conditional update based on the update flag. If the update status is set, the function will update ...
Definition: dcl_df23.h:206
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_df23::a1
float32_t a1
neg. coefficient to u(k-1)
Definition: dcl_df23.h:79
_DCL_CRIT_ACCESS
#define _DCL_CRIT_ACCESS
Defines the scope of critical dcl functions.
Definition: dcl_common.h:70
DCL_DF23_SPS
Defines DCL_DF23 shadow parameter set used for updating compensator parameter.
Definition: dcl_df23.h:58
DCL_runDF23Clamp
_DCL_CRIT_ACCESS float32_t DCL_runDF23Clamp(DCL_DF23 *df, float32_t ek, float32_t Umax, float32_t Umin)
Executes a 3rd order Direct Form 2 controller with clamp.
Definition: dcl_df23.h:323
DCL_DF23
_DCL_VOLATILE struct dcl_df23 DCL_DF23
float32_t
float float32_t
Definition: dcl_common.h:58
dcl_df23
DCL_DF23 object for storing df23 specific parameters.
Definition: dcl_df23.h:73
DCL_resetDF23
_DCL_CODE_ACCESS void DCL_resetDF23(DCL_DF23 *df)
Resets DF23 internal storage data with interrupt protection.
Definition: dcl_df23.h:154
dcl_df23::b3
float32_t b3
pos. coefficient to e(k-3)
Definition: dcl_df23.h:78
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