模糊PID控制的C程序

合集下载

模糊PID的c语言算法

模糊PID的c语言算法

#include <cvirte.h>#include <userint.h>#include "succus.h"#include <rs232.h>#include <ansi_c.h>#include <formatio.h>#include <math.h>#include <string.h>#define parameterPID 0.1 //PID常数#define maxcontroldata 10 //最大控制量#define parameterfuzzy 12 //模糊控制常数#define Pe1 4 //隶属度范围#define Pe2 8#define Psess1 2#define Psess2 4#define parainput 100 //输入常数static int panelHandle;static int L_PIDstart; //运行标签static int L_fuzzystart;static float P_control; //获得参数static float I_control;static float D_control;static int whatmode;static float model_K; //模型参数static float model_T;static float model_t;static float cycle; //设定周期static float savedata[3]; //储存偏差量static float savecontrol[20]; //存储控制量static float result[2]; //存储仿真结果static float getsum;static char senddata[22]; //通信协议static char recievedata[18];static char nak[6];static char ack[6];int main (int argc, char *argv[]){if (InitCVIRTE (0, argv, 0) == 0)return -1; /* out of memory */if ((panelHandle = LoadPanel (0, "succus.uir", PANEL)) < 0)return -1;OpenComConfig (2, "", 9600, 0, 8, 1, 512, 512); //打开串口senddata[0] = 5; //构造协议senddata[1] = '0';senddata[2] = 'A';senddata[3] = 'F';senddata[4] = 'F';senddata[5] = 'W';senddata[6] = 'W';senddata[7] = '0';senddata[8] = 'D';senddata[9] = '5';senddata[10] = '0';senddata[11] = '6';senddata[12] = '4';senddata[13] = '0';senddata[14] = '1';senddata[21] = 0;recievedata[0] = 5;recievedata[1] = '0';recievedata[2] = 'A';recievedata[3] = 'F';recievedata[4] = 'F';recievedata[5] = 'W';recievedata[6] = 'R';recievedata[7] = '0';recievedata[8] = 'D';recievedata[9] = '5';recievedata[10] = '0';recievedata[11] = '0';recievedata[12] = '0';recievedata[13] = '0';recievedata[14] = '1';recievedata[15] = '4';recievedata[16] = '0';recievedata[17] = 0;nak[0] = 21;nak[1] = '0';nak[2] = 'A';nak[3] = 'F';nak[4] = 'F';nak[5] = 0;ack[0] = 6;ack[1] = '0';ack[2] = 'A';ack[3] = 'F';ack[4] = 'F';ack[5] = 0;FlushInQ (2);FlushOutQ (2);DisplayPanel (panelHandle);RunUserInterface ();CloseCom (2);DiscardPanel (panelHandle);return 0;}int CVICALLBACK autosetPIDCallback (int panel, int control, int event,void *callbackData, int eventData1, int eventData2){switch (event){case EVENT_COMMIT:SetCtrlVal (panelHandle, PANEL_PARAMETER_P, 20.0);SetCtrlVal (panelHandle, PANEL_PARAMETER_I, 0.0);SetCtrlVal (panelHandle, PANEL_PARAMETER_D, 0.0);break;}return 0;}int CVICALLBACK fuzzycontrolCallback (int panel, int control, int event,void *callbackData, int eventData1, int eventData2){switch (event){case EVENT_COMMIT:L_fuzzystart = 1;GetCtrlVal (panelHandle, PANEL_WORKMODE, &whatmode); //获得工作状态if(whatmode == 0){GetCtrlVal (panelHandle, PANEL_EMLUATOR_K, &model_K); //模型GetCtrlVal (panelHandle, PANEL_EMLUATOR_T, &model_T);GetCtrlVal (panelHandle, PANEL_EMLUATOR_t, &model_t);}GetCtrlVal (panelHandle, PANEL_SAMPLINGTIME, &cycle);SetCtrlAttribute (panelHandle, PANEL_TIMER, ATTR_INTERVAL, cycle);SetCtrlAttribute (panelHandle, PANEL_TIMER, ATTR_ENABLED, 1); //获得抽样时间。

模糊PID控制温控系统设计C语言程序代码

模糊PID控制温控系统设计C语言程序代码

模糊PID控制温控系统设计C语言程序代码介绍本文介绍了使用模糊PID控制方法来设计温控系统的C语言程序代码。

本温控系统使用传感器读取室内温度,然后根据读取的数值对应调整冷风机的风速和加热器的加热时间,从而控制室内温度达到一个设定值。

系统设计本温控系统采用模糊PID控制方法,具体实现流程如下:1.根据设定温度和当前室内温度计算出误差值2.使用模糊控制方法将误差值转化为温度调节量3.根据模糊控制输出的温度调节量计算出PID控制器的输出4.根据PID控制器的输出调节冷风机的风速和加热器的加热时间系统设计中需要使用的传感器,冷风机和加热器的具体型号及参数需要根据实际情况进行选择。

此处不做详细说明。

程序代码实现以下代码实现了上述系统设计,包括模糊控制和PID控制。

// 温控系统C语言程序代码#include<stdio.h>#include<stdlib.h>// 模糊控制double GetTemperatureByFuzzy(double error){double delta = 0.5; // 设定的温度调节步长double result = 0;if (error <= -5){result = 1;}else if (error > -5 && error < 0){result = (error + 5) / 5.0;}else if (error >= 0 && error < 5){result = (5 - error) / 5.0;}else{result = 0;}return result * delta;}// PID控制double GetTemperatureByPID(double error, double lastError, double integ ral){double Kp = 0.5; // 比例系数double Ki = 0.01; // 积分系数double Kd = 0.1; // 微分系数double deltaT = 0.1; // 采样时间double derivate = (error - lastError) / deltaT;double result = Kp * error + Ki * integral + Kd * derivate;return result;}// 主函数int main(){double setTemp = 25; // 设定温度double curTemp = 24; // 当前温度,需要从传感器读取double lastError = 0; // 上一次的误差值double integral = 0; // 积分项while (1){double error = setTemp - curTemp; // 计算当前误差值double fuzzyTemp = GetTemperatureByFuzzy(error); // 模糊控制integral += error; // 更新积分项double pidTemp = GetTemperatureByPID(error, lastError, integra l); // PID控制lastError = error; // 更新上一次误差值// 根据pidTemp和fuzzyTemp调节冷风机的风速和加热器的加热时间,省略// 读取传感器更新当前温度,省略// curTemp = GetCurTemp();// 采样时间,省略// sleep(1);}}本文介绍了使用模糊PID控制方法来设计温控系统的C语言程序代码。

模糊PID控制温控系统设计方案C语言程序代码

模糊PID控制温控系统设计方案C语言程序代码

// *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J*模糊PID控制温控系统仿真设计C程序代码/ *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* *J* /#include<reg52.h>#define uchar unsigned char#define uint unsigned int#define PULSE 200#define number 0.035sbit SDO = P2 A0。

sbit SDI = P2A1。

sbit CS = P2A2。

sbit CLK = P2A3。

sbit EOC = P2 A4。

sbit RS = P2A5。

sbit RW = P2A6。

sbit EN = P2 A7。

sbit KEY1= P3A0。

simulink模糊pid控制模型转c语言代码 -回复

simulink模糊pid控制模型转c语言代码 -回复

simulink模糊pid控制模型转c语言代码-回复Simulink模糊PID控制模型转C语言代码Simulink是MATLAB软件中一款用于进行动态系统建模和仿真的工具。

它通过图形化界面提供了易于使用的建模环境,使得用户能够快速构建和测试各种控制系统。

然而,有时我们可能需要将Simulink模型转换为C语言代码,以便在嵌入式系统或其他平台上实现实时控制。

在本篇文章中,我们将介绍如何将Simulink模糊PID控制模型转换为C语言代码。

第一步:理解模糊PID控制器原理在进行代码转换之前,我们先来了解一下模糊PID控制器的原理。

PID 控制器是一种经典的控制器,由比例项、积分项和微分项组成。

它通过对系统实际输出与期望输出的差异进行反馈控制,从而调整系统输入,使得输出接近期望值。

模糊PID控制器与传统PID控制器的主要区别在于它使用了模糊逻辑来处理不确定性和模糊性。

模糊逻辑是一种基于模糊集合理论的控制方法,它可以模拟人的思维方式,通过模糊化的输入和输出变量进行推理和决策。

