找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3681|回复: 0
打印 上一主题 下一主题
收起左侧

PID控制智能小车C语言算法实现

[复制链接]
跳转到指定楼层
楼主
ID:377596 发表于 2019-1-24 13:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在过程控制中,按偏差的比例(P)、积分(I)和微分(D)进行控制的PID控制器(亦称PID调节器)是应用最为广泛的一种自动控制器。它具有原理简单,易于实现,适用面广,控制参数相互独立,参数的选定比较简单等优点;而且在理论上可以证明,对于过程控制的典型对象──“一阶滞后+纯滞后”与“二阶滞后+纯滞后”的控制对象,PID控制器是一种最优控制。PID调节规律是连续系统动态品质校正的一种有效方法,它的参数整定方式简便,结构改变灵活(PI、PD、…)。
参数的选择:
   ①比例系数P对系统性能的影响:比例系数加大,使系统的动作灵敏,速度加快,稳态误差减小;P偏大,振荡次数加多,调节时间加长;P太大时,系统会趋于不稳定;P太小,又会使系统的动作缓慢。P可以选负数,这主要是由执行机构、传感器以及控制对象的特性决定的。如果P的符号选择不当对象测量值就会离控制目标的设定值越来越远,如果出现这样的情况P的符号就一定要取反。同时要注意的是,力控的策略控制器的PID控制块的P参数是PID控制中的增益。
  ②积分控制I对系统性能的影响:积分作用使系统的稳定性下降,I小(积分作用强)会使系统不稳定,但能消除稳态误差,提高系统的控制精度。
  ③微分控制D对系统性能的影响:微分作用可以改善动态特性,D偏大时,超调量较大,调节时间较短;D偏小时,超调量也较大,调节时间也较长;只有D合适,才能使超调量较小,减短调节时间。

C语言实现PID算法:
  1. #include <stdio.h>
  2. #include<math.h>
  3.   struct _pid {
  4.    int pv; /*integer that contains the process value*/
  5.    int sp; /*integer that contains the set point*/
  6.    float integral;
  7.    float pgain;
  8.    float igain;
  9.    float dgain;
  10.    int deadband;
  11.    int last_error;
  12.   };
  13.   struct _pid warm,*pid;
  14.   int process_point, set_point,dead_band;
  15.   float p_gain, i_gain, d_gain, integral_val,new_integ;;
  16.   pid_init
  17.   DESCRIPTION This function initializes the pointers in the _pid structure
  18.   to the process variable and the setpoint. *pv and *sp are
  19.   integer pointers.
  20.   void pid_init(struct _pid *warm, int process_point, int set_point)
  21.   {
  22.    struct _pid *pid;
  23.    pid = warm;
  24.    pid->pv = process_point;
  25.    pid->sp = set_point;
  26.   }   
  27.   pid_tune  
  28.   DESCRIPTION Sets the proportional gain (p_gain), integral gain (i_gain),
  29.   derivitive gain (d_gain), and the dead band (dead_band) of
  30.   a pid control structure _pid.
  31.   void pid_tune(struct _pid *pid, float p_gain, float i_gain, float d_gain, int dead_band)
  32.   {
  33.    pid->pgain = p_gain;
  34.    pid->igain = i_gain;
  35.    pid->dgain = d_gain;
  36.    pid->deadband = dead_band;
  37.    pid->integral= integral_val;
  38.    pid->last_error=0;
  39.   }      
  40. pid_setinteg
  41.     DESCRIPTION Set a new value for the integral term of the pid equation.
  42.   This is useful for setting the initial output of the
  43.   pid controller at start up.  
  44.   void pid_setinteg(struct _pid *pid,float new_integ)
  45.   {
  46.    pid->integral = new_integ;
  47.    pid->last_error = 0;
  48.   }      pid_bumpless
  49.   DESCRIPTION Bumpless transfer algorithim. When suddenly changing
  50.   setpoints, or when restarting the PID equation after an
  51.   extended pause, the derivative of the equation can cause
  52.   a bump in the controller output. This function will help
  53.   smooth out that bump. The process value in *pv should
  54.   be the updated just before this function is used.
  55.     void pid_bumpless(struct _pid *pid)
  56.   {   
  57.    pid->last_error = (pid->sp)-(pid->pv);   
  58.   }
  59. pid_calc   
  60.   DESCRIPTION Performs PID calculations for the _pid structure *a. This function uses the positional form of the pid equation, and incorporates an integral windup prevention algorithim. Rectangular integration is used, so this function must be repeated on a consistent time basis for accurate control.
  61.   
  62.   RETURN VALUE The new output value for the pid loop.   
  63.   USAGE #include "control.h"*/   
  64.   float pid_calc(struct _pid *pid)  {
  65.    int err;
  66.    float pterm, dterm, result, ferror;
  67.      err = (pid->sp) - (pid->pv);
  68.    if (abs(err) > pid->deadband)   {
  69.    ferror = (float) err; /*do integer to float conversion only once*/
  70.    pterm = pid->pgain * ferror;
  71.    if (pterm > 100 || pterm < -100)   {
  72.    pid->integral = 0.0;   }
  73.    else   {
  74.    pid->integral += pid->igain * ferror;
  75.    if (pid->integral > 100.0)
  76.    {
  77.    pid->integral = 100.0;   }
  78.    else if (pid->integral < 0.0) pid->integral = 0.0;   }
  79.    dterm = ((float)(err - pid->last_error)) * pid->dgain;
  80.    result = pterm + pid->integral + dterm;   }
  81.    else result = pid->integral;
  82.    pid->last_error = err;
  83.    return (result);  }
  84.   
  85. void main(void)
  86.   {
  87.    float display_value;
  88.    int count=0;
  89.   
  90.    pid = &warm;
  91.   
  92.   // printf("Enter the values of Process point, Set point, P gain, I gain, D gain \n");
  93.   // scanf("%d%d%f%f%f", &process_point, &set_point, &p_gain, &i_gain, &d_gain);  
  94.    process_point = 30;
  95.    set_point = 40;
  96.    p_gain = (float)(5.2);
  97.    i_gain = (float)(0.77);
  98.    d_gain = (float)(0.18);
  99.     
  100.    dead_band = 2;
  101.    integral_val =(float)(0.01);
  102.     
  103.    printf("The values of Process point, Set point, P gain, I gain, D gain \n");
  104.    printf(" %6d %6d %4f %4f %4f\n", process_point, set_point, p_gain, i_gain, d_gain);
  105.   
  106.    printf("Enter the values of Process point\n");
  107.   
  108.    while(count<=20)
  109.    {  
  110.    scanf("%d",&process_point);  
  111.    pid_init(&warm, process_point, set_point);
  112.    pid_tune(&warm, p_gain,i_gain,d_gain,dead_band);
  113.    pid_setinteg(&warm,0.0); //pid_setinteg(&warm,30.0);
  114.   
  115.    //Get input value for process point
  116.    pid_bumpless(&warm);
  117.   
  118.    // how to display output
  119.    display_value = pid_calc(&warm);
  120.    printf("%f\n", display_value);
  121.    //printf("\n%f%f%f%f",warm.pv,warm.sp,warm.igain,warm.dgain);
  122.    count++;  
  123.    }
复制代码

全部资料51hei下载地址:
PID控制智能小车.doc (32 KB, 下载次数: 28)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表