最近,在某社团的要求下,自学了PID算法。学完后,深切地感受到PID算法之强大。PID算法应用广泛,比如加热器、平衡车、无人机等等,是自动控制理论中比较容易理解但十分重要的算法。

  下面是博主学习过程中所做的笔记,笔记后面提供了4种编程语言的仿真代码(C, C++, Python, Matlab),使实现方式更加灵活,同时增强对PID的理解。(文章较长,可点击右侧目录选择性阅读)


PID算法学习笔记

参考:PID基础入门教程

一、位式控制算法

  1.1 位式控制算法原理

  位式控制算法,通过比较SV(设定值)和PV(当前值),输出高低电平给执行部件,执行部件(如开关)通过执行/停止来控制目标(如加热器),控制对象通过传感器将当前值反馈给控制算法,如图1。

图1 位式控制算法简单应用

  1.2 位式控制算法特点

  位式控制算法具有如下特点:

    (1)输出信号一般只有两种状态(LOW / HIGH)。

    (2)通过比较SV和PV的值来产生OUT值,比如PV < SV输出高电平,PV > SV输出低电平。

    (3)只比较控制对当前的状态值。

  1.3 位式控制算法缺陷

  位式控制算法的缺陷:

    (1)输出信号单一,缺乏包容性。

    (2)仅仅活在当下,没有回顾历史和展望未来。

二、PID控制算法

  2.1 PID算法原理

  PID控制算法,通过分析PV与SV的偏差值(包括当前偏差、历史偏差、最近偏差),输出值(PWM)经过执行器转换后应用于控制对象,控制对象通过传感器将PV反馈给PID,通过硬件寄存器等记录偏差值,以便PID随时调用,如图2。

图2 PID控制算法简单应用

  假设从“0”时刻到 k 时刻,传感器获取的状态值分别为

${X_{0}, X_{1}, X_{2}, ..., X_{k-1}, X_{k}}$

  

  2.2 PID比例控制

  在2.1的条件下,设偏差值 E为设定值与当前值之差,即

${E_{k}=SV-X_{k}}$

  实际应用中的偏差值存在如下3种情况

  分析以上三种情况,不同情况下算法将输出不同值。比如算法在Ek > 0时输出较高的值,以促进当前值接近设定值。而实际应用中,控制对象的状态偏差值一般不能直接作为PWM输出值,需要进行一定比例的放大或缩小,以提高控制灵敏度。因此输出值满足关系式

${P_{out}=K_{p}\cdot E_{k}+OUT_{0}}$  

  其中,POUT为输出值,一般与PWM有关。K为比例系数,对偏差值Ek 进行一定比例的放大或缩小。OUT是当偏差值为 0 时,算法的输出值,防止负载失控。分析公式可知,偏差值E越大,输出值越大,当前值接近设定值的速度越快,当前值超过设定值时,E< 0, 算法输出负值,当前值减小。往复循环,直到当前值稳定在设定值的误差允许范围内。

  2.3 PID积分控制

  在2.2的条件下,将历史偏差相加,其和为

${S_{k}=E_{0}+E{1}+E_{2}+...+E_{k-1}+E_{k}}$

  实际应用中的历史偏差值之和存在如下3种情况

  不同情况下输出值应不同,分析以上情况,可以令输出值满足关系式

${I_{out}=K_{p}\cdot S_{k}+OUT_{0}}$  

  其中Iout为输出值,Kp为比例系数,Sk为历史偏差和,OUT0为初始值。通过上述算法,可以对控制对象的历史状态值进行评估,根据历史状态判断输出值的大小。这种方法比较局限,因为当历史值较多时,当前值的变化将很难引起输出值改变,因此积分控制一般不会从0开始启动,当当前值接近设定值时才开启积分控制,以减少参考的历史值。

  2.4 PID微分控制

  在2.2的条件下,将最近两次偏差值相减,其差为

${D_{k}=E_{k}-E_{k-1}}$

  实际应用中的最近偏差值之差存在如下3种情况

  不同情况下输出值应不同,分析以上情况,可以令输出值满足关系式

