pig881 发表于 2016-4-14 20:40:22

关于PID的奇怪问题

本帖最后由 pig881 于 2016-4-14 20:41 编辑

官方的代码:

#include <PID_v1.h>
double Setpoint,Input ,Output;

PID myPID(&Input,&Output,&Setpoint,2,5,1,DIRECT);
void setup() {

   Serial.begin(9600);
   Input=80;
   Setpoint=100;

myPID.SetMode(AUTOMATIC);
}

void loop() {
Input = 80;

myPID.Compute();
//analogWrite(3,Output);

Serial.print("Output= ");
Serial.println(Output);
delay(500);
}

原代码的 Input 是读取 A0 口的模拟值 ( 有的代码里还会 map(val, 0 ,1023 , 0, 255)   类似这样的);

我这里把 Input 设置为一个固定值, setpoint 定为 100


为什么 OUTPUT 一开始是接近 setpoint,后面就一直向上,直到 255,就不变了,我觉得很纳闷,

到底这个 Input 有什么用?还是代码本身有什么问题?


PINKWALKMAN 发表于 2016-4-15 08:05:56

PID控制不仅仅只考虑你的输入,还有你的反馈与输入的比较最后才有输出。建议先科普一下PID,再去看看这个arduino的PID库文件是怎么做的。还有PID的参数是需要人为输入的,好像程序里没有体现出来。

pig881 发表于 2016-4-15 09:45:11

PINKWALKMAN 发表于 2016-4-15 08:05 static/image/common/back.gif
PID控制不仅仅只考虑你的输入,还有你的反馈与输入的比较最后才有输出。建议先科普一下PID,再去看看这个ar ...

这是他们官方的程序啊,我只是把 INPUT 改成一个固定值了

pig881 发表于 2016-4-15 12:43:08

本帖最后由 pig881 于 2016-4-15 12:47 编辑

PINKWALKMAN 发表于 2016-4-15 08:05 static/image/common/back.gif
PID控制不仅仅只考虑你的输入,还有你的反馈与输入的比较最后才有输出。建议先科普一下PID,再去看看这个ar ...

/*Compute all the working error variables*/
          double input = *myInput;
      double error = *mySetpoint - input;
      ITerm+= (ki * error);
      if(ITerm > outMax) ITerm= outMax;
      else if(ITerm < outMin) ITerm= outMin;
      double dInput = (input - lastInput);

      /*Compute PID Output*/
      double output = kp * error + ITerm- kd * dInput;


源代码是这样的, 我发现只要Input 比Setpoint 大了, OUTPUT 就会变成0, 但是如果Setpoint 不在 Input变化 区间内,就会变成 255

但是只要速度恒定在某个值,比如 Setpoint 为77, 而 Input为 78 ,而且一直不变,那么 Output 就会趋向于0,最终变成0 ,我搞不懂为什么

Champagne 发表于 2016-4-16 03:50:13

pig881 发表于 2016-4-15 12:43 static/image/common/back.gif
/*Compute all the working error variables*/
          double input = *myInput;
      double error = * ...

这是积分的概念,必须是连续的变量值进行对比才能有,有效的积分和微分,设定为固定值当然就是死跑啦

pig881 发表于 2016-4-16 09:15:06

Champagne 发表于 2016-4-16 03:50 static/image/common/back.gif
这是积分的概念,必须是连续的变量值进行对比才能有,有效的积分和微分,设定为固定值当然就是死跑啦

但是在马达转动时,的确有一段时间 输入值是不变的,就连他们官方的代码 Basic sample 里,模拟值的输入,只要不转动电位器,也不变啊

pig881 发表于 2016-4-16 09:19:04

可是官方的代码:

/********************************************************
* PID Basic Example
* Reading analog input 0 to control analog PWM output 3
********************************************************/

#include <PID_v1.h>

#define PIN_INPUT 0
#define PIN_OUTPUT 3

//Define Variables we'll be connecting to
double Setpoint, Input, Output;

//Specify the links and initial tuning parameters
double Kp=2, Ki=5, Kd=1;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

void setup()
{Serial.begin(9600);
//initialize the variables we're linked to
Input = analogRead(PIN_INPUT);
Setpoint = 100;

//turn the PID on
myPID.SetMode(AUTOMATIC);
}

void loop()
{
Input = analogRead(PIN_INPUT);
myPID.Compute();
analogWrite(PIN_OUTPUT, Output);

Serial.print("Input=");
Serial.println(Input);

Serial.print("OUTput= ");
Serial.println(Output);
delay(500);
}



在 Input 为 132 的时候,OUTPUT 也为0 了,真是费解!!

pig881 发表于 2016-4-16 09:30:14

double Kp=2, Ki=0, Kd=1;如果把参数这样设置, 并且输入值比 Setpoint 小,比如 Input=88,那么输出值会是一个接近 24 的常数,这样算不算是 pid 正常了呢?:L:L    但是如果 Input 比 Setpoint 大,则输出值OUTPUT 又变成0 了 :Q:Q
页: [1]
查看完整版本: 关于PID的奇怪问题