AM243x Motor Control SDK  09.00.00
dcl_pi.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Texas Instruments Incorporated
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the
14  * distribution.
15  *
16  * Neither the name of Texas Instruments Incorporated nor the names of
17  * its contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPgResS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #ifndef _DCL_PI_H_
34 #define _DCL_PI_H_
35 
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
39 
48 #include "../dcl_common.h"
49 
50 //--- Linear PI controller ---------------------------------------------------
51 
55 typedef struct dcl_pi_sps
56 {
61 } DCL_PI_SPS;
62 
65 #define PI_SPS_DEFAULTS { 1.0f, 0.0f, 1.0f, -1.0f }
66 
69 typedef _DCL_VOLATILE struct dcl_pi
70 {
71  /* controller parameter */
76 
77  /* internal storage */
81 
82  /* miscellaneous */
86 
89 #define PI_DEFAULTS { 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, \
90  &(DCL_PI_SPS)PI_SPS_DEFAULTS, &(DCL_CSS)DCL_CSS_DEFAULTS }
91 
100 #define PI_INT_DEFAULTS .i6=1.0f, .i10=0.0f, .i11=0.0f, \
101 .sps=&(DCL_PI_SPS)PI_SPS_DEFAULTS, .css=&(DCL_CSS)DCL_CSS_DEFAULTS
102 
108 #define DCL_initPI() &(DCL_PI)PI_DEFAULTS
109 
116 #define DCL_initPIasParam(kp,ki,umax,umin) &(DCL_PI){ .Kp=kp, .Ki=ki, \
117  .Umax=umax, .Umin=umin, PI_INT_DEFAULTS }
118 
129 #define DCL_initPIasSPS(pi_ptr,sps_ptr) \
130 ({ \
131  DCL_PI* new_pi = (pi_ptr) ? pi_ptr : DCL_initPI(); \
132  DCL_PI_SPS* new_sps = (sps_ptr) ? sps_ptr : &(DCL_PI_SPS)PI_SPS_DEFAULTS; \
133  if(sps_ptr) \
134  { \
135  *new_pi = (DCL_PI){ (new_sps)->Kp, (new_sps)->Ki, (new_sps)->Umax, (new_sps)->Umin,\
136  1.0f, 0.0f, 0.0f, (DCL_PI_SPS*)new_sps, &(DCL_CSS)DCL_CSS_DEFAULTS }; \
137  } \
138  new_pi; \
139 })
140 
147 {
149  pi->i6 = 1.0f;
150  pi->i10 = pi->i11 = 0.0f;
151  DCL_restoreInts(ints);
152 }
153 
160 {
161 
162 #ifdef DCL_ERROR_HANDLING_ENABLED
163  uint32_t err_code = dcl_none;
164  err_code |= (pi->sps->Umax <= pi->sps->Umin) ? dcl_param_invalid_err : dcl_none;
165  err_code |= (pi->css->t_sec <= 0.0f) ? dcl_param_range_err : dcl_none;
166  err_code |= (pi->sps->Kp < 0.0f) ? dcl_param_range_err : dcl_none;
167  err_code |= (pi->sps->Ki < 0.0f) ? dcl_param_range_err : dcl_none;
168  if (err_code)
169  {
170  DCL_setError(pi,err_code);
171  DCL_getErrorInfo(pi);
173  }
174 #endif
175 
176  pi->Kp = pi->sps->Kp;
177  pi->Ki = pi->sps->Ki;
178  pi->Umax = pi->sps->Umax;
179  pi->Umin = pi->sps->Umin;
180 }
181 
189 {
190 
191 #ifdef DCL_ERROR_HANDLING_ENABLED
192  uint32_t err_code = dcl_none;
193  err_code |= (pi->sps->Umax <= pi->sps->Umin) ? dcl_param_invalid_err : dcl_none;
194  err_code |= (pi->css->t_sec <= 0.0f) ? dcl_param_range_err : dcl_none;
195  err_code |= (pi->sps->Kp < 0.0f) ? dcl_param_range_err : dcl_none;
196  err_code |= (pi->sps->Ki < 0.0f) ? dcl_param_range_err : dcl_none;
197  if (err_code)
198  {
199  DCL_setError(pi,err_code);
200  DCL_getErrorInfo(pi);
202  }
203 #endif
204 
205  if (!DCL_getUpdateStatus(pi))
206  {
209  pi->Kp = pi->sps->Kp;
210  pi->Ki = pi->sps->Ki;
211  pi->Umax = pi->sps->Umax;
212  pi->Umin = pi->sps->Umin;
214  DCL_restoreInts(ints);
215  return true;
216  }
217  return false;
218 }
219 
230 {
231  if (DCL_getPendingStatus(pi) && DCL_updatePI(pi))
232  {
234  return true;
235  }
236  return false;
237 }
238 
246 {
247  pi->sps->Kp = pi->Kp;
248  pi->sps->Ki = pi->Ki;
249  pi->sps->Umax = pi->Umax;
250  pi->sps->Umin = pi->Umin;
251 }
252 
264 {
265 #ifdef DCL_ERROR_HANDLING_ENABLED
266  uint32_t err_code = dcl_none;
267  err_code |= (zpk->K < 0.0f) ? dcl_param_range_err : dcl_none;
268  err_code |= (crealf(zpk->z1) > (1.0f / (2.0f * pi->css->t_sec))) ? dcl_param_warn_err : dcl_none;
269  if (err_code)
270  {
271  DCL_setError(pi,err_code);
272  DCL_getErrorInfo(pi);
274  }
275 #endif
276 
277  float32_t t_sec = pi->css->t_sec;
278  float32_t z1 = (float32_t) crealf(zpk->z1);
279  pi->sps->Kp = zpk->K * (1.0f + (t_sec * z1) / 2.0f);
280  pi->sps->Ki = (-2.0f * t_sec * z1) / (2.0f + (t_sec * z1));
281 
282 }
283 
294 {
295 #ifdef DCL_ERROR_HANDLING_ENABLED
296  uint32_t err_code = dcl_none;
297  err_code |= (zpk->K < 0.0f) ? dcl_param_range_err : dcl_none;
298  err_code |= (crealf(zpk->z1) > (1.0f / (2.0f * pi->css->t_sec))) ? dcl_param_warn_err : dcl_none;
299  if (err_code)
300  {
301  DCL_setError(pi,err_code);
302  DCL_getErrorInfo(pi);
304  }
305 #endif
306 
307  float32_t t_sec = pi->css->t_sec;
308  float32_t z1 = (float32_t) crealf(zpk->z1);
309  pi->sps->Kp = zpk->K * (1.0f + (t_sec * z1) / 2.0f);
310  pi->sps->Ki = -zpk->K * t_sec * z1;
311 }
312 
322 {
323  float32_t v2, v4, v5, v9;
324 
325  v2 = pi->Kp * (rk - yk);
326  v4 = pi->i10 + (pi->Ki * pi->i6 * v2);
327  v5 = v2 + v4;
328  v9 = DCL_runSat(v5, pi->Umax, pi->Umin);
329  pi->i6 = (v5 == v9) ? 1.0f : 0.0f;
330  pi->i10 = v4;
331 
332 #ifdef DCL_TESTPOINTS_ENABLED
333  pi->css->tpt = v5;
334 #endif
335 
336  return(v9);
337 }
338 
349 {
350  float32_t v1, v2, v4, v5, v9;
351 
352  v1 = rk - yk;
353  v2 = pi->Kp * v1;
354  v4 = (v1 * pi->Ki * pi->i6) + pi->i10;
355  pi->i10 = v4;
356  v5 = v2 + v4;
357  v9 = DCL_runSat(v5, pi->Umax, pi->Umin);
358  pi->i6 = (v5 == v9) ? 1.0f : 0.0f;
359 
360 #ifdef DCL_TESTPOINTS_ENABLED
361  pi->css->tpt = v5;
362 #endif
363 
364  return(v9);
365 }
366 
380 {
381  float32_t v1, v5, v7, v8;
382  bool l11, l14, l17, l18, l19;
383 
384  v1 = rk - yk;
385  v5 = (v1 * pi->Ki * pi->i6) + pi->i10;
386  pi->i10 = v5;
387  v7 = (v1 * pi->Kp) + v5;
388  v8 = DCL_runSat(v7, pi->Umax, pi->Umin);
389  l17 = (v7 == v8) ? true : false;
390  l11 = (DCL_runSat(v5,Imax,Imin) == v5) ? true : false;
391  l19 = (v5 > 0) ? true : false;
392  l14 = (v1 > 0) ? true : false;
393  l18 = l17 && (!l11 || (l19 ^ l14));
394  pi->i6 = (l18) ? 1.0f : 0.0f;
395 
396 #ifdef DCL_TESTPOINTS_ENABLED
397  pi->css->tpt = v7;
398 #endif
399 
400  return(v8);
401 }
402 
412 {
413  float32_t v2, v4, v5, v8, v9;
414 
415  v2 = (rk - yk) * pi->Kp;
416  v8 = v2 * pi->Ki * pi->i6;
417  v4 = v8 + pi->i11 + pi->i10;
418  v5 = v2 + v4;
419  pi->i10 = v4;
420  pi->i11 = v8;
421  v9 = DCL_runSat(v5, pi->Umax, pi->Umin);
422  pi->i6 = (v5 == v9) ? 1.0f : 0.0f;
423 
424 #ifdef DCL_TESTPOINTS_ENABLED
425  pi->css->tpt = v4;
426 #endif
427 
428  return(v9);
429 }
430 
433 #ifdef __cplusplus
434 }
435 #endif // extern "C"
436 
437 #endif // _DCL_PI_H_
dcl_pi::i11
float32_t i11
Tustin integrator storage.
Definition: dcl_pi.h:80
DCL_ZPK3::K
float32_t K
Real gain.
Definition: dcl_zpk3.h:69
DCL_PI_SPS::Kp
float32_t Kp
Proportional gain.
Definition: dcl_pi.h:57
DCL_PI_SPS::Umax
float32_t Umax
Upper saturation limit.
Definition: dcl_pi.h:59
DCL_PI_SPS::Umin
float32_t Umin
Lower saturation limit.
Definition: dcl_pi.h:60
DCL_runPIParallelEnhanced
_DCL_CODE_ACCESS _DCL_CODE_SECTION float32_t DCL_runPIParallelEnhanced(DCL_PI *pi, float32_t rk, float32_t yk, float32_t Imax, float32_t Imin)
Executes a parallel form PI controller with enhanced anti-windup logic incorporating an addintional i...
Definition: dcl_pi.h:379
dcl_param_warn_err
@ dcl_param_warn_err
Parameter warning.
Definition: dcl_error.h:60
_DCL_CODE_SECTION
#define _DCL_CODE_SECTION
Defines dcl function section that users can specify in the linker file(.cmd) and to accelerate perfor...
Definition: dcl_common.h:60
DCL_clearPendingStatus
#define DCL_clearPendingStatus(p)
Definition: dcl_css.h:129
DCL_setUpdateStatus
#define DCL_setUpdateStatus(p)
Macros to set and clear the update-in-progress flag.
Definition: dcl_css.h:116
DCL_runErrorHandler
#define DCL_runErrorHandler(ptr)
Prototype for basic error handler.
Definition: dcl_error.h:107
dcl_pi::Umin
float32_t Umin
Lower control saturation limit.
Definition: dcl_pi.h:75
dcl_param_range_err
@ dcl_param_range_err
Parameter range exceeded.
Definition: dcl_error.h:58
DCL_PI_SPS::Ki
float32_t Ki
Integral gain.
Definition: dcl_pi.h:58
DCL_getUpdateStatus
#define DCL_getUpdateStatus(p)
Determine whether a parameter update-in-progress flag is set.
Definition: dcl_css.h:123
DCL_clearUpdateStatus
#define DCL_clearUpdateStatus(p)
Definition: dcl_css.h:117
_DCL_CODE_ACCESS
#define _DCL_CODE_ACCESS
Defines the scope of dcl functions (static inline/extern inline/none)
Definition: dcl_common.h:55
PI_Handle
_DCL_VOLATILE struct dcl_pi * PI_Handle
dcl_none
@ dcl_none
No error.
Definition: dcl_error.h:57
DCL_resetPI
_DCL_CODE_ACCESS void DCL_resetPI(DCL_PI *pi)
Resets PI internal storage data with interrupt protection.
Definition: dcl_pi.h:146
DCL_loadParallelPIasZPK
_DCL_CODE_ACCESS void DCL_loadParallelPIasZPK(DCL_PI *pi, DCL_ZPK3 *zpk)
Configures a parallel PI controller in "zero-pole-gain" form Note: Sampling period pi->css->t_sec are...
Definition: dcl_pi.h:293
dcl_interrupt_t
uint32_t dcl_interrupt_t
Definition: dcl_common.h:96
DCL_pendingUpdatePI
_DCL_CODE_ACCESS _DCL_CODE_SECTION bool DCL_pendingUpdatePI(DCL_PI *pi)
A conditional update based on the pending-for-update flag. If the pending status is set,...
Definition: dcl_pi.h:229
DCL_runPISeriesTustin
_DCL_CODE_ACCESS _DCL_CODE_SECTION float32_t DCL_runPISeriesTustin(DCL_PI *pi, float32_t rk, float32_t yk)
Executes a series form PI controller with Tustin integrator.
Definition: dcl_pi.h:411
dcl_pi
DCL_PI object for storing PI specific parameters.
Definition: dcl_pi.h:70
dcl_pi::sps
DCL_PI_SPS * sps
updates controller parameter
Definition: dcl_pi.h:83
dcl_param_invalid_err
@ dcl_param_invalid_err
Parameter not valid.
Definition: dcl_error.h:59
dcl_pi::i10
float32_t i10
I path feedback value.
Definition: dcl_pi.h:79
DCL_updatePI
_DCL_CODE_ACCESS _DCL_CODE_SECTION bool DCL_updatePI(DCL_PI *pi)
Updates PI parameter from its SPS parameter with interrupt protection.
Definition: dcl_pi.h:188
DCL_PI
_DCL_VOLATILE struct dcl_pi DCL_PI
DCL_runSat
#define DCL_runSat(data, Umax, Umin)
Macro to saturate a control variable but does not change the data itself unlike runClamp()
Definition: dcl_clamp.h:89
DCL_CSS
Defines the controller common support structure.
Definition: dcl_css.h:57
DCL_getPendingStatus
#define DCL_getPendingStatus(p)
Determine whether a parameter pending-for-update flag is set.
Definition: dcl_css.h:135
dcl_pi::Ki
float32_t Ki
Integral gain.
Definition: dcl_pi.h:73
DCL_restoreInts
#define DCL_restoreInts(v)
Definition: dcl_common.h:95
DCL_fupdatePI
_DCL_CODE_ACCESS void DCL_fupdatePI(DCL_PI *pi)
Loads PI tuning parameter from its SPS parameter
Definition: dcl_pi.h:159
dcl_pi::Umax
float32_t Umax
Upper control saturation limit.
Definition: dcl_pi.h:74
DCL_ZPK3
Defines the DCL_ZPK3 controller structure.
Definition: dcl_zpk3.h:62
_DCL_VOLATILE
#define _DCL_VOLATILE
Defines volatile for DCL strctures Flags can be defined in dcl.h or user files before including DCL l...
Definition: dcl_common.h:68
DCL_loadSeriesPIasZPK
_DCL_CODE_ACCESS void DCL_loadSeriesPIasZPK(DCL_PI *pi, DCL_ZPK3 *zpk)
Configures a series PI controller in "zero-pole-gain" form Note: Sampling period pi->css->t_sec are u...
Definition: dcl_pi.h:263
DCL_getErrorInfo
#define DCL_getErrorInfo(ptr)
Macro to store error info in CSS.
Definition: dcl_error.h:97
DCL_setError
#define DCL_setError(ptr, code)
Macro to set error code in CSS.
Definition: dcl_error.h:79
dcl_pi::Kp
float32_t Kp
Proportional gain.
Definition: dcl_pi.h:72
DCL_PI_SPS
Defines DCL_PI shadow parameter set used for updating controller parameter.
Definition: dcl_pi.h:56
DCL_runPISeries
_DCL_CODE_ACCESS _DCL_CODE_SECTION float32_t DCL_runPISeries(DCL_PI *pi, float32_t rk, float32_t yk)
Executes an inline series form PI controller.
Definition: dcl_pi.h:321
float32_t
float float32_t
Defines single,double precision data type. Note: Assumes ABI to be TI_EABI, does not support legacy T...
Definition: dcl_common.h:51
DCL_runPIParallel
_DCL_CODE_ACCESS _DCL_CODE_SECTION float32_t DCL_runPIParallel(DCL_PI *pi, float32_t rk, float32_t yk)
Executes a parallel form PI controller Implemented as inline C function.
Definition: dcl_pi.h:348
DCL_updatePISPS
_DCL_CODE_ACCESS void DCL_updatePISPS(DCL_PI *pi)
Update SPS parameter with active param, userful when needing to update only few active param from SPS...
Definition: dcl_pi.h:245
dcl_pi::css
DCL_CSS * css
configuration & debugging
Definition: dcl_pi.h:84
DCL_ZPK3::z1
float complex z1
Complex zeros 1.
Definition: dcl_zpk3.h:63
dcl_pi::i6
float32_t i6
Saturation storage.
Definition: dcl_pi.h:78
DCL_disableInts
#define DCL_disableInts()
Define enable and disable interrupt operations.
Definition: dcl_common.h:94