${D_{out}=K_{p}\cdot D_{k}+OUT_{0}}$  

  其中Dout为输出值,Kp为比例系数,Sk为历史偏差和,OUT0为初始值。通过最近偏差值之差,判断偏差值的变化趋势,预测未来的偏差值大小,从而输出对应的PWM。

  2.5 PID算法模型

  根据以上分析,每种控制算法均有较大局限。因此综合①②③算法,令输出值为

${PID_{out_{k}}=P_{out}+I_{out}+D_{out}}$

  代入①②③关系式,并进行简单归并,得到关系式

${PID_{out_{k}}=K_{p}\cdot \left ( E_{k}+S_{k}+D_{k}\right )+OUT_{0}}$  

  分析上式中 S, Dk 的值,假设T为计算周期,即每次运行算法的时间间隔,Ti为积分时间常数,用于控制积分算法对输出值的影响因数,Td为微分时间常数,用于控制微分算法对输出值的影响。

  综上,积分控制Sk满足关系式

${S_{k}=\frac{1}{T_{i}}\cdot\sum_{k=0}^{k}E_{k} \cdot T}$   

  微分控制Dk满足关系式

${D_{k}=T_{d}\cdot\frac{\left ( E_{k}-E_{k-1}\right )}{T}}$   

  综合④⑤⑥,并进行简单的归并处理后,得到PID的输出关系式

${PID_{out_{k}}=P\left (K_{p}\cdot E_{k} \right )+I\left (K_{p}\cdot \frac{T}{T_{i}}\cdot \sum_{k=0}^{k}\cdot E_{k} \right )+D\left [K_{p}\cdot \frac{T_{d}}{T}\cdot\left(E_{k}-E_{k-1}\right) \right ]}$   

  其中P,I,D分别表示比例,积分,微分控制。通过调整 Kp ,Ti ,T的值来调整P, I,D对输出值的影响权重,从而使当前值更快接近并稳定在设定值误差允许范围内。

  上述算法有一个明显的特点,即计算结果输出为PWM值,直接控制负载。因此又被称为“位置式PID算法“

  

  2.6 增量式PID算法

  实际应用中,大部分控制系统具有记忆功能,可以记录每个时刻状态值,因此为了减小累加产生的运算负担,可以采用计算“增量”的方式来输出控制信号。

  增量式PID算法的特点是只计算增加(减小)值,历史值加上增加值即为输出值,满足关系式

${\Delta PID_{out}=PID_{out_{k}}-PID_{out_{k-1}}}$   

  代入④关系式,

${\Delta PID_{out}=P\left [K_{p}\cdot \left ( E_{k}-E_{k-1}\right ) \right ]+I\left (K_{p}\cdot \frac{T}{T_{i}}\cdot E_{k} \right )+D\left [K_{p}\cdot \frac{T_{d}}{T}\cdot \left ( E_{k}-2E_{k-1}-E_{k-2}\right ) \right ]}$ 

  对比⑧式和⑦式,⑧式运算量更小。因此对于有记忆功能的硬件系统,可以使用增量式PID算法,以减少运算,提升性能。


PID仿真实验

一、问题

  既然是仿真实验,那就应该以模拟解决生活中的问题为主,为了进行比较具体,但不复杂的仿真实验,博主绞尽脑汁,终于构造了下面这个题目。

  在《机甲大师》动漫中,主角“单单”拥有一架语音遥控的双旋翼无人机,名叫“KAKA"。如图1,动漫第一集5:35左右,KAKA在追踪飞盘时,突然受海风影响,飞行姿态偏离水平位置。性能超高的KAKA通过内部传感器测得偏角后,迅速调整姿态,恢复水平。请对这一情形进行建模分析。

图1 被海风影响的KAKA

二、解答

  分析题目,需要对KAKA“恢复姿态”这一现象进行分析。围绕这个问题,下面以“建立物理模型→建立数学模型→算法仿真”进行逐步分析。

  2.1 建立物理模型

  首先简化问题,将KAKA看作刚性直杆。如图2.1,一质量为2m,长度为2r的刚性直杆,两端垂直固定一个不计质量的直流电机。直杆可以绕中心自由旋转,初始位置相对水平线偏离θ角。

  为了使直杆恢复水平位置,改变右端电机转速,产生“额外”升力F

  根据以上参数,在理想情况下,可以得到直杆的合外力矩M满足