第二步:在Simulink中设计模糊PID控制模型在Simulink中设计模糊PID控制模型是实现模糊PID控制器代码转换的前提。

我们可以使用Fuzzy Logic Toolbox提供的工具来创建和调整模糊逻辑系统。

首先,我们需要创建输入和输出变量。

输入变量通常是系统的误差(Current Error)和误差的变化率(Error Rate),输出变量一般为控制量(Control Signal)。

然后,我们可以根据实际情况定义模糊集合和模糊规则,以及选择适当的模糊控制器类型(如模糊反向推理控制器或模糊自适应控制器)。

完成模糊PID控制模型设计后,我们可以在Simulink中进行仿真和调试,确保模型能够正确地实现期望的控制效果。

第三步:使用MATLAB Coder将Simulink模型转换为C语言代码实现模糊PID控制模型的C语言代码转换,我们可以使用MATLAB Coder。

模糊PID控制算法的C#实现

模糊PID控制算法的C#实现

模糊PID控制算法的C#实现跑起来的效果看每个类的test⽅法,⾃⼰调⽤来测试⽬的是看看哪个算法好⽤,移植的时候⽐较单纯没有研究懂算法,代码结构也没改动,只是移植到C#⽅便查看代码和测试,⼤家要拷贝也很⽅便,把整个类拷贝到.cs⽂件即可第⼀段算法来⾃模糊PID控制算法的C++实现:blog。

csdn。

net/shuoyueqishilove/article/details/78236541这段算法在实际值低于⽬标值是⼯作正常,超过后会有问题,不知道如何调教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;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){case0: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;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;case2: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;case3: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;case4: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);}//实现模糊控制{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;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++){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}");// target = 300;//}}//fuzzypid.showInfo();}}}第⼆段来⾃模糊PID控制温控系统设计⽅案C语⾔程序代码: wenku。

模糊控制算法c程序

模糊控制算法c程序

由于项目需要,需要模糊控制算法,之前此类知识为0,经过半个多月的研究,终于有的小进展。

开始想从强大的互联网上搜点c代码来研究下,结果搜遍所有搜索引擎都搜不到,以下本人从修改的模糊控制代码,经过自己修改后可在vc6.0,运行!输入e表示输出误差,ec表示误差变化率,经过测试具有很好的控制效果,对于非线性系统和数学模型难以建立的系统来说有更好的控制效果!现将其公开供大家学习研究!#include <stdio.h>#include"math.h"#define PMAX 100#define PMIN -100#define DMAX 100#define DMIN -100#define FMAX 100 /*语言值的满幅值*/int PFF[4]={0,12,24,48};/*输入量D语言值特征点*/int DFF[4]={0,16,32,64};/*输出量U语言值特征点*/int UFF[7]={0,15,30,45,60,75,90};/*采用了调整因子的规则表,大误差时偏重误差,小误差时偏重误差变化*//*a0=0.3,a1=0.55,a2=0.74,a3=0.89 */int rule[7][7]={//误差变化率-3,-2,-1, 0, 1, 2, 3 // 误差{-6,-6,-6,-5,-5,-5,-4,}, // -3{-5,-4,-4,-3,-2,-2,-1,}, // -2{-4,-3,-2,-1, 0, 1, 2,}, // -1{-4,-3,-1, 0, 1, 3, 4,}, // 0{-2,-1, 0, 1, 2, 3, 4,}, // 1{ 1, 2, 2, 3, 4, 4, 5,}, // 2{ 4, 5, 5, 5, 6, 6, 6}}; // 3/**********************************************************/int Fuzzy(int P,int D) /*模糊运算引擎*/{int U; /*偏差,偏差微分以及输出值的精确量*/unsigned int PF[2],DF[2],UF[4]; /*偏差,偏差微分以及输出值的隶属度*/ int Pn,Dn,Un[4];long temp1,temp2;/*隶属度的确定*//*根据PD的指定语言值获得有效隶属度*/if(P>-PFF[3] && P<PFF[3]){if(P<=-PFF[2]){Pn=-2;PF[0]=FMAX*((float)(-PFF[2]-P)/(PFF[3]-PFF[2]));}else if(P<=-PFF[1]){Pn=-1;PF[0]=FMAX*((float)(-PFF[1]-P)/(PFF[2]-PFF[1]));}else if(P<=PFF[0]){Pn=0;PF[0]=FMAX*((float)(-PFF[0]-P)/(PFF[1]-PFF[0]));}else if(P<=PFF[1]){Pn=1; PF[0]=FMAX*((float)(PFF[1]-P)/(PFF[1]-PFF[0]));}else if(P<=PFF[2]){Pn=2; PF[0]=FMAX*((float)(PFF[2]-P)/(PFF[2]-PFF[1]));}else if(P<=PFF[3]){Pn=3; PF[0]=FMAX*((float)(PFF[3]-P)/(PFF[3]-PFF[2]));}}else if(P<=-PFF[3]){Pn=-2; PF[0]=FMAX;}else if(P>=PFF[3]){Pn=3; PF[0]=0;}PF[1]=FMAX-PF[0];if(D>-DFF[3] && D<DFF[3]){if(D<=-DFF[2]){Dn=-2;DF[0]=FMAX*((float)(-DFF[2]-D)/(DFF[3]-DFF[2])); }else if(D<=-DFF[1]){Dn=-1;DF[0]=FMAX*((float)(-DFF[1]-D)/(DFF[2]-DFF[1]));}else if(D<=DFF[0]){Dn=0;DF[0]=FMAX*((float)(-DFF[0]-D)/(DFF[1]-DFF[0]));}else if(D<=DFF[1]){Dn=1;DF[0]=FMAX*((float)(DFF[1]-D)/(DFF[1]-DFF[0]));}else if(D<=DFF[2]){Dn=2; DF[0]=FMAX*((float)(DFF[2]-D)/(DFF[2]-DFF[1])); }else if(D<=DFF[3]){Dn=3; DF[0]=FMAX*((float)(DFF[3]-D)/(DFF[3]-DFF[2])); }}else if(D<=-DFF[3]){Dn=-2;DF[0]=FMAX;else if(D>=DFF[3]){Dn=3;DF[0]=0;}DF[1]=FMAX-DF[0];/*使用误差围优化后的规则表rule[7][7]*//*输出值使用13个隶属函数,中心值由UFF[7]指定*/ /*一般都是四个规则有效*/Un[0]=rule[Pn-1+3][Dn-1+3];Un[1]=rule[Pn+3][Dn-1+3];Un[2]=rule[Pn-1+3][Dn+3];Un[3]=rule[Pn+3][Dn+3];if(PF[0]<=DF[0])UF[0]=PF[0];elseUF[0]=DF[0];if(PF[1]<=DF[0])UF[1]=PF[1];elseUF[1]=DF[0];if(PF[0]<=DF[1])UF[2]=PF[0];elseUF[2]=DF[1];if(PF[1]<=DF[1])UF[3]=PF[1];elseUF[3]=DF[1];/*同隶属函数输出语言值求大*/if(Un[0]==Un[1]){if(UF[0]>UF[1])UF[1]=0;elseUF[0]=0;if(Un[0]==Un[2]){if(UF[0]>UF[2])UF[2]=0;elseUF[0]=0;}if(Un[0]==Un[3]){if(UF[0]>UF[3])UF[3]=0;elseUF[0]=0;}if(Un[1]==Un[2]){if(UF[1]>UF[2])UF[2]=0;elseUF[1]=0;}if(Un[1]==Un[3]){if(UF[1]>UF[3])UF[3]=0;elseUF[1]=0;}if(Un[2]==Un[3]){if(UF[2]>UF[3])UF[3]=0;elseUF[2]=0;}/*重心法反模糊*//*Un[]原值为输出隶属函数标号,转换为隶属函数值*/ if(Un[0]>=0)Un[0]=UFF[Un[0]];elseUn[0]=-UFF[-Un[0]];if(Un[1]>=0)Un[1]=UFF[Un[1]];elseUn[1]=-UFF[-Un[1]];if(Un[2]>=0)Un[2]=UFF[Un[2]];elseUn[2]=-UFF[-Un[2]];if(Un[3]>=0)Un[3]=UFF[Un[3]];elseUn[3]=-UFF[-Un[3]];temp1=UF[0]*Un[0]+UF[1]*Un[1]+UF[2]*Un[2]+UF[3]*Un[3]; temp2=UF[0]+UF[1]+UF[2]+UF[3];U=temp1/temp2;return U;}void main(){int a=0,e,ec;/*int nowpoint,p1,p2=1;FILE *in,*out;in=fopen("in.txt","r");out=fopen("out.txt","w");*///while(!feof(in))while(1){//fscanf(in,"%d",&nowpoint);//p1=nowpoint;//e=0-nowpoint;//ec= p1-p2;printf("请输入e:");scanf("%d",&e);printf("请输入ec:");scanf("%d",&ec);a=Fuzzy(e,ec);//fprintf(out,"%d ",a);//printf("%d: ",p1);printf("e: %d ec: %d ",e,ec);printf("a: %d \n",a); //p2=p1;}//fclose(in);//fclose(out);}。

