STM32Cubemax(十五)——串级PID以控制电机角度值为例

阅读: 评论:0

STM32Cubemax(⼗五)——串级PID以控制电机⾓度值为例STM32 Cubemax(⼗五) —— 串级PID以控制电机⾓度值为例网络广告监测系统
前⾔
很早前说要补的坑,今天补⼀下。之前介绍过单级的PID来控制电机的速度值,建议先看下⾯这篇⽂章,因为后⾯代码和这篇⽂章有关联!
⽽这次,我们来讲解⼀下怎么控制电机的⾓度,如果⽤单级PID控制⾓度会有什么问题,为什么要⽤串级PID。
当然串级PID不只是可以控制电机的⾓度,如现在诸多的控制系统,倒⽴摆,风⼒摆,平衡⼩车等等,都是基于串级PID的控制。
口香糖电池⼀、单级PID控制电机⾓度
如果还⽤我们之前熟知的单级PID来控制⾓度值,我们很容易的可以得出以下框图。
看上去很完美,没有什么问题,但这⾥⾯最⼤的问题就在于单⽚机给电机的是PWM值(或者电压值)并不是直接给定电机旋转的⾓度值,⽽可以认为是经过⼀个函数变换f(PWM)得出的值。
废钯碳回收钯技术⽐如这⾥以⾓度为例,PWM输出的值,经过⼀个g(x)变换得到速度值,速度值经过h(x)(即积分)得到⾓度值,f(PWM)即为
h(g(x))。
根据上述分析可知,对于简单的系统来说,这个f函数的变换,可以⽤较好的PID参数来抵消掉其中的误差量。但当系统变的复杂,⽐如平衡⼩车中,控制的⾓度不仅是单纯电机的⾓度,⽽是车上的位姿姿态,这种时候f(x)就较为复杂!这种时候,⼗分难得到⼀个PID参数来使系统稳定。
所以当我们遇到控制问题时,先看看这个f函数,是不是属于我上述说的情况,来看看单级PID是否可以使⽤。
我们接下来引⼊串级PID来解决上述f函数出现的问题。
⼆、串级PID
其实单级PID来控制⾓度,出现的具体问题就是控制反馈不全导致的!
以控制⾓度为例,其中最⼤的问题不在于h(x),因为h(x)相当于速度对时间的积分,问题在于g(x)的存在,输出的PWM会经过
g(x)得出⼀个不可控的速度值(因为存在电机阻尼,或者外届阻⼒等),那么此时经过h(x)得出的⾓度值,也不会如我们想控制的⼀样。
那么解决⽅案就很简单了,就是去控制这个速度值,使其输出的速度值是我们控制器想要得到的值即可了。我们容易得出下⾯框图。
这⾥我们加了⼀级速度级PID来控制电机的输出速度,外⾯外环仍然使⽤⼀级⾓度级PID来控制电机最终速度⾓度,这就是串级的意义。
矿用运人车其本质内涵,可以认为速度环的引⼊,相当于给系统增加了阻尼,即抑制了g(x)中因为电机阻尼,外界阻尼等因素的影响。
三、串级PID代码
其实如果看懂上⾯串级PID的框图后,代码编写也⼗分简单了,就是相当于计算两次单级PID,其中外
静压主轴
环⾓度环的⽬标值为设定的⾓度,反馈值为电机反馈的⾓度值,内环速度环的输⼊即为外环⾓度环的输出,反馈为电机反馈的速度值。
电机结构体
串级PID结构体
typedef struct _CascadePID
{
PID inner;    // 内环速度环PID
PID outer;    // 外环⾓度环PID
float output;
}CascadePID;
在电机中加⼊串级PID
typedef struct _Motor
{
int32_t lastAngle;      //上次计数结束时转过的⾓度
int32_t totalAngle;      //总共转过的⾓度
int16_t loopNum;        //电机计数过零计数
float speed;            //电机输出轴速度
float targetSpeed;      //添加设定的⽬标速度
CascadePID anglePID;    //串级PID
}Motor;
串级PID计算
//串级PID计算,参数为串级PID指针,⾓度⽬标值,⾓度返回值,速度返回值
void PID_CascadeCalc(CascadePID *pid,float angleRef,float angleFdb,float speedFdb)
{公交门
PID_SingleCalc(&pid->outer,angleRef,angleFdb);            //外环⾓度环
PID_SingleCalc(&pid->inner,pid->outer.output,speedFdb);  //内环速度环
pid->output=pid->inner.output;
}
串级PID初始化
即对内环和外环的参数进⾏初始化
PID_Init(&Motor.anglePID.inner,0,0.0,0,0,0);
PID_Init(&Motor.anglePID.outer,0,0,0,0,0,0);
然后外⾯只需要把Motor_Send⾥的单级PID计算更换成我们的串级PID计算,就完成了串级PID的计算,这⾥要解释⼀下就是这⾥我们⾓度的返回值,填的是totalAngle,即我们编码器总读出来的⾓度值,所以我们这⾥targetAngle是基于totalAngle上的累加值。
void Motor_Send(enum Mode mode)
{
float output = 0;
PID_CascadeCalc(&motor.anglePID, motor.targetAngle, alAngle, motor.speed);
output = motor.anglePID.output;
if(output > 0)
{
__HAL_TIM_SetCompare(&htim5, TIM_CHANNEL_2, (uint32_t)output);
IN1(0);
IN2(1);
}
else
{
__HAL_TIM_SetCompare(&htim5, TIM_CHANNEL_2, (uint32_t)(-output));
IN1(1);
IN2(0);
}
}
四、串级PID调参
我们编写完有关串级PID的代码程序后,就到了最关键的调参环节。我们采⽤的调参⽅式是按照内环稳定,再调外环的⽅式,由我们上述的分析也可知,只有内环速度环稳定后,⾓度环才有意义!
这⾥我们需要先利⽤上次的程序,把内环调好!!,是利⽤上次的函数,即只有单级PID控制速度的程序。
我们把单级速度环调好后,将参数填⼊串级PID的内环中,然后我们就可以开debug去调外环了。
外环的调节⽅式和内环其实是完全⼀致的,具体就不再阐述了,看上篇⽂章,先P再I,最后D,这些都是按⾃⼰的具体项⽬需求分析,看看到底⽤PI控制好,还是PD或者是PID控制效果好。
如果在调节外环的时候发现,不管怎么调都不理想,其中⼀个可能就是内环没有调好!!再次去精调内环的值。
总结
本⽂是根据⾃⼰的实际使⽤经历来写的,有可能有些地⽅表达不是很准确,如果有错误,请指正!整个代码放到gitee上了

本文发布于:2023-06-03 12:17:06,感谢您对本站的认可!

本文链接:https://patent.en369.cn/patent/2/124138.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:速度   电机   控制   内环   度值   反馈   阻尼   问题
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 369专利查询检索平台 豫ICP备2021025688号-20 网站地图