${M = F\cdot r}$ ①

  转动惯量J满足

${J=\frac{2}{3}mr^{2}}$ ②

  由刚体轴转动定理

${M=J\cdot \alpha}$ ③

  其中α为角加速度,满足关系式

${\alpha =\frac{\mathrm{d^2}\theta }{\mathrm{d} t^2}}$ ④

  其中t为时间,联立①②③④,求解微分方程可得到关系式

${\theta _{t}=\frac{3\cdot F}{4\cdot m\cdot r}\cdot t^2}$ ⑤

  其中θ为直杆在力合外力F的作用下,经过时间t后转动的角度。

  2.2 建立数学模型

  设${T}$为计算周期,在⑤式的条件下,令${t=T}$,在${T}$时间内直杆转动角度满足关系式

${\theta _{T} =\frac{3\cdot F}{4\cdot m\cdot r}\cdot T^2}$ ⑥

  假设${F}$随时间的变化周期为${T}$,那么经过${t}$时间后,${F}$变化${n}$次,直杆转动角度满足

${\theta  =\frac{3\cdot T^2}{4\cdot m\cdot r}\cdot\sum_{n=0}^{n} F_{n}}$ ⑦

  直杆与水平线的当前偏差角${E_{k}}$满足

${E_{k}=\theta_{0}-\frac{3\cdot T^2}{4\cdot m\cdot r}\cdot\sum_{n=0}^{k} F_{n}}$ ⑧

  上式即为直杆在恢复水平位置过程中,在合外力F作用下,当前偏角对于时间的函数。

  参考实际情况,由于合外力以T为周期发生变化,该偏角函数曲线应如满足图2.2

图2.2 (预测)直杆偏角对于时间的变化曲线

  分析上图曲线,发现其变化趋势可以用PID算法进行拟合。

  2.3 PID算法仿真

  分析关系式⑧,其中${T}$可以看作采样周期,${F}$为算法输出值,${E_{k}}$为当前偏差角。应用位置式${PID}$算法,设比例系数为${K_{p}}$,积分时间常数为${T_{i}}$,微分时间常数为${T_{d}}$,输出值满足PID算法关系式

${F_{out_{k}}=K_{p}\cdot E_{k} +K_{p}\cdot \frac{T}{T_{i}}\cdot \sum_{k=0}^{k}\cdot E_{k} + K_{p}\cdot \frac{T_{d}}{T}\cdot E_{k}-E_{k-1}}$ ⑨

  分析⑧式,为了简化计算,不妨令

${m = 0.3}$,  ${r=0.1}$,  ${\theta _{0}=\frac{\pi}{3}}$ (${SI}$)

  则当前偏差角满足

${E_{k}=\frac{\pi}{3}-25\cdot T^2\cdot\sum_{n=0}^{k} F_{out_{n}}}$ ⑩

  综上,可以假设如表2.3中的参数

表2.3 PID参数

  下面,在上述模型条件下,用5种编程语言(Matlab, C, C++, Python)进行算法仿真。


1) Matlab

