AM263x Motor Control SDK  09.02.00
dcl_df13.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_DF13_H_
35 #define _DCL_DF13_H_
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
54 #include "../dcl_common.h"
55 
56 //--- Direct Form 1 - 3rd order ----------------------------------------------
57 
61 typedef struct dcl_df13_sps {
70 } DCL_DF13_SPS;
71 
72 #define DF13_SPS_DEFAULTS { 0.25f, 0.25f, 0.25f, 0.25f, 0.0f, 0.0f, 0.0f, 0.0f }
73 
76 typedef _DCL_VOLATILE struct dcl_df13
77 {
78  /* compensator parameter */
86 
87  /* internal storage */
94 
98 
99  /* miscellaneous */
103 
106 #define DF13_DEFAULTS { 0.25f, 0.25f, 0.25f, 0.25f, 0.0f, 0.0f, 0.0f, \
107  0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, \
108  &(DCL_DF13_SPS)DF13_SPS_DEFAULTS, &(DCL_CSS)DCL_CSS_DEFAULTS }
109 
118 #define DF13_INT_DEFAULTS .d1=0.0f, .d2=0.0f, .d3=0.0f, .d4=0.0f, .d5=0.0f, \
119  .d6=0.0f, .a0=0.0f, .d0=0.0f, .d7=0.0f, \
120  .sps=&(DCL_DF13_SPS)DF13_SPS_DEFAULTS, .css=&(DCL_CSS)DCL_CSS_DEFAULTS
121 
127 #define DCL_initDF13() &(DCL_DF13)DF13_DEFAULTS
128 
135 #define DCL_initDF13asParam(_b0,_b1,_b2,_b3,_a1,_a2,_a3) &(DCL_DF13){ .b0=_b0, .b1=_b1, \
136  .b2=_b2, .b3=_b3, .a1=_a1, .a2=_a2, .a3=_a3, DF13_INT_DEFAULTS }
137 
148 #define DCL_initDF13asSPS(df_ptr,sps_ptr) \
149 ({ \
150  DCL_DF13* new_df = (df_ptr) ? df_ptr : DCL_initDF13(); \
151  DCL_DF13_SPS* new_sps = (sps_ptr) ? sps_ptr : &(DCL_DF13_SPS)DF13_SPS_DEFAULTS; \
152  if(sps_ptr) \
153  { \
154  *new_df =(DCL_DF13){ (new_sps)->b0, (new_sps)->b1, (new_sps)->b2, (new_sps)->b3, \
155  (new_sps)->a1, (new_sps)->a2, (new_sps)->a3, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, \
156  0.0f, 0.0f, 0.0f, (DCL_DF13_SPS*)new_sps, &(DCL_CSS)DCL_CSS_DEFAULTS }; \
157  } \
158  new_df; \
159 })
160 
168 {
169  dcl_interrupt_t ints;
170  ints = DCL_disableInts();
171  df->d1 = df->d2 = df->d3 = df->d4 = df->d5 = df->d6 = 0.0f;
172  DCL_restoreInts(ints);
173 }
174 
181 {
182  df->b0 = df->sps->b0;
183  df->b1 = df->sps->b1;
184  df->b2 = df->sps->b2;
185  df->b3 = df->sps->b3;
186  df->a1 = df->sps->a1;
187  df->a2 = df->sps->a2;
188  df->a3 = df->sps->a3;
189 }
190 
197 {
198  dcl_interrupt_t ints;
199  ints = DCL_disableInts();
200  df->b0 = df->sps->b0;
201  df->b1 = df->sps->b1;
202  df->b2 = df->sps->b2;
203  df->b3 = df->sps->b3;
204  df->a1 = df->sps->a1;
205  df->a2 = df->sps->a2;
206  df->a3 = df->sps->a3;
207  DCL_restoreInts(ints);
208 }
209 
220 {
221  if (DCL_getUpdateStatus(df))
222  {
225  return true;
226  }
227  return false;
228 }
229 
237 {
238  return(DCL_isStablePn3(1.0f, df->sps->a1, df->sps->a2, df->sps->a3));
239 }
240 
250 {
251 #ifdef DCL_ERROR_HANDLING_ENABLED
252  uint32_t err_code = dcl_none;
253  err_code |= DCL_isZero(cimagf(zpk->z1) + cimagf(zpk->z2) + cimagf(zpk->z3)) ? dcl_none : dcl_param_invalid_err;
254  err_code |= DCL_isZero(cimagf(zpk->p1) + cimagf(zpk->p2) + cimagf(zpk->p3)) ? dcl_none : dcl_param_invalid_err;
255  if (err_code)
256  {
257  DCL_setError(df,err_code);
258  DCL_getErrorInfo(df);
260  }
261 #endif
262 
263  float32_t beta2 = -(float32_t) crealf(zpk->z1 + zpk->z2 + zpk->z3);
264  float32_t beta1 = (float32_t) crealf((zpk->z1 * zpk->z2) + (zpk->z2 * zpk->z3) + (zpk->z1 * zpk->z3));
265  float32_t beta0 = -(float32_t) crealf(zpk->z1 * zpk->z2 * zpk->z3);
266 
267  float32_t alpha2 = -(float32_t) crealf(zpk->p1 + zpk->p2 + zpk->p3);
268  float32_t alpha1 = (float32_t) crealf((zpk->p1 * zpk->p2) + (zpk->p2 * zpk->p3) + (zpk->p1 * zpk->p3));
269  float32_t alpha0 = -(float32_t) crealf(zpk->p1 * zpk->p2 * zpk->p3);
270 
271  float32_t T = df->css->T;
272 
273  float32_t a0p = 8.0f + (alpha2 * 4.0f * T) + (alpha1 * 2.0f * T * T) + (alpha0 * T * T * T);
274 
275  df->sps->b0 = zpk->K * (8.0f + (beta2 * 4.0f * T) + (beta1 * 2.0f * T * T) + (beta0 * T * T * T)) / a0p;
276  df->sps->b1 = zpk->K * (-24.0f - (beta2 * 4.0f * T) + (beta1 * 2.0f * T * T) + (3.0f * beta0 * T * T * T)) / a0p;
277  df->sps->b2 = zpk->K * (24.0f - (beta2 * 4.0f * T) - (beta1 * 2.0f * T * T) + (3.0f * beta0 * T * T * T)) / a0p;
278  df->sps->b3 = zpk->K * (-8.0f + (beta2 * 4.0f * T) - (beta1 * 2.0f * T * T) + (beta0 * T * T * T)) / a0p;
279 
280  df->sps->a1 = (-24.0f - (alpha2 * 4.0f * T) + (alpha1 * 2.0f * T * T) + (3.0f * alpha0 * T * T * T)) / a0p;
281  df->sps->a2 = (24.0f - (alpha2 * 4.0f * T) - (alpha1 * 2.0f * T * T) + (3.0f * alpha0 * T * T * T)) / a0p;
282  df->sps->a3 = (-8.0f + (alpha2 * 4.0f * T) - (alpha1 * 2.0f * T * T) + (alpha0 * T * T * T)) / a0p;
283 }
284 
293 {
294  float32_t v4 = (ek * df->b0) + (df->d1 * df->b1) + (df->d2 * df->b2) + (df->d3 * df->b3) - (df->d4 * df->a1) - (df->d5 * df->a2) - (df->d6 * df->a3);
295  df->d3 = df->d2;
296  df->d2 = df->d1;
297  df->d1 = ek;
298  df->d6 = df->d5;
299  df->d5 = df->d4;
300  df->d4 = v4;
301 
302  return(v4);
303 }
304 
314 {
315  float32_t v4 = (ek * df->b0) + (df->d1 * df->b1) + (df->d2 * df->b2) + (df->d3 * df->b3) - (df->d4 * df->a1) - (df->d5 * df->a2) - (df->d6 * df->a3);
316  return(v4);
317 }
318 
327 {
328  df->d3 = df->d2;
329  df->d2 = df->d1;
330  df->d1 = ek;
331  df->d6 = df->d5;
332  df->d5 = df->d4;
333  df->d4 = uk;
334 }
335 
344 /*
345  * \details Previously, C28 version of DCL did not implement a function
346  * to run DF13 with clamp. Instead, user had to implement a routine
347  * similar to the following:
348  *
349  * \code{.c} extern DCL_DF13 df;
350  * extern float32_t ek, uk;
351  * float32_t vk = 0;
352  *
353  * float32_t uk = DCL_runDF13_C2/C5(df, ek, vk);
354  * bool is_clamped = DCL_runClamp_C1/C2(&uk, Umax, Umin)
355  * if (!is_clamped)
356  * {
357  * vk = DCL_runDF13_C3/C6(df, ek, uk);
358  * }
359  *
360  * // A new function DCL_runDF13Clamp() was implemented to replace it,
361  * // therefore, user may change the aformentioned routine to just:
362  * uk = DCL_runDF13Clamp(df, ek, Umax, Umin);
363  * \endcode
364  */
367 {
369  bool is_clamped = DCL_runClamp(&uk, Umax, Umin);
370  if(!is_clamped) DCL_runDF13PartialUpdate(df, ek, uk);
371  return(uk);
372 }
373 
384 {
385  p->d4 = (ek * p->b0) + vk;
386 
387  return(p->d4);
388 }
389 
400 {
401  float32_t v9;
402 
403  v9 = (ek * p->b1) + (p->d1 * p->b2) + (p->d2 * p->b3) - (uk * p->a1) - (p->d5 * p->a2) - (p->d6 * p->a3);
404  p->d2 = p->d1;
405  p->d1 = ek;
406  p->d6 = p->d5;
407  p->d5 = uk;
408 
409  return(v9);
410 }
411 
414 #ifdef __cplusplus
415 }
416 #endif // extern "C"
417 
418 #endif // _DCL_DF13_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_DF13_SPS::b2
float32_t b2
pos. coefficient to e(k-2)
Definition: dcl_df13.h:64
DCL_ZPK3::K
float32_t K
Real gain.
Definition: dcl_zpk3.h:69
DCL_loadDF13asZPK
_DCL_CODE_ACCESS void DCL_loadDF13asZPK(DCL_DF13 *df, DCL_ZPK3 *zpk)
Loads the DF13 shadow coefficients from a ZPK3 description.
Definition: dcl_df13.h:249
DCL_ZPK3::z2
float complex z2
Complex zeros 2.
Definition: dcl_zpk3.h:64
DCL_isStableDF13
_DCL_CODE_ACCESS bool DCL_isStableDF13(DCL_DF13 *df)
Determines stability of the shadow compensator.
Definition: dcl_df13.h:236
dcl_df13::b3
float32_t b3
pos. coefficient to e(k-3)
Definition: dcl_df13.h:82
DCL_DF13_SPS::b3
float32_t b3
pos. coefficient to e(k-3)
Definition: dcl_df13.h:65
DCL_DF13_SPS::a0
float32_t a0
No Longer Needed.
Definition: dcl_df13.h:69
DCL_runDF13PartialUpdate
_DCL_CRIT_ACCESS void DCL_runDF13PartialUpdate(DCL_DF13 *df, float32_t ek, float32_t uk)
Update DF13 controller based on pre-computed control effort.
Definition: dcl_df13.h:326
DCL_ZPK3::p2
float complex p2
Complex poles 2.
Definition: dcl_zpk3.h:67
DCL_updateDF13
_DCL_CODE_ACCESS bool DCL_updateDF13(DCL_DF13 *df)
A conditional update based on the update flag. If the update status is set, the function will update ...
Definition: dcl_df13.h:219
dcl_df13::a0
float32_t a0
No longer needed.
Definition: dcl_df13.h:95
DCL_updateDF13NoCheck
_DCL_CODE_ACCESS void DCL_updateDF13NoCheck(DCL_DF13 *df)
Loads DF13 tuning parameter from its SPS parameter with interrupt protection.
Definition: dcl_df13.h:196
dcl_none
@ dcl_none
No error.
Definition: dcl_error.h:57
dcl_df13::d2
float32_t d2
e(k-2)
Definition: dcl_df13.h:89
DCL_resetDF13
_DCL_CODE_ACCESS void DCL_resetDF13(DCL_DF13 *df)
Resets DF13 internal storage data with interrupt protection Implemented as inline C function.
Definition: dcl_df13.h:167
dcl_df13::sps
DCL_DF13_SPS * sps
updates compensator parameter
Definition: dcl_df13.h:100
DCL_DF13_SPS::a2
float32_t a2
neg. coefficient to u(k-2)
Definition: dcl_df13.h:67
dcl_df13::a2
float32_t a2
neg. coefficient to u(k-2)
Definition: dcl_df13.h:84
DCL_runDF13_C5
_DCL_CRIT_ACCESS float32_t DCL_runDF13_C5(DCL_DF13 *p, float32_t ek, float32_t vk)
Legacy C28 Function for maintaining backwards compatibility. It Executes an immediate 3rd order Direc...
Definition: dcl_df13.h:383
DCL_runErrorHandler
#define DCL_runErrorHandler(ptr)
Prototype for basic error handler.
Definition: dcl_error.h:108
DCL_runDF13Clamp
_DCL_CRIT_ACCESS float32_t DCL_runDF13Clamp(DCL_DF13 *df, float32_t ek, float32_t Umax, float32_t Umin)
Executes a 3rd order Direct Form 1 controller with clamp.
Definition: dcl_df13.h:366
DCL_getUpdateStatus
#define DCL_getUpdateStatus(p)
Determine whether a parameter update-in-progress flag is set.
Definition: dcl_css.h:122
DCL_clearUpdateStatus
#define DCL_clearUpdateStatus(p)
Definition: dcl_css.h:116
DCL_DF13_SPS::b0
float32_t b0
pos. coefficient to e(k)
Definition: dcl_df13.h:62
dcl_df13::d1
float32_t d1
e(k-1)
Definition: dcl_df13.h:88
dcl_df13::d7
float32_t d7
No longer needed.
Definition: dcl_df13.h:97
dcl_df13::a3
float32_t a3
neg. coefficient to u(k-3)
Definition: dcl_df13.h:85
DCL_runDF13PartialCompute
_DCL_CRIT_ACCESS float32_t DCL_runDF13PartialCompute(DCL_DF13 *df, float32_t ek)
Immediate computation to obtain DF13 servo error without updating the controller.
Definition: dcl_df13.h:313
_DCL_CODE_ACCESS
#define _DCL_CODE_ACCESS
Defines the scope of dcl functions.
Definition: dcl_common.h:63
dcl_df13::d0
float32_t d0
No longer needed.
Definition: dcl_df13.h:96
DCL_ZPK3::p1
float complex p1
Complex poles 1.
Definition: dcl_zpk3.h:66
dcl_df13::css
DCL_CSS * css
configuration & debugging
Definition: dcl_df13.h:101
dcl_df13::b1
float32_t b1
pos. coefficient to e(k-1)
Definition: dcl_df13.h:80
DCL_DF13_SPS::a1
float32_t a1
neg. coefficient to u(k-1)
Definition: dcl_df13.h:66
dcl_df13
DCL_DF13 object for storing df13 specific parameters.
Definition: dcl_df13.h:77
DCL_forceUpdateDF13
_DCL_CODE_ACCESS void DCL_forceUpdateDF13(DCL_DF13 *df)
Loads DF13 tuning parameter from its SPS parameter without interrupt protection.
Definition: dcl_df13.h:180
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_isZero
#define DCL_isZero(x)
Determines floating point numerical proximity to zero.
Definition: dcl_macro.h:77
DCL_DF13_SPS
Defines the DCL_DF13 shadow parameter set used for updating compensator parameter.
Definition: dcl_df13.h:61
dcl_df13::d4
float32_t d4
u(k-1)
Definition: dcl_df13.h:91
DCL_DF13
_DCL_VOLATILE struct dcl_df13 DCL_DF13
dcl_df13::a1
float32_t a1
neg. coefficient to u(k-1)
Definition: dcl_df13.h:83
DCL_CSS
Defines the controller common support structure.
Definition: dcl_css.h:57
dcl_df13::d6
float32_t d6
u(k-3)
Definition: dcl_df13.h:93
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_df13::b2
float32_t b2
pos. coefficient to e(k-2)
Definition: dcl_df13.h:81
DCL_getErrorInfo
#define DCL_getErrorInfo(ptr)
Macro to store error info in CSS.
Definition: dcl_error.h:98
DCL_runDF13_C6
_DCL_CRIT_ACCESS float32_t DCL_runDF13_C6(DCL_DF13 *p, float32_t ek, float32_t uk)
Legacy C28 Function for maintaining backwards compatibility. It executes a partial pre-computed 3rd o...
Definition: dcl_df13.h:399
DCL_runDF13
_DCL_CRIT_ACCESS float32_t DCL_runDF13(DCL_DF13 *df, float32_t ek)
Executes a 3rd order Direct Form 1 controller.
Definition: dcl_df13.h:292
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_df13::d5
float32_t d5
u(k-2)
Definition: dcl_df13.h:92
dcl_df13::d3
float32_t d3
e(k-3)
Definition: dcl_df13.h:90
float32_t
float float32_t
Definition: dcl_common.h:58
DCL_DF13_SPS::b1
float32_t b1
pos. coefficient to e(k-1)
Definition: dcl_df13.h:63
DCL_DF13_SPS::a3
float32_t a3
neg. coefficient to u(k-3)
Definition: dcl_df13.h:68
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
dcl_df13::b0
float32_t b0
pos. coefficient to e(k)
Definition: dcl_df13.h:79