模糊pid c语言实现

#include "stdio.h"

#include "stdlib.h"

typedef unsigned char uint8;

enum MembershipDegree

{

    NB=-3,NM,NS,ZO,PS,PM,PB

};

struct fuzzyparams

{

    float error;

    float error_mapped;

    float max;

    float min;

    float gradmembership[2];

    uint8 grad_index[2];

};

enum MembershipDegree membership_valus[7]={NB,NM,NS,ZO,PS,PM,PB};

struct fuzzyparams fuzzy_e;

struct fuzzyparams fuzzy_ec;

enum MembershipDegree  Kp_rule_list[7][7] = {

                            {PB,PB,PM,PM,PS,ZO,ZO},     //kp规则表

                            {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} };

enum MembershipDegree   Ki_rule_list[7][7] = {

                            {NB,NB,NM,NM,NS,ZO,ZO},     //ki规则表

                            {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} };    

enum MembershipDegree   Kd_rule_list[7][7] = {

                            {PS,NS,NB,NB,NB,NM,PS},    //kd规则表

                            {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,NS,PS,PS,PS,PS,PB},

                            {PB,PM,PM,PM,PS,PS,PB} };

       

void get_e_membership(struct fuzzyparams* fuzzy)

{

    int i;

    fuzzy->error_mapped=membership_valus[0]+(fuzzy->error-fuzzy->min)*(membership_valus[6]-membership_valus[0])/(fuzzy->max-fuzzy->min);

    if(fuzzy->error_mapped>membership_valus[0]&&fuzzy->error_mapped<membership_valus[6])

    {

        for(i=0;i<6;i++)

        {

            if(fuzzy->error_mapped <= membership_valus[i+1])

            {

                fuzzy->gradmembership[0]=membership_valus[i+1]-fuzzy->error_mapped;

                fuzzy->gradmembership[1]=fuzzy->error_mapped-membership_valus[i];

                fuzzy->grad_index[0]=i;

                fuzzy->grad_index[1]=i+1;

                break;

            }

        }    

    }

    else if(fuzzy->error_mapped <= membership_valus[0])

    {

        fuzzy->gradmembership[0]=1;

        fuzzy->gradmembership[1]=0;

        fuzzy->grad_index[0]=0;

        fuzzy->grad_index[1]=-1;

    }

    else

    {

        fuzzy->gradmembership[0]=1;

        fuzzy->gradmembership[1]=0;

        fuzzy->grad_index[0]=6;

        fuzzy->grad_index[1]=-1;        

    }

}

float get_output_mapped(enum MembershipDegree list[7][7],struct fuzzyparams fuzzy_e,struct fuzzyparams fuzzy_ec,float min,float max)

{

    float output=0;

    float output_mapped=0;

    output =fuzzy_e.gradmembership[0]*fuzzy_ec.gradmembership[0]*list[fuzzy_e.grad_index[0]][fuzzy_ec.grad_index[0]]+

            fuzzy_e.gradmembership[0]*fuzzy_ec.gradmembership[1]*list[fuzzy_e.grad_index[0]][fuzzy_ec.grad_index[1]]+

            fuzzy_e.gradmembership[1]*fuzzy_ec.gradmembership[0]*list[fuzzy_e.grad_index[1]][fuzzy_ec.grad_index[0]]+

            fuzzy_e.gradmembership[1]*fuzzy_ec.gradmembership[1]*list[fuzzy_e.grad_index[1]][fuzzy_ec.grad_index[1]];

    output_mapped=(output-NB)*(max-min)/(PB-NB)+min;

    return output_mapped;

}

struct PID_para

{

    float target;

    float actual;

    float actual_max;

    float actual_min;

    float error;

    float error_pre;

    float error_sum;

    float kp;

    float kp_max;

    float kp_min;  

    float ki;

    float ki_max;

    float ki_min;

    float kd;

    float kd_max;

    float kd_min;

}PID_turn;

void main()

