找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 43566|回复: 62

NXC下用PID算法巡线——算法初步验证成功

 火.. [复制链接]
发表于 2011-2-6 09:44:18 | 显示全部楼层 |阅读模式
本帖最后由 grant7788 于 2011-2-7 00:07 编辑

呵呵,标题党... 因为我试验还没做呢。此帖作为记录帖吧,边写边做。
顶楼留作目录。

1. PID算法通俗解释
2. PID算法解释
3. PID算法巡线例程
4. 试验
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
 楼主| 发表于 2011-2-6 09:46:06 | 显示全部楼层

网上搜到的两个PID算法的通俗解释

解释1:
制模型:你控制一个人让他以PID控制的方式走110步后停下。
(1)P比例控制,就是让他走110步,他按照一定的步伐走到一百零几步(如108步)或100多步(如112步)就停了。
说明:
P比例控制是一种最简单的控制方式。其控制器的输出与输入误差信号成比例关系。当仅有比例控制时系统输出存在稳态误差(Steady-state error)。

(2)PI积分控制,就是他按照一定的步伐走到112步然后回头接着走,走到108步位置时,然后又回头向110步位置走。在110步位置处来回晃几次,最后停在110步的位置。
说明:
在积分I控制中,控制器的输出与输入误差信号的积分成正比关系。对一个自动控制系统,如果在进入稳态后存在稳态误差,则称这个控制系统是有稳态误差的或简称有差系统(System with Steady-state Error)。为了消除稳态误差,在控制器中必须引入“积分项”。积分项对误差取决于时间的积分,随着时间的增加,积分项会增大。这样,即便误差很小,积分项也会随着时间的增加而加大,它推动控制器的输出增大使稳态误差进一步减小,直到等于零。因此,比例+积分(PI)控制器,可以使系统在进入稳态后无稳态误差。

(3)PD微分控制,就是他按照一定的步伐走到一百零几步后,再慢慢地向110步的位置靠近,如果最后能精确停在110步的位置,就是无静差控制;如果停在110步附近(如109步或111步位置),就是有静差控制。
说明:
在微分控制D中,控制器的输出与输入误差信号的微分(即误差的变化率)成正比关系。
自动控制系统在克服误差的调节过程中可能会出现振荡甚至失稳,其原因是由于存在有较大惯性组件(环节)或有滞后(delay)组件,具有抑制误差的作用,其变化总是落后于误差的变化。解决的办法是使抑制误差作用的变化“超前”,即在误差接近零时,抑制误差的作用就应该是零。这就是说,在控制器中仅引入“比例P”项往往是不够的,比例项的作用仅是放大误差的幅值,而目前需要增加的是“微分项”,它能预测误差变化的趋势。这样,具有比例+微分的控制器,就能够提前使抑制误差的控制作用等于零,甚至为负值,从而避免了被控量的严重超调。所以对有较大惯性或滞后的被控对象,比例P+微分D(PD)控制器能改善系统在调节过程中的动态特性。




