BLDC直流无刷电机开环与PID闭环无扰切换
嵌入式crafter全网平台同名,喜欢视频版的可以移步dy、xhs、b站。
前言
在做一个产品的过程中,需要在转弯和手推时切换为BLDC电机的开环控制,而在正常前进和遥控控制情况下切换到PID速度闭环控制。但是起初直接切换总是会造成输出的不匹配,导致电机会剧烈的抖动。后面采用了这个方法,实现了让电机在闭环和开环之间无扰的切换,实现了产品需求。
在此提供这条思路,希望有遇到类似问题的朋友,可以参考。
分别获取开环和闭环的PWM值,然后在需要做开环到闭环的切换的时候,做一次PID误差值的对齐。在我的产品中是能够满足需求的,不管是开环切闭环,还是闭环切开环都是非常流畅。
void PID_Loop(void)
{float pwm_open[2] = {0, 0};float pwm_pid[2] = {0, 0};// --- 分别计算开环和闭环 ---pwm_open[0] = Motor_Open_Loop(Drv[0].target_speed);pwm_open[1] = Motor_Open_Loop(Drv[1].target_speed);pwm_pid[0] = Speed_Pid_Control(Drv[0].Hall_Velo_Measure_rpm,Drv[0].target_speed,&Speed_PID_1);pwm_pid[1] = Speed_Pid_Control(Drv[1].Hall_Velo_Measure_rpm,Drv[1].target_speed,&Speed_PID_2);if (Chassis.mode_change_flag == 1) {Chassis.mode_change_flag = 0;// --- 开环切闭环时,做一次对齐 ---float err0 = Drv[0].target_speed - Drv[0].Hall_Velo_Measure_rpm;Speed_PID_1.err_I = (pwm_open[0] - Speed_PID_1.P * err0) / Speed_PID_1.I; Speed_PID_1.err_Last = err0;float err1 = Drv[1].target_speed - Drv[1].Hall_Velo_Measure_rpm;Speed_PID_2.err_I = (pwm_open[1] - Speed_PID_2.P * err1) / Speed_PID_2.I;Speed_PID_2.err_Last = err1;}if (currentMode == OPEN_LOOP) // 开环逻辑{pwm_target[0] = pwm_open[0];pwm_target[1] = pwm_open[1];} else // 闭环逻辑{pwm_target[0] = pwm_pid[0];pwm_target[1] = pwm_pid[1]; }// 待机模式下直接速度闭环给0锁死。if (Chassis.status == eStop){ pwm_target[0] = Speed_Pid_Control(Drv[0].Hall_Velo_Measure_rpm,0,&Speed_PID_1);pwm_target[1] = Speed_Pid_Control(Drv[1].Hall_Velo_Measure_rpm,0,&Speed_PID_2);}// --- 输出 ---Motor_Move(1, -pwm_target[0]);Motor_Move(2, -pwm_target[1]);
}