什么是嵌入式PID算法?嵌入式PID算法分析

发布者:rho27最新更新时间:2024-01-29 来源: elecfans关键字:嵌入式  PID算法  控制器 手机看文章 扫描二维码
随时随地手机看文章

1.1 概述

比例(Proportion)积分(Integral)微分(Differential)控制器(PID控制器或三项控制器)是一种采用反馈的控制回路机制,广泛应用于工业控制系统和需要连续调制控制的各种其他应用。


PID控制器连续计算误差值 e(t) 作为所需设定点(SP) 和测量过程变量(PV)之间的差值,并应用基于比例、积分和导数项(分别表示为P、I和D)的校正,因此得名。

34dc96ce-7bf5-11ee-939d-92fbcf53809c.png

34e62874-7bf5-11ee-939d-92fbcf53809c.png

r(t) 是期望的过程值或设定点(SP),y(t) 是测量的过程值(PV)。

1.2 历史发展

1911年,第一个PID控制器是由Elmer Sperry开发的。

1922 年,俄裔美国工程师尼古拉斯·米诺斯基 ( Nicolas Minorsky)才首次利用理论分析制定了我们现在所说的 PID 或三项控制的正式控制律。米诺斯基当时正在为美国海军研究和设计自动船舶转向系统,他的分析基于对舵手的观察。

他指出,舵手不仅根据当前航向误差,还根据过去的误差以及当前的变化率来驾驶船舶;然后 Minorsky 对此进行了数学处理。他的目标是稳定,而不是一般控制,这大大简化了问题。

1933年,TIC(泰勒仪器公司)实现了完全可调节的前气动控制器。几年后,控制工程师通过将末端返回到一些假值,直到误差不为零,消除了比例控制器中发现的稳态误差。这个返回包含了误差,这被称为比例积分控制器。

1940年,第一个气动PID控制器通过导数动作开发,以减少超调问题。

1942年,Ziegler & Nichols引入了调谐规则,由工程师发现和设置PID控制器的合适参数。

20世纪50年代中期,自动PID控制器在工业上得到了广泛的应用。工业中大多数现代 PID 控制都是作为DCS、PLC 或单片机程序来实现的。

1.3 应用

•火箭的姿态控制

•无人机悬停控制等

•相机稳定器、相机云台

•平衡小车

•汽车的定速巡航控制、转向控制

•发动机转速控制

•3D打印机上的温度控制器

•工业自动化领域,大约95%的闭环操作使用PID控制器。

1.4 与 ON/OFF 型控制器对比

像PID控制器这样的闭环系统包括一个反馈控制系统。该系统利用一个固定点对反馈变量进行评估,从而产生误差信号。在此基础上,它改变系统输出。这个过程将继续,直到误差达到零,否则反馈变量的值就等于一个固定点。

与ON/OFF型控制器相比,该控制器提供了良好的效果。在开/关型控制器中,只需两个条件即可管理系统。大多数暖通空调系统、冰箱都采用这种方法。

例如,在冰箱中,它会冷却内部直到达到所需温度,然后关闭冷却器,直到达到高于所需温度的设定值。一旦工艺值低于固定点,则开启。

类似地,一旦该值高于固定值,它将关闭。这种控制器的输出不稳定,在不动点的区域内振荡频繁。然而,与ON/OFF型控制器相比,PID 控制器更加稳定和准确。

34f4492c-7bf5-11ee-939d-92fbcf53809c.png

1.6 响应类型

由PID控制器驱动的系统通常具有三种类型的响应:欠阻尼、过阻尼和临界阻尼

35010a5e-7bf5-11ee-939d-92fbcf53809c.png

3505b04a-7bf5-11ee-939d-92fbcf53809c.gif

•欠阻尼响应在稳定之前围绕参考值振荡。

•过阻尼响应上升缓慢并且不会超过参考值。

•临界阻尼响应具有最快的上升时间,且不会超过参考值。

公式

2.1 PID 系统定义与公式

35098cd8-7bf5-11ee-939d-92fbcf53809c.png

r(t) setpoint, reference,是期望的过程值或设定值(SP);

