自适应模糊PID(位置式)C语言实现

一、自适应模糊PID原理

自适应模糊PID 控制系统结构如图所示。控制系统以偏差e和偏差变化率ec作为输入量,利用模糊规则进行模糊推理,输出Δkp,Δki,Δkd。对PID三个参数进行在线分析与调整,而自适应模糊PID 控制器输出u( t) 作用Mosfet开关管上,从而使sepic的输出电压达到要求的实时稳定性。
在这里插入图片描述
图 4.2.1 模糊PID结构图
系统采用两输入一输出的模糊控制器的形式,以密度偏差e 和偏差变化率ec 作为模糊控制器的输入量,以PID 参数的修正量Δkp,Δki,Δkd分别为模糊控制器的输出量。其变量、基本论域、模糊子集、模糊论域、量化因子、比例因子如表所示。考虑到论域覆盖范围和灵敏度,并且为了F28027计算简便,各模糊子集采用三角形隶属函数。

表 4.2.1 ΔKp模糊规则表
在这里插入图片描述

表4.2.2ΔKi模糊规则表
在这里插入图片描述

表4.2.3ΔKd模糊规则表
在这里插入图片描述
在这里插入图片描述
图4.2.2 隶属度函数
根据已经确立的模糊控制规则和隶属度函数,采用Mamdani推理方法,面积重心法非模糊化。
在这里插入图片描述
总结一下,整个模糊自适应PID的运算工程如下所示:

在这里插入图片描述

二、代码实现

该工程来自https://github.com/FlameAlpha/fuzzy-pid
某位国内大佬编写,顶礼膜拜。

fuzzy_pid.h

#ifndef _FUZZY_PID_H_
#define _FUZZY_PID_H_

#ifdef __cplusplus
extern "C" {
#endif


#include "math.h"
#include "stdlib.h"
#include "User_Component/mySci/printf.h"



#ifndef bool
#define bool char
#endif

#ifndef false
#define false (char)0
#endif

#ifndef true
#define true (char)1
#endif


// Fuzzy quantity fields
enum quantity_fields
{
    qf_small = 5,
    qf_middle = 7,
    qf_large = 8
};

#define qf_default qf_middle

struct fuzzy
{
    unsigned int input_num;
    unsigned int output_num;
    unsigned int fo_type;
    unsigned int *mf_type;
    int *mf_params;
    unsigned int df_type;
    int *rule_base;
    float *output;
};

struct PID
{
    float kp;
    float ki;
    float kd;

    float delta_kp_max;
    float delta_ki_max;
    float delta_kd_max;

    float delta_kp;
    float delta_ki;
    float delta_kd;

    float error_max;
    float delta_error_max;

    float last_error;
    float current_error;

    float intergral;
    float intergral_limit;

    float dead_zone;
    float feed_forward;

    float output;

    int output_min_value;
    int output_middle_value;
    int output_max_value;

    float linear_adaptive_kp;

    struct fuzzy *fuzzy_struct;
};

#define NB -3
#define NM -2
#define NS -1
#define ZO 0
#define PS 1
#define PM 2
#define PB 3



//#define fuzzy_pid_debug_print
//#define fuzzy_pid_dead_zone
//#define fuzzy_pid_integral_limit
//#define fuzzy_pid_rule_base_deep_copy

#define pid_params_count 7

#define torque_mode 1
#define position_mode 2
#define control_mode position_mode

#if control_mode == position_mode
#define max_error 5.0f
#define max_delta_error 5.0f
#else
#define max_error 12.0f
#define max_delta_error 12.0f
#endif

#define min_pwm_output 250
#define middle_pwm_output 1500
#define max_pwm_output 2900

struct fuzzy *fuzzy_init(unsigned int input_num, unsigned int output_num);

void fuzzy_params_init(struct fuzzy *fuzzy_struct, unsigned int mf_type, unsigned int fo_type, unsigned int df_type,
                       int mf_params[], int rule_base[][qf_default]);

void fuzzy_control(float e, float de, struct fuzzy *fuzzy_struct);



struct PID *raw_fuzzy_pid_init(float kp, float ki, float kd, float integral_limit, float dead_zone,
                               float feed_forward, float error_max, float delta_error_max, float delta_kp_max,
                               float delta_ki_max, float delta_kd_max, unsigned int mf_type, unsigned int fo_type,
                               unsigned int df_type, int *mf_params, int rule_base[][qf_default],
                               int output_min_value, int output_middle_value, int output_max_value);

//float params[pid_params_count] = {kp, ki, kd, integral_limit, dead_zonefeed_forward, linear_adaptive_kp};


struct PID *fuzzy_pid_init(float *params, float delta_k, unsigned int mf_type, unsigned int fo_type,
                           unsigned int df_type, int mf_params[], int rule_base[][qf_default]);


struct PID **
fuzzy_pid_vector_init(float params[][pid_params_count], float delta_k, unsigned int mf_type, unsigned int fo_type,
                      unsigned int df_type, int *mf_params, int rule_base[][qf_default],
                      unsigned int count);


float fuzzy_pid_control(float real, float idea, struct PID *pid);

int direct_control(int zero_value, int offset_value, bool direct);


int fuzzy_pid_motor_pwd_output(float real, float idea, bool direct, struct PID *pid);

void delete_pid(struct PID *pid);

void delete_pid_vector(struct PID **pid_vector, unsigned int count);

#ifdef __cplusplus
}
#endif