解释2:
  小明接到这样一个任务:有一个水缸有点漏水(而且漏水的速度还不一定固定不变),要求水面高度维持在某个位置,一旦发现水面高度低于要求位置,就要往水缸里加水。 小明接到任务后就一直守在水缸旁边,时间长就觉得无聊,就跑到房里看小说了,每30分钟来检查一次水面高度。水漏得太快,每次小明来检查时,水都快漏完了,离要求的高度相差很远,小明改为每3分钟来检查一次,结果每次来水都没怎么漏,不需要加水,来得太频繁做的是无用功。几次试验后,确定每10分钟来检查一次。这个检查时间就称为采样周期。
  开始小明用瓢加水,水龙头离水缸有十几米的距离,经常要跑好几趟才加够水,于是小明又改为用桶加,一加就是一桶,跑的次数少了,加水的速度也快了,但好几次将缸给加溢出了,不小心弄湿了几次鞋,小明又动脑筋,我不用瓢也不用桶,老子用盆,几次下来,发现刚刚好,不用跑太多次,也不会让水溢出。这个加水工具的大小就称为比例系数。
  小明又发现水虽然不会加过量溢出了,有时会高过要求位置比较多,还是有打湿鞋的危险。他又想了个办法,在水缸上装一个漏斗,每次加水不直接倒进水缸,而是倒进漏斗让它慢慢加。这样溢出的问题解决了,但加水的速度又慢了,有时还赶不上漏水的速度。于是他试着变换不同大小口径的漏斗来控制加水的速度,最后终于找到了满意的漏斗。漏斗的时间就称为积分时间。
  小明终于喘了一口,但任务的要求突然严了,水位控制的及时性要求大大提高,一旦水位过低,必须立即将水加到要求位置,而且不能高出太多,否则不给工钱。小明又为难了!于是他又开努脑筋,终于让它想到一个办法,常放一盆备用水在旁边,一发现水位低了,不经过漏斗就是一盆水下去,这样及时性是保证了,但水位有时会高多了。他又在要求水面位置上面一点将水缸要求的水平面处凿一孔,再接一根管子到下面的备用桶里这样多出的水会从上面的孔里漏出来。这个水漏出的快慢就称为微分时间。 看到几个问采样周期的帖子,临时想了这么个故事。微分的比喻一点牵强,不过能帮助理解就行了,呵呵,入门级的,如能帮助新手理解下PID,于愿足矣。故事中小明的试验是一步步独立做,但实际加水工具、漏斗口径、溢水孔的大小同时都会影响加水的速度,水位超调量的大小,做了后面的实验后,往往还要修改改前面

如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2011-2-6 09:48:49 | 显示全部楼层

[转帖]PID算法解释

原帖来自中电网:http://blog.eccn.com/space.php?uid=353091&do=blog&id=3964
很多同学都不清楚PID是个什么东西,因为很多不是自动化的学生。他们开口就要资料,要程序。
这是明显的学习方法不对,起码,首先,你要理解PID是个什么东西。
本文以通俗的理解,以小车纵向控制举例说明PID的一些理解。
首先,为什么要做PID?
由于外界原因,小车的实际速度有时不稳定,这是其一,
要让小车以最快的时间达达到既定的目标速度,这是其二。
速度控制系统是闭环,才能满足整个系统的稳定要求,必竟速度是系统参数之一,这是其三.
    小车调速肯定不是线性的,外界因素那么多,没人能证明是线性的。如果是线性的,直接用P就可以了。
比如在PWM=60%时,速度是2M/S,那么你要它3M/S,就把PWM提高到90%。因为90/60=3/2,这样一来太完美了。
完美是不可能的。
    那么不是线性的,要怎么怎么控制PWM使速度达到即定的速度呢?即要快,又要准,又要狠。(即快准狠
)系统这个速度的调整过程就必须通过某个算法调整,一般PID就是这个所用的算法。
    可能你会想到,如果通过编码器测得现在的速度是2.0m/s,要达到2.3m/s的速度,那么我把pwm增大一点不
就行了吗?是的,增大pwm多少呢?必须要通过算法,因为PWM和速度是个什么关系,对于整个系统来说,谁也
不知道。要一点一点的试,加个1%,不够,再加1%还是不够,那么第三次你还会加1%吗?很有可能就加2%了。
通过PID三个参数得到一个表达式:△PWM=a *△V1+b *△V2+c *△V3,a b c是通过PID的那个长长的公式展开
,然后约简后的数字,△V1 ,△V2 ,△V3 此前第一次调整后的速度差 ,第二次调整后的速度差,第三次。。
。。。一句话,PID要使当前速度达到目标速度最快,需要建立如何调整pwm和速度之间的关系。

输入输出是什么:
输入就是前次速度,前前次速度,前前前次速度。
输出就是你的PWM应该增加或减小多少。


为了避免教科书公式化的说明,本文用口语化和通俗的语言描述。虽然不一定恰当,但意思差不多,就是那个事。如果要彻头彻尾地弄PID,建议多调试,写几个仿真程序。

PID
一般有两种:位置式PID和增量式PID。在小车里一般用增量式,为什么呢?位置式PID输出与过去的所有状态有关,计算时要对e(每一次的控制误差)进行累加,这个计算量非常大,而明没有必要。而且小车的PID控制器的输出并不是绝对数值,而是一个△,代表增多少,减多少。换句话说,通过增量PID算法,每次输出是PWM要增加多少或者减小多少,而不是PWM的实际值。
下面均以增量式PID说明。
  这里再说一下P、I、D三个参数的作用。P=Proportion,比例的意思,IIntegral,积分,DDifferential微分。