PID控制算法的C语言实现(完整版)

PID控制算法的C语言实现(完整版)

PID控制算法的C语言实现一 PID算法原理最近两天在考虑一般控制算法的C语言实现问题,发现网络上尚没有一套完整的比较体系的讲解。

于是总结了几天,整理一套思路分享给大家。

在工业应用中PID及其衍生算法是应用最广泛的算法之一,是当之无愧的万能算法,如果能够熟练掌握PID算法的设计与实现过程,对于一般的研发人员来讲,应该是足够应对一般研发问题了,而难能可贵的是,在我所接触的控制算法当中,PID控制算法又是最简单,最能体现反馈思想的控制算法,可谓经典中的经典。

经典的未必是复杂的,经典的东西常常是简单的,而且是最简单的,想想牛顿的力学三大定律吧,想想爱因斯坦的质能方程吧,何等的简单!简单的不是原始的,简单的也不是落后的,简单到了美的程度。

先看看PID算法的一般形式:PID的流程简单到了不能再简单的程度,通过误差信号控制被控量,而控制器本身就是比例、积分、微分三个环节的加和。

这里我们规定(在t时刻):1.输入量为rin(t);2.输出量为rout(t);3.偏差量为err(t)=rin(t)-rout(t);pid的控制规律为理解一下这个公式,主要从下面几个问题着手,为了便于理解,把控制环境具体一下:1.规定这个流程是用来为直流电机调速的;2.输入量rin(t)为电机转速预定值;3.输出量rout(t)为电机转速实际值;4.执行器为直流电机;5.传感器为光电码盘,假设码盘为10线;6.直流电机采用PWM调速转速用单位转/min表示;不难看出以下结论:1.输入量rin(t)为电机转速预定值(转/min);2. 输出量rout(t)为电机转速实际值(转/min);3.偏差量为预定值和实际值之差(转/min);那么以下几个问题需要弄清楚:1.通过PID环节之后的U(t)是什么值呢?2.控制执行器(直流电机)转动转速应该为电压值(也就是PWM占空比)。

3.那么U(t)与PWM之间存在怎样的联系呢?/user1/3407/archives/2006/33541.html(见附录1)这篇文章上给出了一种方法,即,每个电压对应一个转速,电压和转速之间呈现线性关系。

simulink模糊pid控制模型转c语言代码

simulink模糊pid控制模型转c语言代码

simulink模糊pid控制模型转c语言代码1.引言1.1 概述在Simulink模糊PID控制模型转换为C语言代码的过程中,我们首先要了解模糊PID控制模型的基本原理和作用。

模糊PID控制模型是一种基于模糊逻辑的控制模型,它能够处理非线性、模糊和不确定的系统,并且具有良好的控制性能。

本文的目的是将Simulink中的模糊PID控制模型转换为可在嵌入式系统中运行的C语言代码。

通过这个转换过程,我们可以将Simulink模型直接应用于实际的嵌入式系统中,从而实现对系统的精确控制。

在转换过程中,我们将介绍Simulink模糊PID控制模型的基本结构和参数设置,以及针对模型的特定需求进行的模糊逻辑设计。

然后,我们将详细讲解如何将Simulink模型转换为可执行的C语言代码,包括代码的结构和实现方法。

转换完成后,我们将对转换结果进行评估和展望,分析代码在嵌入式系统中的实际应用情况,并提出改进和优化的建议。

通过本文的阅读,读者将能够了解Simulink模糊PID控制模型转换为C语言代码的全过程,并具备实际应用的能力。

同时,本文也为相关领域的研究和开发人员提供了一个参考和指导,帮助他们更好地利用Simulink进行系统控制。

1.2文章结构文章结构部分的内容应包括本文的组织架构和各个章节的简要介绍。

文章的组织架构如下所示:引言部分简要介绍了本文的主题和目的,包括Simulink模糊PID控制模型转C语言代码的方法和过程。

正文部分包括了Simulink模糊PID控制模型以及将其转换为C语言代码的方法。

在第2.1节中,我们将介绍Simulink模糊PID控制模型的基本概念和原理,并对其进行详细说明。

在第2.2节中,我们将介绍将Simulink模糊PID控制模型转换为C语言代码的方法和步骤,包括代码生成和优化技巧。

结论部分将对Simulink模糊PID控制模型转C语言代码的过程进行总结,并对转换结果进行评估和展望。

模糊PID控制温控系统设计C语言程序代码

模糊PID控制温控系统设计C语言程序代码

模糊PID控制温控系统设计C语言程序代码请注意,由于1200字的限制,下面的代码只是模糊PID控制温控系统的一个简单示例。

如果您需要更详细和完整的代码,请提供更多的细节和规格要求。

```c#include <stdio.h>//PID参数float kp = 0.5; // 比例系数float ki = 0.2; // 积分系数float kd = 0.1; // 微分系数//PID变量float integral = 0; // 积分累计float previous_error = 0; // 上一次的误差//温度传感器读取函数,返回当前温度float read_temperatur//实现温度传感器读取的代码逻辑//返回当前温度值//控制器输出函数,将控制信号发送给执行机构void control_output(float control_signal)//实现将控制信号发送给执行机构的代码逻辑int mai//设置设定温度float setpoint = 25.0;//主循环while (1)//获取当前温度float current_temperature = read_temperature(;//计算误差float error = setpoint - current_temperature;//计算PID控制信号float p_term = kp * error;integral += ki * error;float d_term = kd * (error - previous_error);float control_signal = p_term + integral + d_term; //更新上一次的误差previous_error = error;//输出控制信号control_output(control_signal);}return 0;```上述代码中,我们首先定义了PID参数和变量,以及温度传感器读取函数和控制器输出函数。

PID控制算法的C语言实现完整版

PID控制算法的C语言实现完整版

PID控制算法的C语言实现一 PID算法原理最近两天在考虑一般控制算法的C语言实现问题,发现网络上尚没有一套完整的比较体系的讲解。

于是总结了几天,整理一套思路分享给大家。

在工业应用中PID及其衍生算法是应用最广泛的算法之一,是当之无愧的万能算法,如果能够熟练掌握PID算法的设计与实现过程,对于一般的研发人员来讲,应该是足够应对一般研发问题了,而难能可贵的是,在我所接触的控制算法当中,PID控制算法又是最简单,最能体现反馈思想的控制算法,可谓经典中的经典。

经典的未必是复杂的,经典的东西常常是简单的,而且是最简单的,想想牛顿的力学三大定律吧,想想爱因斯坦的质能方程吧,何等的简单简单的不是原始的,简单的也不是落后的,简单到了美的程度。

先看看PID算法的一般形式:PID的流程简单到了不能再简单的程度,通过误差信号控制被控量,而控制器本身就是比例、积分、微分三个环节的加和。

这里我们规定在t时刻:1.输入量为rin t ;2.输出量为rout t ;3.偏差量为err t =rin t -rout t ;pid的控制规律为理解一下这个公式,主要从下面几个问题着手,为了便于理解,把控制环境具体一下:1.规定这个流程是用来为直流电机调速的;2.输入量rin t 为电机转速预定值;3.输出量rout t 为电机转速实际值;4.执行器为直流电机;5.传感器为光电码盘,假设码盘为10线;6.直流电机采用PWM调速转速用单位转/min表示;不难看出以下结论:1.输入量rin t 为电机转速预定值转/min ;2. 输出量rout t 为电机转速实际值转/min ;3.偏差量为预定值和实际值之差转/min ;那么以下几个问题需要弄清楚:1.通过PID环节之后的U t 是什么值呢2.控制执行器直流电机转动转速应该为电压值也就是PWM占空比。

3.那么U t 与PWM之间存在怎样的联系呢见附录1 这篇文章上给出了一种方法,即,每个电压对应一个转速,电压和转速之间呈现线性关系。

模糊PID C语言程序

