26#ifndef _ACFUTILS_PID_CTL_H_
27#define _ACFUTILS_PID_CTL_H_
67static inline void pid_ctl_reset(
pid_ctl_t *pid);
68static inline void pid_ctl_set_k_p(
pid_ctl_t *pid,
double k_p);
69static inline void pid_ctl_set_k_i(
pid_ctl_t *pid,
double k_i);
70static inline void pid_ctl_set_lim_i(
pid_ctl_t *pid,
double lim_i);
71static inline void pid_ctl_set_k_d(
pid_ctl_t *pid,
double k_d);
72static inline void pid_ctl_set_r_d(
pid_ctl_t *pid,
double r_d);
95pid_ctl_init_noreset(
pid_ctl_t *pid,
double k_p,
double k_i,
double lim_i,
96 double k_d,
double r_d)
107 pid->integ_clamp = B_TRUE;
110pid_ctl_init(
pid_ctl_t *pid,
double k_p,
double k_i,
double lim_i,
double k_d,
114 pid_ctl_init_noreset(pid, k_p, k_i, lim_i, k_d, r_d);
119pid_ctl_set_integ_clamp(
pid_ctl_t *pid, bool_t flag)
122 pid->integ_clamp = flag;
141pid_ctl_update_dV(
pid_ctl_t *pid,
double e,
double V,
double d_t)
147 delta_V = (V - pid->V_prev) / d_t;
148 if (isnan(pid->integ))
150 pid->integ =
clamp(pid->integ + e * d_t, -pid->lim_i, pid->lim_i);
155 if (pid->integ_clamp) {
157 pid->integ = MAX(pid->integ, e);
159 pid->integ = MIN(pid->integ, e);
162 FILTER_IN_NAN(pid->deriv, delta_V, d_t, pid->r_d);
173pid_ctl_update(
pid_ctl_t *pid,
double e,
double d_t)
175 pid_ctl_update_dV(pid, e, e, d_t);
192 ASSERT(!isnan(pid->e_prev));
193 return (pid->k_p_gain * pid->k_p * pid->e_prev +
194 pid->k_i_gain * pid->k_i * pid->integ +
195 pid->k_d_gain * pid->k_d * pid->deriv);
218pid_ctl_set_k_p(
pid_ctl_t *pid,
double k_p)
232pid_ctl_set_k_p_gain(
pid_ctl_t *pid,
double k_p_gain)
235 pid->k_p_gain = k_p_gain;
239pid_ctl_get_k_p_gain(
const pid_ctl_t *pid)
242 return (pid->k_p_gain);
250pid_ctl_set_k_i(
pid_ctl_t *pid,
double k_i)
264pid_ctl_set_k_i_gain(
pid_ctl_t *pid,
double k_i_gain)
267 pid->k_i_gain = k_i_gain;
271pid_ctl_get_k_i_gain(
const pid_ctl_t *pid)
274 return (pid->k_i_gain);
282pid_ctl_set_lim_i(
pid_ctl_t *pid,
double lim_i)
300pid_ctl_set_k_d(
pid_ctl_t *pid,
double k_d)
314pid_ctl_set_k_d_gain(
pid_ctl_t *pid,
double k_d_gain)
317 pid->k_d_gain = k_d_gain;
321pid_ctl_get_k_d_gain(
const pid_ctl_t *pid)
324 return (pid->k_d_gain);
328pid_ctl_set_r_d(
pid_ctl_t *pid,
double r_d)
342pid_ctl_set_integ(
pid_ctl_t *pid,
double integ)
356pid_ctl_set_deriv(
pid_ctl_t *pid,
double deriv)
373pid_ctl_set_gain(
pid_ctl_t *pid,
double gain)
375 pid_ctl_set_k_p_gain(pid, gain);
376 pid_ctl_set_k_d_gain(pid, gain);
377 pid_ctl_set_k_i_gain(pid, gain);
380#define PID_CTL_DEBUG(pid_ptr) \
382 const pid_ctl_t *pid = (pid_ptr); \
383 printf(#pid_ptr ": e: %f integ: %f deriv: %f\n", \
384 pid->e_prev, pid->integ, pid->deriv); \
static double clamp(double x, double min_val, double max_val)