打个比方,如果现在的输出是1,目标输出是100,那么P的作用是以最快的速度达到100,把P理解为一个系数即可;而I呢?大家学过高数的,0的积分才能是一个常数,I就是使误差为0而起调和作用;D呢?大家都知道微分是求导数,导数代表切线是吧,切线的方向就是最快到至高点的方向。这样理解,最快获得最优解,那么微分就是加快调节过程的作用了。
公式本来需要推导的,我就不来这一套了。直接贴出来:

看看最后的结果:
△Uk=A*e(k)+B*e(k-1)+C*e(k-2)
这里KP是P的值,TD是D的值,1/Ti是I的值,都是常数,哦,还有一个T,T是采样周期,也是已知。A
B
C
是由P I D换算来的,按这个公式,就可以简化计算量了,因为 P I D 是常数,那么A B C可以用一个宏表示。这样看来,只需要求e(k) e(k-1) e(k-2)就可以知道△Uk的值了,按照△Uk来调节PWM的大小就OK了。PID三个参数的确定有很多方法,不在本文讨论范围内。采样周期也是有据可依的,不能太大,也不能太小。
   ........................
   ........................
   写着写着成了老太婆的裹脚了,本来说拿个程序来说明一下,看来只能在下一文中了。

PID实际编程的过程的,要注意的东西还是有几点的。PID这东西可以做得很深。1 PID的诊定。凑试法,临界比例法,经验法。2 T的确定,采样周期应远小于过程的扰动信号的周期,在小车程序中一般是ms级别。3 目标速度何时赋值问题,如何更新新的目标速度?这个问题一般的人都乎略了。目标速度肯定不是个恒定的,那么何时改变目标速度呢?4 改变了目标速度,那么e(k) e(k-1) e(k-2)怎么改变呢?是赋0还是要怎么变?5 是不是PID要一直开着?6 error为多少时就可以当速度已达到目标?7 PID的优先级怎么处理,如果和图像采集有冲突怎么办?8 PID的输入是速度,输出是PWM,按理说PWM产生速度,但二者不是同一个东西,有没有问题?9 PID计算如何优化其速度?指针,汇编,移位?都可以试!
  1. //*****************************************************
  2. //定义PID结构体
  3. //*****************************************************
  4. typedef struct PID
  5. {
  6.     int SetPoint; //设定目标 Desired Value
  7.     double Proportion; //比例常数 Proportional Const
  8.     double Integral; //积分常数 Integral Const
  9.     double Derivative; //微分常数 Derivative Const
  10.     int LastError; //Error[-1]
  11.     int PrevError; //Error[-2]
  12. } PID;
  13. //*****************************************************
  14. //定义相关宏
  15. //*****************************************************
  16. #define P_DATA 100
  17. #define I_DATA  0.6
  18. #define D_DATA  1
  19. #define HAVE_NEW_VELOCITY 0X01
  20. //*****************************************************
  21. //声明PID实体
  22. //*****************************************************
  23. static PID sPID;
  24. static PID *sptr = &sPID;
  25. //*****************************************************
  26. //PID参数初始化
  27. //*****************************************************
  28. void IncPIDInit(void)
  29. {
  30. sptr->LastError = 0; //Error[-1]
  31. sptr->PrevError = 0; //Error[-2]
  32. sptr->Proportion = P_DATA; //比例常数 Proportional Const
  33. sptr->Integral = I_DATA; //积分常数Integral Const
  34. sptr->Derivative = D_DATA; //微分常数 Derivative Const
  35. sptr->SetPoint =100;  目标是100
  36. }
  37. //*****************************************************
  38. //增量式PID控制设计
  39. //*****************************************************
  40. int IncPIDCalc(int NextPoint)
  41. {
  42.    int iError, iIncpid; //当前误差
  43.    iError = sptr->SetPoint - NextPoint; //增量计算
  44.    iIncpid = sptr->Proportion * iError //E[k]项
  45.              - sptr->Integral * sptr->LastError //E[k-1]项
  46.              + sptr->Derivative * sptr->PrevError; //E[k-2]项
  47.     sptr->PrevError = sptr->LastError;   //存储误差,用于下次计算
  48.     sptr->LastError = iError;
  49.     return(iIncpid);                          //返回增量值
  50. }
  51. Int g_CurrentVelocity;
  52. Int g_Flag;

  53. void main(void)
  54. {
  55.     DisableInterrupt
  56. InitMCu();
  57.     IncPIDInit();
  58. g_CurrentVelocity=0;   //全局变量也初始化
  59. g_Flag=0;                //全局变量也初始化
  60. EnableInterrupt;
  61.      While(1)
  62. {
  63.    if (g_Flag& HAVE_NEW_VELOCITY)
  64.       {
  65.           PWMOUT+= IncPIDCalc(CurrentVelocity);
  66.             g_Flag&=~ HAVE_NEW_VELOCITY;
  67. }
  68. }
  69. }
  70. //****************************************
  71. //采样周期T
  72. //****************************************
  73. Interrrupt TIME void
  74. {
  75.    CurrentVelocity =GetCurrentVelocity;
  76.    g_Flag|= HAVE_NEW_VELOCITY;
  77. }