模糊PID C语言程序

C语言PID演示程序#include <string.h>#include<stdio.h>typedef struct PID{double Command; //输入指令double Proportion; //比例系数double Integral; //积分系数double Derivative; //微分系数double preErr; //前一拍误差double sumErr; //误差累积}PID;double PIDCale(PID *p,double feedback){double dErr,Err;Err=p->Command-feedback; //当前误差p->sumErr+=Err; //误差累加dErr=Err-p->preErr; //误差微分p->preErr=Err;return(p->Proportion*Err //比例项+p->Derivative*dErr //微分项+p->Integral*p->sumErr); //积分项}void PIDInit(PID *p){memset(p,0,sizeof(PID)); //初始化}typedef struct motor{double lastY;double preY;double lastU;double preU;}motor;void motorInit(motor *m){memset(m,0,sizeof(motor));}double motorCal(motor *m,double u)doubley=1.9753*m->lastY-0.9753*m->preY+0.00003284*u+0.00006568*m->lastU+0.0000 3284*m->preU;//二阶系统m->preY=m->lastY;m->lastY=y;m->preU=m->lastU;m->lastU=u;return y;}void main(){FILE *fp=fopen("data.txt","w+");PID sPID;motor m_motor;int k=0;double u;double y=0;PIDInit(&sPID);sPID.Proportion=2;sPID.Derivative=1;sPID.Integral=0.00001;mand=10;motorInit(&m_motor);while(k<=1000){•fprintf(fp,"%d 设定值=%f 被控量=%f 偏差=%f 控制量=%f\n",k,mand,y,mand-y,u);u=PIDCale(&sPID,y);y=motorCal(&m_motor,u);k++;}printf("%f\n",y);fclose(fp);}增量式PID控制C语言代码增量式PID控制C语言代码////////////////////////////////////////////////////////////////// 定义PID参数结构体///////////////////////////////////////////////////////////////typedef struct PID { //结构体定义int SetPoint //设定值int Proportion; // Proportion 比例系数int Integral; // Integral 积分系数int Derivative; // Derivative 微分系数int LastError; // Error[-1] 前一拍误差int PreError; // Error[-2] 前两拍误差} PID;main(){PID vPID; //定义结构变量名PIDInit ( &vPID ); //Initialize StructurevPID.Proportion = 10; //Set PID CoefficientsvPID.Integral = 10; // Set PID IntegralvPID.Derivative = 10; // Set PID DerivativevPID. SetPoint = //根据实际情况设定while(1){Verror=Measure(); //得到AD的输出值Error =vPID. SetPoint- Verror; //与设定值比较,得到误差值tempi=PIDCal(&vPID, Error;laser.Value+=tempi; // Value与Num[2]为共同体,共同体名laserLASERH=laser.Num[0];LASERL=laser.Num[1];}}/////////////////////////////////////////////////////////////////////////Title:PID参数初始化//Description: Proportion="0"// Integral=0// LastError=0//Input: PID的P、I控制常数和之前的误差量(PID *pp)//Return://////////////////////////////////////////////////////////////////////void PIDInit (PID *pp) //PID参数初始化,都置0 {memset ( pp,0,sizeof(PID));//memset()的函数,它可以一字节一字节地把整个数组设置为一个指定的值。

模糊自适应整定PID控制程序FUZZY_PID

模糊自适应整定PID控制程序FUZZY_PID
ecFuzzy[2] = (ec - ecRule[1])/(ecRule[2] - ecRule[1]);
//return(V_out);
}
/****************************************************************************
*
*文件名:FUZZY_Calc_Kp(float e,float ec)
*
*功 能:模糊算法kp计算部分
*
*作 者: Sahara
*
*入口参数:float e,float ec
*
*出口参数:Kp
*
****************************************************************************/
void FUZZY_Calc_Kp(float e,float ec)
{
eFuzzy[2] = (e - eRule[3])/(eRule[2] - eRule[3]);
eFuzzy[3] = (e - eRule[2])/(eRule[3] - eRule[2]);
eFuzzy_Out[2] = eFuzzy[2] > eFuzzy[3] ? eFuzzy[2] : eFuzzy[3];
Pe = 5;
}
else
{
eFuzzy_Out[5] = 1.0;
Pe = 5;
}
//eFuzzy_Out[1] = 1.0 - eFuzzy_Out[0];
/****************************************************************************

(完整版)模糊PID控制的C程序

(完整版)模糊PID控制的C程序

(完整版)模糊PID控制的C程序//e:[-3,3] ec:[-3,3] kp:[-0.3,0.3]#include#define NB 0#define NM 1#define NS 2#define ZO 3#define PS 4#define PM 5#define PB 6/*********************************************************/ float uf(float x,float a,float b,float c);float cuf(float x,float a,float b,float c);float ufl(float x,float a,float b);float cufl(float x,float a,float b);float ufr(float x,float a,float b);float cufr(float x,float a,float b);float ufr(float x,float a,float b);float cufr(float x,float a,float b);float fand(float a,float b);float forr(float a,float b);float FuzzyKp(float e,float ec);//主程序void main(){float a,b,Kp;printf("The E is:");scanf("%f",&a);printf("The Ec is:");scanf("%f",&b);Kp=FuzzyKp(a,b);printf("The parameter Kp is: %f\n\n",Kp);float FuzzyKp(float e,float ec){float es[7];float ecs[7];/******模糊推理规则的可信度通过取小点运算得到*****/ float form[7][7];//(表X7)(隶属度表)int i,j;/*************求得的最大值赋给form[a][b]*********/ int a=0,b=0;float lsd;int p;float detkp;/**************************/int kp[7][7]={{PB,PB,PM,PS,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}};es[NB]=ufl(e,-3,-1);es[NM]=uf(e,-3,-2,0);es[NS]=uf(e,-3,-1,1);es[ZO]=uf(e,-2,0,2);es[PS]=uf(e,-1,1,3);es[PM]=uf(e,0,2,3);es[PB]=ufr(e,1,3);ecs[NB]=ufl(ec,-3,-1);//ececs[NM]=uf(ec,-3,-2,0);ecs[NS]=uf(ec,-3,-1,1);ecs[ZO]=uf(ec,-2,0,2);ecs[PS]=uf(ec,-1,1,3);ecs[PM]=uf(ec,0,2,3);ecs[PB]=ufr(ec,1,3);for(i=0;i<7;i++){float w,h,r;for(j=0;j<7;j++){h=es[i];r=ecs[j];w=fand(h,r);form[i][j]=w;}}for(i=0;i<7;i++){for(j=0;j<7;j++){if(form[a][b]<form[i][j])< p="">{a=i;b=j;}}}lsd=form[a][b];//es和ecs最值中的最大值p=kp[a][b]; if(p==NB)detkp=cufl(lsd,-0.3,-0.1);else if(p==NM)detkp=cuf(lsd,-0.3,0.2,0);else if(p==NS)detkp=cuf(lsd,-0.3,-0.1,0.1);else if(p==ZO)detkp=cuf(lsd,-0.2,0,0.2);else if(p==PS)detkp=cuf(lsd,-0.1,0.1,0.3);else if(p==PM)detkp=cuf(lsd,0,0.2,0.3);else if(p==PB)detkp=cufr(lsd,0.1,0.3);return detkp;}/**************************************以下为附属子函数*//**************求隶属度(三角形)模糊化处理***************/ float uf(float x,float a,float b,float c){if(x<=a)return (0);else if((a<x)&&(x<=b))< p="">return( (x-a)/(b-a));else if((b<x)&&(x<=c))< p="">return( (c-x)/(c-b));else if(x>c)return (0);}/****************三角形反模糊化处理(最大隶属度法)**********************/float cuf(float x,float a,float b,float c){float y,z;z=(b-a)*x+a;y=c-(c-b)*x;return (y+z)/2;}/*****************梯形(左)求隶属度模糊化*******************/ float ufl(float x,float a,float b){if(x<=a)return 1;else if((a<x)&&(x<=b))< p="">return (b-x)/(b-a);else if(x>b)return 0;}/*******************梯形反模糊化***********************/ float cufl(float x,float a,float b){return b-(b-a)*x;}/*****************梯形(右)求隶属度模糊化*******************/ float ufr(float x,float a,float b){if(x<=a)return 0;if((a<x)&&(x<b))< p="">return (x-a)/(b-a);if(x>=b)return 1;}/*******************梯形反模糊化***********************/ float cufr(float x,float a,float b){return (b-a)*x +a;}/*******************求交集***********************/ float fand(float a,float b){return (a}/*******************求并集***********************/ float forr(float a,float b){return (a<b)?b:a;< p="">}</b)?b:a;<></x)&&(x<b))<></x)&&(x<=b))<></x)&&(x<=c))<></x)&&(x<=b))<></form[i][j])<>。

simulink模糊pid控制模型转c语言代码 -回复

simulink模糊pid控制模型转c语言代码 -回复

simulink模糊pid控制模型转c语言代码-回复"Simulink模糊PID控制模型转C语言代码"在控制系统中,PID(比例-积分-微分)控制器被广泛应用于实现对系统的稳定和精确控制。

然而,当面对非线性、不确定性或者复杂度较高的系统时,传统的PID控制往往无法满足需求。

这时,模糊控制成为一种有效的替代方法。

模糊PID控制结合了传统的PID控制和模糊控制的优点,是在复杂系统控制中常用的一种方法。

本文将介绍如何将Simulink模糊PID控制模型转化为C语言代码的步骤。

第一步:设计模糊PID控制模型在Simulink环境下,设计一个模糊PID控制模型。

首先,根据系统特性选择合适的输入和输出变量,如温度和控制信号。

然后,选择适当的模糊集合和隶属函数。

根据系统的动态响应,确定合适的模糊规则,并使用模糊推理机制进行系统的控制。

最后,评估和调整模型以满足系统的需求。

第二步:构建模糊PID控制器的C语言数据结构根据设计的模糊PID控制模型,构建对应的C语言数据结构。

首先,定义输入和输出变量的数据类型和范围。

然后,定义模糊控制器的数据结构,包括模糊集合、隶属函数和模糊规则等。

最后,定义需要使用的参数,如模糊PID控制器的增益和偏差。

第三步:实现模糊控制算法在C语言中,实现模糊控制算法。

首先,读取输入变量的传感器数据,如温度值。

然后,将传感器数据映射到相应的模糊集合上,并计算隶属度。

接下来,使用模糊推理机制基于模糊规则来确定输出变量的控制信号。

最后,使用PID控制算法对控制信号进行修正,以实现系统的稳定和精确控制。

第四步:测试和优化C语言代码在C语言环境下,对已实现的模糊PID控制算法进行测试和优化。

首先,使用模拟数据或者仿真实验验证C语言代码的正确性和准确性。

然后,根据需要对代码进行调整和优化,以满足系统的性能要求。

最后,使用实际系统进行验证和性能测试,对模糊PID控制算法进行进一步改进和优化。

PID控制算法的C语言实现完整版

PID控制算法的C语言实现完整版

