fuzzy-pid

鉴于控制算法常于嵌入式平台使用,所以博主使用C语言实现模糊PID控制算法,该项目已上传至GitHub以及码云。实现的功能包括但不限于:

  • 隶属度函数 Membership function

    • 高斯隶属度函数 Gaussian membership function
    • 广义钟形隶属度函数 Generalized bell-shaped membership function
    • S形隶属度函数 Sigmoidal membership function
    • 梯形隶属度函数 Trapezoidal membership function
    • 三角形隶属度函数 Triangular membership function
    • Z形隶属度函数 Z-shaped membership function
  • 模糊算子 Fuzzy operator
    • 并算子 Union operator
    • 交算子 Intersection operator
    • 平衡算子 Equilibrium operator
  • 中心平均解模糊器 Center average defuzzifier

API使用的示例代码如下:

#include "fuzzyPID.h"#define DOF 6int main() {// Default fuzzy rule base of delta kp/ki/kdint 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 functionint 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};// Default parameters of pid controllerfloat fuzzy_pid_params[DOF][pid_params_count] = {{0.65f,  0,     0,    0, 0.5f,  -2.4f,    1},{-0.34f, 0,     0,    0, 0.5f, 0.536f, 2.3f},{-1.1f,  0,     0,    0, 0.5f,  0.00f,    1},{-2.4f,  0,     0,    0, 0.5f,   2.3f,    1},{1.2f,   0,     0,    0, 0.5f,  -0.7f, 2.3f},{1.2f,   0.05f, 0.1f, 0,    0,      0,    1}};// Obtain the PID controller vector according to the parametersstruct PID **pid_vector = fuzzy_vector_pid_init(fuzzy_pid_params, 2.0f, 4, 1, 0, mf_params, rule_base, DOF);printf("output:\n");bool direct[DOF] = {true, false, false, false, true, true};float real = 0;float idea = max_error * 0.9f;for (int j = 0; j < 500; ++j) {int out = fuzzy_pid_motor_pwd_output(real, idea, direct[5], pid_vector[5]);real += (float) (out - middle_pwm_output) / (float) middle_pwm_output * (float) max_error * 0.1f;printf("%d,%f\n", out, real);}delete_pid_vector(pid_vector, DOF);return 0;
}

下面进行详细讲解,一般的模糊控制流程图如下:

可以需要根据参考输入与被控对象的实际输出产生的误差 eee 、误差变化量 Δe\Delta eΔe 以及整定得的模糊规则表获取最终的模糊控制量。本项目主要针对模糊PID控制算法,所以选择的模糊条件语句为双输入多输出,即:

IF eis A∨Δeis BTHEN Δkpis C1and Δkiis C2and Δkdis C3⋯\text{IF } e \text{ is } A \vee \Delta e \text{ is } B \text{ THEN } \Delta k_p \text{ is } C_1 \text{ and } \Delta k_i \text{ is } C_2 \text{ and } \Delta k_d \text{ is } C_3 \cdots IF e is A∨Δe is B THEN Δkp​ is C1​ and Δki​ is C2​ and Δkd​ is C3​⋯

其中 ∨\vee∨ 代表并 (and) 操作,当然也可以用或 (or, ∧\wedge∧) 生成条件语句。同时由于模糊概念的存在,误差 eee 、误差变化量 Δe\Delta eΔe 是 AAA 和 BBB 呈一定概率,该概率则使用隶属度函数计算得出。项目的源码实现如下:

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];

其中使用 fuzzy_struct->mf_type 存储隶属度函数类型, fuzzy_struct->mf_params 存储隶属度函数所需的参数,通过调用 mf 便可实现隶属度的计算,同时多输入的情况下需要使用交并函数(模糊算子)求出联合隶属度。项目的源码实现如下:

// Joint membership
float joint_membership[count[0] * count[1]];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);}
}

其中使用 fuzzy_struct->fo_type 存储交并函数类型,通过调用 fo 实现联合隶属度的求取。在得到每个语言值的联合隶属度,便可以通过模糊推理求取。项目的源码实现如下:

// 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];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]];}}}for (unsigned int l = 0; l < fuzzy_struct->output_num; ++l) {fuzzy_struct->output[l] = numerator_count[l] / denominator_count;}
}

