关于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 有什么用?还是代码本身有什么问题?
PID控制不仅仅只考虑你的输入,还有你的反馈与输入的比较最后才有输出。建议先科普一下PID,再去看看这个arduino的PID库文件是怎么做的。还有PID的参数是需要人为输入的,好像程序里没有体现出来。 PINKWALKMAN 发表于 2016-4-15 08:05 static/image/common/back.gif
PID控制不仅仅只考虑你的输入,还有你的反馈与输入的比较最后才有输出。建议先科普一下PID,再去看看这个ar ...
这是他们官方的程序啊,我只是把 INPUT 改成一个固定值了 本帖最后由 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 ,我搞不懂为什么 pig881 发表于 2016-4-15 12:43 static/image/common/back.gif
/*Compute all the working error variables*/
double input = *myInput;
double error = * ...
这是积分的概念,必须是连续的变量值进行对比才能有,有效的积分和微分,设定为固定值当然就是死跑啦 Champagne 发表于 2016-4-16 03:50 static/image/common/back.gif
这是积分的概念,必须是连续的变量值进行对比才能有,有效的积分和微分,设定为固定值当然就是死跑啦
但是在马达转动时,的确有一段时间 输入值是不变的,就连他们官方的代码 Basic sample 里,模拟值的输入,只要不转动电位器,也不变啊 可是官方的代码:
/********************************************************
* 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 了,真是费解!! double Kp=2, Ki=0, Kd=1;如果把参数这样设置, 并且输入值比 Setpoint 小,比如 Input=88,那么输出值会是一个接近 24 的常数,这样算不算是 pid 正常了呢?:L:L 但是如果 Input 比 Setpoint 大,则输出值OUTPUT 又变成0 了 :Q:Q
页:
[1]