#endif //_FUZZY_PID_H_

fuzzy_pid.c

#include "User_Component/myPID/fuzzy_pid.h"

struct fuzzy *fuzzy_init(unsigned int input_num, unsigned int output_num)
{
    struct fuzzy *fuzzy_struct = (struct fuzzy *) malloc(sizeof(struct fuzzy));
    fuzzy_struct->input_num = input_num;
    fuzzy_struct->output_num = output_num;
    fuzzy_struct->mf_type = (unsigned int *) malloc((input_num + output_num) * sizeof(unsigned int));
#ifdef fuzzy_pid_rule_base_deep_copy
    fuzzy_struct->mf_params = (int *) malloc(4 * qf_default * sizeof(int));
    fuzzy_struct->rule_base = (int *) malloc(output_num * qf_default * qf_default * sizeof(int));
#endif
    fuzzy_struct->output = (float *) malloc(output_num * sizeof(float));
    return fuzzy_struct;
}

void delete_fuzzy(struct fuzzy *fuzzy_struct)
{
    free(fuzzy_struct->mf_type);
    free(fuzzy_struct->output);
    free(fuzzy_struct);
}

void fuzzy_params_init(struct fuzzy *fuzzy_struct, unsigned int mf_type, unsigned int fo_type, unsigned int df_type,
                       int mf_params[], int rule_base[][qf_default])
{
    for (unsigned int i = 0; i < fuzzy_struct->input_num + fuzzy_struct->output_num; ++i)
    {
        fuzzy_struct->mf_type[i] = mf_type;
    }

    for (unsigned int i = 0; i < fuzzy_struct->output_num; ++i)
    {
        fuzzy_struct->output[i] = 0;
    }

#ifdef fuzzy_pid_rule_base_deep_copy
    for (unsigned int j = 0; j < 4 * qf_default; ++j)
    {
        fuzzy_struct->mf_params[j] = mf_params[j];
    }

    for (unsigned int k = 0; k < fuzzy_struct->output_num * qf_default; ++k)
    {
        for (unsigned int i = 0; i < qf_default; ++i)
        {
            fuzzy_struct->rule_base[k * 7 + i] = rule_base[k][i];
        }
    }
#else
    fuzzy_struct->mf_params = mf_params;
    fuzzy_struct->rule_base = (int *) rule_base;
#endif

    fuzzy_struct->fo_type = fo_type;
    fuzzy_struct->df_type = df_type;
}

