├── CHAPTER1 ├── rand.exe ├── chap1_1.exe ├── chap1_2.exe ├── chap1_3.exe ├── chap1_4.exe ├── chap1_5.exe ├── chap1_6.exe ├── chap1_7.exe ├── chap1_8.exe ├── chap1_9.exe ├── test1.exe ├── chap1_10.exe ├── chap1_11.exe ├── test1.c ├── rand.c ├── readme.md ├── test.c ├── chap1_1.c ├── chap1_2.c ├── chap1_10.c ├── chap1_9.c ├── chap1_6.c ├── chap1_11.c ├── chap1_3.c ├── chap1_8.c ├── chap1_7.c ├── chap1_5.c └── chap1_4.c ├── CHAPTER2 ├── chap2_1.exe ├── readme.md ├── chap2_3.c ├── chap2_2.c └── chap2_1.c ├── test.c ├── resource ├── automation.pdf ├── PID_Compensation_Animated.gif └── PID控制器 - 维基百科,自由的百科全书_files │ ├── wikimedia-button.png │ ├── 320px-PID_varyingP.jpg │ ├── 220px-Scross_helmsman.jpg │ ├── 320px-Change_with_Kd.png │ ├── 320px-Change_with_Ki.png │ ├── 300px-PI_controller.svg.png │ ├── PID_Compensation_Animated.gif │ ├── poweredby_mediawiki_88x31.png │ ├── 300px-Pid-feedback-nct-int-correct.png │ ├── 32769037c408874e1890f77554c65f39c523ebe2 │ ├── 38a7dcde9730ef0853809fefc18d88771f95206c │ ├── cd253103f0876afc68ebead27a5aa9867d927467 │ ├── 65658b7b223af9e1acc877d848888ecdb4466560 │ ├── 8c28867ecd34e2caed12cf38feadf6a81a7ee542 │ ├── f5f3c8921a3b352de45446a6789b104458c9f90b │ ├── a8dd1c50cb9436474f83624c3f679ccf3eebbfef │ ├── ddff09f5647bf3a8e9f36dd56d07aa1c4b95a1b0 │ ├── 70cadcc969636b990957852f205868f9f7178840 │ ├── 719736a1feb0bd7e73bb1425641a61229f55bb6d │ ├── 3691880f8c6ad9971b0649667f25849d22a5cf3b │ ├── af467d41e25cebc9640cba0240778eaae4057181 │ ├── 81d33ac9af047e93746da20160e9952cdfad0d17 │ ├── f55ec74c52b2360304758209076697f0d681a217 │ ├── 3d24c07f2b10d9bf12ba7b777a0cf2a7274da1f5 │ ├── b375df3b65d282f8715835dc91ccb22f46993959 │ ├── 1fe9735b1cbc55a36b7369a788f6d31bc9ab344b │ ├── 1c4fe4e196a23ae543249312141a225bcbbf6944 │ ├── 0ca1c869ab18973211164e73d25167010c093eec │ ├── e636d527b99f7a462006d55ae19104ad0be6b943 │ ├── d2aa1de9ed2d542360df6d9e799fdd4cece9f45c │ ├── 5bd02caa6aa3dcf79c1fe7b498e5fc189f577a14 │ ├── 5ebdaa7838b08517273db1ef8b624e76edb1d604 │ ├── 536836e7477819f300b8b4bbc6b0f1a43ecd5a8a │ ├── 1978a11f9869aeb4aff2ff6f5f628da046ccee4a │ ├── c5132c7e4a7a0f0ab62370c04bfd9fdf7797c93e │ ├── 3ec70456ca882a84f28b0ab97bbb042eeec409a0 │ ├── a334b8764ebdf38546bcc1205aa031ec7b68d5ad │ ├── 138aa9136de2f9d82461a36ce9a97dbcf542a468 │ ├── 551e87abef2e4c0cdcdb77b20fe6fec43f8065b6 │ ├── 150e66e2e72506e9058a270ef3add9856ebbd0b7 │ ├── 9cefae809b8fe094f3ae2d08e761633e9af74cc3 │ ├── f2049854f9827e54120fa2e8f6deceb526709c83 │ ├── b8d86ad0f4901b65f0a78ffe4226b0fbf2b505e5 │ ├── f5ea055f9e855fd6c022da5c7ecc635c034a8593 │ ├── 5cb6638fd1e72c31965c1f89420d47d74999e13c │ ├── 41d9a9a49911d0af5e5bc2600736a495c4882cda │ ├── cc8f62341a051d80d9433b422f75e81fd69aa82a │ ├── 9a9de8b9f870d26bc73b8894317bff87ec6845d3 │ ├── d7939ea1ba5b7440fb345b7e2fd2f7560f252277 │ ├── 4bcc71d1907c848d280095716df41b5a71ecd1c5 │ ├── 019908a560c84432c3a34d6fcd15d9c89bf87f29 │ ├── 19a2dc014104aec448e80812c730ba971be1c924 │ └── b26d3e50dff13b4aeb56e24ef2185492148a0601 ├── CHAPTER3 ├── readme.md ├── chap3_3.c ├── chap3_2.c └── chap3_1.c ├── article └── pid_big_talk │ └── 01origin.md ├── CHAPTER4 ├── readme.md └── chap4_1.c ├── readme.md └── basic_concept.md /CHAPTER1/rand.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/CHAPTER1/rand.exe -------------------------------------------------------------------------------- /CHAPTER1/chap1_1.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/CHAPTER1/chap1_1.exe -------------------------------------------------------------------------------- /CHAPTER1/chap1_2.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/CHAPTER1/chap1_2.exe -------------------------------------------------------------------------------- /CHAPTER1/chap1_3.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/CHAPTER1/chap1_3.exe -------------------------------------------------------------------------------- /CHAPTER1/chap1_4.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/CHAPTER1/chap1_4.exe -------------------------------------------------------------------------------- /CHAPTER1/chap1_5.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/CHAPTER1/chap1_5.exe -------------------------------------------------------------------------------- /CHAPTER1/chap1_6.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/CHAPTER1/chap1_6.exe -------------------------------------------------------------------------------- /CHAPTER1/chap1_7.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/CHAPTER1/chap1_7.exe -------------------------------------------------------------------------------- /CHAPTER1/chap1_8.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/CHAPTER1/chap1_8.exe -------------------------------------------------------------------------------- /CHAPTER1/chap1_9.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/CHAPTER1/chap1_9.exe -------------------------------------------------------------------------------- /CHAPTER1/test1.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/CHAPTER1/test1.exe -------------------------------------------------------------------------------- /CHAPTER2/chap2_1.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/CHAPTER2/chap2_1.exe -------------------------------------------------------------------------------- /CHAPTER1/chap1_10.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/CHAPTER1/chap1_10.exe -------------------------------------------------------------------------------- /CHAPTER1/chap1_11.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/CHAPTER1/chap1_11.exe -------------------------------------------------------------------------------- /test.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | printf("hello world!\n"); 6 | return 0; 7 | } -------------------------------------------------------------------------------- /resource/automation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/resource/automation.pdf -------------------------------------------------------------------------------- /resource/PID_Compensation_Animated.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/resource/PID_Compensation_Animated.gif -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/wikimedia-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/resource/PID控制器 - 维基百科,自由的百科全书_files/wikimedia-button.png -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/320px-PID_varyingP.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/resource/PID控制器 - 维基百科,自由的百科全书_files/320px-PID_varyingP.jpg -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/220px-Scross_helmsman.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/resource/PID控制器 - 维基百科,自由的百科全书_files/220px-Scross_helmsman.jpg -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/320px-Change_with_Kd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/resource/PID控制器 - 维基百科,自由的百科全书_files/320px-Change_with_Kd.png -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/320px-Change_with_Ki.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/resource/PID控制器 - 维基百科,自由的百科全书_files/320px-Change_with_Ki.png -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/300px-PI_controller.svg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/resource/PID控制器 - 维基百科,自由的百科全书_files/300px-PI_controller.svg.png -------------------------------------------------------------------------------- /CHAPTER3/readme.md: -------------------------------------------------------------------------------- 1 | 2 | * 该项目主要针对实际运用中的PID算法实现, 3 | * 故目录的编写与原书有所出入... 4 | * 根据实际情况,编撰目录如下: 5 | 6 | 【第三章 专家PID控制和模糊PID控制】 7 | 8 | 1. 专家PID控制 9 | 2. 模糊自适应整定PID控制 10 | 3. 模糊免疫PID控制算法 -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/PID_Compensation_Animated.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/resource/PID控制器 - 维基百科,自由的百科全书_files/PID_Compensation_Animated.gif -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/poweredby_mediawiki_88x31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/resource/PID控制器 - 维基百科,自由的百科全书_files/poweredby_mediawiki_88x31.png -------------------------------------------------------------------------------- /CHAPTER2/readme.md: -------------------------------------------------------------------------------- 1 | 2 | * 该项目主要针对实际运用中的PID算法实现, 3 | * 故目录的编写与原书有所出入... 4 | * 根据实际情况,编撰目录如下: 5 | 6 | 【第二章 常用的PID控制系统】 7 | 8 | 1. 串级PID控制 9 | 2. 纯滞后系统的大林控制算法 10 | 3. 纯滞后系统的Smith控制算法 11 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/300px-Pid-feedback-nct-int-correct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinyeats/pid-control/HEAD/resource/PID控制器 - 维基百科,自由的百科全书_files/300px-Pid-feedback-nct-int-correct.png -------------------------------------------------------------------------------- /article/pid_big_talk/01origin.md: -------------------------------------------------------------------------------- 1 | # 大话PID之起源 2 | 3 | --- 4 | 5 | 记得以前在网上看到过一个小故事,某人到一家单位公干,该处管理严格、戒备森然,在大门口,门卫拦住了某人的去路,一连问出了三个问题:“你是谁?你从哪里来?要到哪里去?”,某人一下子陷入了巨大的惶恐,因为门卫的几个问题正是哲学的三大终极问题,人类穷尽几千年的智慧都没法给出一个满意的答案,又怎么可能让一个普通人在瞬间给出合理的回复呢? 6 | 7 | 8 | -------------------------------------------------------------------------------- /CHAPTER1/test1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define a 2 4 | #define b 3 5 | #define c (float)(a*b)/5 6 | 7 | int main() 8 | { 9 | if(a==4) 10 | printf("c=%f\n",c); 11 | else if(a==3) 12 | {} 13 | else if(b==3) 14 | printf("c=%f\n",c); 15 | return 0; 16 | } -------------------------------------------------------------------------------- /CHAPTER4/readme.md: -------------------------------------------------------------------------------- 1 | 2 | * 该项目主要针对实际运用中的PID算法实现, 3 | * 故目录的编写与原书有所出入... 4 | * 根据实际情况,编撰目录如下: 5 | 6 | 【第四章 神经PID控制】 7 | 8 | 9 | 1. 单神经元自适应PID控制 10 | 2. 基于二次型性能指标学习算法的单神经元自适应PID控制 11 | 3. 基于BP神经网络整定的PID控制 12 | 4. 基于RBF神经网络整定的PID控制 13 | 5. 基于RBF神经网络辨识的单神经元PID模型参考自适应控制 14 | 6. 基于CMAC(神经网络)与PID的并行控制 -------------------------------------------------------------------------------- /CHAPTER1/rand.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | srand(time(NULL)); 8 | float random,D; 9 | 10 | int i=20; 11 | while(i--) 12 | { 13 | random = (float)(rand()%1000)/1000; 14 | D = 5.0*random; 15 | printf("D=%f\n",D); 16 | } 17 | 18 | return 0; 19 | } -------------------------------------------------------------------------------- /CHAPTER1/readme.md: -------------------------------------------------------------------------------- 1 | 2 | * 该项目主要针对实际运用中的PID算法实现, 3 | * 故目录的编写与原书有所出入... 4 | * 根据实际情况,编撰目录如下: 5 | 6 | 【第一章 数字PID控制】 7 | 8 | 1. 位置式PID控制算法 9 | 2. 增量式PID控制算法 10 | 3. 积分分离PID控制算法 11 | 4. 抗积分饱和PID控制算法 12 | 5. 变速积分PID控制算法 13 | 6. 带滤波器的PID控制算法 14 | 7. 不完全微分PID控制算法 15 | 8. 微分先行PID控制算法 16 | 9. 带死区的PID控制算法(参数未完全调试好) 17 | 10. 基于前馈补偿的PID控制算法 18 | 11. 步进式PID控制算法 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | PID-Control 2 | Edit by Alvin Yeats 3 | This project is licensed under a FreeBSD License 4 | 5 | In this project,you will learn more pid-control methods. 6 | 7 | - 供您参考:[PID基本概念](basic_concept.md) 8 | - 该项目主要是针对刘金琨老师的《先进pid控制及其MATLAB仿真》所做的源码翻译工作 9 | - 因本人能力有限,目前只进行C语言版本的翻译工作。 10 | - 陆续将推出c++版本和python版本,敬请期待! 11 | 12 | 另:对该项目感兴趣的朋友可通过邮箱联系我,一起进行源码翻译工作,合作愉快! -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/32769037c408874e1890f77554c65f39c523ebe2: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/38a7dcde9730ef0853809fefc18d88771f95206c: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/cd253103f0876afc68ebead27a5aa9867d927467: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/65658b7b223af9e1acc877d848888ecdb4466560: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /CHAPTER1/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define Max 10.0 5 | #define Min 8.0 6 | 7 | struct pid_data 8 | { 9 | float SetData; 10 | float ActualData; 11 | float err; 12 | float err_last; 13 | float Kp,Ki,Kd; 14 | float sum; 15 | float integral; 16 | }pid; 17 | 18 | void PID_init() 19 | { 20 | printf("PID_init begin\n"); 21 | pid.SetData = 0.0; 22 | pid.ActualData = 0.0; 23 | pid.err = 0.0; 24 | pid.err_last = 0.0; 25 | pid.sum = 0.0; 26 | pid.integral = 0.0; 27 | pid.Kp = 0.2; 28 | pid.Ki = 0.015; 29 | pid.Kd = 0.2; 30 | printf("PID_init end\n"); 31 | } 32 | 33 | float PID_realize(float desired) 34 | { 35 | if(desired > Max) 36 | desired = Max; 37 | else if(desired < Min) 38 | desired = Min; 39 | 40 | 41 | pid.SetData = desired; 42 | pid.err = pid.SetData - pid.ActualData; 43 | pid.integral += pid.err; 44 | pid.sum = pid.Kp*pid.err + pid.Ki*pid.integral + pid.Kd*(pid.err - pid.err_last); 45 | pid.err_last = pid.err; 46 | pid.ActualData = pid.sum*1.0; 47 | 48 | return pid.ActualData; 49 | } 50 | 51 | int main() 52 | { 53 | printf("System begin \n"); 54 | PID_init(); 55 | int count = 0; 56 | while(count < 1000) 57 | { 58 | float real= PID_realize(2); 59 | printf("%f\n",real); 60 | count++; 61 | } 62 | 63 | return 0; 64 | } 65 | 66 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/8c28867ecd34e2caed12cf38feadf6a81a7ee542: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/f5f3c8921a3b352de45446a6789b104458c9f90b: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /CHAPTER3/chap3_3.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************************** 2 | * 3 | * 模糊免疫PID控制算法 4 | * 5 | * 免疫PID控制器是借鉴生物系统的免疫机理而设计出的一种非线性控制器。 6 | * 免疫系统虽然十分复杂,但其抗御抗原的自适应能力却是十分明显的。 7 | * 8 | * 注:因算法本身的复杂度问题,该程序未整定完全,具体参数和计算方式请根据实际情况定义! 9 | ****************************************************************************************/ 10 | 11 | #include 12 | #include 13 | 14 | #define Kp 1.0 15 | #define Ki 0.50 16 | #define Kd 0.10 17 | 18 | #define Ts 20 19 | 20 | 21 | //构造结构体 22 | struct pid_data 23 | { 24 | float rin; 25 | float yout; 26 | float err; 27 | float err_last; 28 | float integral; 29 | float u; 30 | }; 31 | 32 | //定义结构体类型 33 | typedef struct pid_data pid_t; 34 | 35 | //机构体初始化 36 | struct pid_data* pid_init(float rin, float yout, 37 | float err, float err_last, float u) 38 | { 39 | struct pid_data* tset = malloc(sizeof(struct pid_data)); 40 | 41 | tset->rin = rin; 42 | tset->yout = yout; 43 | tset->err = err; 44 | tset->err_last = err_last; 45 | tset->u = u; 46 | 47 | return tset; 48 | } 49 | 50 | //The Increment PID Control Algorithm 51 | float pid_calc(pid_t* pid) 52 | { 53 | //pass 54 | } 55 | 56 | int main() 57 | { 58 | printf("System test begin \n"); 59 | 60 | pid_t* tset; 61 | int count = 0; 62 | float real = 0; 63 | 64 | tset = pid_init(23,0,0,0,0,0,0,0); 65 | 66 | while(count < 100) 67 | { 68 | real = pid_calc(tset); 69 | printf("%f\n",real); 70 | count++; 71 | } 72 | 73 | free(tset); 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /CHAPTER1/chap1_1.c: -------------------------------------------------------------------------------- 1 | /*************************************** 2 | * The positional PID control algorithm 3 | * 位置式PID控制 4 | * 5 | * input:just for Step Signal 6 | * 目前只针对阶跃信号输入情况 7 | ***************************************/ 8 | #include 9 | #include 10 | 11 | #define Kp 0.32 12 | #define Ki 0.64 13 | #define Kd 0.04 14 | 15 | struct pid_data 16 | { 17 | float SetPoint; 18 | float FeedBack; 19 | float err; 20 | float err_last; 21 | float integral; 22 | float u_sum; 23 | }; 24 | 25 | typedef struct pid_data pid_t; 26 | 27 | 28 | //pid struct data init 29 | struct pid_data* pid_init(float SetPoint,float FeedBack, 30 | float err, float err_last, float u_sum) 31 | { 32 | struct pid_data* tset = malloc(sizeof(struct pid_data)); 33 | 34 | tset->SetPoint = SetPoint; 35 | tset->FeedBack = FeedBack; 36 | tset->err = err; 37 | tset->err_last = err_last; 38 | tset->u_sum = u_sum; 39 | 40 | return tset; 41 | } 42 | 43 | 44 | float pid_calc(pid_t* pid) 45 | { 46 | pid->err = pid->SetPoint - pid->FeedBack; 47 | pid->integral += pid->err; 48 | pid->u_sum = Kp*pid->err + Ki*pid->integral + Kd*(pid->err - pid->err_last); 49 | pid->err_last = pid->err; 50 | pid->FeedBack = pid->u_sum*1.0; 51 | 52 | return pid->FeedBack; 53 | } 54 | 55 | int main() 56 | { 57 | printf("System test begin \n"); 58 | 59 | pid_t* tset; 60 | int count = 0; 61 | float real = 0; 62 | 63 | tset = pid_init(89,0,0,0,0); 64 | 65 | while(count < 100) 66 | { 67 | real = pid_calc(tset); 68 | printf("%f\n",real); 69 | count++; 70 | } 71 | 72 | free(tset); 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /basic_concept.md: -------------------------------------------------------------------------------- 1 | 没有金刚钻,不揽瓷器活。 2 | 为了能够掌握并运用PID,我们非常有必要学习下基本概念来武装自己,部分概念后面我会配上实际工程中常用的表示方法,以“实:”开头。 3 | 4 | 1. 被调量:反映被调对象的实际波动的量值。被调量是经常变化的。 5 | 实:常用检测到的反馈值表示,如yout(t)。 6 | 7 | 2. 设定值:PID调节器设定值就是人们期待被调量需要达到的值。设定值可以是固定的,也可以是变化的。 8 | 实:人为设定,多用rin(t)表示。 9 | 10 | 3. 控制输出:PID调节器根据被调量的变化情况运算之后发出的让外部执行结构按照它的要求动作的指令,即整个调节器的输出。请注意与被调量yout(t)的区别,这两个是完全不同的概念,经常有人在混淆这两个概念。 11 | 实:你经常看到的公式“u(t)=kp[e(t)+1/TI∫e(t)dt+TD*de(t)/dt]”中的u(t)。 12 | 13 | 4. 输入偏差:输入偏差时被调量和设定值之间的差值。 14 | 实:error(t)=rin(t)-yout(t)。 15 | 16 | 5. P(比例):P就是比例作用,简单说就是输入偏差乘以一个系数。 17 | 实:如kp,KP都是一样的。 18 | 19 | 6. I(积分):I就是积分,简单说就是将输入偏差进行积分运算。 20 | 实:如ki。 21 | 22 | 7. D(积分):D就是微分,简单说就是将输入偏差进行微分运算。 23 | 实:如kd。 24 | 25 | 8. PID基本公式PID调节器参数整定过程通俗讲就是先把系统调为纯比例作用,逐步增强比例作用让系统产生等幅振荡,记录下比例作用和振荡周期,然后这个比例作用乘以0.6,积分作用适当延长 26 | ```c 27 | KP= 0.6*Km 28 | KD= KP*π/4ω 或 KD= KP*tu/8 29 | KI= KP*ω/π 或 KI= 2KP/tu 30 | ``` 31 | KP:比例控制参数; 32 | KD:积分控制参数; 33 | KI:微分控制参数; 34 | Km:系统开始振荡时的比例值,通常称为临界比例值; 35 | ω:等幅振荡时的频率,tu为振荡周期。这里 tu*ω =2π,而不是tu*ω=1,学过傅里叶和拉氏变换的同学应该明白这是为什么,这里不做深入探讨。 36 | 37 | 9. 单回路:单回路就是只有一个PID的调节系统。 38 | 39 | 10. 串级:一个PID不够用,串级就是把两个PID串接起来形成一个串级调节系统,也被成为双回路调节系统。串级调节系统里PID调节器有主调和副调之分。 40 | 在串级调节系统中要调节被调量的PID叫做主调,输出直接去指挥执行器动作的PID叫做副调,主调的控制输出进入副调作为副调的设定值。主调选用单回路PID调节器,副调选用外给定调节器。 41 | 42 | 11. 正作用 43 | 对于PID调节器而言,控制输出随被调量增高而增高,随被调量减少而减少的作用,叫做PID正作用。 44 | 45 | 12. 负作用 46 | 对于PID调节器而言,控制输出随被调量增高而降低,随被调量减少而增高的作用,叫做PID负作用。 47 | 48 | 13. 动态偏差 49 | 在调节过程中,被调量和设定值之间的偏差随时改变,任意时刻两者之间的偏差叫做动态偏差。 50 | 51 | 14. 静态偏差 52 | 调节趋于稳定之后,被调量和设定值之间还存在的偏差交静态偏差。消除静态偏差是通过PID调节器积分作用来实现的。 53 | 54 | 15. 回调 55 | 调节器调节作用显示,使被调量开始由上升变为下降,或者由下降变为上升趋势成为回调。 -------------------------------------------------------------------------------- /CHAPTER3/chap3_2.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************************** 2 | * 3 | * 模糊自适应整定PID控制 4 | * 5 | * 自适应模糊PID控制器以误差e和误差ec作为输入,可以满足不同时刻的e和ec对PID参数自整 6 | * 定的要求。利用模糊控制规则在线对PID参数进行修改,便构成了自适应模糊PID控制器。 7 | * PID参数模糊自整定是找出PID三个参数与e和ec之间的模糊关系,在运行中通过不断检测e和ec, 8 | * 根据模糊控制原理来对3个参数进行在线修改,以满足不同e和ec时对控制参数的不同要求,而使被 9 | * 控对象有良好的动、静态性能。 10 | * 11 | * 12 | * 注:因算法本身的复杂度问题,该程序未整定完全,具体参数和计算方式请根据实际情况定义! 13 | ****************************************************************************************/ 14 | 15 | #include 16 | #include 17 | 18 | #define Kp 1.0 19 | #define Ki 0.50 20 | #define Kd 0.10 21 | 22 | #define Ts 20 23 | 24 | 25 | //构造结构体 26 | struct pid_data 27 | { 28 | float rin; 29 | float yout; 30 | float err; 31 | float err_last; 32 | float integral; 33 | float u; 34 | }; 35 | 36 | //定义结构体类型 37 | typedef struct pid_data pid_t; 38 | 39 | //机构体初始化 40 | struct pid_data* pid_init(float rin, float yout, 41 | float err, float err_last, float u) 42 | { 43 | struct pid_data* tset = malloc(sizeof(struct pid_data)); 44 | 45 | tset->rin = rin; 46 | tset->yout = yout; 47 | tset->err = err; 48 | tset->err_last = err_last; 49 | tset->u = u; 50 | 51 | return tset; 52 | } 53 | 54 | //The Increment PID Control Algorithm 55 | float pid_calc(pid_t* pid) 56 | { 57 | //pass 58 | } 59 | 60 | int main() 61 | { 62 | printf("System test begin \n"); 63 | 64 | pid_t* tset; 65 | int count = 0; 66 | float real = 0; 67 | 68 | tset = pid_init(23,0,0,0,0,0,0,0); 69 | 70 | while(count < 100) 71 | { 72 | real = pid_calc(tset); 73 | printf("%f\n",real); 74 | count++; 75 | } 76 | 77 | free(tset); 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/a8dd1c50cb9436474f83624c3f679ccf3eebbfef: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /CHAPTER1/chap1_2.c: -------------------------------------------------------------------------------- 1 | /*************************************** 2 | * The integral separate PID control arithmetic 3 | * 增量式PID控制算法 4 | * 5 | * input:just for Step Signal 6 | * 目前只针对阶跃信号输入情况 7 | ***************************************/ 8 | 9 | #include 10 | #include 11 | 12 | #define Kp 0.3 13 | #define Ki 0.60 14 | #define Kd 0.0375 15 | 16 | //basic data of pid control 17 | struct pid_data 18 | { 19 | float SetPoint; //Desired Value 20 | float FeedBack; //feedback value 21 | float LastError; //Error[-1] 22 | float PreError; //Error[-2] 23 | float u_sum; 24 | }; 25 | 26 | typedef struct pid_data pid_t; 27 | 28 | //pid struct data init 29 | struct pid_data* pid_init(float SetPoint, float FeedBack, float LastError, float PreError, float u_sum) 30 | { 31 | struct pid_data* tset = malloc(sizeof(struct pid_data)); 32 | 33 | tset->SetPoint = SetPoint; 34 | tset->FeedBack = FeedBack; 35 | tset->LastError = LastError; 36 | tset->PreError = PreError; 37 | tset->u_sum = u_sum; 38 | 39 | return tset; 40 | } 41 | 42 | 43 | //Integral Separate PID Control Arithmetic 44 | float pid_calc(pid_t* pid) 45 | { 46 | float iErr,pErr,dErr; 47 | iErr = pid->SetPoint - pid->FeedBack; //The current error 48 | pErr = iErr - pid->PreError; //Proportion of incremental error 49 | dErr = iErr - 2*pid->LastError + pid->PreError; //Differential incremental error 50 | 51 | pid->u_sum = Kp*pErr + Ki*iErr + Kd*dErr; //Control increase quantity 52 | 53 | pid->PreError = pid->LastError; 54 | pid->LastError = iErr; 55 | 56 | pid->FeedBack += pid->u_sum*1.0; 57 | return pid->FeedBack; 58 | } 59 | 60 | int main() 61 | { 62 | printf("System test begin \n"); 63 | 64 | pid_t* tset; 65 | int count = 0; 66 | float real = 0; 67 | 68 | tset = pid_init(23,0,0,0,0); 69 | 70 | while(count < 100) 71 | { 72 | real = pid_calc(tset); 73 | printf("%f\n",real); 74 | count++; 75 | } 76 | 77 | free(tset); 78 | return 0; 79 | } -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/ddff09f5647bf3a8e9f36dd56d07aa1c4b95a1b0: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/70cadcc969636b990957852f205868f9f7178840: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /CHAPTER4/chap4_1.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************************** 2 | * 3 | * 单神经元自适应PID控制 4 | * 5 | * 单神经元自适应控制器是通过对加权系数的调整来实现自适应、自组织功能,权系数的调整 6 | * 是按监督的Hebb学习规则实现的。 7 | * 8 | * 注:因算法本身的复杂度问题,该程序未整定完全,具体参数和计算方式请根据实际情况定义! 9 | ****************************************************************************************/ 10 | 11 | #include 12 | 13 | 14 | //K:神经元比例系数,越大快速性越好,但易引起超调量过大,导致系统不稳定 15 | #define K 0.06 16 | 17 | 18 | //学习率、权重的初始化random 19 | float xite_p=0.40,xite_i=0.35,xite_d=0.40;//学习率初始化 20 | float wk_p[3]={0.10,0.10,0.10},wk_i[3]={0.10,0.10,0.10},wk_d[3]={0.10,0.10,0.10};//权重初始化 21 | float w11[3]={0,0,0},w22[3]={0,0,0},w33[3]={0,0,0}; 22 | float x_1=0,x_2=0,x_3=0; 23 | float error=0,error_1=0,error_2=0; 24 | float wadd=0; 25 | float range[3]={20,3,3}; 26 | 27 | 28 | /******************************************************** 29 | rin :传入的控制量/设定量(可经过公式转换为控制效果,理想姿态量),我们想要达到的目标值 30 | yout :我们实际得到的控制效果(检测到的姿态量) 31 | pid[]:经过自适应神经元迭代得出的PID量 32 | *********************************************************/ 33 | void snn_get_pid(float rin,float yout,float *pid) 34 | { 35 | 36 | int i=0; 37 | 38 | //误差计算 39 | 40 | 41 | error = rin - yout; 42 | 43 | for(i=0;i<3;i++) 44 | { 45 | //PID权重值的调整 46 | wk_p[i] = wk_p[i] + xite_p*pid[i]*x_1; 47 | wk_i[i] = wk_i[i] + xite_i*pid[i]*x_2; 48 | wk_d[i] = wk_d[i] + xite_d*pid[i]*x_3; 49 | } 50 | 51 | //增量式PID误差计算 52 | x_1 = error - error_1; 53 | x_2 = error; 54 | x_3 = error - 2*error_1 + error_2; 55 | 56 | for(i=0;i<3;i++) 57 | { 58 | //归一化处理 59 | wadd[i] = fabs(wk_p[i]) + fabs(wk_i[i]) + fabs(wk_d[i]); 60 | w11[i]=wk_p[i]/wadd[i]; 61 | w22[i]=wk_i[i]/wadd[i]; 62 | w33[i]=wk_d[i]/wadd[i]; 63 | 64 | //计算出新的控制量 65 | pid[i] = pid[i] + K*(w11[i]*x_1 + w22[i]*x_2 + w33[i]*x_3); 66 | 67 | //参数范围的限制 68 | if(pid[i] > range[i]) 69 | pid[i] = range[i]; 70 | else if(pid[i] < ((-1)*range[i])) 71 | pid[i] = (-1)*range[i]; 72 | 73 | } 74 | 75 | //迭代更新 76 | error_2 = error_1; 77 | error_1 = error; 78 | } -------------------------------------------------------------------------------- /CHAPTER2/chap2_3.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************************** 2 | * 3 | * 纯滞后系统的Smith控制算法 4 | * 5 | * 在工业过程控制中,许多被控对象具有纯滞后的性质。Smith(史密斯)提出了一种 6 | * 纯滞后补偿模型,其原理为:与PID控制器并接一补偿环节,该补偿环节称为Smith预估器。 7 | * 8 | * 注:因算法本身的复杂度问题,该程序未整定完全,具体参数和计算方式请根据实际情况定义! 9 | ****************************************************************************************/ 10 | 11 | #include 12 | #include 13 | 14 | #define Kp 1.0 15 | #define Ki 0.50 16 | #define Kd 0.10 17 | 18 | #define Ts 20 19 | 20 | 21 | //构造结构体 22 | struct pid_data 23 | { 24 | float rin; 25 | float yout; 26 | float err; 27 | float err_last; 28 | float integral; 29 | float u; 30 | }; 31 | 32 | //定义结构体类型 33 | typedef struct pid_data pid_t; 34 | 35 | //机构体初始化 36 | struct pid_data* pid_init(float rin, float yout, 37 | float err, float err_last, float u) 38 | { 39 | struct pid_data* tset = malloc(sizeof(struct pid_data)); 40 | 41 | tset->rin = rin; 42 | tset->yout = yout; 43 | tset->err = err; 44 | tset->err_last = err_last; 45 | tset->u = u; 46 | 47 | return tset; 48 | } 49 | 50 | //The Increment PID Control Algorithm 51 | float pid_calc(pid_t* pid) 52 | { 53 | //wait 54 | float err_1,err_2,err_3; 55 | pid->err = pid->rin - pid->yout; 56 | 57 | int M=1; 58 | if M==1 59 | { 60 | wkp = wkp + xiteP*u*x(1); //P 61 | wkd = whi + xiteI*u*x(2); //I 62 | wkd = whd + xiteD*u*x(3); //D 63 | } 64 | 65 | else if (M == 2) 66 | { 67 | pid->integral += pid->err; 68 | pid->u = Kp*pid->err + Kd*(pid->err - pid->err_last)/ts + Ki*pid->integral; 69 | } 70 | 71 | pid->err_last = pid->err; 72 | pid->yout = pid->u; 73 | 74 | return pid->yout; 75 | } 76 | 77 | int main() 78 | { 79 | printf("System test begin \n"); 80 | 81 | pid_t* tset; 82 | int count = 0; 83 | float real = 0; 84 | 85 | tset = pid_init(23,0,0,0,0,0,0,0); 86 | 87 | while(count < 100) 88 | { 89 | real = pid_calc(tset); 90 | printf("%f\n",real); 91 | count++; 92 | } 93 | 94 | free(tset); 95 | return 0; 96 | } 97 | -------------------------------------------------------------------------------- /CHAPTER2/chap2_2.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************************** 2 | * 3 | * 纯滞后系统的大林控制算法 4 | * 5 | * 早在1968年,美国IBM公司的大林(Dahlin)就提出了一种不同于常规PID控制规律 6 | * 的新型算法,即大林算法。该算法的最大特点是将期望的闭环响应设计成一阶惯性加纯 7 | * 延迟,然后反过来得到满足这种闭环响应的控制器。 8 | * 9 | * 注:因算法本身的复杂度问题,该程序未整定完全,具体参数和计算方式请根据实际情况定义! 10 | ****************************************************************************************/ 11 | 12 | #include 13 | #include 14 | 15 | #define Kp 1.0 16 | #define Ki 0.50 17 | #define Kd 0.10 18 | 19 | #define ts 0.5 20 | 21 | //构造结构体 22 | struct pid_data 23 | { 24 | float rin; 25 | float yout; 26 | float err; 27 | float err_last; 28 | float integral; 29 | float u; 30 | }; 31 | 32 | //定义结构体类型 33 | typedef struct pid_data pid_t; 34 | 35 | //机构体初始化 36 | struct pid_data* pid_init(float rin, float yout, 37 | float err, float err_last, float u) 38 | { 39 | struct pid_data* tset = malloc(sizeof(struct pid_data)); 40 | 41 | tset->rin = rin; 42 | tset->yout = yout; 43 | tset->err = err; 44 | tset->err_last = err_last; 45 | tset->u = u; 46 | 47 | return tset; 48 | } 49 | 50 | //The Increment PID Control Algorithm 51 | float pid_calc(pid_t* pid) 52 | { 53 | //wait 54 | float err_1,err_2,err_3; 55 | pid->err = pid->rin - pid->yout; 56 | 57 | int M=1; 58 | if M==1 59 | { 60 | pid->u = (num_1*err + num_2*err_1 + num_3*err_2 + num_4*err_3 61 | -den_3*u_1 - den_4*u_2 - den_5*u_3 - den_6*u_4 - den_7*u_5)/den_2; 62 | } 63 | else if (M == 2) 64 | { 65 | pid->integral += pid->err; 66 | pid->u = Kp*pid->err + Kd*(pid->err - pid->err_last)/ts + Ki*pid->integral; 67 | } 68 | 69 | pid->err_last = pid->err; 70 | pid->yout = pid->u; 71 | 72 | return pid->yout; 73 | } 74 | 75 | int main() 76 | { 77 | printf("System test begin \n"); 78 | 79 | pid_t* tset; 80 | int count = 0; 81 | float real = 0; 82 | 83 | tset = pid_init(23,0,0,0,0,0,0,0); 84 | 85 | while(count < 100) 86 | { 87 | real = pid_calc(tset); 88 | printf("%f\n",real); 89 | count++; 90 | } 91 | 92 | free(tset); 93 | return 0; 94 | } 95 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/719736a1feb0bd7e73bb1425641a61229f55bb6d: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /CHAPTER1/chap1_10.c: -------------------------------------------------------------------------------- 1 | /************************************************************************************ 2 | * The PID control algorithm based on feedforward compensation 3 | * 基于前馈补偿的PID控制算法 4 | * 5 | * 在高精度伺服控制中,前馈控制可用来提高系统的跟踪性能。经典控制理论中的 6 | * 前馈控制设计是基于复合控制思想,当闭环系统为连续系统时,使前馈环节与闭环系 7 | * 统的传递函数之积为1,从而实现输出完全复现输入。作者利用前馈控制的思想,针对 8 | * PID控制设计了前馈补偿,以提高系统的跟踪性能 9 | * 10 | * input:just for Step Signal 11 | * 目前只针对阶跃信号输入情况 12 | * 13 | * 注:因算法本身的复杂度问题,该程序未整定完全,具体参数和计算方式请根据实际情况定义! 14 | ************************************************************************************/ 15 | 16 | #include 17 | #include 18 | 19 | #define ts 0.001 20 | 21 | #define Kp 80 22 | #define Ki 20 23 | #define Kd 2.0 24 | 25 | //basic data of pid control 26 | struct pid_data 27 | { 28 | float SetPoint; //Desired Value 29 | float FeedBack; //feedback value 30 | float err; 31 | float err_last; 32 | float integral; 33 | float u_k; 34 | }; 35 | 36 | typedef struct pid_data pid_t; 37 | 38 | //pid struct data init 39 | struct pid_data* pid_init(float SetPoint, float FeedBack, float err, float err_last, float u_k) 40 | { 41 | struct pid_data* tset = malloc(sizeof(struct pid_data)); 42 | 43 | tset->SetPoint = SetPoint; 44 | tset->FeedBack = FeedBack; 45 | tset->err = err; 46 | tset->err_last = err_last; 47 | tset->u_k = u_k; 48 | 49 | return tset; 50 | } 51 | 52 | //The Increment PID Control Algorithm 53 | float pid_calc(pid_t* pid) 54 | { 55 | pid->err = pid->SetPoint - pid->FeedBack; 56 | pid->integral += pid->err; 57 | 58 | 59 | //需引入前馈补偿量drin_k和ddrin_k 60 | float up_k,uf_k; 61 | float drin_k = 0.65, 62 | ddrin_k = 0.45; 63 | 64 | up_k = Kp*pid->err + Ki*pid->integral + Kd*(pid->err - pid->err_last)/ts; 65 | uf_k = (25/133)*drin_k + (1/133)*ddrin_k; 66 | 67 | int M=2; 68 | if(M==1) 69 | pid->u_k = up_k; 70 | else if(M==2) 71 | pid->u_k = up_k + uf_k; 72 | 73 | pid->err_last = pid->err; 74 | 75 | return pid->u_k; 76 | } 77 | 78 | int main() 79 | { 80 | printf("System test begin \n"); 81 | 82 | pid_t* tset; 83 | int count = 0; 84 | float real = 0; 85 | 86 | tset = pid_init(35,0,0,0,0); 87 | 88 | while(count < 100) 89 | { 90 | real = pid_calc(tset); 91 | printf("%f\n",real); 92 | count++; 93 | } 94 | 95 | free(tset); 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/3691880f8c6ad9971b0649667f25849d22a5cf3b: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /CHAPTER1/chap1_9.c: -------------------------------------------------------------------------------- 1 | /************************************************************************************ 2 | * The PID control algorithm with dead zone 3 | * 带死区的PID控制算法 4 | * 5 | * 在计算机控制系统中,某些系统为了避免控制作用过于频繁,消除由于频繁动作所 6 | * 引起的振荡,可采用带死区的PID控制算法,控制算式为 7 | * 当abs(e_k) <= abs(e0)时,e_k=0; 8 | * 当abs(e_k) > abs(e0)时,e_k=e_k. 9 | * 式中,e_k为位置跟踪偏差,e_0是一个可调参数,其具体数值可根据实际控制对象由实验确定。 10 | * 若e0值太小,会使控制动作过于频繁,达不到稳定被控对象的目的;若e0太大,则系统将产生 11 | * 较大的滞后。 12 | * 带死区的控制系统实际上是一个非线性系统,当abs(e_k)<=abs(e0)时,数字调节器输出 13 | * 为零;当abs(e_k)>abs(e0)时,数字输出调节器有PID输出。 14 | * 15 | * input:just for Step Signal 16 | * 目前只针对阶跃信号输入情况 17 | ************************************************************************************/ 18 | 19 | #include 20 | #include 21 | 22 | #define Kp 1.209 23 | #define Ki 0 24 | #define Kd 0.001 25 | 26 | //basic data of pid control 27 | struct pid_data 28 | { 29 | float SetPoint; //Desired Value 30 | float FeedBack; //feedback value 31 | float err; 32 | float err_last; 33 | float integral; 34 | float u_k; 35 | }; 36 | 37 | typedef struct pid_data pid_t; 38 | 39 | //pid struct data init 40 | struct pid_data* pid_init(float SetPoint, float FeedBack, float err, float err_last, float u_k) 41 | { 42 | struct pid_data* tset = malloc(sizeof(struct pid_data)); 43 | 44 | tset->SetPoint = SetPoint; 45 | tset->FeedBack = FeedBack; 46 | tset->err = err; 47 | tset->err_last = err_last; 48 | tset->u_k = u_k; 49 | 50 | return tset; 51 | } 52 | 53 | //The Increment PID Control Algorithm 54 | float pid_calc(pid_t* pid) 55 | { 56 | pid->err = pid->SetPoint - pid->FeedBack; 57 | if(abs(pid->err) <= 0.20) 58 | pid->integral += pid->err; 59 | else 60 | pid->integral = 0; 61 | 62 | pid->u_k = Kp*pid->err + Kd*(pid->err - pid->err_last) + Ki*pid->integral; 63 | 64 | int M = 2; 65 | if(M == 1) 66 | {} 67 | else if(M == 2) 68 | { 69 | if(abs(pid->err) <= 0.10) 70 | pid->u_k=0; 71 | } 72 | 73 | pid->FeedBack += pid->u_k*1.0; 74 | pid->err_last = pid->err; 75 | 76 | return pid->FeedBack; 77 | } 78 | 79 | int main() 80 | { 81 | printf("System test begin \n"); 82 | 83 | pid_t* tset; 84 | int count = 0; 85 | float real = 0; 86 | 87 | tset = pid_init(23,0,0,0,0); 88 | 89 | while(count < 100) 90 | { 91 | real = pid_calc(tset); 92 | printf("%f\n",real); 93 | count++; 94 | } 95 | 96 | free(tset); 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/af467d41e25cebc9640cba0240778eaae4057181: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /CHAPTER1/chap1_6.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * The PID control algorithm with filter 3 | * 带滤波器的PID控制算法 4 | * 5 | * 本例旨在验证低通滤波器的滤波性能, 6 | * 低通滤波器对高频信号具有很好的滤波作用 7 | * 8 | * 采样时间:1ms 9 | * 干扰信号加在对象的输出端。分三种情况: 10 | * M=1时,为未加干扰信号; 11 | * M=2时,为加干扰信号未加滤波; 12 | * M=3时,为加干扰信号加滤波。 13 | * 14 | * input:just for Step Signal 15 | * 目前只针对阶跃信号输入情况 16 | *****************************************************************************/ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #define Kp 1.00 23 | #define Ki 0.08 24 | 25 | //basic data of pid control 26 | struct pid_data 27 | { 28 | float SetPoint; //Desired Value 29 | float FeedBack; //feedback value 30 | float err; 31 | float integral; 32 | float u_sum; 33 | }; 34 | 35 | typedef struct pid_data pid_t; 36 | 37 | //pid struct data init 38 | struct pid_data* pid_init(float SetPoint, float FeedBack, float err, float integral, float u_sum) 39 | { 40 | struct pid_data* tset = malloc(sizeof(struct pid_data)); 41 | 42 | tset->SetPoint = SetPoint; 43 | tset->FeedBack = FeedBack; 44 | tset->err = err; 45 | tset->integral = integral; 46 | tset->u_sum = u_sum; 47 | 48 | return tset; 49 | } 50 | 51 | //The Increment PID Control Algorithm 52 | float pid_calc(pid_t* pid) 53 | { 54 | float filty,yyout,err; 55 | int M = 2; 56 | 57 | if(M == 1) 58 | { 59 | err = pid->SetPoint - pid->FeedBack; 60 | filty = pid->FeedBack; 61 | } 62 | 63 | float random = (float)(rand()%100)/100.0; 64 | float D = 5.0*random; 65 | yyout = pid->FeedBack + D; 66 | 67 | if(M == 2) 68 | { 69 | filty = yyout; 70 | err = pid->SetPoint - filty; 71 | } 72 | 73 | //I separation 74 | if(abs(err) <= 0.8) 75 | pid->integral += err; 76 | else 77 | pid->integral = 0; 78 | 79 | pid->u_sum = Kp*err + Ki*pid->integral; 80 | pid->FeedBack += pid->u_sum*1.0; 81 | 82 | return pid->FeedBack; 83 | } 84 | 85 | int main() 86 | { 87 | printf("System test begin \n"); 88 | 89 | pid_t* tset; 90 | int count = 0; 91 | float real = 0; 92 | 93 | tset = pid_init(35,0,0,0,0); 94 | srand(time(NULL)); 95 | while(count < 100) 96 | { 97 | real = pid_calc(tset); 98 | printf("%f\n",real); 99 | count++; 100 | } 101 | 102 | free(tset); 103 | return 0; 104 | } 105 | -------------------------------------------------------------------------------- /CHAPTER1/chap1_11.c: -------------------------------------------------------------------------------- 1 | /************************************************************************************ 2 | * The step PID control algorithm 3 | * 步进式PID控制算法 4 | * 5 | * 在阶跃响应较大时,很容易产生超调。采用不仅是积分分离PID控制,该方法不直接 6 | * 对阶跃信号进行响应,而是使输入指令信号一步一步地逼近所要求的阶跃信号,可使对象 7 | * 运行平稳,适用于高精度伺服系统的位置跟踪。 8 | * 9 | * input:just for Step Signal 10 | * 目前只针对阶跃信号输入情况 11 | * 12 | * 注:因算法本身的复杂度问题,该程序未整定完全,具体参数和计算方式请根据实际情况定义! 13 | ************************************************************************************/ 14 | 15 | #include 16 | #include 17 | 18 | #define ts 0.001 19 | 20 | #define Kp 80 21 | #define Ki 20 22 | #define Kd 2.0 23 | 24 | int k = 0;//循环次数,全局变量 25 | 26 | //basic data of pid control 27 | struct pid_data 28 | { 29 | float SetPoint; //Desired Value 30 | float FeedBack; //feedback value 31 | float err; 32 | float integral; 33 | float u_k; 34 | }; 35 | 36 | typedef struct pid_data pid_t; 37 | 38 | //pid struct data init 39 | struct pid_data* pid_init(float SetPoint, float FeedBack, float err, float u_k) 40 | { 41 | struct pid_data* tset = malloc(sizeof(struct pid_data)); 42 | 43 | tset->SetPoint = SetPoint; 44 | tset->FeedBack = FeedBack; 45 | tset->err = err; 46 | tset->u_k = u_k; 47 | 48 | return tset; 49 | } 50 | 51 | //The Increment PID Control Algorithm 52 | float pid_calc(pid_t* pid) 53 | { 54 | float rate = 0.25, 55 | rini = 0.0, 56 | rd = 20; 57 | 58 | int M=2; 59 | if(M==1) 60 | { 61 | pid->SetPoint = rd; 62 | pid->err = pid->SetPoint - pid->FeedBack; 63 | } 64 | 65 | if(M==2) 66 | { 67 | if(rini < (rd - 0.25)) 68 | rini = rini + k*ts*rate; 69 | else if(rini > (rd + 0.25)) 70 | rini = rini - k*ts*rate; 71 | else 72 | rini = rd; 73 | 74 | pid->SetPoint = rini; 75 | pid->err = pid->SetPoint - pid->FeedBack; 76 | } 77 | 78 | //PID with I separation 79 | if(abs(pid->err) <= 0.8) 80 | pid->integral += ts*pid->err; 81 | else 82 | pid->integral = 0; 83 | 84 | pid->u_k = Kp*pid->err + Ki*pid->integral; 85 | 86 | return pid->u_k; 87 | } 88 | 89 | int main() 90 | { 91 | printf("System test begin \n"); 92 | pid_t* tset; 93 | float real = 0; 94 | 95 | tset = pid_init(35,0,0,0); 96 | while(k < 100) 97 | { 98 | real = pid_calc(tset); 99 | printf("%f\n",real); 100 | k++; 101 | } 102 | 103 | free(tset); 104 | return 0; 105 | } 106 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/81d33ac9af047e93746da20160e9952cdfad0d17: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/f55ec74c52b2360304758209076697f0d681a217: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /CHAPTER1/chap1_3.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * The increment PID control algorithm 3 | * 积分分离PID控制算法 4 | * 5 | * 积分分离的基本控制思路: 6 | * 当被控量与设定值偏差较大时,取消积分作用,以免由于积分作用 7 | * 使系统稳定性降低,超调量增大;当被控量接近给定值时,引入积分控制,以便 8 | * 消除静差,提高控制精度。 9 | * 10 | * input:just for Step Signal 11 | * 目前只针对阶跃信号输入情况 12 | *****************************************************************************/ 13 | 14 | #include 15 | #include 16 | 17 | #define Kp 0.2 18 | #define Ki 0.05 19 | #define Kd 0.2 20 | 21 | //basic data of pid control 22 | struct pid_data 23 | { 24 | float SetPoint; //Desired Value 25 | float FeedBack; //feedback value 26 | float err; 27 | float err_last; 28 | float integral; 29 | float u_sum; 30 | }; 31 | 32 | typedef struct pid_data pid_t; 33 | 34 | //pid struct data init 35 | struct pid_data* pid_init(float SetPoint, float FeedBack, float err, float err_last,float integral, float u_sum) 36 | { 37 | struct pid_data* tset = malloc(sizeof(struct pid_data)); 38 | 39 | tset->SetPoint = SetPoint; 40 | tset->FeedBack = FeedBack; 41 | tset->err = err; 42 | tset->err_last = err_last; 43 | tset->integral = integral; 44 | tset->u_sum = u_sum; 45 | 46 | return tset; 47 | } 48 | 49 | //The Increment PID Control Algorithm 50 | float pid_calc(pid_t* pid) 51 | { 52 | pid->err = pid->SetPoint - pid->FeedBack; 53 | pid->integral += pid->err; 54 | 55 | //judgment of Integral separation 56 | float err = pid->err; 57 | float beta = 0; 58 | 59 | int M = 2; 60 | if(M == 1) 61 | { 62 | if((abs(err) >= 30) && (abs(err) <= 40)) 63 | beta = 0.3; 64 | else if((abs(err) >= 20) && (abs(err) <=30)) 65 | beta = 0.6; 66 | else if((abs(err) >= 10) && (abs(err) <=20)) 67 | beta = 0.9; 68 | else 69 | beta = 1.0; 70 | } 71 | else if(M == 2) 72 | { 73 | beta = 1.0; 74 | } 75 | 76 | pid->u_sum = Kp*pid->err + Kd*(pid->err - pid->err_last) + beta*Ki*pid->integral; 77 | pid->FeedBack = pid->u_sum*1.0; 78 | pid->err_last = pid->err; 79 | 80 | return pid->FeedBack; 81 | } 82 | 83 | int main() 84 | { 85 | printf("System test begin \n"); 86 | 87 | pid_t* tset; 88 | int count = 0; 89 | float real = 0; 90 | 91 | tset = pid_init(35,0,0,0,0,0); 92 | 93 | while(count < 100) 94 | { 95 | real = pid_calc(tset); 96 | printf("%f\n",real); 97 | count++; 98 | } 99 | 100 | free(tset); 101 | return 0; 102 | } 103 | 104 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/3d24c07f2b10d9bf12ba7b777a0cf2a7274da1f5: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/b375df3b65d282f8715835dc91ccb22f46993959: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /CHAPTER1/chap1_8.c: -------------------------------------------------------------------------------- 1 | /************************************************************************************ 2 | * The derivative ahead PID control algorithm 3 | * 微分先行PID控制算法 4 | * 5 | * 取M=1,采用微分先行PID控制方法; 6 | * 取M=2,采用普通PID方法。 7 | * 8 | * 对于给定值rin(k)频繁升降的场合,引入微分先行后,可以避免给定值升降时 9 | * 所引起的系统振荡,明显地改善了系统的动态特性。 10 | * 11 | * input:just for Step Signal 12 | * 目前只针对阶跃信号输入情况 13 | ************************************************************************************/ 14 | 15 | #include 16 | #include 17 | 18 | #define gama 0.50 19 | #define Td Kd/Kp 20 | #define Ti 0.89 21 | 22 | #define Kp 0.63 23 | #define Ki 0.252 24 | #define Kd 1.06 25 | 26 | //basic data of pid control 27 | struct pid_data 28 | { 29 | float SetPoint; //Desired Value 30 | float FeedBack; //feedback value 31 | float err; 32 | float err_last; 33 | float integral; 34 | float u_k; 35 | }; 36 | 37 | typedef struct pid_data pid_t; 38 | 39 | //pid struct data init 40 | struct pid_data* pid_init(float SetPoint, float FeedBack, float err, float err_last, float u_k) 41 | { 42 | struct pid_data* tset = malloc(sizeof(struct pid_data)); 43 | 44 | tset->SetPoint = SetPoint; 45 | tset->FeedBack = FeedBack; 46 | tset->err = err; 47 | tset->err_last = err_last; 48 | tset->u_k = u_k; 49 | 50 | return tset; 51 | } 52 | 53 | //The Increment PID Control Algorithm 54 | float pid_calc(pid_t* pid) 55 | { 56 | float c1,c2,c3; 57 | float ud_k,ud_1 = 0; 58 | c1 = gama*Td/(gama*Td + ts); 59 | c2 = (Td + ts)/(gama*Td + ts); 60 | c3 = Td/(gama*Td + ts); 61 | 62 | pid->err = pid->SetPoint - pid->FeedBack; 63 | pid->integral += pid->err; 64 | 65 | float y_1 = 0; 66 | int M = 2; 67 | 68 | if(M == 1) 69 | { 70 | ud_k = c1*ud_1 + c2*pid->FeedBack - c3*y_1; 71 | pid->u_k = Kp*pid->err + ud_k + Ki*pid->integral; 72 | } 73 | else if(M == 2) 74 | { 75 | pid->u_k = Kp*pid->err + Kd*(pid->err - pid->err_last)/ts + Ki*pid->integral; 76 | } 77 | 78 | pid->FeedBack = pid->u_k*1.0; 79 | 80 | 81 | y_1 = pid->FeedBack; 82 | pid->err_last = pid->err; 83 | 84 | return pid->FeedBack; 85 | } 86 | 87 | int main() 88 | { 89 | printf("System test begin \n"); 90 | 91 | pid_t* tset; 92 | int count = 0; 93 | float real = 0; 94 | 95 | tset = pid_init(80,0,0,0,0); 96 | 97 | while(count < 1000) 98 | { 99 | real = pid_calc(tset); 100 | printf("%f\n",real); 101 | count++; 102 | } 103 | 104 | free(tset); 105 | return 0; 106 | } 107 | -------------------------------------------------------------------------------- /CHAPTER2/chap2_1.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************************* 2 | * The Cascade PID control 3 | * 串级PID控制 4 | * 5 | * 主外副内,在一般的串级PID控制中,外环被称为主回路,内环被称为副回路。 6 | * 主调节器的输出控制量u1作为副回路的给定量R2(s)。 7 | * 串级控制系统的计算顺序是先主回路(PID1),后副回路(PID2)。控制方式有两种:一 8 | * 种是异步采样控制,即主回路的采样控制周期T1是副回路采样控制周期T2的整数倍。这是因为 9 | * 一般串级控制系统中主控对象的响应速度慢、副控对象的响应速度快的缘故。另一种是同步采 10 | * 样控制,即主、副回路的采样周期相同。这时,应根据副回路选择采样周期,因为副回路的受 11 | * 控对象的响应速度较快。 12 | * 13 | * 注:因算法本身的复杂度问题,该程序未整定完全,具体参数和计算方式请根据实际情况定义! 14 | *******************************************************************************************/ 15 | 16 | #include 17 | #include 18 | 19 | #define Kp 1.20 20 | #define Ki 0.02 21 | #define Kd 0.00 22 | 23 | //构造结构体 24 | struct pid_data 25 | { 26 | float rin; //主回路输入 27 | float yout1; //主回路输出 28 | float yout2; //副回路输出 29 | float err; //主回路反馈误差 30 | float err_last; //上一次的主回路反馈误差 31 | float integral; //主回路反馈误差积分 32 | float u1; //主回路控制量 33 | float u2; //副回路控制量 34 | float err2; //副回路反馈误差 35 | }; 36 | 37 | //定义结构体类型 38 | typedef struct pid_data pid_t; 39 | 40 | //机构体初始化 41 | struct pid_data* pid_init(float rin, float yout1,float yout2, 42 | float err, float err_last, float u1, float u2, float err2) 43 | { 44 | struct pid_data* tset = malloc(sizeof(struct pid_data)); 45 | 46 | tset->rin = rin; 47 | tset->yout1 = yout1; 48 | tset->yout2 = yout2; 49 | tset->err = err; 50 | tset->err_last = err_last; 51 | tset->u1 = u1; 52 | tset->u2 = u2; 53 | tset->err2 = err2; 54 | 55 | return tset; 56 | } 57 | 58 | //The Increment PID Control Algorithm 59 | float pid_calc(pid_t* pid) 60 | { 61 | //副回路反馈误差权重 62 | 63 | float alpha = 0.85, 64 | beta = 0.15, 65 | mju = 0.66, 66 | nju = 0.88; 67 | 68 | pid->err = pid->rin - pid->yout1; 69 | pid->integral += pid->err; 70 | pid->u1 = Kp*pid->err + Ki*pid->integral; 71 | 72 | //具体计算方式根据实际情况而定,切勿生搬硬套! 73 | pid->err2 = pid->u1 - pid->yout2; 74 | pid->u2 = 0.05*pid->err2; 75 | 76 | pid->yout2 = mju*pid->yout2 + nju*pid->u2; 77 | pid->yout1 = alpha*pid->yout1 + beta*pid->yout2; 78 | pid->err_last = pid->err; 79 | 80 | return pid->yout1; 81 | } 82 | 83 | int main() 84 | { 85 | printf("System test begin \n"); 86 | 87 | pid_t* tset; 88 | int count = 0; 89 | float real = 0; 90 | 91 | tset = pid_init(23,0,0,0,0,0,0,0); 92 | 93 | while(count < 100) 94 | { 95 | real = pid_calc(tset); 96 | printf("%f\n",real); 97 | count++; 98 | } 99 | 100 | free(tset); 101 | return 0; 102 | } 103 | -------------------------------------------------------------------------------- /CHAPTER1/chap1_7.c: -------------------------------------------------------------------------------- 1 | /************************************************************************************ 2 | * The incomplete differential PID control algorithm 3 | * 不完全微分PID控制算法 4 | * 5 | * 在PID控制中,微分信号的引入可改善系统的动态性能,但也容易引进高频干扰, 6 | * 在误差扰动突变时尤其显出微分项的不足。若在控制算法中加入低通滤波器,则可使 7 | * 系统性能得到改善。 8 | * 克服上述缺点的方法之一是在PID算法中加入一个一阶惯性环节(低通滤波器) 9 | * G_t(s)=1/(1+T_f_s) 10 | * 当M=1时,采用具有不完全微分PID方法; 11 | * 当M=2时,采用普通PID方法; 12 | * 13 | * 引入不完全微分,能有效的克服普通PID的不足。尽管不完全微分PID控制算法比普 14 | * 通PID控制算法要复杂些,但由于其良好的控制特性,近年来越来越得到广泛的应用。 15 | * 16 | * input:just for Step Signal 17 | * 目前只针对阶跃信号输入情况 18 | ************************************************************************************/ 19 | 20 | #include 21 | #include 22 | 23 | #define ts 20 24 | #define Tf 180 25 | #define TD 140 26 | 27 | #define Kc 0.035 28 | #define Ki 0.265 29 | #define Kd (float)(Kc*TD)/ts 30 | 31 | //basic data of pid control 32 | struct pid_data 33 | { 34 | float SetPoint; //Desired Value 35 | float FeedBack; //feedback value 36 | float err; 37 | float err_last; 38 | float integral; 39 | float u_k; 40 | }; 41 | 42 | typedef struct pid_data pid_t; 43 | 44 | //pid struct data init 45 | struct pid_data* pid_init(float SetPoint, float FeedBack, float err, float err_last, float u_k) 46 | { 47 | struct pid_data* tset = malloc(sizeof(struct pid_data)); 48 | 49 | tset->SetPoint = SetPoint; 50 | tset->FeedBack = FeedBack; 51 | tset->err = err; 52 | tset->err_last = err_last; 53 | tset->u_k = u_k; 54 | 55 | return tset; 56 | } 57 | 58 | //The Increment PID Control Algorithm 59 | float pid_calc(pid_t* pid) 60 | { 61 | float alfa,ud_k; 62 | float ud_1=0; 63 | int M = 1; 64 | 65 | pid->err = pid->SetPoint - pid->FeedBack; 66 | pid->integral += pid->err; 67 | if(M == 1) 68 | { 69 | alfa = Tf/(ts+Tf); 70 | ud_k = Kd*(1 - alfa)*(pid->err - pid->err_last) + alfa*ud_1; 71 | ud_1 = ud_k; 72 | pid->u_k = Kc*pid->err + ud_k + Ki*pid->integral; 73 | } 74 | else if(M == 2) 75 | { 76 | pid->u_k = Kc*pid->err + Kd*(pid->err - pid->err_last) + Ki*pid->integral; 77 | } 78 | 79 | pid->FeedBack = pid->u_k*1.0; 80 | pid->err_last = pid->err; 81 | 82 | return pid->FeedBack; 83 | } 84 | 85 | int main() 86 | { 87 | printf("System test begin \n"); 88 | 89 | pid_t* tset; 90 | int count = 0; 91 | float real = 0; 92 | 93 | tset = pid_init(35,0,0,0,0); 94 | 95 | while(count < 100) 96 | { 97 | real = pid_calc(tset); 98 | printf("%f\n",real); 99 | count++; 100 | } 101 | 102 | free(tset); 103 | return 0; 104 | } 105 | -------------------------------------------------------------------------------- /CHAPTER1/chap1_5.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * The gearshift integral PID control algorithm 3 | * 变速积分PID控制算法 4 | * 5 | * 基本思想: 6 | * 在普通的PID控制算法中,由于积分系数Ki是常数,所以在整个控制过程中, 7 | * 积分增量不变。而系统对积分项的要求是,系统偏差大时积分作用应减弱甚至全 8 | * 无,而在偏差小时则应加强。积分系数取大了会产生超调,甚至积分饱和,取小 9 | * 了又迟迟不能消除静差。因此,如何根据系统偏差大小改变积分的速度,对于提 10 | * 高系统品质是很重要的。变速积分PID可较好的解决这一问题。 11 | * 变速积分PID的基本思想是设法改变积分项的累加速度,使其与偏差大小相对 12 | * 应:偏差越大,积分越慢,反之则越快。 13 | * 14 | * input:just for Step Signal 15 | * 目前只针对阶跃信号输入情况 16 | *****************************************************************************/ 17 | 18 | #include 19 | #include 20 | 21 | #define Kp 0.8 22 | #define Ki 0.7 23 | #define Kd 0.05 24 | 25 | //basic data of pid control 26 | struct pid_data 27 | { 28 | float SetPoint; //Desired Value 29 | float FeedBack; //feedback value 30 | float err; 31 | float err_last; 32 | float integral; 33 | float u_sum; 34 | }; 35 | 36 | typedef struct pid_data pid_t; 37 | 38 | //pid struct data init 39 | struct pid_data* pid_init(float SetPoint, float FeedBack, float err, float err_last,float integral, float u_sum) 40 | { 41 | struct pid_data* tset = malloc(sizeof(struct pid_data)); 42 | 43 | tset->SetPoint = SetPoint; 44 | tset->FeedBack = FeedBack; 45 | tset->err = err; 46 | tset->err_last = err_last; 47 | tset->integral = integral; 48 | tset->u_sum = u_sum; 49 | 50 | return tset; 51 | } 52 | 53 | //The Increment PID Control Algorithm 54 | float pid_calc(pid_t* pid) 55 | { 56 | pid->err = pid->SetPoint - pid->FeedBack; 57 | pid->integral += (pid->err + pid->err_last)/2; 58 | 59 | 60 | float err = pid->err; 61 | 62 | int M = 2; 63 | int A = 0.4,B = 0.6; 64 | float flag; 65 | 66 | if(M == 1) 67 | { 68 | if(abs(err) <= B) 69 | flag = 1.0; 70 | else if((abs(err) > B) && (abs(err) <= (A+B))) 71 | flag = (A - abs(err) + B)/A; 72 | else 73 | flag = 0.0; 74 | } 75 | else if(M == 2) 76 | { 77 | flag = 1.0; 78 | } 79 | 80 | pid->u_sum = Kp*pid->err + Kd*(pid->err - pid->err_last) + flag*Ki*pid->integral; 81 | pid->FeedBack = pid->u_sum*1.0; 82 | pid->err_last = pid->err; 83 | 84 | return pid->FeedBack; 85 | } 86 | 87 | int main() 88 | { 89 | printf("System test begin \n"); 90 | 91 | pid_t* tset; 92 | int count = 0; 93 | float real = 0; 94 | 95 | tset = pid_init(35,0,0,0,0,0); 96 | 97 | while(count < 100) 98 | { 99 | real = pid_calc(tset); 100 | printf("%f\n",real); 101 | count++; 102 | } 103 | 104 | free(tset); 105 | return 0; 106 | } 107 | 108 | -------------------------------------------------------------------------------- /CHAPTER1/chap1_4.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * The integral saturation PID control algorithm 3 | * 抗积分饱和PID控制算法 4 | * 5 | * 基本思想: 6 | * 作为防止积分饱和的方法之一就是抗积分饱和法,该方法的思路是在 7 | * 计算u(k)时,首先判断上一时刻的控制量u(k-1)是否已超出限制范围: 8 | * 若u(k-1)>u_max,则只累加负偏差;若u(k-1) 16 | #include 17 | 18 | #define Kp 0.2 19 | #define Ki 0.8 20 | #define Kd 0.0 21 | 22 | //basic data of pid control 23 | struct pid_data 24 | { 25 | float SetPoint; //Desired Value 26 | float FeedBack; //feedback value 27 | float err; 28 | float err_last; 29 | float integral; 30 | float u_sum; 31 | }; 32 | 33 | typedef struct pid_data pid_t; 34 | 35 | //pid struct data init 36 | struct pid_data* pid_init(float SetPoint, float FeedBack, float err, float err_last,float integral, float u_sum) 37 | { 38 | struct pid_data* tset = malloc(sizeof(struct pid_data)); 39 | 40 | tset->SetPoint = SetPoint; 41 | tset->FeedBack = FeedBack; 42 | tset->err = err; 43 | tset->err_last = err_last; 44 | tset->integral = integral; 45 | tset->u_sum = u_sum; 46 | 47 | return tset; 48 | } 49 | 50 | //The Increment PID Control Algorithm 51 | float pid_calc(pid_t* pid) 52 | { 53 | pid->err = pid->SetPoint - pid->FeedBack; 54 | //pid->integral += pid->err; 55 | 56 | float err = pid->err; 57 | float u_sum = pid->u_sum; 58 | int alpha = 0; 59 | 60 | int M = 2; 61 | int um = 6; 62 | if(M == 1) 63 | { 64 | if(u_sum > um) 65 | { 66 | if(err >= 0) 67 | alpha = 0; 68 | else 69 | alpha = 1; 70 | } 71 | else if(u_sum <= -um) 72 | { 73 | if(err > 0) 74 | alpha = 1; 75 | else 76 | alpha = 0; 77 | } 78 | else 79 | { 80 | alpha = 1; 81 | } 82 | } 83 | else if(M==2) 84 | alpha = 1; 85 | 86 | pid->integral += alpha*pid->err; 87 | pid->u_sum = Kp*pid->err + Kd*(pid->err - pid->err_last) + Ki*pid->integral; 88 | pid->FeedBack = pid->u_sum*1.0; 89 | pid->err_last = pid->err; 90 | 91 | return pid->FeedBack; 92 | } 93 | 94 | int main() 95 | { 96 | printf("System test begin \n"); 97 | 98 | pid_t* tset; 99 | int count = 0; 100 | float real = 0; 101 | 102 | tset = pid_init(100,0,0,0,0,0); 103 | 104 | while(count < 100) 105 | { 106 | real = pid_calc(tset); 107 | printf("%f\n",real); 108 | count++; 109 | } 110 | 111 | free(tset); 112 | return 0; 113 | } 114 | 115 | -------------------------------------------------------------------------------- /CHAPTER3/chap3_1.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************************** 2 | * 3 | * 专家PID控制 4 | * 5 | * 专家控制的实质是基于受控对象和控制规律的各种知识,并以只能的方式利用这些知识来 6 | * 设计控制器。利用专家经验来设计PID参数便构成专家PID控制。 7 | * 8 | * 注:因算法本身的复杂度问题,该程序未整定完全,具体参数和计算方式请根据实际情况定义! 9 | ****************************************************************************************/ 10 | 11 | #include 12 | #include 13 | 14 | #define Kp 1.0 15 | #define Ki 0.50 16 | #define Kd 0.10 17 | 18 | #define Ts 20 19 | 20 | 21 | //构造结构体 22 | struct pid_data 23 | { 24 | float rin; 25 | float yout; 26 | float err; 27 | float err_last; 28 | float integral; 29 | float u; 30 | }; 31 | 32 | //定义结构体类型 33 | typedef struct pid_data pid_t; 34 | 35 | //机构体初始化 36 | struct pid_data* pid_init(float rin, float yout, 37 | float err, float err_last, float u) 38 | { 39 | struct pid_data* tset = malloc(sizeof(struct pid_data)); 40 | 41 | tset->rin = rin; 42 | tset->yout = yout; 43 | tset->err = err; 44 | tset->err_last = err_last; 45 | tset->u = u; 46 | 47 | return tset; 48 | } 49 | 50 | //The Increment PID Control Algorithm 51 | float pid_calc(pid_t* pid) 52 | { 53 | //第一种情况:开环控制阶段 54 | //误差绝对值已经很大。不论误差变化趋势如何,都应考虑控制器的输出应按最大(或最小) 55 | //输出,以达到迅速调整误差,使误差绝对值以最大速度减小。 56 | if(abs(x_1) > 0.8) 57 | pid->u = 0.45; 58 | else if(abs(x_1) > 0.40) 59 | pid->u = 0.40; 60 | else if(abs(x_1) > 0.20) 61 | pid->u = 0.12; 62 | else if(abs(x_1) > 0.01) 63 | pid->u = 0.10; 64 | 65 | //第二种情况: 66 | //误差仍较大,考虑由控制器实施较强的控制作用,以达到扭转误差绝对值朝减小方向变化, 67 | //并迅速减小误差的绝对值。 68 | if((x_1*x_2 > 0)||(x_2 == 0)) 69 | { 70 | if(abs(x_1) >= 0.05) 71 | pid->u = u_1 + 2*Kp*x_1; 72 | else 73 | pid->u = u_1 + 0.4*Kp*x_1; 74 | } 75 | 76 | //第三种情况: 77 | //误差的绝对值朝较小的方向变化,已经达到平衡状态。此时,可考虑采取保持控制器输出不变。 78 | if((x_1*x_2 < 0)&&(x_2*x2_1 > 0)||(x_1 == 0)) 79 | pid->u = pid->u; 80 | 81 | //第四种情况: 82 | //误差的绝对值较大,考虑实施较强的控制作用 83 | if((x_1*x_2 < 0)&&(x_2*x2_1 < 0)) 84 | { 85 | if(abs(x_1) >= 0.05) 86 | pid->u = u_1 + 2*Kp*pid->err_last; 87 | else 88 | pid->u = u_1 + 0.6*Kp*pid->err_last; 89 | } 90 | 91 | //第五种情况: 92 | //误差的绝对值很小,此时加入积分,减少稳态误差。 93 | if(abs(x_1) <= 0.001) 94 | pid->u = 0.5*x_1 + 0.010*x_3; 95 | 96 | x_1 = pid->err; 97 | x2_1 = x_2; 98 | x_2 = (pid->err - pid->err_last)/Ts; 99 | x_3 = x_3 + pid->err*Ts; 100 | 101 | pid->err_last = pid->err; 102 | 103 | return pid->u; 104 | } 105 | 106 | int main() 107 | { 108 | printf("System test begin \n"); 109 | 110 | pid_t* tset; 111 | int count = 0; 112 | float real = 0; 113 | 114 | tset = pid_init(23,0,0,0,0,0,0,0); 115 | 116 | while(count < 100) 117 | { 118 | real = pid_calc(tset); 119 | printf("%f\n",real); 120 | count++; 121 | } 122 | 123 | free(tset); 124 | return 0; 125 | } 126 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/1fe9735b1cbc55a36b7369a788f6d31bc9ab344b: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/1c4fe4e196a23ae543249312141a225bcbbf6944: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/0ca1c869ab18973211164e73d25167010c093eec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/e636d527b99f7a462006d55ae19104ad0be6b943: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/d2aa1de9ed2d542360df6d9e799fdd4cece9f45c: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/5bd02caa6aa3dcf79c1fe7b498e5fc189f577a14: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/5ebdaa7838b08517273db1ef8b624e76edb1d604: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/536836e7477819f300b8b4bbc6b0f1a43ecd5a8a: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/1978a11f9869aeb4aff2ff6f5f628da046ccee4a: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/c5132c7e4a7a0f0ab62370c04bfd9fdf7797c93e: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/3ec70456ca882a84f28b0ab97bbb042eeec409a0: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/a334b8764ebdf38546bcc1205aa031ec7b68d5ad: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/138aa9136de2f9d82461a36ce9a97dbcf542a468: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/551e87abef2e4c0cdcdb77b20fe6fec43f8065b6: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/150e66e2e72506e9058a270ef3add9856ebbd0b7: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/9cefae809b8fe094f3ae2d08e761633e9af74cc3: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/f2049854f9827e54120fa2e8f6deceb526709c83: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/b8d86ad0f4901b65f0a78ffe4226b0fbf2b505e5: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/f5ea055f9e855fd6c022da5c7ecc635c034a8593: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/5cb6638fd1e72c31965c1f89420d47d74999e13c: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/41d9a9a49911d0af5e5bc2600736a495c4882cda: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/cc8f62341a051d80d9433b422f75e81fd69aa82a: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/9a9de8b9f870d26bc73b8894317bff87ec6845d3: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/d7939ea1ba5b7440fb345b7e2fd2f7560f252277: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/4bcc71d1907c848d280095716df41b5a71ecd1c5: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/019908a560c84432c3a34d6fcd15d9c89bf87f29: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/19a2dc014104aec448e80812c730ba971be1c924: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /resource/PID控制器 - 维基百科,自由的百科全书_files/b26d3e50dff13b4aeb56e24ef2185492148a0601: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | --------------------------------------------------------------------------------