y(t) output, process variable,是测量的过程值,输出值(PV);

e(t) error,是偏差;

u(t) control effort,是控制量;

PID控制器的显着特点是能够利用比例、积分和微分这三个控制项对控制器输出的影响来进行精确和最优的控制。

PID 控制器,不断计算误差值e(t) 作为所需设定点之间的差异SP=r(t) 和测量的过程变量PV=y(t):e(t)=r(t)−y(t) ,并应用基于比例、积分和导数项的修正。

控制器尝试通过调整控制变量来最小化随时间变化的误差u(t)。manipulated variable (MV)。

351e9b14-7bf5-11ee-939d-92fbcf53809c.png

3531bd0c-7bf5-11ee-939d-92fbcf53809c.png

3540ddfa-7bf5-11ee-939d-92fbcf53809c.png

2.2 PID 数字公式

由于计算机控制是一种采样控制,它只能根据采样时刻的偏差计算控制量,而不能像模拟控制那样连续输出控制量,进行连续控制。由于这一特点,(式 1-1)中的积分项和微分项不能直接使用,必须进行离散化处理。

离散化处理的方法为:以τ作为采样周期,k作为采样序号,则离散采样时间kτ对应着连续时间t,用矩形法数值积分近似代替积分,用一阶后向差分近似代替微分,可作如下近似变换:

354e672c-7bf5-11ee-939d-92fbcf53809c.png

2.3 位置式 PID 算法

将(式 2-1)代入(式 1-1),就可以得到离散的 PID 表达式为

3555cae4-7bf5-11ee-939d-92fbcf53809c.png

将(式 2-1)代入(式 1-2),就可以得到离散的PID 表达式为

3559f6a0-7bf5-11ee-939d-92fbcf53809c.png

积分系数、微分系数做如下替换:

注意:必须使τ为定值,或者变化小到可以忽略,这样P、I、D才是固定常数,才可能调节

35618780-7bf5-11ee-939d-92fbcf53809c.png357065de-7bf5-11ee-939d-92fbcf53809c.png

2.4 增量式 PID 算法

357d1d74-7bf5-11ee-939d-92fbcf53809c.png

增量式 PID 控制算法可以通过(式 2-2)推导出。由(式 2-2)可以得到控制器的第 k-1 个采样时刻的输出值为:

35901f5a-7bf5-11ee-939d-92fbcf53809c.png

由(式 2-3)可以得到控制器的第 k-1 个采样时刻的输出值为:

359a381e-7bf5-11ee-939d-92fbcf53809c.png

用(式 2-3)减去(式 2-7)相减并整理,就可以得到增量式 PID 控制算法公式:

35a18e34-7bf5-11ee-939d-92fbcf53809c.png

由(式 2-8)可以看出,如果计算机控制系统采用恒定的采样周期τ,一旦确定 A、 B、 C,只要使用前后三次测量的偏差值,就可以由(式 2-8)求出控制量。

增量式 PID 控制算法与位置式 PID 算法(式 2-3)相比,只需要保持当前时刻以前三个时刻的偏差值即可,累计误差较小,计算量小的多,因此在实际中得到广泛的应用。

而位置式 PID 控制算法也可以通过增量式控制算法推出递推计算公式:

35a5b5c2-7bf5-11ee-939d-92fbcf53809c.png

(式 2-9)就是目前在计算机控制中广泛应用的数字递推 PID 控制算法。

调试技巧

35b0c1ce-7bf5-11ee-939d-92fbcf53809c.gif

代码实现


python


import numpy as np

import matplotlib.pyplot as plt