#define inverse(parameter) 1.0f/(float)parameter

// Gaussian membership function
float gaussmf(float x, float sigma, float c)
{
    return expf(-powf(((x - c) / sigma), 2.0f));
}

// Generalized bell-shaped membership function
float gbellmf(float x, float a, float b, float c)
{
    return inverse(1.0f + powf(fabsf((x - c) / a), 2.0f * b));
}

// Sigmoidal membership function
float sigmf(float x, float a, float c)
{
    return inverse(1.0f + expf(a * (c - x)));
}

// Trapezoidal membership function
float trapmf(float x, float a, float b, float c, float d)
{
    if (x >= a && x < b)
        return (x - a) / (b - a);
    else if (x >= b && x < c)
        return 1.0f;
    else if (x >= c && x <= d)
        return (d - x) / (d - c);
    else return 0.0f;
}

// Triangular membership function
float trimf(float x, float a, float b, float c)
{
    return trapmf(x, a, b, b, c);
}

// Z-shaped membership function
float zmf(float x, float a, float b)
{
    if (x <= a)
        return 1.0f;
    else if (x >= a && x <= (a + b) / 2.0f)
        return 1.0f - 2.0f * powf((x - a) / (b - a), 2.0f);
    else if (x >= (a + b) / 2.0f && x < b)
        return 2.0f * powf((x - b) / (b - a), 2.0f);
    else return 0;
}

// Membership function
float mf(float x, unsigned int mf_type, int *params)
{
    switch (mf_type)
    {
    case 0:
        return gaussmf(x, params[0], params[1]);
    case 1:
        return gbellmf(x, params[0], params[1], params[2]);
    case 2:
        return sigmf(x, params[0], params[2]);
    case 3:
        return trapmf(x, params[0], params[1], params[2], params[3]);
    case 5:
        return zmf(x, params[0], params[1]);
    default: // set triangular as default membership function
        return trimf(x, params[0], params[1], params[2]);
    }
}

// Union operator
float or (float a, float b, unsigned int type)
{
    if (type == 1)   // algebraic sum
    {
        return a + b - a * b;
    }
    else if (type == 2)     // bounded sum
    {
        return fminf(1, a + b);
    }
    else     // fuzzy union
    {
        return fmaxf(a, b);
    }
}

// Intersection operator
float and (float a, float b, unsigned int type)
{
    if (type == 1)   // algebraic product
    {
        return a * b;
    }
    else if (type == 2)     // bounded product
    {
        return fmaxf(0, a + b - 1);
    }
    else     // fuzzy intersection
    {
        return fminf(a, b);
    }
}

// Equilibrium operator
float equilibrium(float a, float b, float params)
{
    return powf(a * b, 1 - params) * powf(1 - (1 - a) * (1 - b), params);
}

// Fuzzy operator
float fo(float a, float b, unsigned int type)
{
    if (type < 3)
    {
        return and (a, b, type);
    }
    else if (type < 6)
    {
        return or (a, b, type - 3);
    }
    else
    {
        return equilibrium(a, b, 0.5f);
    }
}

