liba 0.1.15

An algorithm library based on C/C++
Documentation
/*!
 @file pid_fuzzy.h
 @brief fuzzy proportional integral derivative controller
*/

#ifndef LIBA_PID_FUZZY_H
#define LIBA_PID_FUZZY_H

#include "pid.h"
#include "fuzzy.h"

/*!
 @ingroup liba
 @addtogroup a_pid_fuzzy fuzzy proportional integral derivative controller
 @{
*/

typedef struct a_pid_fuzzy a_pid_fuzzy;

/*!
 @brief enumeration for fuzzy PID controller operator
*/
enum
{
    A_PID_FUZZY_EQU, //!< sqrt(a,b)*sqrt(1-(1-a)*(1-b))
    A_PID_FUZZY_CAP, //!< min(a,b)
    A_PID_FUZZY_CAP_ALGEBRA, //!< a*b
    A_PID_FUZZY_CAP_BOUNDED, //!< max(a+b-1,0)
    A_PID_FUZZY_CUP, //!< max(a,b)
    A_PID_FUZZY_CUP_ALGEBRA, //!< a+b-a*b
    A_PID_FUZZY_CUP_BOUNDED //!< min(a+b,1)
};

#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */

/*!
 @brief initialize for fuzzy PID controller
 @param[in,out] ctx points to an instance of fuzzy PID controller
*/
#define a_pid_fuzzy_init(ctx) a_pid_fuzzy_zero(ctx)

/*!
 @brief get fuzzy relational operator for fuzzy PID controller
 @param[in] opr enumeration for fuzzy PID controller operator
 @return fuzzy relational operator for fuzzy PID controller
*/
A_EXTERN a_float (*a_pid_fuzzy_opr(unsigned int opr))(a_float, a_float);

/*!
 @brief set fuzzy relational operator for fuzzy PID controller
 @param[in,out] ctx points to an instance of fuzzy PID controller
 @param[in] opr enumeration for fuzzy PID controller operator
*/
A_EXTERN void a_pid_fuzzy_set_opr(a_pid_fuzzy *ctx, unsigned int opr);

/*!
 @brief get memory block for fuzzy PID controller
 @param[in,out] ctx points to an instance of fuzzy PID controller
 @return memory block for fuzzy PID controller
*/
A_EXTERN void *a_pid_fuzzy_bfuzz(a_pid_fuzzy const *ctx);

/*!
 @brief set memory block for fuzzy PID controller
 @param[in,out] ctx points to an instance of fuzzy PID controller
 @param[in] ptr points to a buffer at least A_PID_FUZZY_BFUZZ(num)
 @param[in] num the maximum number triggered by the rule
*/
A_EXTERN void a_pid_fuzzy_set_bfuzz(a_pid_fuzzy *ctx, void *ptr, a_size num);

/*!
 @brief compute size of memory block for fuzzy PID controller
 @param[in] n the maximum number triggered by the rule
*/
#define A_PID_FUZZY_BFUZZ(n) (sizeof(unsigned int) * (n) * 2 + sizeof(a_float) * (n) * (2 + (n)))

/*!
 @brief set rule base for fuzzy PID controller
 @param[in,out] ctx points to an instance of fuzzy PID controller
 @param[in] nrule number of order in the square matrix
 @param[in] me points to e's membership function parameter table
 @param[in] mec points to ec's membership function parameter table
 @param[in] mkp points to Kp's rule base table which must be a square matrix
 @param[in] mki points to Ki's rule base table which must be a square matrix
 @param[in] mkd points to Kd's rule base table which must be a square matrix
*/
A_EXTERN void a_pid_fuzzy_set_rule(a_pid_fuzzy *ctx, unsigned int nrule, a_float const *me, a_float const *mec,
                                   a_float const *mkp, a_float const *mki, a_float const *mkd);

/*!
 @brief set proportional integral derivative constant for fuzzy PID controller
 @param[in,out] ctx points to an instance of fuzzy PID controller
 @param[in] kp proportional constant
 @param[in] ki integral constant
 @param[in] kd derivative constant
*/
A_EXTERN void a_pid_fuzzy_set_kpid(a_pid_fuzzy *ctx, a_float kp, a_float ki, a_float kd);

/*!
 @brief calculate for fuzzy PID controller
 @param[in,out] ctx points to an instance of fuzzy PID controller
 @param[in] set setpoint value
 @param[in] fdb feedback value
 @return setpoint value
*/
A_EXTERN a_float a_pid_fuzzy_run(a_pid_fuzzy *ctx, a_float set, a_float fdb);

/*!
 @brief calculate for positional fuzzy PID controller
 @param[in,out] ctx points to an instance of fuzzy PID controller
 @param[in] set setpoint value
 @param[in] fdb feedback value
 @return output value
*/
A_EXTERN a_float a_pid_fuzzy_pos(a_pid_fuzzy *ctx, a_float set, a_float fdb);

/*!
 @brief calculate for incremental fuzzy PID controller
 @param[in,out] ctx points to an instance of fuzzy PID controller
 @param[in] set setpoint value
 @param[in] fdb feedback value
 @return output value
*/
A_EXTERN a_float a_pid_fuzzy_inc(a_pid_fuzzy *ctx, a_float set, a_float fdb);

/*!
 @brief zeroing for fuzzy PID controller
 @param[in,out] ctx points to an instance of fuzzy PID controller
*/
A_EXTERN void a_pid_fuzzy_zero(a_pid_fuzzy *ctx);

#if defined(__cplusplus)
} /* extern "C" */
namespace a
{
typedef struct a_pid_fuzzy pid_fuzzy;
} /* namespace a */
#endif /* __cplusplus */

/*!
 @brief instance structure for fuzzy PID controller
*/
struct a_pid_fuzzy
{
    a_pid pid; //!< instance structure for PID controller

    a_float const *me; //!< points to e's membership function parameter table
    a_float const *mec; //!< points to ec's membership function parameter table
    a_float const *mkp; //!< points to Kp's rule base, which must be a square matrix
    a_float const *mki; //!< points to Ki's rule base, which must be a square matrix
    a_float const *mkd; //!< points to Kd's rule base, which must be a square matrix

    unsigned int *idx; //!< the memory block for membership index, >= 2N
    a_float *val; //!< the memory block for membership value and membership outer product of e and ec, >= (2+N)N

    a_float (*opr)(a_float, a_float); //!< fuzzy relational operator

    a_float kp; //!< base proportional constant
    a_float ki; //!< base integral constant
    a_float kd; //!< base derivative constant

    unsigned int nrule; //!< number of order in the square matrix
    unsigned int nfuzz; //!< maximum number triggered by the rule
#if defined(__cplusplus)
    A_INLINE void init() { a_pid_fuzzy_init(this); }
    A_INLINE void set_opr(unsigned int opr_)
    {
        a_pid_fuzzy_set_opr(this, opr_);
    }
    A_INLINE void *bfuzz() const { return a_pid_fuzzy_bfuzz(this); }
    A_INLINE void set_bfuzz(void *ptr, a_size num)
    {
        a_pid_fuzzy_set_bfuzz(this, ptr, num);
    }
    A_INLINE void set_rule(unsigned int nrule_, a_float const *me_, a_float const *mec_,
                           a_float const *mkp_, a_float const *mki_, a_float const *mkd_)
    {
        a_pid_fuzzy_set_rule(this, nrule_, me_, mec_, mkp_, mki_, mkd_);
    }
    A_INLINE void set_kpid(a_float kp_, a_float ki_, a_float kd_)
    {
        a_pid_fuzzy_set_kpid(this, kp_, ki_, kd_);
    }
    A_INLINE a_float run(a_float set, a_float fdb)
    {
        return a_pid_fuzzy_run(this, set, fdb);
    }
    A_INLINE a_float pos(a_float set, a_float fdb)
    {
        return a_pid_fuzzy_pos(this, set, fdb);
    }
    A_INLINE a_float inc(a_float set, a_float fdb)
    {
        return a_pid_fuzzy_inc(this, set, fdb);
    }
    A_INLINE void zero() { a_pid_fuzzy_zero(this); }
#endif /* __cplusplus */
};

/*! @} a_pid_fuzzy */

#endif /* a/pid_fuzzy.h */