class PositionPID(object):

  """位置式PID算法实现"""



  def __init__(self, target, cur_val, dt, max, min, p, i, d) -> None:

    self.dt = dt # 循环时间间隔

    self._max = max # 最大输出限制,规避过冲

    self._min = min # 最小输出限制

    self.k_p = p # 比例系数

    self.k_i = i # 积分系数

    self.k_d = d # 微分系数



    self.target = target # 目标值

    self.cur_val = cur_val # 算法当前PID位置值,第一次为设定的初始位置

    self._pre_error = 0 # t-1 时刻误差值

    self._integral = 0 # 误差积分值





  def calculate(self):

    """

    计算t时刻PID输出值cur_val

    """

    error = self.target - self.cur_val # 计算当前误差

    # 比例项

    p_out = self.k_p * error 

    # 积分项

    self._integral += (error * self.dt)

    i_out = self.k_i * self._integral

    # 微分项

    derivative = (error - self._pre_error) / self.dt

    d_out = self.k_d * derivative



    # t 时刻pid输出

    output = p_out + i_out + d_out



    # 限制输出值

    if output > self._max:

      output = self._max

    elif output < self._min:

            output = self._min

        

        self._pre_error = error

        self.cur_val = output

        return self.cur_val



    def fit_and_plot(self, count = 200):

        """

        使用PID拟合setPoint

        """

        counts = np.arange(count)

        outputs = []



        for i in counts:

            outputs.append(self.calculate())

            print('Count %3d: output: %f' % (i, outputs[-1]))



        print('Done')

        # print(outputs)

        

        plt.figure()

        plt.axhline(self.target, c='red')

        plt.plot(counts, np.array(outputs), 'b.')

        plt.ylim(min(outputs) - 0.1 * min(outputs), max(outputs) + 0.1 * max(outputs))

        plt.plot(outputs)

        plt.show()



pid = PositionPID(10, -5, 0.5, 100, -100, 0.2, 0.1, 0.01)

pid.fit_and_plot(150)


92bc30d4babd87bea5c7ab6673aec5c0_wKgZomVIQTKADgw4AAEiki3ksPM572.png

c/c++


//首先定义PID结构体用于存放一个PID的数据

typedef struct

{

   float kp,ki,kd;//三个系数

  float error,lastError;//误差、上次误差

  float integral,maxIntegral;//积分、积分限幅

  float output,maxOutput;//输出、输出限幅

}PID;

 

//用于初始化pid参数的函数

void PID_Init(PID *pid,float p,float i,float d,float maxI,float maxOut)

{

  pid->kp=p;

  pid->ki=i;

  pid->kd=d;

  pid->maxIntegral=maxI;

  pid->maxOutput=maxOut;

}

 

//进行一次pid计算

//参数为(pid结构体,目标值,反馈值),计算结果放在pid结构体的output成员中

void PID_Calc(PID *pid,float reference,float feedback)

{

  //更新数据

  pid->lastError=pid->error;//将旧error存起来

  pid->error=reference-feedback;//计算新error

  //计算微分

  float dout=(pid->error-pid->lastError)*pid->kd;

  //计算比例

  float pout=pid->error*pid->kp;

  //计算积分

  pid->integral+=pid->error*pid->ki;

  //积分限幅

  if(pid->integral > pid->maxIntegral) pid->integral=pid->maxIntegral;

  else if(pid->integral < -pid->maxIntegral) pid->integral=-pid->maxIntegral;

  //计算输出

  pid->output=pout+dout+pid->integral;

  //输出限幅

  if(pid->output > pid->maxOutput) pid->output=pid->maxOutput;

  else if(pid->output < -pid->maxOutput) pid->output=-pid->maxOutput;

}

 

PID mypid;//创建一个PID结构体变量

 

int main()

{

  //...这里有些其他初始化代码

  PID_Init(&mypid,10,1,5,800,1000);//初始化PID参数

  while(1)//进入循环运行

  {

    float feedbackValue=...;//这里获取到被控对象的反馈值

    float targetValue=...;//这里获取到目标值

    PID_Calc(&mypid,targetValue,feedbackValue);//进行PID计算,结果在output成员变量中

    设定执行器输出大小(mypid.output);

    delay(10);//等待一定时间再开始下一次循环

  }

}


单环效果

35df68f8-7bf5-11ee-939d-92fbcf53809c.gif

35fd9314-7bf5-11ee-939d-92fbcf53809c.png


串级PID的C语言代码


//此处需要插入上面的单级PID相关代码

 

//串级PID的结构体,包含两个单级PID

typedef struct

{

  PID inner;//内环

  PID outer;//外环

  float output;//串级输出,等于inner.output

}CascadePID;

 