复制代码




如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2011-2-6 10:01:17 | 显示全部楼层

PID算法巡线例程

例程来自这里... 同时有小车的LDD图及程序代码下载。
http://www.techbricks.nl/My-NXT-projects/nxtlinefollower.html这段代码在论坛里看到过,不过不完整。

  1. /* Techbricks.nl Line Follower
  2.    Based on a PID controller, using the NXT 2.0 color sensor
  3.    NXC firmware 1.28
  4.    www.techbricks.nl
  5.    last modified 03/03/2010                                    */

  6. /* Proportional gain, straight forward reaction of the controller
  7.    Larger values typically mean faster response since the larger the error,
  8.    the larger the proportional term compensation.
  9.    An excessively large proportional gain will lead to process instability and oscillation.*/
  10. #define Kproportional 6

  11. /* Integral gain, improves the controller accuracy
  12.    Larger values imply steady state errors are eliminated more quickly.
  13.    The trade-off is larger overshoot: any negative error integrated during transient response
  14.    must be integrated away by positive error before reaching steady state.*/
  15. #define Kintegral 0.0002

  16. /* Derivative gain, improves the controller speed
  17.    Larger values decrease overshoot, but slow down transient response
  18.    and may lead to instability due to signal noise amplification in the differentiation of the error.*/
  19. #define Kderivative 100

  20. // Sample time, determined the reaction rate
  21. #define dt 25

  22. // NXT 2.0 Color sensor connected to port 2.
  23. #define COLORSENSOR SENSOR_2

  24. task main()
  25. {
  26. int error = 0;
  27. float previous_error = 0;
  28. float setpoint = 0;
  29. float actual_position = 0;
  30. float proportional = 0;
  31. int integral = 0;
  32. float derivative = 0;
  33. float output = 0;
  34. float left = 0;
  35. float right = 0;

  36. // Set the motor speed.
  37. float speed=50;

  38. // Set the color sensor light on.
  39. SetSensorColorFull(IN_2);

  40. // Read the value from the light sensor at the start position. The sensor must be place above the black line.
  41. TextOut(1,LCD_LINE1,"Setpoint");
  42. setpoint = COLORSENSOR;
  43. NumOut(50,LCD_LINE1,setpoint);

  44. // never ending loop.
  45. while (true)
  46.   {
  47.    // Read the actual color sensor value.
  48.    actual_position = COLORSENSOR;
  49.    TextOut(1,LCD_LINE2,"Actual");
  50.    NumOut(50,LCD_LINE2,actual_position);

  51.    // Calculate the error, the differance between the setpoint and actual position.
  52.    error = setpoint - actual_position;
  53.    // Play a sound when the sensor is off the line
  54.    if (error <> 0) PlayTone(TONE_B7, 1);

  55.    // Proportional term makes a change to the output that is proportional to the current error value.
  56.    proportional = Kproportional * error;

  57.    // Integrate, sum of errors
  58.    integral = integral + error;

  59.    // Derivative, rate of change of the process error is calculated by determining the slope of the error over time.
  60.    derivative = (error - previous_error) / dt;

  61.    // Calculate sum of Proportional, Integral and Derivative.
  62.    output = proportional + Kintegral * dt * integral + Kderivative * derivative;

  63.    // save error value for period.
  64.    previous_error = error;

  65.    // Controll left motor
  66.    left = speed - output;
  67.    
  68.    // Controll right motor
  69.    right = speed + output;

  70.    // Adjust the left and right motor value.
  71.    if (left >   100) left  =  100;
  72.    if (left <  -100) left  = -100;
  73.    if (right >  100) right =  100;
  74.    if (right < -100) right = -100;

  75.    if (left < 0 )
  76.      {
  77.       OnFwd(OUT_A,-left);
  78.       TextOut(1,LCD_LINE4,"Left  Rev");
  79.       NumOut(55,LCD_LINE4,-left);
  80.      }
  81.    else
  82.      {
  83.       OnRev(OUT_A,left);
  84.       TextOut(1,LCD_LINE4,"Left  Fwd");
  85.       NumOut(55,LCD_LINE4,left);
  86.      }

  87.    if (right < 0 )
  88.      {
  89.        OnFwd(OUT_B,-right);
  90.        TextOut(1,LCD_LINE5,"Right Rev");
  91.        NumOut(55,LCD_LINE5,-right);
  92.       }
  93.     else
  94.       {
  95.        OnRev(OUT_B,right);
  96.        TextOut(1,LCD_LINE5,"Right Fwd");
  97.        NumOut(55,LCD_LINE5,right);
  98.        }

  99.    // Wait sample time.
  100.    Wait(dt);
  101.    }
  102. }
