1 #define MAIN(x) pid_expert##x
5 #define A_EXTERN A_EXPORT extern
9 @brief expert proportional integral derivative controller
12 #ifndef LIBA_PID_EXPERT_H
13 #define LIBA_PID_EXPERT_H
19 @addtogroup A_PID_EXPERT expert proportional integral derivative controller
23 typedef struct a_pid_expert a_pid_expert
;
25 #if defined(__cplusplus)
27 #endif /* __cplusplus */
30 @brief initialize for expert PID controller
31 @param[in,out] ctx points to an instance of expert PID controller
33 #define a_pid_expert_init(ctx) a_pid_expert_zero(ctx)
36 @brief set proportional integral derivative constant for expert PID controller
37 @param[in,out] ctx points to an instance of expert PID controller
38 @param[in] kp proportional constant
39 @param[in] ki integral constant
40 @param[in] kd derivative constant
42 A_EXTERN
void a_pid_expert_kpid(a_pid_expert
*ctx
, a_float kp
, a_float ki
, a_float kd
);
45 @brief calculate for expert PID controller
46 @param[in,out] ctx points to an instance of expert PID controller
47 @param[in] set setpoint value
48 @param[in] fdb feedback value
51 A_EXTERN a_float
a_pid_expert_iter(a_pid_expert
*ctx
, a_float set
, a_float fdb
);
54 @brief zeroing for expert PID controller
55 @param[in,out] ctx points to an instance of expert PID controller
57 A_EXTERN
void a_pid_expert_zero(a_pid_expert
*ctx
);
59 #if defined(__cplusplus)
65 #endif /* __cplusplus */
68 @brief instance structure for expert PID controller
72 a_pid pid
; //!< instance structure for PID controller
73 a_float ec
; //!< error change
74 a_float outmax
; //!< maximum output
75 a_float epsilon
; //!< precision
76 a_float max1
; //!< first error bound
77 a_float gain
; //!< gain coefficient
78 a_float max2
; //!< second error bound
79 a_float loss
; //!< loss coefficient
80 #if defined(__cplusplus)
81 A_INLINE
void init() { a_pid_expert_init(this); }
82 A_INLINE
void kpid(a_float kp
, a_float ki
, a_float kd
)
84 a_pid_expert_kpid(this, kp
, ki
, kd
);
86 A_INLINE a_float
operator()(a_float set
, a_float fdb
)
88 return a_pid_expert_iter(this, set
, fdb
);
90 A_INLINE
void zero() { a_pid_expert_zero(this); }
91 #endif /* __cplusplus */
94 /*! @} A_PID_EXPERT */
96 #endif /* a/pid_expert.h */
98 // #include "a/math.h"
100 static A_INLINE a_float
input(a_float
const x
)
102 #if defined(LIBA_MATH_H)
103 return a_float_sin(4 * A_FLOAT_PI
* x
);
109 int main(int argc
, char *argv
[]) // NOLINT(misc-definitions-in-headers)
111 main_init(argc
, argv
, 1);
113 a_float num
[] = {A_FLOAT_C(6.59492796e-05), A_FLOAT_C(6.54019884e-05)};
114 a_float den
[] = {A_FLOAT_C(-1.97530991), A_FLOAT_C(0.97530991)};
117 a_float tf_input
[A_LEN(num
)];
118 a_float tf_output
[A_LEN(den
)];
119 a_tf_init(&tf
, A_LEN(num
), num
, tf_input
, A_LEN(den
), den
, tf_output
);
122 ctx
.pid
.kp
= A_FLOAT_C(10.0);
123 ctx
.pid
.ki
= A_FLOAT_C(0.5);
124 ctx
.pid
.kd
= A_FLOAT_C(10.0);
125 ctx
.pid
.outmax
= +A_FLOAT_MAX
;
126 ctx
.pid
.outmin
= -A_FLOAT_MAX
;
127 ctx
.max1
= A_FLOAT_C(0.4);
128 ctx
.gain
= A_FLOAT_C(2.0);
129 ctx
.max2
= A_FLOAT_C(0.1);
130 ctx
.loss
= A_FLOAT_C(0.5);
131 ctx
.outmax
= A_FLOAT_C(10.0);
132 ctx
.epsilon
= A_FLOAT_C(0.01);
133 a_pid_expert_init(&ctx
);
134 for (unsigned int i
= 0; i
< 500; ++i
)
136 a_float in
= input(A_FLOAT_C(0.001) * a_float_c(i
));
137 a_tf_iter(&tf
, a_pid_expert_iter(&ctx
, in
, *tf
.output
));
138 debug(A_FLOAT_PRI("+", "f,") A_FLOAT_PRI("+", "f,") A_FLOAT_PRI("+", "f,") A_FLOAT_PRI("+", "f\n"),
139 A_FLOAT_C(0.001) * a_float_c(i
), in
, *tf
.output
, ctx
.pid
.err
);
141 a_pid_expert_zero(&ctx
);
144 #if defined(__cplusplus) && (__cplusplus > 201100L)
145 A_ASSERT_BUILD(std::is_pod
<a_pid_expert
>::value
);
146 #endif /* __cplusplus */