最终便可以实现模糊PID控制算法了。同时项目中提供了便捷的模糊PID控制器的数组生成器,便于生成多个控制器服务于多自由度控制需求,调用接口如下:

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);

其中 count 用于设定控制器个数,rule_base 用于传递模糊规则库,delta_k 用于控制PID的三个参数在初始值的基础上可以调节的程度,params 用于传递基础的PID参数,mf_typefo_typedf_type三个参数分别决定了隶属度函数类型、模糊算子类型以及解模糊器类型。

文中的理论分析以及模糊规则表摘自东北大学毛志忠老师编写的《先进控制技术》

模糊PID控制算法 之 C语言实现相关推荐

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

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

  2. 微分先行PID控制算法用C语言实现!

    1.微分先行PID控制算法框图 2.微分先行PID控制算法公式 3.微分先行PID控制公式用C语言实现 微分先行的PID算法实现,包括位置型和增量型两种实现方式. (1)位置型 void PIDReg ...

  3. 经典PID控制算法用C语言实现!

    1.经典PID控制算法框图 2.经典PID控制算法公式 3. 经典PID控制公式用C语言实现 float pidUpdate(PidObject* pid, const float error) {f ...

  4. PID控制算法实践应用(二):位置式PID控制算法的C语言实现

    目录 前言 一.实现步骤 1.定义PID变量结构体 2.初始化变量 3.编写控制算法

  5. PID控制算法的C语言实现六 抗积分饱和的PID控制算法C语言实现

    所谓的积分饱和现象是指如果系统存在一个方向的偏差,PID控制器的输出由于积分作用的不断累加而加大,从而导致执行机构达到极限位置,若控制器输出U(k)继续增大,执行器开度不可能再增大,此时计算机输出控制 ...

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

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

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

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

  8. 经典PID控制算法原理以及优化思路

    文章目录 0.概念 1.理解 2.实现 3.优化 4.引用 0.概念 PID算法是工业应用中最广泛算法之一,在闭环系统的控制中,可自动对控制系统进行准确且迅速的校正.PID控制,即Proportion ...

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

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

  10. 四旋翼无人机飞控系统设计(PID控制算法)

    PID控制算法   PID控制器是一个结构简单并且成熟稳定的控制器,在工业上应用广泛.包括比例(Proportion).积分(Integral).微分(Differential)三个控制元素,三者是对 ...

最新文章

  1. Android Jetpack组件App Startup简析
  2. WinCE上BINFS实现详解
  3. iOS ffmpeg 之编译ffmpeg
  4. CUDA从入门到精通(零):写在前面
  5. Linux压缩包和用户管理及开关机指令
  6. 男人别让爱你的女孩流泪
  7. Docker安装ssh,supervisor等基础工具
  8. cadence自动生成铺铜_干货 | 国内铜湿法冶金工艺现状分析
  9. Ajax技术原理小结
  10. office插件开发_Office神插件,打开新世界的大门
  11. java web接收tcp_Java多线程实现TCP网络Socket编程(C/S通信)
  12. Pytorch中Tensor和numpy数组的互相转化
  13. 基于WebRTC开源框架的实时视频聊天项目,搭建私人实时通信服务
  14. MATLAB快速排序算法
  15. c++实现简单的qq连连看秒杀挂
  16. Windows 10虚拟机Vmware 安装 黑苹果macos10.14
  17. export default (imported as router) was not found_一篇文章搞定as四大用法
  18. 牛客每日练习----分元宵,送分啦-QAQ,字符串的问题
  19. bzoj3786: 星系探索 //ETT
  20. 小技巧(8)pimple模式

热门文章

  1. 多易大数据学习实况记录
  2. ThinkPad T400 笔记本详细拆机过程 清理风扇(图文教程)
  3. 数学建模——怎样学习数学建模
  4. 【学习笔记】尚硅谷-AJAX
  5. redis 过期删除策略和淘汰策略 -redis设计与实现笔记
  6. 绘图技术采用计算机什么软件,计算机绘图好用的软件
  7. Ubuntu图形化数据库连接工具
  8. [excel]舒尔特练习法
  9. 我的世界光影Java优化_我的世界7款超级棒的光影包推荐 让你的世界从此变得真实无比...
  10. matlab调用refprop完全说明,Matlab调用REFPROP完