复制代码



如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2011-2-6 11:35:02 | 显示全部楼层
本帖最后由 grant7788 于 2011-2-6 12:18 编辑

回复 grant7788 的帖子

补充:该作者试验了三种不同的传感器巡线,分别是NXT 2的ColorSensor, NXT 1的LightSensor,以及第三方Hitechnic Color。
各Sensor的返回值及在程序中对PID的参数设置值见下表(看不清楚的话点击看大图):

follow_diff.jpg
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2011-2-6 12:22:44 | 显示全部楼层
再转一篇... PID控制简介
http://home.cepark.com/space.php?uid=7047&do=blog&id=1030

目前工业自动化水平已成为衡量各行各业现代化水平的一个重要标志。同时,控制理论的发展也经历了古典控制理论、现代控制理论和智能控制理论三个阶段。智能控制的典型实例是模糊全自动洗衣机等。自动控制系统可分为开环控制系统和闭环控制系统。一个控控制系统包括控制器﹑传感器﹑变送器﹑执行机构﹑输入输出接口。控制器的输出经过输出接口﹑执行机构﹐加到被控系统上﹔控制系统的被控量﹐经过传感器﹐变送器﹐通过输入接口送到控制器。不同的控制系统﹐其传感器﹑变送器﹑执行机构是不一样的。比如压力控制系统要采用压力传感器。电加热控制系统的传感器是温度传感器。目前,PID控制及其控制器或智能PID控制器(仪表)已经很多,产品已在工程实际中得到了广泛的应用,有各种各样的PID控制器产品,各大公司均开发了具有PID参数自整定功能的智能调节器(intelligent regulator),其中PID控制器参数的自动调整是通过智能化调整或自校正、自适应算法来实现。有利用PID控制实现的压力、温度、流量、液位控制器,能实现PID控制功能的可编程控制器(PLC),还有可实现PID控制的PC系统等等。 可编程控制器(PLC)是利用其闭环控制模块来实现PID控制,而可编程控制器(PLC)可以直接与ControlNet相连,如Rockwell的PLC-5等。还有可以实现PID    控制功能的控制器,如Rockwell 的Logix产品系列,它可以直接与ControlNet相连,利用网络来实现其远程控制功能。
   1、开环控制系统
  开环控制系统(open-loop control system)是指被控对象的输出(被控制量)对控制器(controller)的输出没有影响。在这种控制系统中,不依赖将被控量反送回来以形成任何闭环回路。
  2、闭环控制系统
  闭环控制系统(closed-loop control system)的特点是系统被控对象的输出(被控制量)会反送回来影响控制器的输出,形成一个或多个闭环。闭环控制系统有正反馈和负反馈,若反馈信号与系统给定值信号相反,则称为负反馈( Negative Feedback),若极性相同,则称为正反馈,一般闭环控制系统均采用负反馈,又称负反馈控制系统。闭环控制系统的例子很多。比如人就是一个具有负反馈的闭环控制系统,眼睛便是传感器,充当反馈,人体系统能通过不断的修正最后作出各种正确的动作。如果没有眼睛,就没有了反馈回路,也就成了一个开环控制系统。另例,当一台真正的全自动洗衣机具有能连续检查衣物是否洗净,并在洗净之后能自动切断电源,它就是一个闭环控制系统。
  3、阶跃响应
  阶跃响应是指将一个阶跃输入(step function)加到系统上时,系统的输出。稳态误差是指系统的响应进入稳态后﹐系统的期望输出与实际输出之差。控制系统的性能可以用稳、准、快三个字来描述。稳是指系统的稳定性(stability),一个系统要能正常工作,首先必须是稳定的,从阶跃响应上看应该是收敛的﹔准是指控制系统的准确性、控制精度,通常用稳态误差来(Steady-state error)    描述,它表示系统输出稳态值与期望值之差﹔快是指控制系统响应的快速性,通常用上升时间来定量描述。
  4、PID控制的原理和特点
  在工程实际中,应用最为广泛的调节器控制规律为比例、积分、微分控制,简称PID控制,又称PID调节。PID控制器问世至今已有近70年历史,它以其结构简单、稳定性好、工作可靠、调整方便而成为工业控制的主要技术之一。当被控对象的结构和参数不能完全掌握,或得不到精确的数学模型时,控制理论的其它技术难以采用时,系统控制器的结构和参数必须依靠经验和现场调试来确定,这时应用PID控制技术最为方便。即当我们不完全了解一个系统和被控对象﹐或不能通过有效的测量手段来获得系统参数时,最适合用PID控制技术。PID控制,实际中也有PI和PD控制。PID控制器就是根据系统的误差,利用比例、积分、微分计算出控制量进行控制的。
  比例(P)控制
  比例控制是一种最简单的控制方式。其控制器的输出与输入误差信号成比例关系。当仅有比例控制时系统输出存在稳态误差(Steady-state error)。
  积分(I)控制
  在积分控制中,控制器的输出与输入误差信号的积分成正比关系。对一个自动控制系统,如果在进入稳态后存在稳态误差,则称这个控制系统是有稳态误差的或简称有差系统(System with Steady-state Error)。为了消除稳态误差,在控制器中必须引入“积分项”。积分项对误差取决于时间的积分,随着时间的增加,积分项会增大。这样,即便误差很小,积分项也会随着时间的增加而加大,它推动控制器的输出增大使稳态误差进一步减小,直到等于零。因此,比例+积分(PI)控制器,可以使系统在进入稳态后无稳态误差。
  微分(D)控制
  在微分控制中,控制器的输出与输入误差信号的微分(即误差的变化率)成正比关系。 自动控制系统在克服误差的调节过程中可能会    出现振荡甚至失稳。其原因是由于存在有较大惯性组件(环节)或有滞后(delay)组件,具有抑制误差的作用,其变化总是落后于误差的变化。解决的办法是使抑制误差的作用的变化“超前”,即在误差接近零时,抑制误差的作用就应该是零。这就是说,在控制器中仅引入“比例”项往往是不够的,比例项的作用仅是放大误差的幅值,而目前需要增加的是“微分项”,它能预测误差变化的趋势,这样,具有比例+微分的控制器,就能够提前使抑制误差的控制作用等于零,甚至为负值,从而避免了被控量的严重超调。所以对有较大惯性或滞后的被控对象,比例+微分(PD)控制器能改善系统在调节过程中的动态特性。
  5、PID控制器的参数整定
  PID控制器的参数整定是控制系统设计的核心内容。它是根据被控过程的特性确定PID控制器的比例系数、积分时间和微分时间的大小。PID控制器参数整定的方法很多,概括起来有两大类:一是理论计算整定法。它主要是依据系统的数学模型,经过理论计算确定控制器参数。这种方法所得到的计算数据未必可以直接用,还必须通过工程实际进行调整和修改。二是工程整定方法,它主要依赖工程经验,直接在控制系统的试验中进行,且方法简单、易于掌握,在工程实际中被广泛采用。PID控制器参数的工程整定方法,主要有临界比例法、反应曲线法和衰减法。三种方法各有其特点,其共同点都是通过试验,然后按照工程经验公式对控制器参数进行整定。但无论采用哪一种方法所得到的控制器参数,都需要在实际运行中进行最后调整与完善。现在一般采用的是临界比例法。利用该方法进行PID控制器参数的整定步骤如下:(1)首先预选择一个足够短的采样周期让系统工作﹔(2)仅加入比例控制环节,直到系统对输入的阶跃响应出现临界振荡,记下这时的比例放大系数和临界振荡周期﹔(3)在一定的控制度下通过公式计算得到PID控制器的参数。
