基于B站视频【【干货教程】单片机项目速成-电赛智能送药小车 STM32HAL库CubeMX+串级PID控制+OpenMV数字识别】 https://www.bilibili.com/video/BV1UL411V7XK/?p=7&share_source=copy_web&vd_source=068659ed82b6b715cbbf159da8fa83a4
理解加总结。
1、串级PID
其中小车使用了两个电机,分别控制左右轮,其中我们最终目的是获取期望PWM值,使用的电机是带有编码器的。
其中这里代码逻辑:
直走函数void Car_go(int32_t location_cm) location_cm要直走多少cm的路程
Car_location = ( location_cm / (2 * WheelR * 3.1416) ) * (REDUCTION_RATIO*ENCODER_TOTAL_RESOLUTION) ;//前面是走指定路程所需多少圈,后面是车轮转动一圈对应脉冲数=(电机减速比*编码器经过倍频之后的分辨率)
两个相乘可以计算出对应这么多路程的脉冲数
之后设置Car_location为目标PID值,以便后面使用PID进行控制。
使用location_pid_control(void)得出实际脉冲数的值actual_location = g_lMotorPulseSigma;实际脉冲数的值可以通过定时器的值获取__HAL_TIM_GET_COUNTER(&htim3)。之后获得的实际值进入location_pid_realize(_pid *pid, float actual_val)函数里面,下面是PID的核心代码
PID算法实现:pid->actual_val = pid->Kp*pid->err
+pid->Ki*pid->integral
+pid->Kd*(pid->err-pid->err_last);
之后经过PID控制出来的位置值location_Outval传进速度环PID控制中充当PID目标值。
经过下面公式算出速度的实际值
actual_speed = ((float)g_nMotorPulse*1000.0*60.0)/(ENCODER_TOTAL_RESOLUTION*REDUCTION_RATIO*SPEED_PID_PERIOD);
通过速度PID控制函数speed_pid_realize(&pid_speed, actual_speed);得到PID控制后的值speed_Outval。
到这里完成了串级控制PID的流程。之后就是使用灰度传感器的巡线补偿加上speed_Outval去控制电机PWM。
2、调试PID参数 口诀:
参数整定找最佳,从小到大顺序查。先是比例后积分,最后再把微分加。曲线振荡很频繁,比例度盘要放大。曲线漂浮绕大弯,比例度盘往小扳。曲线偏离回复慢,曲线波动周期长,曲线振荡频率快,动差大来波动慢,理想曲线两个波,一看二调多分析,积分时间往下降。积分时间再加长。先把微分降下来。微分时间应加长。前高后低四比一。调节质量不会低。