在PID控制中,输出通常是一个控制量,而不是直接的PWM占空比。输出的具体含义可以根据具体的系统和应用而变化。在这段代码中,PID控制器的输出是 output_calc
。
而 CCR_duty
是控制施肥系统的PWM占空比,这是通过PID控制的输出和曲线计算得出的结果的组合。
CCR_duty = output_calc + curve;
在这里,curve
是通过 rpm2duty
函数将目标转速 calc_rpm
转换为占空比的曲线部分。
//转速和占空比关系曲线
// CCR_duty = 0.1263 * calc_rpm + 11.31;
float rpm2duty(float rpm)
{
//return (0.1263 * rpm + 11.31)/2.5;
return 0.0505 * rpm + 11.315;
}
然后将PID控制的输出 output_calc
添加到曲线部分,得到最终的PWM占空比 CCR_duty
。
所以,CCR_duty
不是直接的PID输出,而是PID输出和转速-占空比曲线的组合,以实现更精确的控制。这种组合可以根据具体的系统需求来调整和优化。
calc_rpm = CalcBaseFatRpm(work_speed,pre_BaseFatSet,tooth_num);
if(s_BaseFatRpm.rpm == 0) //曲线
{
CCR_duty = rpm2duty(calc_rpm);
}
else //PID
{/*pid*/
// 计算速度误差
float speed_error = calc_rpm - s_BaseFatRpm.rpm;
// 使用PID控制器计算PWM
float output_calc = PIDController_Compute(&s_PWMPid, speed_error);
float curve = rpm2duty(calc_rpm);
CCR_duty = (output_calc + curve);
// CCR_duty += (output_calc + 0);
}
一文读懂PID控制算法(抛弃公式,从原理上真正理解PID控制)-CSDN博客https://blog.csdn.net/qq_25352981/article/details/81007075
假设我有一个水缸,最终的控制目的是要保证水缸里的水位永远的维持在1米的高度。假设初始时刻,水缸里的水位是0.2米,那么当前时刻的水位和目标水位之间是存在一个误差的error,且error为0.8.
这个时候,假设旁边站着一个人,这个人通过往缸里加水的方式来控制水位。如果单纯的用比例控制算法,就是指加入的水量u和误差error是成正比的。即
u=kp*error
假设kp取0.5,那么t=1时(表示第1次加水,也就是第一次对系统施加控制),那么u=0.5*0.8=0.4,所以这一次加入的水量会使水位在0.2的基础上上升0.4,达到0.6.
接着,t=2时刻(第2次施加控制),当前水位是0.6,所以error是0.4。u=0.5*0.4=0.2,会使水位再次上升0.2,达到0.8.
如此这么循环下去,就是比例控制算法的运行方法。可以看到,最终水位会达到我们需要的1米。
但是,单单的比例控制存在着一些不足,其中一点就是 –稳态误差!
像上述的例子,根据kp取值不同,系统最后都会达到1米,只不过kp大了到达的快,kp小了到达的慢一些。不会有稳态误差。
但是,考虑另外一种情况,假设这个水缸在加水的过程中,存在漏水的情况,假设每次加水的过程,都会漏掉0.1米高度的水。仍然假设kp取0.5,那么会存在着某种情况,假设经过几次加水,水缸中的水位到0.8时,水位将不会再变换!!!
因为,水位为0.8,则误差error=0.2. 所以每次往水缸中加水的量为u=0.5*0.2=0.1.同时,每次加水,缸里又会流出去0.1米的水!!!加入的水和流出的水相抵消,水位将不再变化!!
也就是说,我的目标是1米,但是最后系统达到0.8米的水位就不再变化了,且系统已经达到稳定。由此产生的误差就是稳态误差了。
还是用上面的例子,如果仅仅用比例,可以发现存在暂态误差,最后的水位就卡在0.8了。于是,在控制中,我们再引入一个分量,该分量和误差的积分是正比关系。所以,比例+积分控制算法为:
u=kp*error+ ki∗∫ error
还是用上面的例子来说明,第一次的误差error是0.8,第二次的误差是0.4,至此,误差的积分(离散情况下积分其实就是做累加),∫error=0.8+0.4=1.2. 这个时候的控制量,除了比例的那一部分,还有一部分就是一个系数ki乘以这个积分项。由于这个积分项会将前面若干次的误差进行累计,所以可以很好的消除稳态误差(假设在仅有比例项的情况下,系统卡在稳态误差了,即上例中的0.8,由于加入了积分项的存在,会让输入增大,从而使得水缸的水位可以大于0.8,渐渐到达目标的1.0.)这就是积分项的作用。