比较方便,可以先通过Matlb仿真确定PID系数

  源码:

  1. clear,clc,close all % 清屏
  2.  
  3. syms x
  4. SV = 0; % 设定值,角(弧)度 0 (rad)
  5. T = 0.01; % 计算周期/采样周期
  6. Kp = 50; % 比例系数
  7. Ti = 5; % 积分时间常数
  8. Td = 0.05; % 微分时间常数
  9.  
  10. E = []; % 历史偏差
  11. Fout = []; % 输出值,升力
  12. E(1) = pi ./3; % 初始角度 π/3 (rad)
  13.  
  14. for i = 1:1:3 % 绘制3种比较曲线
  15. if i == 2;
  16. Kp = 50; % 比例系数
  17. Ti = 0.05; % 积分时间常数
  18. Td = 0.05; % 微分时间常数
  19. E = []; % 历史偏差
  20. Fout = []; % 输出值,升力
  21. E(1) = pi ./3; % 初始角度 π/3 (rad)
  22. end % if i ==2
  23.  
  24. if i ==3;
  25. Kp = 50; % 比例系数
  26. Ti = 5; % 积分时间常数
  27. Td = 0.005; % 微分时间常数
  28. E = []; % 历史偏差
  29. Fout = []; % 输出值,升力
  30. E(1) = pi ./3; % 初始角度 π/3 (rad)
  31. end % if i ==3
  32.  
  33. for t = 0:0.01:3; % 计算300
  34. k = round(t*100 + 2); % 当前指数
  35.  
  36. E(k) = E(1) - 25*(T^2)*sum(Fout); % 获取当前值
  37.  
  38. %#### 核心,PID计算输出值 ####%
  39. if k>2;
  40. if E(k) != 0;
  41. Fout(k) = Kp*(E(k) + (T./Ti)*sum(E) + (Td./T)*(E(k)-E(k-1)));
  42. end % end if E(k) !=0
  43. end % end if k>2
  44. %#############################%
  45.  
  46. k++; % 当前指数+1
  47.  
  48. end % end for 计算400
  49.  
  50. hold on
  51. plot(E) % 显示数据图
  52. end # for 绘制3种比较曲线
  53.  
  54. legend('PID(50, 5, 0.05)','PID(50, 0.05, 0.05)','PID(20, 5, 0.005)')
  55.  
  56. hold on
  57. plot([0,300],[0,0],'--'); % 显示参考线,斜率0,截距0

  运行结果


2) C语言

  1. /**@file main.c
  2. * @brief 位置式PID C语言算法仿真
  3. * @author BROSY
  4. * @copyright CSU | BROSY
  5. ********************************************************************************/
  6.  
  7. /*************************************************************************************
  8. 注:以便查阅,我将所有函数和声明都放在main.c中,进行项目实践时,再设计文件架构
  9. *************************************************************************************/
  10.  
  11. #include<stdio.h>
  12. #define PI (3.1416)
  13.  
  14. typedef struct {
  15. const int SV = ; // 设定值(弧度rad)
  16.  
  17. double InitVal; //初始偏差值
  18. double T; // 采样周期
  19. double Kp; // 比例系数
  20. double Ti; // 积分时间常数
  21. double Td; // 微分时间常数
  22. double Ek; //当前偏差
  23. double SumEk; //历史偏差之和
  24. double Ek_1; //上次偏差
  25. double SumFout; // 输出值之和
  26. }PID_Structure;
  27.  
  28. /**
  29. @brief 位置式PID输出函数
  30. @param [in] PID结构体
  31. @return 算法输出值(额外升力)
  32. */
  33. double PID_OUT(PID_Structure* PID)
  34. {
  35. double Fout;
  36. Fout = PID->Kp * (PID->Ek
  37. + (PID->T / PID->Ti) * PID->SumEk
  38. + (PID->Td / PID->T) * (PID->Ek - PID->Ek_1));
  39.  
  40. return Fout; // 输出值(额外升力)
  41. }
  42.  
  43. /**
  44. @brief 获取当前偏差值
  45. @param [in] PID结构体, 历史输出值(数组)
  46. @return kaka当前状态偏差值
  47. */
  48. double GetCurrE(PID_Structure PID)
  49. {
  50. double Ek;
  51. Ek = PID.InitVal - * (PID.T * PID.T) * PID.SumFout;
  52. return Ek;
  53. }
  54.  
  55. int main()
  56. {
  57. PID_Structure PID; // 创建PID
  58.  
  59. PID.InitVal = PI / ;
  60. PID.T = 0.01;
  61. PID.Kp = ;
  62. PID.Ti = ;
  63. PID.Td = 0.005;
  64. PID.Ek = ;
  65. PID.Ek_1 = ;
  66. PID.SumFout = ;
  67. PID.SumEk = ;
  68.  
  69. // 计算400次
  70. for (int i = ; i < ; i++)
  71. {
  72. if (i > )
  73. {
  74. PID.Ek_1 = PID.Ek; // 获取k-1的偏差值
  75. }
  76. PID.Ek = GetCurrE(PID); // 获取当前偏差值
  77. PID.SumEk += PID.Ek; // 历史偏差之和
  78.  
  79. printf("%f\n", PID.Ek);
  80. if (PID.Ek != && i > ) // 误差
  81. {
  82. PID.SumFout += PID_OUT(&PID); // 获取输出值之和
  83.  
  84. }
  85. else
  86. {
  87. PID.SumFout += ; // 储存输出值
  88. }
  89. }
  90.  
  91. }

//C show all

将输出结果导入到excel中并绘制曲线:


3) C++

  1. /**@file main.cpp
  2. * @brief 位置式PID C语言算法仿真
  3. * @author BROSY
  4. * @copyright CSU | BROSY
  5. ********************************************************************************/
  6.  
  7. #include "PID.h"
  8.  
  9. int main()
  10. {
  11. PID* pid[]; // 创建PID
  12.  
  13. pid[] = new PID(, , 0.05); // 初始化PID1
  14. pid[] = new PID(, 0.05, 0.05); // 初始化PID2
  15. pid[] = new PID(, , 0.005); // 初始化PID3
  16.  
  17. for (int i = ; i < ; i++)
  18. {
  19. pid[i]->Loop();// 计算400次
  20. delete pid[i]; // 释放内存
  21. }
  22. }

//main.cpp 展开全部

  1. #include "PID.h"
  2. #include <iostream>
  3. /**
  4. @brief 初始化PID参数
  5. @param [in] P I D系数
  6. 只设置P I D的系数,其余默认
  7. */
  8. PID::PID(double P, double I, double D)
  9. {
  10. Kp = P;
  11. Ti = I;
  12. Td = D;
  13.  
  14. InitVal = (3.1426)/; // 初始偏差值π/3
  15. T = 0.01; // 采样周期
  16. Ek = ; //当前偏差
  17. SumEk = ; //历史偏差之和
  18. Ek_1 = ; //上次偏差
  19. SumFout = ; // 输出值之和
  20. }
  21.  
  22. /**
  23. @brief 位置式PID输出函数
  24. @return 算法输出值(额外升力)
  25. */
  26. double PID::PID_OUT()
  27. {
  28. double Fout;
  29.  
  30. Fout = Kp * (Ek
  31. + (T / Ti) * SumEk
  32. + (Td / T) * (Ek - Ek_1));
  33.  
  34. return Fout; // 输出值(额外升力)
  35. }
  36.  
  37. /**
  38. @brief 获取当前偏差值
  39. @return kaka当前状态偏差值
  40. */
  41. double PID::GetCurrE()
  42. {
  43. double Ek;
  44. Ek = InitVal - * (T * T) * SumFout;
  45. return Ek;
  46. }
  47.  
  48. /**
  49. @brief 循环计算并输出值
  50. @param [in] 计算次数
  51. */
  52. void PID::Loop(int times)
  53. {
  54. std::cout << "计算次数:" << times << std::endl;
  55. std::cout << "P = " << Kp << std::endl;
  56. std::cout << "I = " << Ti << std::endl;
  57. std::cout << "D = " << Td << std::endl<<std::endl;
  58.  
  59. for (int i = ; i < times; i++)
  60. {
  61. if (i > )
  62. {
  63. Ek_1 = Ek; // 获取k-1的偏差值
  64. }
  65. Ek = GetCurrE(); // 获取当前偏差值
  66. SumEk += Ek; // 历史偏差之和
  67.  
  68. std::cout << Ek << std::endl;
  69. if (Ek != && i > ) // 误差
  70. {
  71. SumFout += PID_OUT(); // 获取输出值之和
  72.  
  73. }
  74. else
  75. {
  76. SumFout += ; // 储存输出值
  77. }
  78. }
  79. }

//PID.cpp

  1. #pragma once
  2. class PID
  3. {
  4. private:
  5. const int SV = ; // 设定值(弧度rad)
  6.  
  7. double InitVal; //初始偏差值
  8. double T; // 采样周期
  9. double Kp; // 比例系数
  10. double Ti; // 积分时间常数
  11. double Td; // 微分时间常数
  12. double Ek; //当前偏差
  13. double SumEk; //历史偏差之和
  14. double Ek_1; //上次偏差
  15. double SumFout; // 输出值之和
  16.  
  17. public:
  18. PID(double P, double I, double D); // PID初始化,只输入PID系数,其余默认
  19.  
  20. double PID_OUT(); // PID算法核心,计算输出值
  21. double GetCurrE(); // 获取当前值
  22.  
  23. void Loop(int times); // 循环计算输入计算次数
  24. };