{

    PID_turn.target=30;

    PID_turn.actual=50;

    PID_turn.actual_max=80;

    PID_turn.actual_min=20;

    PID_turn.kp_max=0.18;

    PID_turn.kp_min=0;

    PID_turn.kd_max=0;

    PID_turn.kd_min=0;

    PID_turn.ki_max=0;

    PID_turn.ki_min=0;

    int i;

    for(i=0;i<40;i++)

    {

        PID_turn.error=PID_turn.target-PID_turn.actual;//20

        fuzzy_e.error=PID_turn.error;

        PID_turn.error_sum+=PID_turn.error;

        fuzzy_e.max=PID_turn.target-PID_turn.actual_min;//50

        fuzzy_e.min=PID_turn.target-PID_turn.actual_max;//-10

        fuzzy_ec.error=PID_turn.error-PID_turn.error_pre;

        fuzzy_ec.max=60;

        fuzzy_ec.min=0;

        PID_turn.error_pre=fuzzy_e.error;

        get_e_membership(&fuzzy_e);

        get_e_membership(&fuzzy_ec);

        PID_turn.kp=get_output_mapped(Kp_rule_list,fuzzy_e,fuzzy_ec,PID_turn.kp_min,PID_turn.kp_max);    

        PID_turn.ki=get_output_mapped(Ki_rule_list,fuzzy_e,fuzzy_ec,PID_turn.ki_min,PID_turn.ki_max);

        PID_turn.kd=get_output_mapped(Kd_rule_list,fuzzy_e,fuzzy_ec,PID_turn.kd_min,PID_turn.kd_max);  

        PID_turn.actual=PID_turn.kp*PID_turn.error+PID_turn.kd*fuzzy_ec.error+PID_turn.ki*PID_turn.error_sum;

        printf("%f\n",PID_turn.actual);


 

    }

    system("pause");

}

简单调试了一下结果如下:

不知道为什么,不加id效果反而更好

  • 26
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 模糊PID算法是一种基于模糊控制原理的PID优化控制算法,它利用模糊逻辑对PID参数进行调整,以提高系统的控制性能。C语言实现模糊PID算法需要定义模糊变量,定义模糊规则,定义模糊控制输出,以及定义控制器的控制策略等。 ### 回答2: 模糊PID算法是一种应用于控制系统的调节算法,用于自动化系统的控制和调节。它是在传统PID(比例-积分-微分)控制算法的基础上引入了模糊逻辑的概念,以便更好地应对非线性、时变的系统。 模糊PID算法的实现过程主要包括以下几个步骤: 1. 确定模糊规则库:首先需要确定系统的输入和输出变量,并将其进行模糊化处理,将连续的输入和输出转化为模糊集合,如“大、中、小”等。然后,根据经验和专家知识,建立模糊规则库,即描述输入和输出之间的关系。 2. 模糊推理:将输入变量和模糊规则库进行匹配,通过使用模糊逻辑运算,计算出模糊输出。 3. 解模糊化:将模糊输出转化为具体的数值,以便后续的控制操作。 4. PID控制:将解模糊化后的输出与实际输出进行比较,计算出PID控制器的输出。其中,比例控制项与模糊输出成正比,积分控制项与过去的误差累积成正比,微分控制项与误差的变化速度成正比。将PID控制器的输出作为控制系统的控制信号,进行系统的控制和调节。 模糊PID算法的实现可以使用C语言进行编程。首先需要定义输入和输出的模糊集合,并实现模糊化和解模糊化的函数。然后,根据专家经验和知识,建立模糊规则库,并通过模糊推理的方法计算出模糊输出。最后,根据PID控制的原理,结合模糊输出和实际输出,计算PID控制器的输出值,并实施系统的控制和调节。 总之,模糊PID算法是一种利用模糊逻辑的方法来实现控制系统自动调节的算法。通过合理地定义模糊集合、建立模糊规则库和采用模糊推理方法,可以有效地应对复杂的非线性、时变系统。而在C语言实现模糊PID算法,则需要考虑输入输出的模糊化与解模糊化方法,以及模糊推理和PID控制的具体实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值