【串级PID】浅谈串级PID作用及意义——快速理解串级PID结构优势(附图)

答应为实验室的同学做一次简单的关于串级PID的介绍,主要从感性认识串级PID的结构与作用切入,因此笔者尽量避免引入公式及其推导,因为这些推导在各类控制类书籍与相关论文中均有介绍,我就不再班门弄斧了。

本文假设读者已有单级PID控制的基础,对于PID的原理不做描述。


 

假设我们需要解决这样一个问题:

控制小车从当走到红色标签位置,设小车实时位置为x0(t)

 

如果我们使用单级PID,运动框图应该如下图所示:

误差e来自小车当前位置与目标位置的差值,即 e = x1 - x0;

误差e经过PID算法得到输出小车给定速度v;

小车给定速度v经过建立的电机小车模型传递函数(实际上是一个积分器,对速度积分即可得到位移),得到小车的当前位置x0;

选取一组合适的PID参数,我们就可以很好的实现这个任务。根据不同的要求,我们可以找到不同的PID参数以实现快速收敛控制,或者无超调控制。

但是现在考虑这样一个情况:

小车所在的路面与水平面存在一个非零的夹角θ:

现在如果我们还拿之前的PID参数去解决这个问题,我们可能就会发现小车的运行情况没有之前那么理想了,可能会出现但不限于收敛速度变慢无超调控制的PID参数出现超调小车在目的地附近振荡等情况。

这是为什么呢,我们仔细看一下之前框图里的执行环节Motors-Car,把它打开看一下:

我们发现,真正的积分器环节是Car,而积分器环节Car的真正输入是v';

v恒等于v'吗?换言之,我叫小车电机以v的速度运行,他会立刻响应并保持在这一速度吗?答案显然是否定的:

v'与v不完全一致,这就是原有的单级PID控制算法出现问题的原因,我们实际供给电机的是电压,一定的电压对应一定的转速v,然而电机转速v不是关于电压的单值函数电机转速v受到很多条件的影响,鉴于电机模型复杂且对于不同种类的电机模型也不尽相似,我们只讨论其中的另一个主要变量:负载转矩。当小车启动制动,走上坡道都会造成负载转矩的变化,从而进一步影响电机转速v

如何解决?我们可以对电机Motors环节做一个转速闭环:

这样就可以改善这个问题(注意是改善,不是解决!)

有了这个闭环,就可以让电机的实际转速v'快速的跟踪给定速度v,至于有多快,还是要看电机模型和PID参数,但是一定比之前开环控制的效果要好。

我们将这个改良的执行环节 Improved Motors-Car 替换原先单级PID运动框图中的执行环节Motors-Car,就可以得到这样一个串级PID的结构框图了:

如此操作,在倾斜的坡道上,原来的参数也能较好的适应了。我们来看这个结构框图,里面有两个反馈箭头,也就形成了两个闭环,一个环在内,一个环在外。

其中转速闭环称为串级PID的内环位置闭环称为串级PID的外环,现在去想象一下小车实际运行的情况,是不是能比较好的理解课本上 内环先稳定,外环后稳定的原因了?

 

 

 


笔者希望这篇博文能够起到抛砖引玉的作用,让各位读者在之后系统学习串级PID的推导时更好的理解串级PID的思想。如果您觉得这篇博文有帮助,请您点下右上角的点赞,谢谢!

串级PID控制是一种常见的控制策略,可以用于控制系统中多个环节的变量。在Arduino上实现串级PID控制,需要分别设计两个PID控制器,一个用于内环控制,另一个用于外环控制。内环控制器控制内环变量,外环控制器控制外环变量,然后将内环输出作为外环的输入。 下面是一个简单的串级PID控制器示例代码: ``` double Setpoint = 30.0; double Input, Output; double Kp = 2.0, Ki = 5.0, Kd = 1.0; // 外环PID参数 double Kp1 = 1.0, Ki1 = 2.0, Kd1 = 0.5; // 内环PID参数 double lastInput, lastOutput; double innerSetpoint = 50.0; PID innerPID(&Input, &lastInput, &innerSetpoint, Kp1, Ki1, Kd1, DIRECT); PID outerPID(&lastOutput, &Output, &Setpoint, Kp, Ki, Kd, DIRECT); void setup() { Serial.begin(9600); innerPID.SetMode(AUTOMATIC); outerPID.SetMode(AUTOMATIC); innerPID.SetOutputLimits(-255, 255); outerPID.SetOutputLimits(-255, 255); } void loop() { Input = analogRead(A0); // 读取内环传感器 innerPID.Compute(); // 内环PID计算 lastInput = Output; // 内环输出作为外环输入 outerPID.Compute(); // 外环PID计算 analogWrite(3, Output); // 控制外环执行器 Serial.print(Input); Serial.print(" "); Serial.println(Output); delay(100); } ``` 在上面的代码中,我们使用了Arduino的PID库来实现PID控制器。首先,定义两个PID对象innerPID和outerPID,分别用于内环和外环控制。在setup函数中,我们将两个PID对象设置为自动模式(AUTOMATIC),同时设置了输出范围。在loop函数中,我们读取内环传感器的值,计算内环PID控制器的输出lastInput,然后将其作为外环PID控制器的输入,计算外环PID控制器的输出Output,最后通过analogWrite函数将Output作为控制外环执行器的PWM信号输出。 需要注意的是,在串级PID控制器中,内环控制器的控制周期应该要比外环控制器短,以保证内环控制器能够及时响应内环变量的变化,从而更好地控制外环变量。
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值