PID控制算法(de)C语言实现一 PID算法原理最近两天在考虑一般控制算法(de)C语言实现问题,发现网络上尚没有一套完整(de)比较体系(de)讲解.于是总结了几天,整理一套思路分享给大家.在工业应用中PID及其衍生算法是应用最广泛(de)算法之一,是当之无愧(de)万能算法,如果能够熟练掌握PID算法(de)设计与实现过程,对于一般(de)研发人员来讲,应该是足够应对一般研发问题了,而难能可贵(de)是,在我所接触(de)控制算法当中,PID控制算法又是最简单,最能体现反馈思想(de)控制算法,可谓经典中(de)经典.经典(de)未必是复杂(de),经典(de)东西常常是简单(de),而且是最简单(de),想想牛顿(de)力学三大定律吧,想想爱因斯坦(de)质能方程吧,何等(de)简单简单(de)不是原始(de),简单(de)也不是落后(de),简单到了美(de)程度.先看看PID算法(de)一般形式:PID(de)流程简单到了不能再简单(de)程度,通过误差信号控制被控量,而控制器本身就是比例、积分、微分三个环节(de)加和.这里我们规定(在t时刻):1.输入量为rin(t);2.输出量为rout(t);3.偏差量为err(t)=rin(t)-rout(t);pid(de)控制规律为理解一下这个公式,主要从下面几个问题着手,为了便于理解,把控制环境具体一下:1.规定这个流程是用来为直流电机调速(de);2.输入量rin(t)为电机转速预定值;3.输出量rout(t)为电机转速实际值;4.执行器为直流电机;5.传感器为光电码盘,假设码盘为10线;6.直流电机采用PWM调速转速用单位转/min表示;不难看出以下结论:1.输入量rin(t)为电机转速预定值(转/min);2. 输出量rout(t)为电机转速实际值(转/min);3.偏差量为预定值和实际值之差(转/min);那么以下几个问题需要弄清楚:1.通过PID环节之后(de)U(t)是什么值呢2.控制执行器(直流电机)转动转速应该为电压值(也就是PWM占空比).3.那么U(t)与PWM之间存在怎样(de)联系呢(见附录1)这篇文章上给出了一种方法,即,每个电压对应一个转速,电压和转速之间呈现线性关系.但是我考虑这种方法(de)前提是把直流电机(de)特性理解为线性了,而实际情况下,直流电机(de)特性绝对不是线性(de),或者说在局部上是趋于线性(de),这就是为什么说PID调速有个范围(de)问题.具体看一下(见附录2)这篇文章就可以了解了.所以在正式进行调速设计之前,需要现有开环系统,测试电机和转速之间(de)特性曲线(或者查阅电机(de)资料说明),然后再进行闭环参数整定.这篇先写到这,下一篇说明连续系统(de)离散化问题.并根据离散化后(de)特点讲述位置型PID和增量型PID(de)用法和C语言实现过程.PID控制算法(de)C语言实现二 PID算法(de)离散化上一节中,我论述了PID算法(de)基本形式,并对其控制过程(de)实现有了一个简要(de)说明,通过上一节(de)总结,基本已经可以明白PID控制(de)过程.这一节中先继续上一节内容补充说明一下.1.说明一下反馈控制(de)原理,通过上一节(de)框图不难看出,PID控制其实是对偏差(de)控制过程;2.如果偏差为0,则比例环节不起作用,只有存在偏差时,比例环节才起作用.3.积分环节主要是用来消除静差,所谓静差,就是系统稳定后输出值和设定值之间(de)差值,积分环节实际上就是偏差累计(de)过程,把累计(de)误差加到原有系统上以抵消系统造成(de)静差.4.而微分信号则反应了偏差信号(de)变化规律,或者说是变化趋势,根据偏差信号(de)变化趋势来进行超前调节,从而增加了系统(de)快速性.好了,关于PID(de)基本说明就补充到这里,下面将对PID连续系统离散化,从而方便在处理器上实现.下面把连续状态(de)公式再贴一下:假设采样间隔为T,则在第K T时刻:偏差err(K)=rin(K)-rout(K);积分环节用加和(de)形式表示,即err(K)+err(K+1)+……;微分环节用斜率(de)形式表示,即[err(K)-err(K-1)]/T;从而形成如下PID离散表示形式:则u(K)可表示成为:至于说Kp、Ki、Kd三个参数(de)具体表达式,我想可以轻松(de)推出了,这里节省时间,不再详细表示了.其实到这里为止,PID(de)基本离散表示形式已经出来了.目前(de)这种表述形式属于位置型PID,另外一种表述方式为增量式PID,由U上述表达式可以轻易得到:那么:这就是离散化PID(de)增量式表示方式,由公式可以看出,增量式(de)表达结果和最近三次(de)偏差有关,这样就大大提高了系统(de)稳定性.需要注意(de)是最终(de)输出结果应该为u(K)+增量调节值;PID(de)离散化过程基本思路就是这样,下面是将离散化(de)公式转换成为C语言,从而实现微控制器(de)控制作用.PID控制算法(de)C语言实现三位置型PID(de)C语言实现上一节中已经抽象出了位置性PID和增量型PID(de)数学表达式,这一节,重点讲解C语言代码(de)实现过程,算法(de)C语言实现过程具有一般性,通过PID算法(de)C语言实现,可以以此类推,设计其它算法(de)C语言实现.第一步:定义PID变量结构体,代码如下:struct _pid{float SetSpeed;例系数Kp(de)作用是加快系统(de)响应速度,提高系统(de)调节精度.Kp越大,系统(de)响应速度越快,系统(de)调节精度越高,但是容易产生超调,甚至会使系统不稳定.Kp取值过小,则会降低调节精度,使响应速度缓慢,从而延长调节时间,是系统静态、动态特性变差;2.积分作用系数Ki(de)作用是消除系统(de)稳态误差.Ki越大,系统(de)静态误差消除(de)越快,但是Ki过大,在响应过程(de)初期会产生积分饱和(de)现象,从而引起响应过程(de)较大超调.若Ki过小,将使系统静态误差难以消除,影响系统(de)调节精度;3.微分系数Kd(de)作用是改善系统(de)动态特性,其作用主要是在响应过程中抑制偏差向任何方向(de)变化,对偏差变化进行提前预报.但是kd过大,会使响应过程提前制动,从而延长调节时间,而且会降低系统(de)抗干扰性.反应系统性能(de)两个参数是系统误差e和误差变化律ec,这点还是好理解(de):首先我们规定一个误差(de)极限值,假设为Mmax;规定一个误差(de)比较大(de)值,假设为Mmid;规定一个误差(de)较小值,假设为Mmin;当abs(e)>Mmax时,说明误差(de)绝对值已经很大了,不论误差变化趋势如何,都应该考虑控制器(de)输入应按最大(或最小)输出,以达到迅速调整误差(de)效果,使误差绝对值以最大(de)速度减小.此时,相当于实施开环控制.当eec>0时,说明误差在朝向误差绝对值增大(de)方向变化,此时,如果abs(e)>Mmid,说明误差也较大,可考虑由控制器实施较强(de)控制作用,以达到扭转误差绝对值向减小(de)方向变化,并迅速减小误差(de)绝对值.此时如果abs(e)<Mmid,说明尽管误差是向绝对值增大(de)方向变化,但是误差绝对值本身并不是很大,可以考虑控制器实施一般(de)控制作用,只需要扭转误差(de)变化趋势,使其向误差绝对值减小(de)方向变化即可.当eerr<0且eerr(k-1)>0或者e=0时,说明误差(de)绝对值向减小(de)方向变化,或者已经达到平衡状态,此时保持控制器输出不变即可.当eerr<0且eerr(k-1)<0时,说明误差处于极限状态.如果此时误差(de)绝对值较大,大于Mmin,可以考虑实施较强控制作用.如果此时误差绝对值较小,可以考虑实施较弱控制作用.当abs(e)<Mmin时,说明误差绝对值很小,此时加入积分,减小静态误差.上面(de)逻辑判断过程,实际上就是对于控制系统(de)一个专家判断过程.(未完待续)PID控制算法(de)C语言实现十模糊算法简介在PID控制算法(de)C语言实现九中,文章已经对模糊PID(de)实质做了一个简要说明.本来打算等到完成毕业设计,工作稳定了再着力完成剩下(de)部分.鉴于网友(de)要求和信任,抽出时间来,对模糊PID做一个较为详细(de)论述,这里我不打算做出仿真程序了,但就基本概念和思路进行一下说明,相信有C语言基础(de)朋友可以通过这些介绍性(de)文字自行实现.这篇文章主要说明一下模糊算法(de)含义和原理.实际上模糊算法属于智能算法,智能算法也可以叫非模型算法,也就是说,当我们对于系统(de)模型认识不是很深刻,或者说客观(de)原因导致我们无法对系统(de)控制模型进行深入研究(de)时候,智能算法常常能够起到不小(de)作用.这点是方便理解(de),如果一个系统(de)模型可以轻易(de)获得,那么就可以根据系统(de)模型进行模型分析,设计出适合系统模型(de)控制器.但是现实世界中,可以说所有(de)系统都是非线性(de),是不可预测(de).但这并不是说我们就无从建立控制器,因为,大部分(de)系统在一定(de)条件和范围内是可以抽象成为线性系统(de).问题(de)关键是,当我们系统设计(de)范围超出了线性(de)范围,我们又该如何处理.显然,智能算法是一条很不错(de)途径.智能算法包含了专家系统、模糊算法、遗传算法、神经网络算法等.其实这其中(de)任何一种算法都可以跟PID去做结合,而选择(de)关键在于,处理(de)实时性能不能得到满足.当我们处理器(de)速度足够快速时,我们可以选择更为复杂(de)、精度更加高(de)算法.但是,控制器(de)处理速度限制了我们算法(de)选择.当然,成本是限制处理器速度最根本(de)原因.这个道理很简单,51单片机和DSP(de)成本肯定大不相同.专家PID和模糊PID是常用(de)两种PID选择方式.其实,模糊PID适应一般(de)控制系统是没有问题.文章接下来将说明模糊算法(de)一些基本常识.模糊算法其实并不模糊.模糊算法其实也是逐次求精(de)过程.这里举个例子说明.我们设计一个倒立摆系统,假如摆针偏差<5°,我们说它(de)偏差比较“小”;摆针偏差在5°和10°之间,我们说它(de)偏差处于“中”(de)状态;当摆针偏差>10°(de)时候,我们说它(de)偏差有点儿“大”了.对于“小”、“中”、“大”这样(de)词汇来讲,他们是精确(de)表述,可问题是如果摆针偏差是3°呢,那么这是一种什么样(de)状态呢.我们可以用“很小”来表述它.如果是7°呢,可以说它是“中”偏“小”.那么如果到了80°呢,它(de)偏差可以说“非常大”.而我们调节(de)过程实际上就是让系统(de)偏差由非常“大”逐渐向非常“小”过度(de)过程.当然,我们系统这个调节过程是快速稳定(de).通过上面(de)说明,可以认识到,其实对于每一种状态都可以划分到大、中、小三个状态当中去,只不过他们隶属(de)程度不太一样,比如6°隶属于小(de)程度可能是,隶属于中(de)程度是,隶属于大(de)程度是0.这里实际上是有一个问题(de),就是这个隶属(de)程度怎么确定这就要求我们去设计一个隶属函数.详细内容可以查阅相关(de)资料,这里没有办法那么详细(de)说明了.(见附录3)这里面有些说明.那么,知道了隶属度(de)问题,就可以根据目前隶属(de)程度来控制电机以多大(de)速度和方向转动了,当然,最终(de)控制量肯定要落实在控制电压上.这点可以很容易(de)想想,我们控制(de)目(de)就是让倒立摆从隶属“大”(de)程度为1(de)状态,调节到隶属“小”(de)程度为1(de)状态.当隶属大多一些(de)时候,我们就加快调节(de)速度,当隶属小多一些(de)时候,我们就减慢调节(de)速度,进行微调.可问题是,大、中、小(de)状态是汉字,怎么用数字表示,进而用程序代码表示呢其实我们可以给大、中、小三个状态设定三个数字来表示,比如大表示用3表示,中用2表示,小用1表示.那么我们完全可以用1+2+3=来表示它,当然这个公式也不一定是这样(de),这个公式(de)设计是系统模糊化和精确化(de)一个过程,读者也可参见相关文献理解.但就这个数字而言,可以说明,目前6°(de)角度偏差处于小和中之间,但是更偏向于中.我们就可以根据这个数字来调节电机(de)转动速度和时间了.当然,这个数字与电机转速(de)对应关系,也需要根据实际情况进行设计和调节.前面一个例子已经基本上说明了模糊算法(de)基本原理了.可是实际上,一个系统(de)限制因素常常不是一个.上面(de)例子中,只有偏差角度成为了系统调节(de)参考因素.而实际系统中,比如PID系统,我们需要调节(de)是比例、积分、微分三个环节,那么这三个环节(de)作用就需要我们认清,也就是说,我们需要根据超调量、调节时间、震荡情况等信息来考虑对这三个环节调节(de)比重,输入量和输出量都不是单一(de),可是其中必然有某种内在(de)逻辑联系.所以这种逻辑联系就成为我们设计工作(de)重点了.下一篇文章将详细分析PID三个变量和系统性能参数之间(de)联系.PID控制算法(de)c语言实现十一(PID系列完结篇)模糊PID(de)参数整定这几天一直在考虑如何能够把这一节(de)内容说清楚,对于PID而言应用并没有多大难度,按照基本(de)算法设计思路和成熟(de)参数整定方法,就算是没有经过特殊训练和培训(de)人,也能够在较短(de)时间内容学会使用PID算法.可问题是,如何能够透彻(de)理解PID算法,从而能够根据实际(de)情况设计出优秀(de)算法呢.通过讲述公式和基本原理肯定是最能说明问题(de),可是这样(de)话怕是犯了“专家”(de)错误了.对于门槛比较低(de)技术人员来讲,依然不能透彻理解.可是说(de)入耳了,能不能透彻说明也是一个问题,所以斟酌了几天,整理了一下思路才开始完成PID系列文章(de)最后一篇.我所说(de)最后一篇不代表PID(de)功能和发展就止步与此,仅仅是说明,透过这一些列(de)文章,基本上已经可以涵盖PID设计(de)要点,至于更深入(de)研究,就交给有需要(de)读者去做.上一节中大致讲述了一下模糊算法.实际上模糊算法(de)很多概念在上一节中并没有深入(de)解释.举(de)例子也只是为了说明模糊算法(de)基本含义,真正(de)模糊算法是不能这么设计(de),当然也不会这么简单.模糊算法(de)核心是模糊规则,如果模糊规则制定(de)出色,那么模糊算法(de)控制效率就高.其实这是智能算法(de)一般特性,规则是系统判断和处理(de)前提.那么就说说PID(de)规则该怎么制定.我们知道,模糊算法(de)本质是对PID(de)三个参数进行智能调节.那么首先要提出(de)问题是如何对PID(de)参数进行调节这个问题其实是参数整定(de)问题,现实当中有很多整定方法.可是我们需要从根本上了解为什么这么整定,才能知道该如何建立数学模型进行分析.那么要回答如何整定参数(de)问题,就需要先明白PID参数(de)作用都是什么对系统有什么影响我们从作用和副作用两个方面说明参数对系统(de)影响.1.比例环节Kp,作用是加快系统(de)响应速度,提高系统(de)调节精度,副作用是会导致超调;2.积分环节Ki,作用是消除稳态误差,副作用是导致积分饱和现象;3.微分环节Kd,作用是改善系统(de)动态性能,副作用是延长系统(de)调节时间.理解了上述问题,那么就可以“辩证施治,对症下药”了.比如说,如果系统响应速度慢,我们就加大Kp(de)取值,如果超调量过大我们就减小Kp(de)取值等等.可是问题这些语言(de)描述该如何用数学形式表达出来呢.我们所知道(de),反馈系统(de)实质就是系统(de)输出量作为反馈量与系统(de)输入量进行作差,从而得到系统(de)误差e,那么这个误差e就能够反应目前系统所处(de)状态.误差e可以表明目前系统(de)输出状态到底偏离要求多少.而误差e(de)变化律ec,表示误差变化(de)速度.这样,我们可以根据这两个量(de)状态来分析三个参数此时应该如何取值,假如e为负方向比较大,ec也为负方向增大状态,此时比例环节要大一些,从而加快调节速度,而积分环节要小一些,甚至不加积分环节,从而防止负方向上出现饱和积分(de)现象.微分环节可以稍加一些,在不影响调节时间(de)情况下,起到改善系统动态性能(de)作用.附录1看到有不少人问到底如何让UK值与PWM占空比值对应,进而实现占空比输出和输出控制电压对应.(注意,我这里讨论(de)前提是输出控制(de)是电压,不是PWM方波.PWM输出后要经过滤波整形再输出控制.)前提条件:输出电压控制电压范围是0-10V.给定、反馈、输出电压采样输入电压范围是0-5V(经过运放).使用单片机AD为10位AD芯片.那么10位AD芯片电压采集得到(de)数据范围就是0-1024.PWM为 8位可调占空比方波,0对应输出占空比为0(de)方波,255对应输出占空比100%(de)方波,127对应输出50%(de)方波.比如当前给定是,反馈电压是1V.(KP,KI,KD等系数略,关于PID算法(de)整数实现我在前文中有论述如何实现).那么经过AD采样1、给定对应为 5122、反馈1V对应为 205假定经过PID计算得到(de)UK为400也就意味着输出电压应当为(400(UPWM峰值电压))/1024那么UK对应(de)PWM占空比是多少呢我们知道,UK=1024对应占空比为100,也就是PWM(de)占空比系数为255.可知,PWM系数 = UK/4;那么400就应当对应系数 400/4=100.也就是输出电压=40010/1024=同时,由于采样精度以及PWM输出占空比精度控制(de)问题,将导致输出电压和期望值不是那么线性,所以,我在项目内加入了输出电压采样(de)控制.采样AD输入为0-5V,所以,对于输出0-10V有一个缩小(de)比例.输出10V则采样值对应为255输出5V则采样之对应127可知,对应AD结果为97采样输出电压值,可以针对性(de)调整一下占空比输出,从而得到误差允许范围内(de)一个控制输出电压.同时,经过一些加速控制(de)手段.可以比较迅速(de)达到控制(de)目(de).下文中(de)UK控制方法是针对增量式PID控制而来做(de).//void PWMProcess(void){uint16 idata temp;uint16 idata UKTemp;temp = 0;UKTemp = 0;if( = 0 ) //判断是否需要改变占空比{ //是否需要改变占空比和你(de)被控系统特性有关= 0;UKTemp = + ;//计算UK控制量//控制量和计算值以及一个开关量有关,我这里(de)开关量是系统需要(de)时候叠加在控制量上(de)一个变量.if(UKTemp>999){UKTemp = 999;}//这里只所以是999封顶而不是1024是因为我(de)系统PWM(de)峰值电压是12V导致.while(1) //如果输出电压和期望电压相差 Delta,则继续调整占空比,直到在误差以内{ADChPro(UPWMADCH); //测量输出电压if( [UPWMADCH] == UKTemp){return;}if( [UPWMADCH] > UKTemp) //如果当前电压大于输出电压,减小占空比{if( ( [UPWMADCH] - UKTemp ) > UDELTA ){temp = [UPWMADCH] - UKTemp; //temp = temp / 2; //下降可以加速下降,所以下降参数加倍if( > temp ){= - temp;else{= 0;}}else{return;}}else //如果当前电压小于输出电压{if( ( UKTemp - [UPWMADCH] ) > UDELTA ){temp = UKTemp - [UPWMADCH];temp = temp / 4; //上升处理不要超调,所以每次只+一半 if( > temp ){+= (temp/2);}else{= 255;}}elsereturn;}}DisPlayVoltage();PWMChangeDuty; //改变占空比Delay(10,10);}}}//附录2直流电机PWM调速系统中控制电压非线性研究引言由于线性放大驱动方式效率和散热问题严重,目前绝大多数直流电动机采用开关驱动方式.开关驱动方式是半导体功率器件工作在开关状态,通过脉宽调制PWM控制电动机电枢电压,实现调速.目前已有许多文献介绍直流电机调速,宋卫国等用89C51单片机实现了直流电机闭环调速;张立勋等用AVR单片机实现了直流电机PWM调速;郭崇军等用C8051实现了无刷直流电机控制;张红娟等用PIC单片机实现了直流电机PWM调速;王晨阳等用DSP实现了无刷直流电机控制.上述文献对实现调速(de)硬件电路和软件流程(de)设计有较详细(de)描述,但没有说明具体(de)调压调速方法,也没有提及占空比与电机端电压平均值之间(de)关系.在李维军等基于单片机用软件实现直流电机PWM调速系统中提到平均速度与占空比并不是严格(de)线性关系,在一般(de)应用中,可以将其近似地看作线性关系.但没有做深入(de)研究.本文通过实验验证,在不带电机情况下,PWM波占空比与控制输出端电压平均值之间呈线性关系;在带电机情况下,占空比与电机端电压平均值满足抛物线方程,能取得精确(de)控制.本文(de)电机闭环调速是运用Matlab拟合(de)关系式通过PID控制算法实现.1 系统硬件设计本系统是基于TX-1C实验板上(de)AT89C52单片机,调速系统(de)硬件原理图如图1所示,主要由AT89C52单片机、555振荡电路、L298驱动电路、光电隔离、霍尔元件测速电路、MAX 232电平转换电路等组成.图1 闭环控制系统示意图2 系统软件设计系统采用模块化设计,软件由1个主程序,3个中断子程序,即外部中断0、外部中断1,定时器0子程序,PID算法子程序,测速子程序及发送数据到串口显示子程序组成,主程序流程图如图2所示.外部中断0通过比较直流电平与锯齿波信号产生PWM波,外部中断1用于对传感器(de)脉冲计数.定时器0用于对计数脉冲定时.测得(de)转速通过串口发送到上位机显示,通过PID模块调整转速到设定值.本实验采用M/T法测速,它是同时测量检测时间和在此检测时间内霍尔传感器所产生(de)转速脉冲信号(de)个数来确定转速.由外部中断1对霍尔传感器脉冲计数,同时起动定时器0,当计数个数到预定值2 000后,关定时器0,可得到计2 000个脉冲(de)计数时间,由式计算出转速:n=60f/K=60N/(KT) (1)式中:n为直流电机(de)转速;K为霍尔传感器转盘上磁钢数;f为脉冲频率;N为脉冲个数;T为采样周期.图2 主程序流程图3 实验结果及原因分析3.1 端电压平均值与转速关系3.1.1 实验结果实验用(de)是永磁稳速直流电机,型号是EG-530YD-2BH,额定转速2 000~4 000 r/min,额定电压12 V.电机在空载(de)情况下,测得(de)数据用Matlab做一次线性拟合,拟合(de)端电压平均值与转速关系曲线如图3(a)所示.相关系数R-square:0.952 1.拟合曲线方程为:y=0.001 852x+0.296 3 (2)由式(2)可知,端电压平均值与转速可近似为线性关系,根椐此关系式,在已测得(de)转速(de)情况下可以计算出当前电压.为了比较分析,同样用Matlab做二次线性拟合,拟合(de)端电压平均值与转速关系曲线如图3(b)所示.相关系数R-square:0.986 7.图3 端电压平均值与转速关系曲线图3.1.2 原因分析比较图3(a)可知,当转速在0~1 500 r/min和4 000~5 000 r/min,端电压平均值与转速间存在(de)非线性,用二次曲拟合如图3(b)所示,拟合相关系数较高.由图3(a)可见,当电机转速为0时电机两端电压平均值约为1.3 V.这是因为电机处于静止状态时,摩擦力为静摩擦力,静摩擦力是非线性(de).随着外力(de)增加而增加,最大值发生在运动前(de)瞬间.电磁转矩为负载制动转矩和空载制动转矩之和,由于本系统不带负载,因此电磁转矩为空载制动转矩.空载制动转矩与转速之间此时是非线性(de).。

simulink模糊pid控制模型转c语言代码 -回复

simulink模糊pid控制模型转c语言代码 -回复

simulink模糊pid控制模型转c语言代码-回复如何将Simulink模糊PID控制模型转换为C语言代码在控制系统领域,模糊PID控制器是一种基于模糊逻辑和PID控制器的混合控制器。

它能够根据系统的特性自适应地调整PID控制器的参数,以提高系统的稳定性和性能。

Simulink是一款强大的数学建模和仿真工具,可以用于设计和验证各种控制系统。

但是,对于一些嵌入式系统来说,直接在硬件上运行Simulink 模型可能并不实际或经济。

因此,将Simulink模糊PID控制模型转换为C语言代码是一种常见的做法。

下面是一步一步的方法来完成这个过程。

步骤1:设计模糊PID控制模型首先,在Simulink中设计和调整模糊PID控制模型,确保其在仿真中能够达到预期的性能指标。

步骤2:将模型转换为C语言嵌入式代码Simulink提供了Embedded Coder工具,可以将Simulink模型转换为C语言嵌入式代码。

通过选择适当的目标硬件平台和编译器选项,生成相应的C代码文件。

步骤3:导出C源代码在Embedded Coder工具中,选择“Code Generation > Generate Code”选项,将Simulink模型导出为C源代码。

将生成的C源代码保存到本地目录中。

步骤4:分析和修改C源代码打开生成的C源代码文件,阅读和分析其结构和功能。

根据实际需求,可能需要对代码进行一些修改和优化,以适应目标硬件平台的特性和限制。

步骤5:编译和部署代码使用适当的C编译器和嵌入式开发环境,将修改后的C代码编译成可执行文件。

然后,将可执行文件上传到目标硬件平台,并进行测试和调试。

步骤6:验证和优化控制性能在目标硬件平台上,使用实际的输入和输出信号对C代码进行验证和性能优化。

根据结果调整控制器的参数和代码,以达到最佳的控制性能。

总结:将Simulink模糊PID控制模型转换为C语言代码需要一些复杂的过程,包括设计模型、代码转换、代码分析和修改、编译和部署以及性能验证等。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

//e:[-3,3] ec:[-3,3] kp:[-0.3,0.3]
#include<stdio.h>
#define NB 0
#define NM 1
#define NS 2
#define ZO 3
#define PS 4
#define PM 5
#define PB 6
/*********************************************************/ float uf(float x,float a,float b,float c);
float cuf(float x,float a,float b,float c);
float ufl(float x,float a,float b);
float cufl(float x,float a,float b);
float ufr(float x,float a,float b);
float cufr(float x,float a,float b);
float ufr(float x,float a,float b);
float cufr(float x,float a,float b);
float fand(float a,float b);
float forr(float a,float b);
float FuzzyKp(float e,float ec);
//主程序
void main()
{
float a,b,Kp;
printf("The E is:");
scanf("%f",&a);
printf("The Ec is:");
scanf("%f",&b);
Kp=FuzzyKp(a,b);
printf("The parameter Kp is: %f\n\n",Kp);
float FuzzyKp(float e,float ec)
{float es[7];
float ecs[7];
/******模糊推理规则的可信度通过取小点运算得到*****/ float form[7][7];//(表X7)(隶属度表)
int i,j;
/*************求得的最大值赋给form[a][b]*********/ int a=0,b=0;
float lsd;int p;
float detkp;
/**************************/
int kp[7][7]={{PB,PB,PM,PS,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}};
es[NB]=ufl(e,-3,-1);
es[NM]=uf(e,-3,-2,0);
es[NS]=uf(e,-3,-1,1);
es[ZO]=uf(e,-2,0,2);
es[PS]=uf(e,-1,1,3);
es[PM]=uf(e,0,2,3);
es[PB]=ufr(e,1,3);
ecs[NB]=ufl(ec,-3,-1);//ec
ecs[NM]=uf(ec,-3,-2,0);
ecs[NS]=uf(ec,-3,-1,1);
ecs[ZO]=uf(ec,-2,0,2);
ecs[PS]=uf(ec,-1,1,3);
ecs[PM]=uf(ec,0,2,3);
ecs[PB]=ufr(ec,1,3);
for(i=0;i<7;i++)
{
float w,h,r;
for(j=0;j<7;j++)
{
h=es[i];
r=ecs[j];
w=fand(h,r);
form[i][j]=w;
}
}
for(i=0;i<7;i++)
{
for(j=0;j<7;j++)
{
if(form[a][b]<form[i][j])
{
a=i;
b=j;
}
}
}
lsd=form[a][b];//es和ecs最值中的最大值p=kp[a][b];
if(p==NB)
detkp=cufl(lsd,-0.3,-0.1);
else if(p==NM)
detkp=cuf(lsd,-0.3,0.2,0);
else if(p==NS)
detkp=cuf(lsd,-0.3,-0.1,0.1);
else if(p==ZO)
detkp=cuf(lsd,-0.2,0,0.2);
else if(p==PS)
detkp=cuf(lsd,-0.1,0.1,0.3);
else if(p==PM)
detkp=cuf(lsd,0,0.2,0.3);
else if(p==PB)
detkp=cufr(lsd,0.1,0.3);
return detkp;
}
/**************************************以下为附属子函数*/
/**************求隶属度(三角形)模糊化处理***************/ float uf(float x,float a,float b,float c)
{
if(x<=a)
return (0);
else if((a<x)&&(x<=b))
return( (x-a)/(b-a));
else if((b<x)&&(x<=c))
return( (c-x)/(c-b));
else if(x>c)
return (0);
}
/****************三角形反模糊化处理(最大隶属度法)
**********************/
float cuf(float x,float a,float b,float c)
{
float y,z;
z=(b-a)*x+a;
y=c-(c-b)*x;
return (y+z)/2;
}
/*****************梯形(左)求隶属度模糊化*******************/ float ufl(float x,float a,float b)
{if(x<=a)
return 1;
else if((a<x)&&(x<=b))
return (b-x)/(b-a);
else if(x>b)
return 0;
}
/*******************梯形反模糊化***********************/ float cufl(float x,float a,float b)
{return b-(b-a)*x;
}
/*****************梯形(右)求隶属度模糊化*******************/ float ufr(float x,float a,float b)
{if(x<=a)
return 0;
if((a<x)&&(x<b))
return (x-a)/(b-a);
if(x>=b)
return 1;
}
/*******************梯形反模糊化***********************/ float cufr(float x,float a,float b)
{return (b-a)*x +a;
}
/*******************求交集***********************/
float fand(float a,float b)
{return (a<b)?a:b;//(返回a,b中较小值)
}
/*******************求并集***********************/
float forr(float a,float b)
{return (a<b)?b:a;
}。

相关文档
最新文档