//PID.h

将输出结果导入到excel中并绘制曲线:


4) Python

  1. import matplotlib.pyplot as plt # 导入绘图库
  2. import numpy as np
  3.  
  4. '''
  5. @brief 位置式PID输出函数
  6. @param [in] PID结构体
  7. @return 算法输出值(额外升力)
  8. '''
  9.  
  10. def pid_out():
  11. f_out = Kp * (Ek
  12. + (T / Ti) * sum_Ek
  13. + (Td / T) * (Ek - Ek_1))
  14. return f_out
  15.  
  16. '''
  17. @brief 获取当前偏差值
  18. @param [in] PID结构体, 历史输出值(数组)
  19. @return kaka当前状态偏差值
  20. '''
  21.  
  22. def get_curr_e():
  23. ek = init_val - 25 * (T ** 2) * sum_f_out
  24. return ek
  25.  
  26. sv = 0.0 # 设定值
  27. init_val = (3.1416) / 3 # 初始值
  28. T = 0.01 # 采样周期
  29. times = 300 # 计算次数
  30. e = np.zeros(times)
  31. for t in range(3):
  32. Ek = 0.0 # 当前偏差
  33. sum_Ek = 0.0 # 历史偏差之和
  34. Ek_1 = 0.0 # 上一次偏差
  35. sum_f_out = 0.0 # 输出值之和(升力)
  36.  
  37. if t == 0:
  38. Kp = 50 # 比例系数
  39. Ti = 5 # 积分时间常数
  40. Td = 0.05 # 微分时间常数
  41. if t == 1:
  42. Kp = 50 # 比例系数
  43. Ti = 0.05 # 积分时间常数
  44. Td = 0.05 # 微分时间常数
  45. if t == 2:
  46. Kp = 50 # 比例系数
  47. Ti = 5 # 积分时间常数
  48. Td = 0.005 # 微分时间常数
  49.  
  50. '''
  51. @brief 循环计算并输出值
  52. @param [in] 计算次数
  53. '''
  54. for i in range(times):
  55. if i > 0:
  56. Ek_1 = Ek
  57.  
  58. Ek = get_curr_e() # 获取当前值
  59. sum_Ek = sum_Ek + Ek # 获取历史值之和
  60.  
  61. e[i] = Ek # 储存当前值,方便后面绘图
  62.  
  63. if Ek != 0 and i > 0:
  64. sum_f_out = sum_f_out + pid_out() # 获取输出值之和
  65.  
  66. plt.plot(e, label='PID({0}, {1}, {2})'.format(Kp, Ti, Td)) # 画曲线图,显示PID图例
  67.  
  68. plt.plot(np.zeros(times + 25), label='SV', linestyle='--') # 设定值
  69. plt.legend() # 显示图例
  70.  
  71. plt.show()

#

下载源码

链接:PID仿真源码    密码:hhh

