跑起来的效果看每个类的test方法,自己调用来测试

目的是看看哪个算法好用,移植的时候比较单纯没有研究懂算法,代码结构也没改动,只是移植到C#方便查看代码和测试,大家要拷贝也很方便,把整个类拷贝到.cs文件即可

这段算法在实际值低于目标值c#教程是工作正常,超过后会有问题,不知道如何调教

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace FuzzyPID
{class FuzzyPID{public const int N = 7;double target; //系统的控制目标double actual; //采样获得的实际值double e; //误差double e_pre_1; //上一次的误差double e_pre_2; //上上次的误差double de;   //误差的变化率double emax;  //误差基本论域上限double demax;  //误差辩化率基本论域的上限double delta_Kp_max;  //delta_kp输出的上限double delta_Ki_max;  //delta_ki输出上限double delta_Kd_max;  //delta_kd输出上限double Ke;   //Ke=n/emax,量化论域为[-3,-2,-1,0,1,2,3]double Kde;   //Kde=n/demax,量化论域为[-3,-2,-1,0,1,2,3]double Ku_p;  //Ku_p=Kpmax/n,量化论域为[-3,-2,-1,0,1,2,3]double Ku_i;  //Ku_i=Kimax/n,量化论域为[-3,-2,-1,0,1,2,3]double Ku_d;  //Ku_d=Kdmax/n,量化论域为[-3,-2,-1,0,1,2,3]int[,] Kp_rule_matrix = new int[N, N];//Kp模糊规则矩阵int[,] Ki_rule_matrix = new int[N, N];//Ki模糊规则矩阵int[,] Kd_rule_matrix = new int[N, N];//Kd模糊规则矩阵string mf_t_e;    //e的隶属度函数类型string mf_t_de;   //de的隶属度函数类型string mf_t_Kp;   //kp的隶属度函数类型string mf_t_Ki;   //ki的隶属度函数类型string mf_t_Kd;   //kd的隶属度函数类型double[] e_mf_paras; //误差的隶属度函数的参数double[] de_mf_paras;//误差的偏差隶属度函数的参数double[] Kp_mf_paras; //kp的隶属度函数的参数double[] Ki_mf_paras; //ki的隶属度函数的参数double[] Kd_mf_paras; //kd的隶属度函数的参数double Kp;double Ki;double Kd;double A;double B;double C;public FuzzyPID(double e_max, double de_max, double kp_max, double ki_max, double kd_max, double Kp0, double Ki0, double Kd0){emax = e_max;demax = de_max;delta_Kp_max = kp_max;delta_Ki_max = ki_max;delta_Kd_max = kd_max;e = target - actual;de = e - e_pre_1;Ke = (N / 2) / emax;Kde = (N / 2) / demax;Ku_p = delta_Kp_max / (N / 2);Ku_i = delta_Ki_max / (N / 2);Ku_d = delta_Kd_max / (N / 2);Kp = Kp0;Ki = Ki0;Kd = Kd0;A = Kp + Ki + Kd;B = -2 * Kd - Kp;C = Kd;}//三角隶属度函数double trimf(double x, double a, double b, double c){double u;if (x >= a && x <= b)u = (x - a) / (b - a);else if (x > b && x <= c)u = (c - x) / (c - b);elseu = 0;return u;}//正态隶属度函数double gaussmf(double x, double ave, double sigma){double u;if (sigma < 0){throw new Exception("In gaussmf, sigma must larger than 0");}u = Math.Exp(-Math.Pow(((x - ave) / sigma), 2));return u;}//梯形隶属度函数double trapmf(double x, double a, double b, double c, double d){double u;if (x >= a && x < b)u = (x - a) / (b - a);else if (x >= b && x < c)u = 1;else if (x >= c && x <= d)u = (d - x) / (d - c);elseu = 0;return u;}//设置模糊规则Matrixpublic void setRuleMatrix(int[,] kp_m, int[,] ki_m, int[,] kd_m){for (int i = 0; i < N; i++)for (int j = 0; j < N; j++){Kp_rule_matrix[i, j] = kp_m[i, j];Ki_rule_matrix[i, j] = ki_m[i, j];Kd_rule_matrix[i, j] = kd_m[i, j];}}//设置模糊隶属度函数的子函数void setMf_sub(string type, double[] paras, int n){int N_mf_e = 0, N_mf_de = 0, N_mf_Kp = 0, N_mf_Ki = 0, N_mf_Kd = 0;switch (n){case 0:if (type == "trimf" || type == "gaussmf" || type == "trapmf")mf_t_e = type;elsethrow new Exception("Type of membership function must be \"trimf\" or \"gaussmf\" or \"trapmf\"");if (mf_t_e == "trimf")N_mf_e = 3;else if (mf_t_e == "gaussmf")N_mf_e = 2;else if (mf_t_e == "trapmf")N_mf_e = 4;e_mf_paras = new double[N * N_mf_e];for (int i = 0; i < N * N_mf_e; i++)e_mf_paras[i] = paras[i];break;case 1:if (type == "trimf" || type == "gaussmf" || type == "trapmf")mf_t_de = type;elsethrow new Exception("Type of membership function must be \"trimf\" or \"gaussmf\" or \"trapmf\"");if (mf_t_de == "trimf")N_mf_de = 3;else if (mf_t_de == "gaussmf")N_mf_de = 2;else if (mf_t_de == "trapmf")N_mf_de = 4;de_mf_paras = new double[N * N_mf_de];for (int i = 0; i < N * N_mf_de; i++)de_mf_paras[i] = paras[i];break;case 2:if (type == "trimf" || type == "gaussmf" || type == "trapmf")mf_t_Kp = type;elsethrow new Exception("Type of membership function must be \"trimf\" or \"gaussmf\" or \"trapmf\"");if (mf_t_Kp == "trimf")N_mf_Kp = 3;else if (mf_t_Kp == "gaussmf")N_mf_Kp = 2;else if (mf_t_Kp == "trapmf")N_mf_Kp = 4;Kp_mf_paras = new double[N * N_mf_Kp];for (int i = 0; i < N * N_mf_Kp; i++)Kp_mf_paras[i] = paras[i];break;case 3:if (type == "trimf" || type == "gaussmf" || type == "trapmf")mf_t_Ki = type;elsethrow new Exception("Type of membership function must be \"trimf\" or \"gaussmf\" or \"trapmf\"");if (mf_t_Ki == "trimf")N_mf_Ki = 3;else if (mf_t_Ki == "gaussmf")N_mf_Ki = 2;else if (mf_t_Ki == "trapmf")N_mf_Ki = 4;Ki_mf_paras = new double[N * N_mf_Ki];for (int i = 0; i < N * N_mf_Ki; i++)Ki_mf_paras[i] = paras[i];break;case 4:if (type == "trimf" || type == "gaussmf" || type == "trapmf")mf_t_Kd = type;elsethrow new Exception("Type of membership function must be \"trimf\" or \"gaussmf\" or \"trapmf\"");if (mf_t_Kd == "trimf")N_mf_Kd = 3;else if (mf_t_Kd == "gaussmf")N_mf_Kd = 2;else if (mf_t_Kd == "trapmf")N_mf_Kd = 4;Kd_mf_paras = new double[N * N_mf_Kd];for (int i = 0; i < N * N_mf_Kd; i++)Kd_mf_paras[i] = paras[i];break;default: break;}}//设置模糊隶属度函数的类型和参数public void setMf(string mf_type_e, double[] e_mf,string mf_type_de, double[] de_mf,string mf_type_Kp, double[] Kp_mf,string mf_type_Ki, double[] Ki_mf,string mf_type_Kd, double[] Kd_mf){setMf_sub(mf_type_e, e_mf, 0);setMf_sub(mf_type_de, de_mf, 1);setMf_sub(mf_type_Kp, Kp_mf, 2);setMf_sub(mf_type_Ki, Ki_mf, 3);setMf_sub(mf_type_Kd, Kd_mf, 4);}//实现模糊控制public double realize(double t, double a){double[] u_e = new double[N],u_de = new double[N],u_u = new double[N];int[] u_e_index = new int[3], u_de_index = new int[3];//假设一个输入最多激活3个模糊子集double delta_Kp, delta_Ki, delta_Kd;double delta_u;target = t;actual = a;e = target - actual;de = e - e_pre_1;e = Ke * e;de = Kde * de;/* 将误差e模糊化*/int j = 0;for (int i = 0; i < N; i++){if (mf_t_e == "trimf")u_e[i] = trimf(e, e_mf_paras[i * 3], e_mf_paras[i * 3 + 1], e_mf_paras[i * 3 + 2]);//e模糊化,计算它的隶属度else if (mf_t_e == "gaussmf")u_e[i] = gaussmf(e, e_mf_paras[i * 2], e_mf_paras[i * 2 + 1]);//e模糊化,计算它的隶属度else if (mf_t_e == "trapmf")u_e[i] = trapmf(e, e_mf_paras[i * 4], e_mf_paras[i * 4 + 1], e_mf_paras[i * 4 + 2], e_mf_paras[i * 4 + 3]);//e模糊化,计算它的隶属度if (u_e[i] != 0)u_e_index[j++] = i;        //存储被激活的模糊子集的下标,可以减小计算量}for (; j < 3; j++) u_e_index[j] = 0;       //富余的空间填0/*将误差变化率de模糊化*/j = 0;for (int i = 0; i < N; i++){if (mf_t_de == "trimf")u_de[i] = trimf(de, de_mf_paras[i * 3], de_mf_paras[i * 3 + 1], de_mf_paras[i * 3 + 2]);//de模糊化,计算它的隶属度else if (mf_t_de == "gaussmf")u_de[i] = gaussmf(de, de_mf_paras[i * 2], de_mf_paras[i * 2 + 1]);//de模糊化,计算它的隶属度else if (mf_t_de == "trapmf")u_de[i] = trapmf(de, de_mf_paras[i * 4], de_mf_paras[i * 4 + 1], de_mf_paras[i * 4 + 2], de_mf_paras[i * 4 + 3]);//de模糊化,计算它的隶属度if (u_de[i] != 0)u_de_index[j++] = i;      //存储被激活的模糊子集的下标,可以减小计算量}for (; j < 3; j++) u_de_index[j] = 0;     //富余的空间填0double den = 0, num = 0;/*计算delta_Kp和Kp*/for (int m = 0; m < 3; m++)for (int n = 0; n < 3; n++){num += u_e[u_e_index[m]] * u_de[u_de_index[n]] * Kp_rule_matrix[u_e_index[m], u_de_index[n]];den += u_e[u_e_index[m]] * u_de[u_de_index[n]];}delta_Kp = num / den;delta_Kp = Ku_p * delta_Kp;if (delta_Kp >= delta_Kp_max) delta_Kp = delta_Kp_max;else if (delta_Kp <= -delta_Kp_max) delta_Kp = -delta_Kp_max;Kp += delta_Kp;if (Kp < 0) Kp = 0;/*计算delta_Ki和Ki*/den = 0; num = 0;for (int m = 0; m < 3; m++)for (int n = 0; n < 3; n++){num += u_e[u_e_index[m]] * u_de[u_de_index[n]] * Ki_rule_matrix[u_e_index[m], u_de_index[n]];den += u_e[u_e_index[m]] * u_de[u_de_index[n]];}delta_Ki = num / den;delta_Ki = Ku_i * delta_Ki;if (delta_Ki >= delta_Ki_max) delta_Ki = delta_Ki_max;else if (delta_Ki <= -delta_Ki_max) delta_Ki = -delta_Ki_max;Ki += delta_Ki;if (Ki < 0) Ki = 0;/*计算delta_Kd和Kd*/den = 0; num = 0;for (int m = 0; m < 3; m++)for (int n = 0; n < 3; n++){num += u_e[u_e_index[m]] * u_de[u_de_index[n]] * Kd_rule_matrix[u_e_index[m], u_de_index[n]];den += u_e[u_e_index[m]] * u_de[u_de_index[n]];}delta_Kd = num / den;delta_Kd = Ku_d * delta_Kd;if (delta_Kd >= delta_Kd_max) delta_Kd = delta_Kd_max;else if (delta_Kd <= -delta_Kd_max) delta_Kd = -delta_Kd_max;Kd += delta_Kd;if (Kd < 0) Kd = 0;A = Kp + Ki + Kd;B = -2 * Kd - Kp;C = Kd;delta_u = A * e + B * e_pre_1 + C * e_pre_2;delta_u = delta_u / Ke;if (delta_u >= 0.95 * target) delta_u = 0.95 * target;else if (delta_u <= -0.95 * target) delta_u = -0.95 * target;e_pre_2 = e_pre_1;e_pre_1 = e;return delta_u;}void showMf(string type, double[] mf_paras){int tab = 0;if (type == "trimf")tab = 2;else if (type == "gaussmf")tab = 1;else if (type == "trapmf")tab = 3;this.WriteLine($"函数类型:{mf_t_e}");this.WriteLine("函数参数列表:");double[] p = mf_paras;for (int i = 0; i < N * (tab + 1); i++){this.Write(p[i] + " ");if (i % (tab + 1) == tab)this.Write("\r\n");}}public void showInfo(){this.WriteLine("Info of this fuzzy controller is as following:");this.WriteLine($"基本论域e:[{-emax},{emax}]");this.WriteLine($"基本论域de:[{-demax},{demax}]");this.WriteLine($"基本论域delta_Kp:[{-delta_Kp_max},{delta_Kp_max}]");this.WriteLine($"基本论域delta_Ki:[{-delta_Ki_max},{delta_Ki_max}]");this.WriteLine($"基本论域delta_Kd:[{-delta_Kd_max},{delta_Kd_max}]");this.WriteLine("误差e的模糊隶属度函数参数:");showMf(mf_t_e, e_mf_paras);this.WriteLine("误差变化率de的模糊隶属度函数参数:");showMf(mf_t_de, de_mf_paras);this.WriteLine("delta_Kp的模糊隶属度函数参数:");showMf(mf_t_Kp, Kp_mf_paras);this.WriteLine("delta_Ki的模糊隶属度函数参数:");showMf(mf_t_Ki, Ki_mf_paras);this.WriteLine("delta_Kd的模糊隶属度函数参数:");showMf(mf_t_Kd, Kd_mf_paras);this.WriteLine("模糊规则表:");this.WriteLine("delta_Kp的模糊规则矩阵");for (int i = 0; i < N; i++){for (int j = 0; j < N; j++){this.Write(Kp_rule_matrix[i, j]);}this.Write("\r\n");}this.WriteLine("delta_Ki的模糊规则矩阵"); ;for (int i = 0; i < N; i++){for (int j = 0; j < N; j++){this.WriteLine(Ki_rule_matrix[i, j]);}WriteEnd();}this.WriteLine("delta_Kd的模糊规则矩阵"); ;for (int i = 0; i < N; i++){for (int j = 0; j < N; j++){this.WriteLine(Kd_rule_matrix[i, j]);}WriteEnd();}this.WriteLine($"误差的量化比例因子Ke={Ke}");this.WriteLine($"误差变化率的量化比例因子Kde={Kde}");this.WriteLine($"输出的量化比例因子Ku_p={Ku_p}");this.WriteLine($"输出的量化比例因子Ku_i={Ku_i}");this.WriteLine($"输出的量化比例因子Ku_d={Ku_d}");this.WriteLine($"设定目标target={target}");this.WriteLine($"误差e={e}");this.WriteLine($"Kp={Kp}");this.WriteLine($"Ki={Ki}");this.WriteLine($"Kd={Kd}");WriteEnd();}public void Write(object str){Console.Write(str);}public void WriteLine(object str){Console.WriteLine(str);}public void WriteEnd(){Console.Write("\r\n");}public static void test(){int NB = -3;int NM = -2;int NS = -1;int ZO = 0;int PS = 1;int PM = 2;int PB = 3;double target = 300;double actual = 400;double u = 0;int[,] deltaKpMatrix = new int[7, 7] {{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}};int[,] deltaKiMatrix = new int[7, 7]{{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}};int[,] deltaKdMatrix = new int[7, 7]{{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,NS,PS,PS,PS,PS,PB},{PB,PM,PM,PM,PS,PS,PB}};double[] e_mf_paras = { -3, -3, -2, -3, -2, -1, -2, -1, 0, -1, 0, 1, 0, 1, 2, 1, 2, 3, 2, 3, 3 };double[] de_mf_paras = { -3, -3, -2, -3, -2, -1, -2, -1, 0, -1, 0, 1, 0, 1, 2, 1, 2, 3, 2, 3, 3 };double[] Kp_mf_paras = { -3, -3, -2, -3, -2, -1, -2, -1, 0, -1, 0, 1, 0, 1, 2, 1, 2, 3, 2, 3, 3 };double[] Ki_mf_paras = { -3, -3, -2, -3, -2, -1, -2, -1, 0, -1, 0, 1, 0, 1, 2, 1, 2, 3, 2, 3, 3 };double[] Kd_mf_paras = { -3, -3, -2, -3, -2, -1, -2, -1, 0, -1, 0, 1, 0, 1, 2, 1, 2, 3, 2, 3, 3 };var fuzzypid = new FuzzyPID(1500, 1000, 0.3, 0.9, 0.6, 0.01, 0.04, 0.01);fuzzypid.setMf("trimf", e_mf_paras, "trimf", de_mf_paras, "trimf", Kp_mf_paras, "trimf", Ki_mf_paras, "trimf", Kd_mf_paras);fuzzypid.setRuleMatrix(deltaKpMatrix, deltaKiMatrix, deltaKdMatrix);for (int i = 0; i < 50; i++){u = fuzzypid.realize(target, actual);actual += u;Console.WriteLine($"{i}  {target} {u} {actual}");//if (i>19)//{//  target = 300;//}}//fuzzypid.showInfo();}}
}

以上就是c# 实现模糊PID控制算法的详细内容

c# 实现模糊PID控制算法相关推荐

  1. 自适应模糊PID控制算法

    一.自适应模糊PID控制 自适应模糊PID控制将模糊控制与传统PID控制相结合,将两种控制方式进行结合,取长补短,对传统的算法进行优化,形成一种新的控制算法,自适应模糊PID控制可以用于很多场景,比如 ...

  2. 模糊pid算法实现一般步骤

    模糊PID控制算法(Fuzzy PID Control Algorithm)是根据模糊控制理论和PID控制理论相结合的方法,可以解决传统PID控制在控制非线性.大惯性.复杂系统时效果不佳的问题. 模糊 ...

  3. 位置式\增量式PID、模糊PID、BRF-PID的Matlab实现以及封装

    位置式\增量式PID.模糊PID.BRF-PID的Matlab实现以及封装 位置式\增量式PID.模糊PID.BRF-PID的Matlab实现以及封装 简要 Model类 Strategy 类 PID ...

  4. Pid控制算法-专家PID与模糊PID的C++实现

    PID控制算法的C语言实现 八 专家PID与模糊PID的C语言实现    本节是PID控制算法的C++语言实现系列的最后一节,前面7节中,已经分别从PID的实现到深入的过程进行了一个简要的讲解,从前面 ...

  5. Pid控制算法-模糊算法简介

    PID控制算法的C++实现 九 模糊算法简介   在PID控制算法的C++语言实现中,文章已经对模糊PID的实质做了一个简要说明.基本概念和思路进行一下说明,相信有C++语言基础的朋友可以通过这些介绍 ...

  6. matlab步进电机模糊pid和BP神经网络控制

    1.内容简介 略 303-可以交流.咨询.答疑 2.内容说明 栽苗机育苗移栽是农业生产过程中的一个重要技术环节,它具有对气候的补偿作用 和使作物生育提早的综合效益,同时它可以充分利用光热资源,其经济效 ...

  7. 模糊PID控制器MATLAB仿真探讨,模糊PID控制器MATLAB仿真探讨

    模糊PID控制器MATLAB仿真探讨 技术探讨 l E H C LE P O ATO C NIA X L R I N T 馕表 Cl S UET l阅俄嚣 H A T MN TN中 Nl R N AO ...

  8. 基于模糊PID的柴油机调速系统

    <轮机工程>@EnzoReventon 基于模糊PID的柴油机调速系统 本文是我研一做的课堂大作业,主要介绍基于模糊PID的柴油机调速系统,通过与传统PID的柴油机调速系统的对比,突出展示 ...

  9. 温控中使用PID控制算法

    本文主要介绍各种PID控制算法的调节器在温度控制中控制特性.功能及主要应用场合,对大家合理选用用于温度控制提供方向. 对于温度控制算法包括常规PID.模糊控制.神经网络.Fuzzy_PID.神经网络P ...

  10. 用计算机程序实现离散化的对象模型,模糊PID应用

    回复: 120 模糊PID应用 (428202811) 出0入0汤圆 电梯直达 发表于 2007-12-4 12:24:18 | 只看该作者 |倒序浏览 |阅读模式 (1)模糊控制原理 模糊控制是以模 ...

最新文章

  1. 博士申请 | 澳门大学汪澎洋助理教授招收机器学习方向全奖博士生
  2. 005_JavaScript使用
  3. java minor gc_Java Minor发布计划再次进行了调整
  4. DIN+DIEN,机器学习唯一指定涨点技Attention
  5. linux 下export的作用,linux export 的作用
  6. 队列 开源 php,消息队列 - 基于think-queue消息队列 – 基于ThinkPHP和Bootstrap的极速后台开发框架...
  7. (1)鼠标单独移动两个actor
  8. u-boot源码汇编段简要分析
  9. 操作系统 第二部分 进程管理(四)
  10. 记一次代码被公司电脑加密后,编译不通过
  11. 论文笔记——分布式深度学习框架下基于性能感知的DBS—SGD算法
  12. matlab dlt标定,实验三 Matlab图像处理基本操作及摄像机标定(DLT)
  13. 网络管理员考试试题讲解
  14. Google搜索命令语法
  15. 漆翔宇计算机学院浙江大学,浙江大学20172018学年大学生学科竞赛获奖清单.pdf
  16. python中add方法_python中add函数怎么用
  17. 交叉电缆与以太网电缆有哪些区别之处,弱电工程师必知!
  18. Zbrush中常用的8种笔刷,笔刷中的八大金刚你用过几个?
  19. [Unity-26] AnimationClip压缩-动画文件压缩
  20. 05.OpenWrt-写入mac地址

热门文章

  1. 小编详解网络蜘蛛的安全隐患及预防方法
  2. Linux常用命令详解2
  3. android 大牛播放组件,大牛播放器安卓版_大牛播放器好不好用
  4. Java实现图书管理系统
  5. Java后台基础设施
  6. mysql汉字转拼音首字母报错_MySQL 汉字转拼音
  7. Python学习:[Microsoft][ODBC 驱动程序管理器] 未发现数据源名称并且未指定默认驱动程序 的解决方案
  8. 电话机器人图文+源码介绍
  9. Vulkan学习(一):Vulkan环境搭建(Windows)官方教程--(Base code Instance Validation layers)
  10. Nmap命令:-sP和-sN的区别