书上的常用口诀:
  
  参数整定找最佳,从小到大顺序查
  先是比例后积分,最后再把微分加
  曲线振荡很频繁,比例度盘要放大
  曲线漂浮绕大湾,比例度盘往小扳
  曲线偏离回复慢,积分时间往下降
  曲线波动周期长,积分时间再加长
  曲线振荡频率快,先把微分降下来
  动差大来波动慢。微分时间应加长
  理想曲线两个波,前高后低4比1
  一看二调多分析,调节质量不会低
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2011-2-6 15:23:04 | 显示全部楼层
这么详细啊!LZ厉害,学习了。
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2011-2-6 16:42:29 | 显示全部楼层
好详细……楼主厉害,怎么没去当大学自动化的老师?
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2011-2-6 20:15:41 | 显示全部楼层
回复 grant7788 的帖子

请问LZ两轮自平衡机器人的PID算法和走黑线一样吗?很希望能得到你的回复.
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2011-2-6 22:39:57 | 显示全部楼层
lmd 发表于 2011-2-6 20:15
回复 grant7788 的帖子

请问LZ两轮自平衡机器人的PID算法和走黑线一样吗?很希望能得到你的回复.

我前两天看的那个程序,应该是和走黑线基本一样的。我没仔细看所有的算法,等把走黑线的弄完了去看那个。当时大致看了一下,是用颜色传感器当成光强传感器用,预先要设定平衡位置,程序记下这个时刻的光强值,然后就去接近这个值。
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2011-2-6 22:40:39 | 显示全部楼层
liuxiaoyi002 发表于 2011-2-6 16:42
好详细……楼主厉害,怎么没去当大学自动化的老师?