//串级PID的计算函数

//参数(PID结构体,外环目标值,外环反馈值,内环反馈值)

void PID_CascadeCalc(CascadePID *pid,float outerRef,float outerFdb,float innerFdb)

{

  PID_Calc(&pid->outer,outerRef,outerFdb);//计算外环

  PID_Calc(&pid->inner,pid->outer.output,innerFdb);//计算内环

  pid->output=pid->inner.output;//内环输出就是串级PID的输出

}

 

CascadePID mypid;//创建串级PID结构体变量

 

int main()

{

  //...其他初始化代码

  PID_Init(&mypid.inner,10,0,0,0,1000);//初始化内环参数

  PID_Init(&mypid.outer,5,0,5,0,100);//初始化外环参数

  while(1)//进入循环运行

  {

    float outerTarget=...;//获取外环目标值

    float outerFeedback=...;//获取外环反馈值

    float innerFeedback=...;//获取内环反馈值

    PID_CascadeCalc(&mypid,outerTarget,outerFeedback,innerFeedback);//进行PID计算

    设定执行机构输出大小(mypid.output);

    delay(10);//延时一段时间

  }

}


双环效果

360af194-7bf5-11ee-939d-92fbcf53809c.gif

双环控制

串联

如果电机控制既要控制速度又要控制位置,因为速度和位置相关,所以需要串联。

3613d250-7bf5-11ee-939d-92fbcf53809c.png

并联

姿态角度与速度间无相关性,各自单独算一路控制

36183444-7bf5-11ee-939d-92fbcf53809c.png

示例

循迹小车

可见小车的循迹效果。

野火中步进电机位置速度双环控制

步进电机速度环控制实现和 10. 步进电机位置环控制实现介绍了单环控制已经能很好地提高电机的性能了,但是仍有其局限性。

使用速度环精确控制了电机的转速,但是停止的位置难以精确控制;

使用位置环精确控制了电机转过的角度,却不得不人为限制速度来防止堵转。

位置环和速度环双环控制,既实现位置的精确调节又实现速度的自动控制。

3627684c-7bf5-11ee-939d-92fbcf53809c.png

该控制下,编码器不仅起到了反馈位置的作用,也起到了反馈速度的作用。

调参技巧:在PID参数整定时,采取先内环再外环的方法,也就是先单独使用速度环控制,得到满意的参数后, 再把位置环套在外面,整定位置环参数,最后根据整体效果对速度环参数进行微调。


bsp_pid.h


/*pid*/

typedef struct

{

 float target_val;   //目标值

 float actual_val;   //实际值

 float err;      //定义当前偏差值

 float err_next;    //定义下一个偏差值

 float err_last;    //定义上一个偏差值

 float Kp, Ki, Kd;   //定义比例、积分、微分系数

}_pid;

bsp_stepper_ctrl.h


/*宏定义*/

/*******************************************************/

#define TIM_STEP_FREQ   (SystemCoreClock/TIM_PRESCALER) // 频率ft值



/*电机单圈参数*/

#define STEP_ANGLE             1.8f         //步进电机的步距角 单位:度

#define FSPR       (360.0f/STEP_ANGLE) //步进电机的一圈所需脉冲数



#define MICRO_STEP    32                     //细分器细分数

#define SPR        (FSPR*MICRO_STEP)  //细分后一圈所需脉冲数



#define PULSE_RATIO    (float)(SPR/ENCODER_TOTAL_RESOLUTION)//步进电机单圈脉冲数与编码器单圈脉冲的比值

#define SAMPLING_PERIOD  50          //PID采样频率,单位Hz



#define MOVE_CTRL     0.1f          //启用速度环控制量

#define TARGET_DISP    20          //步进电机运动时的目标圈数,单位:转

#define TARGET_SPEED_MAX 800         // 目标速度的最大值



typedef struct {

 unsigned char stepper_dir : 1;        //步进电机方向

 unsigned char stepper_running : 1;      //步进电机运行状态

 unsigned char MSD_ENA : 1;          //驱动器使能状态

}__SYS_STATUS;