// Mean of centers defuzzifier, only for two input multiple index
void moc(const float *joint_membership, const unsigned int *index, const unsigned int *count, struct fuzzy *fuzzy_struct)
{

    float denominator_count = 0;
//    float numerator_count[fuzzy_struct->output_num];
    //注意 TI的C99编译器并不是完全支持动态数组的特性,所以这里改变了一下(c89写法)
    float *numerator_count= (float *)malloc(fuzzy_struct->output_num*sizeof(float));

    for (unsigned int l = 0; l < fuzzy_struct->output_num; ++l)
    {
        numerator_count[l] = 0;
    }

    for (int i = 0; i < count[0]; ++i)
    {
        for (int j = 0; j < count[1]; ++j)
        {
            denominator_count += joint_membership[i * count[1] + j];
        }
    }

    for (unsigned int k = 0; k < fuzzy_struct->output_num; ++k)
    {
        for (unsigned int i = 0; i < count[0]; ++i)
        {
            for (unsigned int j = 0; j < count[1]; ++j)
            {
                numerator_count[k] += joint_membership[i * count[1] + j] *
                                      fuzzy_struct->rule_base[k * qf_default * qf_default + index[i] * qf_default +
                                                index[count[0] + j]];
            }
        }
    }

#ifdef fuzzy_pid_debug_print
    printf("output:\n");
#endif
    for (unsigned int l = 0; l < fuzzy_struct->output_num; ++l)
    {
        fuzzy_struct->output[l] = numerator_count[l] / denominator_count;
#ifdef fuzzy_pid_debug_print
        printf("%f,%f,%f\n", numerator_count[l], denominator_count, fuzzy_struct->index[l]);
#endif
    }
    free(numerator_count);//有借有还再借不难
}

// Defuzzifier
void df(const float *joint_membership, const unsigned int *output, const unsigned int *count, struct fuzzy *fuzzy_struct,
        int df_type)
{
    if (df_type == 0)
        moc(joint_membership, output, count, fuzzy_struct);
    else
    {
        printf("Waring: No such of defuzzifier!\n");
        moc(joint_membership, output, count, fuzzy_struct);
    }
}

void fuzzy_control(float e, float de, struct fuzzy *fuzzy_struct)
{
    float membership[qf_default * 2]; // Store membership
    unsigned int index[qf_default * 2]; // Store the index of each membership
    unsigned int count[2] = {0, 0};

    {
        int j = 0;
        for (int i = 0; i < qf_default; ++i)
        {
            float temp = mf(e, fuzzy_struct->mf_type[0], fuzzy_struct->mf_params + 4 * i);
//            if (temp > 1e-4)
//            {
                membership[j] = temp;
                index[j++] = i;
//            }
        }

        count[0] = j;

        for (int i = 0; i < qf_default; ++i)
        {
            float temp = mf(de, fuzzy_struct->mf_type[1], fuzzy_struct->mf_params + 4 * i);
//            if (temp > 1e-4)
//            {
                membership[j] = temp;
                index[j++] = i;
//            }
        }

        count[1] = j - count[0];
    }

#ifdef fuzzy_pid_debug_print
    printf("membership:\n");
    for (unsigned int k = 0; k < j; ++k)
    {
        printf("%f\n", membership[k]);
    }

    printf("index:\n");
    for (unsigned int k = 0; k < j; ++k)
    {
        printf("%d\n", index[k]);
    }

    printf("count:\n");
    for (unsigned int k = 0; k < 2; ++k)
    {
        printf("%d\n", count[k]);
    }
#endif

    if (count[0] == 0 || count[1] == 0)
    {
        for (unsigned int l = 0; l < fuzzy_struct->output_num; ++l)
        {
            fuzzy_struct->output[l] = 0;
        }
        return;
    }

    // Joint membership
//注意 TI的C99编译器并不是完全支持动态数组的特性,所以这里改变了一下(c89写法)
//    float joint_membership[count[0] * count[1]];
    float *joint_membership= (float *)malloc(count[0] * count[1]*sizeof(float));

    for (int i = 0; i < count[0]; ++i)
    {
        for (int j = 0; j < count[1]; ++j)
        {
            joint_membership[i * count[1] + j] = fo(membership[i], membership[count[0] + j], fuzzy_struct->fo_type);
        }
    }

    df(joint_membership, index, count, fuzzy_struct, 0);

    free(joint_membership);
}

struct PID *raw_fuzzy_pid_init(float kp, float ki, float kd, float integral_limit, float dead_zone,
                               float feed_forward, float error_max, float delta_error_max, float delta_kp_max,
                               float delta_ki_max, float delta_kd_max, unsigned int mf_type, unsigned int fo_type,
                               unsigned int df_type, int mf_params[], int rule_base[][qf_default],
                               int output_min_value, int output_middle_value, int output_max_value)
{
    struct PID *pid = (struct PID *) malloc(sizeof(struct PID));
    pid->kp = kp;
    pid->ki = ki;
    pid->kd = kd;

    pid->delta_kp_max = delta_kp_max;
    pid->delta_ki_max = delta_ki_max;
    pid->delta_kd_max = delta_kd_max;

    pid->delta_kp = 0;
    pid->delta_ki = 0;
    pid->delta_kd = 0;

    pid->error_max = error_max;
    pid->delta_error_max = delta_error_max;

    int output_count = 1;
    if (ki > 1e-4)
    {
        output_count += 1;
        if (kd > 1e-4)
            output_count += 1;
    }

    pid->fuzzy_struct = fuzzy_init(2, output_count);
    fuzzy_params_init(pid->fuzzy_struct, mf_type, fo_type, df_type, mf_params, rule_base);

    pid->last_error = 0;
    pid->current_error = 0;

    pid->intergral = 0;
    pid->intergral_limit = integral_limit;

    pid->dead_zone = dead_zone;
    pid->feed_forward = feed_forward;

    pid->output_max_value = output_max_value;
    pid->output_middle_value = output_middle_value;
    pid->output_min_value = output_min_value;

    return pid;
}

struct PID *fuzzy_pid_init(float *params, float delta_k, unsigned int mf_type, unsigned int fo_type,
                           unsigned int df_type, int mf_params[], int rule_base[][qf_default])
{
    return raw_fuzzy_pid_init(params[0], params[1], params[2], params[3], params[4], params[5], max_error,
                              max_delta_error, params[0] / delta_k, params[1] / delta_k, params[2] / delta_k, mf_type,
                              fo_type, df_type, mf_params,
                              rule_base, min_pwm_output, middle_pwm_output, max_pwm_output);
}


int round_user(float parameter)
{
    if ((int)(parameter * 10.0) % 10 >= 5)
        return parameter + 1;
    else
        return parameter;
}

int limit(int value, int max_limit, int min_limit)
{
    if (value > max_limit)
        return max_limit;
    if (value < min_limit)
        return min_limit;
    return value;
}
float limits(float value, float max_limit, float min_limit)
{
    if (value > max_limit)
        return max_limit;
    if (value < min_limit)
        return min_limit;
    return value;
}

float fuzzy_pid_control(float real, float idea, struct PID *pid)
{
    pid->last_error = pid->current_error;
    pid->current_error = idea - real;
    float delta_error = pid->current_error - pid->last_error;
    float uk;
#ifdef fuzzy_pid_dead_zone
    if (pid->current_error < pid->dead_zone && pid->current_error > -pid->dead_zone)
    {
        pid->current_error = 0;
    }
    else
    {
        if (pid->current_error > pid->dead_zone)
            pid->current_error = pid->current_error - pid->dead_zone;
        else
        {
            if (pid->current_error < -pid->dead_zone)
                pid->current_error = pid->current_error + pid->dead_zone;
        }
    }
#endif

    //关键代码
    fuzzy_control(pid->current_error / pid->error_max * 3.0f, delta_error / pid->delta_error_max * 3.0f,
                  pid->fuzzy_struct);

//    pid->delta_kp = limits(pid->fuzzy_struct->output[0]/3.0f * pid->delta_kp_max, pid->delta_kp_max ,-pid->delta_kp_max);
    pid->delta_kp = limits(pid->fuzzy_struct->output[0], pid->delta_kp_max ,-pid->delta_kp_max);

    if (pid->fuzzy_struct->output_num >= 2)

//        pid->delta_ki = limits(pid->fuzzy_struct->output[1]/3.0f * pid->delta_ki_max, pid->delta_ki_max ,-pid->delta_ki_max);
        pid->delta_ki = limits(pid->fuzzy_struct->output[1], pid->delta_ki_max ,-pid->delta_ki_max);
    else pid->delta_ki = 0;

    if (pid->fuzzy_struct->output_num >= 3)

//        pid->delta_kd =limits(pid->fuzzy_struct->output[2]/3.0f * pid->delta_kd_max, pid->delta_kd_max ,-pid->delta_kd_max);
        pid->delta_kd =limits(pid->fuzzy_struct->output[2], pid->delta_kd_max ,-pid->delta_kd_max);

    else pid->delta_kd = 0;

#ifdef fuzzy_pid_debug_print
    printf("kp : %f, ki : %f, kd : %f\n", pid->kp + pid->delta_kp, pid->ki + pid->delta_ki, pid->kd + pid->delta_kd);
#endif

//    printf("kpkikd:%f,%f,%f,%f\n", pid->kp + pid->delta_kp, pid->ki + pid->delta_ki, pid->kd + pid->delta_kd,0.0);

    pid->intergral += (pid->ki + pid->delta_ki) * pid->current_error;
#ifdef fuzzy_pid_integral_limit
    if (pid->intergral > pid->intergral_limit)
        pid->intergral = pid->intergral_limit;
    else
    {
        if (pid->intergral < -pid->intergral_limit)
            pid->intergral = -pid->intergral_limit;
    }
#endif
    // //这里位置式PID算法

//    pid->output = (pid->kp + pid->delta_kp) * pid->current_error + pid->intergral +
//                  (pid->kd + pid->delta_kd) * (pid->current_error - pid->last_error);

    uk = (pid->kp + pid->delta_kp) * pid->current_error + pid->intergral +
                  (pid->kd + pid->delta_kd) * (pid->current_error - pid->last_error);

//    pid->output += pid->feed_forward * (float) idea;

    uk +=pid->feed_forward * (float) idea;//前馈环节

    pid->output = uk;

    //限幅
    if(pid->output<pid ->output_min_value)
        pid->output=pid ->output_min_value;
    else if (pid->output>pid ->output_max_value)
        pid->output=pid ->output_max_value;

    return pid->output;
}


void delete_pid(struct PID *pid)
{
    if (pid->fuzzy_struct != NULL)
    {
        delete_fuzzy(pid->fuzzy_struct);
    }
    free(pid);
}

void delete_pid_vector(struct PID **pid_vector, unsigned int count)
{
    for (unsigned int i = 0; i < count; ++i)
    {
        delete_pid(pid_vector[i]);
    }
    free(pid_vector);
}



struct PID **
fuzzy_pid_vector_init(float params[][pid_params_count], float delta_k, unsigned int mf_type, unsigned int fo_type,
                      unsigned int df_type, int *mf_params, int rule_base[][qf_default],
                      unsigned int count)
{
    struct PID **pid = (struct PID **) malloc(sizeof(struct PID *) * count);
    for (unsigned int i = 0; i < count; ++i)
    {
        pid[i] = fuzzy_pid_init(params[i], delta_k, mf_type, fo_type, df_type, mf_params, rule_base);
    }
    return pid;
}

int direct_control(int zero_value, int offset_value, bool direct)
{
    if (direct == true)
    {
        return zero_value + offset_value;
    }
    else
    {
        return zero_value - offset_value;
    }
}

int fuzzy_pid_motor_pwd_output(float real, float idea, bool direct, struct PID *pid)
{
    return limit(direct_control(pid->output_middle_value, fuzzy_pid_control(real, idea, pid), direct),
                 pid->output_max_value, pid->output_min_value);
}



调用方法

//全局变量定义方式
struct PID **pid_vector;