啊?Copy & Paste啊... 我全部注明了出处的。有啥厉害的...另外,大学的自动化的老师,都很厉害吗?


如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2011-2-6 22:41:18 | 显示全部楼层
lmd 发表于 2011-2-6 15:23
这么详细啊!LZ厉害,学习了。

只是在收集资料,还没动手弄呢。白天NXT的所有权归女儿,我只有打下手的份儿。 
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2011-2-6 22:42:19 | 显示全部楼层
啊?这么快就加精华了?
惭愧惭愧... 现在这个帖子的份量肯定是不够的。我努力...
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2011-2-7 00:15:26 | 显示全部楼层
本帖最后由 grant7788 于 2011-2-7 00:33 编辑

刚才做了个试验。刚好今天在和女儿玩这个车子,
http://www.nxtprograms.com/NXT2/bumper_car/index.html
直接把前方的碰撞机构和按钮传感器拿下来,装了颜色传感器上去。
测试就用的8547带的那张图上的椭圆黑圈。
程序代码如下:
  1. // PID参数设定值
  2. #define Kproportional 0.7         // Kp, 比例因子
  3. #define Kintegral 0.0005          // Ki,积分因子
  4. #define Kderivative 10            // Kd,微分因子
  5. #define dt 25                     // 取样时间

  6. int ReadSensorColorFast(int iPort)
  7. {
  8.     unsigned int raw[3]={0,0,0};
  9.     int Y;

  10.     ReadSensorColorRaw(iPort, raw);
  11.     // Y = 0.299*raw[0] + 0.587*raw[1] + 0.114*raw[2];
  12.     // Y = (299*raw[0] + 587*raw[1] + 114*raw[2])/1000;
  13.     Y = (raw[0]*19595 + raw[1]*38469 + raw[2]*7472) >> 16;
  14.     return Y;
  15. }

  16. task main()
  17. {
  18.     int error = 0;
  19.     float previous_error = 0;
  20.     float setpoint = 0;
  21.     float actual_position = 0;
  22.     float proportional = 0;
  23.     int integral = 0;
  24.     float derivative = 0;
  25.     float output = 0;
  26.     float left = 0;
  27.     float right = 0;

  28.     // 设定马达初始速度
  29.     float speed=85;

  30.     // 开传感器
  31.     SetSensorColorFull(IN_3);
  32.    
  33.     // 设定初始值。请将传感器放在一半黑线一半白线上
  34.     TextOut(1,LCD_LINE1,"Setpoint");
  35.     setpoint = ReadSensorColorFast(S3);
  36.     NumOut(50,LCD_LINE1,setpoint);

  37.     // 循环
  38.     while (true)
  39.     {
  40.         // 读取传感器当前值
  41.         actual_position = ReadSensorColorFast(S3);
  42.         TextOut(1,LCD_LINE2,"Actual");
  43.         NumOut(50,LCD_LINE2,actual_position);

  44.         // 计算误差
  45.         error = setpoint - actual_position;
  46.         // 偏离航线... 发出声音示警
  47.         // if (error <> 0) PlayTone(TONE_B7, 1);

  48.         // 比例部分: 当前误差 x 比例因子
  49.         proportional = Kproportional * error;

  50.         // 积分: 误差累积
  51.         integral = integral + error;

  52.         // 微分: 误差变化率
  53.         derivative = (error - previous_error) / dt;

  54.         // 比例、积分、微分三部分加总
  55.         output = proportional + Kintegral * dt * integral + Kderivative * derivative;

  56.         // 保存当前误差,留作下次计算时的前次误差
  57.         previous_error = error;

  58.         // 控制左侧马达
  59.         left = speed - output;

  60.         // 控制右侧马达
  61.         right = speed + output;

  62.         // 判断是否越界
  63.         if (left >   100) left  =  100;
  64.         if (left <  -100) left  = -100;
  65.         if (right >  100) right =  100;
  66.         if (right < -100) right = -100;

  67.         if (left < 0 )
  68.         {
  69.             OnRev(OUT_B,-left);
  70.             TextOut(1,LCD_LINE4,"Left  Rev");
  71.             NumOut(55,LCD_LINE4,-left);
  72.         }
  73.         else
  74.         {
  75.             OnFwd(OUT_B,left);
  76.             TextOut(1,LCD_LINE4,"Left  Fwd");
  77.             NumOut(55,LCD_LINE4,left);
  78.         }

  79.         if (right < 0 )
  80.         {
  81.             OnRev(OUT_C,-right);
  82.             TextOut(1,LCD_LINE5,"Right Rev");
  83.             NumOut(55,LCD_LINE5,-right);
  84.         }
  85.         else
  86.         {
  87.             OnFwd(OUT_C,right);
  88.             TextOut(1,LCD_LINE5,"Right Fwd");
  89.             NumOut(55,LCD_LINE5,right);
  90.         }

  91.         // 等待取样时间
  92.         Wait(dt);
  93.     }
  94. }
复制代码



如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2011-2-7 00:18:09 | 显示全部楼层
调试过程:
1. 确定Kp:
a. Kp = 5, 振荡... 一路向下试到Kp = 1开始出现振荡
b. Kp = 0.9开始振荡消失
c. 取Kp = 0.7

2. 确定Ki:
a. Ki = 1, 严重振荡... 一路降到0.001,稍有振荡。
b. 0.0008时振荡消失,
c. 取0.0005

3. 确定Kd
a. Kd = 50时振荡
b. 30时消失
c. 取10


如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

QQ|手机版|中文乐高 ( 桂ICP备13001575号-7 )

GMT+8, 2024-4-25 10:13 , Processed in 0.592079 second(s), 21 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

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