某科学的PID算法学习笔记的更多相关文章

  1. C / C++算法学习笔记(8)-SHELL排序

    原始地址:C / C++算法学习笔记(8)-SHELL排序 基本思想 先取一个小于n的整数d1作为第一个增量(gap),把文件的全部记录分成d1个组.所有距离为dl的倍数的记录放在同一个组中.先在各组 ...

  2. Manacher算法学习笔记 | LeetCode#5

    Manacher算法学习笔记 DECLARATION 引用来源:https://www.cnblogs.com/grandyang/p/4475985.html CONTENT 用途:寻找一个字符串的 ...

  3. Johnson算法学习笔记

    \(Johnson\)算法学习笔记. 在最短路的学习中,我们曾学习了三种最短路的算法,\(Bellman-Ford\)算法及其队列优化\(SPFA\)算法,\(Dijkstra\)算法.这些算法可以快 ...

  4. Johnson 全源最短路径算法学习笔记

    Johnson 全源最短路径算法学习笔记 如果你希望得到带互动的极简文字体验,请点这里 我们来学习johnson Johnson 算法是一种在边加权有向图中找到所有顶点对之间最短路径的方法.它允许一些 ...

  5. PID算法学习记录

    最近做项目需要用到PID算法,这个本来是我的专业(控制理论与控制工程),可是我好像是把这个东西全部还给老师了. 没办法,只好抽时间来学习了. 先占个座,后续将持续更新!

  6. 算法学习笔记——sort 和 qsort 提供的快速排序

    这里存放的是笔者在学习算法和数据结构时相关的学习笔记,记录了笔者通过网络和书籍资料中学习到的知识点和技巧,在供自己学习和反思的同时为有需要的人提供一定的思路和帮助. 从排序开始 基本的排序算法包括冒泡 ...

  7. PID控制学习笔记(二)

    不管是基本的PID控制还是变形的PID控制算法,其核心都是对输入信号(设定值信号.测量信号或者偏差信号等)做基本的比例.积分.微分运算,最终提供给被控过程良好的调节信号. 在过程控制仪表,特别是在数字 ...

  8. R语言实现关联规则与推荐算法(学习笔记)

    R语言实现关联规则 笔者前言:以前在网上遇到很多很好的关联规则的案例,最近看到一个更好的,于是便学习一下,写个学习笔记. 1 1 0 0 2 1 1 0 0 3 1 1 0 1 4 0 0 0 0 5 ...

  9. 二次剩余Cipolla算法学习笔记

    对于同余式 \[x^2 \equiv n \pmod p\] 若对于给定的\(n, P\),存在\(x\)满足上面的式子,则乘\(n\)在模\(p\)意义下是二次剩余,否则为非二次剩余 我们需要计算的 ...

随机推荐

  1. DataGridView行号发生变化 使用的事件

    DataGridView并没有这么专门为行号发生变化时触发的事件,我们只能用SelectionChanged和CurrentCellChanged做些设置后实现. 1.使用SelectionChang ...

  2. 智能可视化搭建系统 Atom 服务架构演变

    作者:凹凸曼 - Manjiz Atom 是什么?Atom 是集结业内各色资深电商行业设计师,提供一站式专业智能页面和小程序设计服务的平台.经过 2 年紧凑迭代,项目越来越庞大,需求不断变更优化,内部 ...

  3. react: typescript import images alias

    1.webpack.config.js resolve: { extensions: ["ts", "tsx", "js", "j ...

  4. tf.keras的模块

          

  5. SVM之不一样的视角

    在上一篇学习SVM中 从最大间隔角度出发,详细学习了如何用拉格朗日乘数法求解约束问题,一步步构建SVM的目标函数,这次尝试从另一个角度学习SVM. 回顾监督学习要素 数据:(\(x_i,y_i\)) ...

  6. Nginx(1)---安装及基础命令

    一.简述 Nginx是一个高性能WEB服务器,除它之外Apache.Tomcat.Jetty.IIS,它们都是Web服务器 Nginx  相对基它WEB服务有什么优势:Tomcat.Jetty 面向j ...

  7. springboot+dubbo简单分布式RPC调用demo

    使用springboot+dubbo搭建RPC入门案例 本文背景简述: 最近在学习公司的一套RPC框架,初步接触的时候感觉挺复杂的.但是知道其原理肯定是和dubbo很相似的,毕竟都是RPC框架嘛,只是 ...

  8. 2019-2020-1 20199328《Linux内核原理与分析》第六周作业

    使用gdb跟踪分析一个系统调用内核函数 首先我们删除本身的menu目录,并从github上克隆一个menu,并进行编译 编译过程 现在找到test.c文件,加入上个实验中做的getPid()方法 利用 ...

  9. windows下怎么同时使用python2和3

    windows命令行下,怎么能够自由的切换python2和3呢?当然不是切换目录!很多帖子告诉你,将python2目录下的python.exe文件改成python2.exe,pyhton3目录下的py ...

  10. CtsVerifier-Bluetooth-LE-SEcure-ClientServer-Test测试pass但是无法选择passbutton

    [问题描述] CtsVerifier-Bluetooth-LE-SEcure-ClientServer-Test测试pass但是无法选择Pass-Button 工具版本:9.0-r11 其他信息: 上 ...