//main函数中初始化

     int rule_base[][qf_default] = {
            //delta kp rule base
            {PB, PB, PM, PM, PS, ZO, ZO},
            {PB, PB, PM, PS, PS, ZO, NS},
            {PM, PM, PM, PS, ZO, NS, NS},
            {PM, PM, PS, ZO, NS, NM, NM},
            {PS, PS, ZO, NS, NS, NM, NM},
            {PS, ZO, NS, NM, NM, NM, NB},
            {ZO, ZO, NM, NM, NM, NB, NB},
            //delta ki rule base
            {NB, NB, NM, NM, NS, ZO, ZO},
            {NB, NB, NM, NS, NS, ZO, ZO},
            {NB, NM, NS, NS, ZO, PS, PS},
            {NM, NM, NS, ZO, PS, PM, PM},
            {NM, NS, ZO, PS, PS, PM, PB},
            {ZO, ZO, PS, PS, PM, PB, PB},
            {ZO, ZO, PS, PM, PM, PB, PB},
            //delta kd rule base
            {PS, NS, NB, NB, NB, NM, PS},
            {PS, NS, NB, NM, NM, NS, ZO},
            {ZO, NS, NM, NM, NS, NS, ZO},
            {ZO, NS, NS, NS, NS, NS, ZO},
            {ZO, ZO, ZO, ZO, ZO, ZO, ZO},
            {PB, PS, PS, PS, PS, PS, PB},
            {PB, PM, PM, PM, PS, PS, PB}};

     // Default parameters of membership function
     int mf_params[4 * qf_default] = {-3, -3, -2, 0,
                                     -3, -2, -1, 0,
                                     -2, -1,  0, 0,
                                     -1,  0,  1, 0,
                                      0,  1,  2, 0,
                                      1,  2,  3, 0,
                                      2,  3,  3, 0};

     float fuzzy_pid_params[1][pid_params_count] = {{25.4597502f,  10.0053997f,    15.59500027f,    1800, 0, 0, 1}};

     struct PID **subpid_vector = fuzzy_pid_vector_init(fuzzy_pid_params, 4.0f, 4, 1, 0, mf_params, rule_base, 1);

     pid_vector=subpid_vector;
     
//中断中调用
        control_uk = fuzzy_pid_control(Voltage_Real, pid.Ref, pid_vector[0]);
        if(control_uk<150)
            control_uk=150;
        else if (control_uk>2800)
            control_uk=2800;

  • 52
    点赞
  • 529
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
自适应模糊PID算法在温度控制方面具有很好的应用效果,可以实现更加精确的温度控制。下面是一个简单的C语言代码示例: ```c #include <stdio.h> // 定义PID参数 float kp = 0.5; // 比例系数 float ki = 0.2; // 积分系数 float kd = 0.1; // 微分系数 // 定义PID变量 float error = 0; // 当前温度误差 float integral = 0; // 温度误差积分项 float derivative = 0; // 温度误差微分项 float lastError = 0; // 上一次温度误差 // 定义温度变量 float setTemp = 37.0; // 目标温度 float currentTemp = 30.0; // 当前温度 // PID算法函数 float pid_algorithm() { // 计算温度误差 error = setTemp - currentTemp; // 计算积分项 integral += error; // 计算微分项 derivative = error - lastError; lastError = error; // 计算PID输出 float output = kp * error + ki * integral + kd * derivative; return output; } int main() { // 模拟温度控制过程 for (int i = 0; i < 10; i++) { // 通过传感器获取当前温度 currentTemp += pid_algorithm(); // 输出当前温度 printf("当前温度:%.2f\n", currentTemp); } return 0; } ``` 以上是一个简单的自适应模糊PID算法的C语言代码示例,首先定义了PID参数(比例系数、积分系数和微分系数),然后定义了PID变量(温度误差、温度误差积分项、温度误差微分项和上一次温度误差)。 在主函数中,通过循环模拟了一个温度控制过程。在每次循环中,通过传感器获取当前温度,并利用PID算法计算出控制输出。最后输出当前温度。注意:此示例仅供参考,实际使用时需根据具体需求进行参数调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值