bsp_stepper_ctrl.c-增量式PID算法实现-增量式PID


/**

  * @brief 增量式PID算法实现

  * @param val:当前实际值

  * @note  无

  * @retval 通过PID计算后的输出

  */

 float PID_realize(_pid *pid, float temp_val)

{

  /*传入实际值*/

  pid->actual_val = temp_val;

  /*计算目标值与实际值的误差*/

  pid->err=pid->target_val-pid->actual_val;



  /*PID算法实现*/

  float increment_val = pid->Kp*(pid->err - pid->err_next) + pid->Ki*pid->err + pid->Kd*(pid->err - 2 * pid->err_next + pid->err_last);

[1] [2]
关键字:嵌入式  PID算法  控制器 引用地址:什么是嵌入式PID算法?嵌入式PID算法分析

上一篇:低压断路器选型的一般原则
下一篇:SIMATIC S7-1500 PLC与ET200MP的PROFIBUS-DP通信

推荐阅读最新更新时间:2024-11-08 18:42

飞思卡尔扩大Kinetis微控制器在安全领域的领导地位
飞思卡尔为市场提供的最安全ARM Cortex M级MCU实现量产,是新一代mPOS应用的新系列节能产品 飞思卡尔半导体(NYSE:FSL)日前宣布在全球批量供货其Kinetis K8x微控制器系列,这是业界基于ARM Cortex -M技术最安全的微控制器。该公司还推出了引脚兼容的Kinetis KL8x系列,该系列保留了许多相同的世界级安全功能,同时利用ARM Cortex -M0 +内核的节能高效,满足POS产品等安全移动应用的需求。 IHS研究院表示:随着消费者支持简单易用和便捷的无现金非接触式支付,全球零售商继续投资电子移动POS(mPOS)解决方案,预计该市场到2018年将增长至超过8000万台
[单片机]
意法半导体开始量产STM32 F0系列入门型微控制器
中国,2012年5月15日 ——横跨多重电子应用领域、全球领先的半导体供应商、世界领先的微控制器制造商意法半导体(STMicroelectronics,简称ST;纽约证券交易所代码:STM)开始量产STM32 F0系列32位微控制器。设计目标是彻底消除8位/16位微控制器在应用上的局限性,性能差距。 意法半导体还推出一套叫做探索套件的STM32F0专用评估板,依托规模庞大的STM32开发生态系统,现在,工程师采用意法半导体的ARM®Cortex™-M0微控制器开发应用万事俱备,能够轻松地将其应用到成本敏感型消费电子和工业产品中。 意法半导体微控制器产品部经理Michel Buffa表示:“现在,STM32 F0系列已进入量产阶
[单片机]
嵌入式系统硬件抽象层的原理与实现
    摘要: 板级支持包(BSP)是嵌入式系统中常用的硬件抽象形式,是介于操作系统和硬件之间的软件层次。介绍BSP的功能和特点,并结合工作实践提出了设计BSP的一般方法;最后针对当前嵌入式系统中BSP的设计方法所面临的问题提出了可行的解决办法。     关键词: 嵌入式系统 嵌入式实时操作系统(RTOS) 硬件抽象层(HAL) 板级支持包(BSP) 随着计算机硬件技术的快速发展,出现了越来越多的便携设备和智能设备。这些设备中通常包含控制用的CPU和相应的操作系统;这类特殊的计算机系统叫做嵌入式实时系统。嵌入式实时系统以其简洁高效等特点在计算机、通信等领域中广泛使用。 由于嵌入式实时系统应用环境的特
[嵌入式]
威盛发布搭载Qualcomm® Snapdragon™ 820E嵌入式平台AI开发套件
针对需要视频处理的人工智能应用进行优化,加快人工智能系统和设备的上市时间 2018年5月15日北京讯—威盛电子股份有限公司今日宣布推出最新的威盛Edge AI人工智能开发套件。这是一款高度集成Qualcomm® Snapdragon™ 820E嵌入式平台,降低了设计,测试和部署人工智能系统和设备的成本和复杂性。 该套件将威盛SOM-9X20 SOM模块和SOMDB2载板与13MP摄像头模块相结合,针对智能实时视频采集,处理和边缘分析进行了优化。 Android 8.0 BSP支持Edge AI应用程序开发,包括对Snapdragon神经处理引擎(NPE)的支持、Qualcomm® Hexagon™ DSP的全面加速
[物联网]
威盛发布搭载Qualcomm® Snapdragon™ 820E<font color='red'>嵌入式</font>平台AI开发套件
GSMA持续关注物联网,高通公司获嵌入式移动模块大奖
物联网产业正被各界关注。日前,全球移动通信系统协会(GSMA)在亚洲移动通信大会期间颁布嵌入式移动模块大赛获奖名单,高通公司IEM6270荣获3G领域该项大奖。 资料显示,从去年开始,GSMA开始在亚洲移动通信大会期间设立嵌入式移动模块大赛,旨在激励健康、公共事业、汽车、消费电子等关键垂直行业进行嵌入式移动设备及服务的创新,帮助增加全球连接设备的数量。 据了解,今年该奖项由沃达丰、Orange、AT&T、意大利电信、韩国电信 和 Smart Communications等移动运营商共同评出,吸引了全球M2M 嵌入式模块供应商参加2G/3G两大领域评选,最终有18种模块入围。 “今年的角逐非常激烈,大多
[网络通信]
展示嵌入式最新成果 促进交流共谋发展
  以交流促合作,以合作求发展——10月17日于北京举办的第五届嵌入式技术应用高峰论坛大打交流牌,本届峰会组委会特别组织了英特尔与联强国际、奥吉通与MOXA互动交流环节。本届峰会立足中国,面向世界,致力于推动嵌入式技术的国际交流、两岸交流、国内交流,促成产业自动化、智能化、信息化领域的不断发展。   本届峰会是国内最富权威的嵌入式会议,由中国计算机用户协会、中国计算机学会嵌入式系统专业委员会主办;研祥智能科技股份有限公司、奥吉通公司承办;英特尔(中国)有限公司、微软(中国)有限公司、MOXA科技、联强国际联合支持。   届时,研祥将邀请国内业界知名专家到会,中国计算机用户协会理事长陈正清、中国自动化学会秘书长王春恒、中国计算机
[焦点新闻]
基于嵌入式ARM处理器的M2M终端总体设计
引言 目前,对输油管道、电力装置、油井等进行远程监控主要采用人工巡逻的方式,这种方式存在实时性差、成本高、浪费人力资源、无法对环境恶劣的地区进行监控、可能出现误报等缺点。随着工业领域现代化水平的提高和通信技术的发展,这种生产方式亟待得到改善。 M2M是指应用无线移动通信技术,实现机器与机器、机器与人之间数据通信和交流的一系列技术及其组合的总称。GPRS具有覆盖地域广、通信距离远、网络 可靠性高等优点。随着GPRS的推广和应用,以及基于GPRS的M2M产品的推出,采用GPRS技术来解决上述问题成为一种较好的方案。 嵌入式系统是当前国内外研究的热点之一。采用嵌入式系统技术设计一种可以解决远程监控领域数据传输
[单片机]
基于<font color='red'>嵌入式</font>ARM处理器的M2M终端总体设计
嵌入式学习之Nand Flash
Nand Flash是flash存储器的一种,其内部采用非线性宏单元模式,为固态大容量内存的实现提供了廉价有效的解决方案。Nand Flash存储器具有容量较大,改写速度快等优点,适用于大量数据的存储,因而在业界得到了越来越广泛的应用,如嵌入式产品中包括数码相机、MP3随身听 记忆卡、体积小巧的U盘等。NAND型闪存以块为单位进行擦除操作。闪存的写入操作必须在空白区域进行,如果目标区域已经有数据,必须先擦除后写入,因此 擦除操作是闪存的基本操作。 S3C2410的Nand Flash控制器有一个特殊的功能,在S3C2410上电后,NandFlash控制器会自动的把Nand Flash上的前4K数据搬移到4K内部SRAM中,并把
[单片机]
<font color='red'>嵌入式</font>学习之Nand Flash
小广播
最新嵌入式文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved