Expert PID (implemented in C language)

1, Principle of expert PID

Expert PID control mainly uses the knowledge of controlled object and control law to control. For the controlled object, there is no need for accurate model, and expert experience is used to design and control the system model. For the control of system model, expert PID has flexibility, adaptability and robustness. It can flexibly select the corresponding control law to control according to the working state and error of the system, and actively adjust the parameters of the controller according to expert knowledge and experience to adapt to the changes of object characteristics and environment. By using expert rules, the control system model can work reliably under nonlinear and large deviation.

Expert PID is mainly composed of five control laws. Through the working state and error, select the corresponding control law to stabilize the data, and adjust the parameters to stabilize the control system. The control structure is shown in the figure.

Set a maximum value of deviation, which is recorded as Mmax; Set an intermediate value with large deviation and record it as Mmid; Set a minimum value of deviation, which is recorded as Mmin. According to the above deviation, deviation increment and deviation extreme value setting, our analysis is as follows:

(1) If | e (k) | > mmax (rule 1)

This situation shows that the absolute value of the deviation has been very large. Regardless of the variation trend of the deviation, it should be considered that the input of the controller should be output according to the maximum (or minimum) to achieve the effect of quickly adjusting the deviation and reduce the absolute value of the deviation at the maximum speed. At the same time, avoid overshoot, which is equivalent to open-loop control.

(2) When e(k) * ∆ e(k) > 0 or ∆ e(k)=0 (Rule 2)

This situation shows that the deviation changes in the direction of increasing the absolute value of the deviation, or the deviation is a fixed value. At this time, we judge the relationship between the absolute value of the deviation and the intermediate value Mmid of the deviation.

(2.1) at this time, if | e (k) | > mmid

It shows that the deviation is also large. It can be considered that the controller can implement a strong control function to achieve the change of the absolute value of torsional deviation to the decreasing direction and quickly reduce the absolute value of deviation.

(2.2) at this time, if | e(k) | ≤ Mmid

It shows that although the deviation changes in the direction of increasing the absolute value, the absolute value of the deviation itself is not very large. It can be considered that the controller implements the general control function, and only needs to reverse the change trend of the deviation and make it change in the direction of decreasing the absolute value of the deviation.

(3) When e(k) * ∆ e(k) < 0 and ∆ e(k) * ∆ e (k-1) > 0 or e(k)=0

It indicates that the absolute value of the deviation changes in the decreasing direction or has reached the equilibrium state. At this time, keep the controller output unchanged.

(4) When e(k) * ∆ e(k) < 0 and ∆ e(k) * ∆ e (k-1) < 0

Indicates that the deviation is in the limit state.

(4.1) if the absolute value of the deviation is large at this time, |e (k) | > mmid

Strong control can be considered.

(4.2) if the absolute value of deviation is small at this time, |e (k) | < mmid

Weak control can be considered.

Where k1 is the gain amplification factor, and k1 takes a value greater than 1; k2 is the gain suppression coefficient, which is greater than 0 but less than 1.

(5) If | e (k) | < mmin

This situation actually shows that the absolute value of the deviation is very small. This deviation may be caused by the system static error. At this time, the integral action must be introduced to reduce the steady-state error of the system.

(6) if u(k) has not changed

This indicates that none of the above rules has been triggered, so the output remains unchanged. Otherwise, it will (the control quantity is directly 0, oscillation)

2, Source code

sp_pid.h

#ifndef INCLUDE_SP_PID_H_
#define INCLUDE_SP_PID_H_

#include "xxxxx underlying file XXXXX.h"


typedef  struct
{
    float  Ref;           // Input: Reference input
    float  Fdb;           // Input: Feedback input
    float  Err;            //deviation
    float  Err_1;          // Variable: error signal e (k-1) variable: error
    float  Err_2;          // Variable: error signal e (K-2) variable: error
    float  Ts;            // Control cycle


    float  Kp;            // Parameter: Proportional gain
    float  Ki;            // Parameter: Integral gain
    float  Kd;            // Parameter: differential gain


    float ErrorAbsMax;            /*Absolute maximum deviation*/
    float ErrorAbsMid;            /*Deviation absolute value median value*/
    float ErrorAbsMin;            /*Absolute deviation minimum*/

    float  OutPreSat;     // Variable: saturated outputvariable: pre saturated output
    float  OutMax;        // Parameter: Maximum output
    float  OutMin;        // Parameter: Minimum output
    float  Out;           // Output: SP_PID output: SP_PID output

    void (*init)();          // Pointer to the init funcion
    void (*calc)();         // Pointer to calculation function
} SP_PID;
typedef   SP_PID  *SP_PID_handle;
/*-----------------------------------------------------------------------------
  Default initializer for the aw_ PID object.
-----------------------------------------------------------------------------*/
#define  SP_PID_DEFAULTS { 0, 0, 0, 0, 0, 0,\
                           0, 0, 0, \
                           0, 0, 0,\
                           0, 0, 0, 0, \
                           (void (*)(unsigned long)) sp_pid_init,\
                           (void (*)(unsigned long)) sp_pid_calc }
/*------------------------------------------------------------------------------
  Prototypes for the functions in < sp_ PID. c>
------------------------------------------------------------------------------*/

void sp_pid_init(SP_PID_handle);
void sp_pid_calc(SP_PID_handle);


#endif /* INCLUDE_SP_PID_H_ */



sp_pid.c


#include "sp_pid.h"

#include <stdlib.h>

// include the header for PID data structure definition

void sp_pid_init(SP_PID *v)
{
    //The following initialization steps are for step inputs

    v->ErrorAbsMax = v->Ref * 0.20f;
    v->ErrorAbsMid = v->Ref * 0.10f;
    v->ErrorAbsMin = v->Ref * 0.05f;

//    v->ErrorAbsMax = v->Ref *0.45f;
//    v->ErrorAbsMid = v->Ref *0.30f;
//    v->ErrorAbsMin = v->Ref *0.1f;
}



void sp_pid_calc(SP_PID *v)
{

    float Delta_Err;                  //e(k)-e(k-1)
    float Last_Delta_Err;             //e(k-1)-e(k-2)
    float uk=0;                         //Output value of this regulation

    v->Err = v->Ref - v->Fdb;
    Delta_Err = v->Err - v->Err_1;
    Last_Delta_Err = v->Err_1 - v->Err_2;

    if (fabs(v->Err) >= v->ErrorAbsMax)
    {
        /*Execute rule 1*/
        if (v->Err > 0)
        {
//            uk = v->OutMax;
            uk = v->Ref / (12+v->Ref) * 6000;
        }
        if (v->Err < 0)
        {
//            uk = v->OutMin;
            uk = v->Ref / (12+v->Ref) * 6000;
        }
    }

    if ((v->Err * Delta_Err > 0) || (Delta_Err == 0))
    {
        /*Implementation rule 2*/
        if (fabs(v->Err) >= v->ErrorAbsMid)
        {
            uk = v->Out + 1.5f * (v->Kp * Delta_Err + v->Ki * v->Err + v->Kd * (Delta_Err - Last_Delta_Err));
        }
        else
        {
            uk = v->Out + 0.3f * (v->Kp * Delta_Err + v->Ki * v->Err + v->Kd * (Delta_Err - Last_Delta_Err));
        }
    }

    if (((v->Err * Delta_Err < 0) && (Delta_Err * Last_Delta_Err > 0)) || (v->Err == 0))
    {
        /*Implementation rule 3*/
        uk = v->Out;
    }

    if ((v->Err * Delta_Err < 0) && (Delta_Err * Last_Delta_Err < 0))
    {
        /*Implementation rule 4*/
        if (fabs(v->Err) >= v->ErrorAbsMid)
        {
            uk = v->Out + 1.5f * v->Kp * v->Err;
        }
        else
        {
            uk = v->Out + 0.4f * v->Kp * v->Err;
        }
    }

    if ((fabs(v->Err) <= v->ErrorAbsMin) && (fabs(v->Err) > 0))
    {
        /*Implementation rule 5*/
        uk = v->Out + 0.5f * v->Kp * Delta_Err + 0.3f * v->Ki * v->Err;
    }

    if(uk==0)//Prevent these five rules from triggering, resulting in an output of 0
        uk=v->Out;
    v->OutPreSat = uk;

    // Saturate the output
    if (v->OutPreSat > v->OutMax)
        v->Out =  v->OutMax;
    else if (v->OutPreSat < v->OutMin)
        v->Out =  v->OutMin;
    else
        v->Out = v->OutPreSat;
    v->OutPreSat = v->Out;

    v->Err_2 = v->Err_1;
    v->Err_1 = v->Err;


}


Explanation: rules are dead and people are alive

For example, rule 1, if the deviation is large, open-loop output is required

In motor control, the maximum voltage can be directly supplied;

However, in the power control, it can not give this, but output a fixed duty cycle.

Control in other areas may be different.

PS; The code is transplanted from the expert PID control of intelligent control

For details, please refer to my blog post Matlab simulation of expert PID control_ Long chentian's blog - CSDN blog_ Expert PID control matlab

3, Call method

//statement
SP_PID pid = SP_PID_DEFAULTS;

//initialization
    
     /*Incremental PID initialization*/
     pid.Kp = 25.4597502;
     pid.Ki = 10.053997;
     pid.Kd = 15.59500027;

     pid.Ts = Ts;


     pid.OutMax = 2900;
     pid.OutMin =  100;
     pid.Ref = VoltageRef2;

//Note that the following must be initialized after changing the given value (the size of maximum deviation, minimum deviation, etc.)
     pid.init(&pid);

//Feedback call     
   pid.Fdb = man;
   pid.calc(&pid);
   control_uk = pid.Out;

Keywords: C Back-end

Added by py343 on Mon, 10 Jan 2022 01:06:52 +0200