- 代码的基本逻辑:目前只是使用了电流环,我们设定目标Iq_set = 0.3,然后调用PID控制函数,返回值传给Uq
- 目前存在的问题:肉眼观察下电机可以正常的转动,但是高负载的情况下转不动。目前通过调试观察 Iq 的值,发现Iq根本无法稳定在 0.3 附近,而且无规律的跳动。使用上位机观察UWV其中两项的电流值,电流曲线有点正弦波的样子,但是很杂。搞了很长时间找不出问题在哪里,求指导。
typedef struct{ float error; // 当前误差 float errorLast; // 上一次误差 float feedforward; // 前馈 float integral; // 积分 float satura
tion; // 饱和 float differ; // 差值 float kp; // 比例增益 float ki; // 积分增益 float kd; // 微分增益 float ns; // 速度限制 float ka; // 加速度限制 float limit; // 限制} PID_LocTypeDef;/* 初始化PID参数 */PID_Init(&PID_Iq, 0.65, 0.12, 0, 10, 0.01);foc.Uq = PID_Loc(0.3, cur.Iq, &PID_Iq);void PID_Init(PID_LocTypeDef* pidHandle, float kp, float ki, float kd, float limit, float ns){ pidHandle->kp = kp; pidHandle->ki = ki; pidHandle->kd = kd; pidHandle->limit = limit; pidHandle->ns = ns;}foc.Uq = PID_Loc(0.3, cur.Iq, &PID_Iq);setPhaseVoltage(&foc, angle.Eangle);这是foc的SVPWM代码
// FOC核心函数:输入Ud、Uq和电角度,输出PWMvoid setPhaseVoltage(sfoc *foc, float angle){ foc->angle_el = angle; foc->angle_el = _normalizeAngle(foc->angle_el); float cos_angle = arm_cos_f32(foc->angle_el); float sin_angle = arm_sin_f32(foc->angle_el); // 反park变换 foc->U_alpha = foc->Ud * cos_angle - foc->Uq * sin_angle; foc->U_beta = foc->Ud * sin_angle + foc->Uq * cos_angle; foc->Uref = _sqrtf(foc->U_alpha * foc->U_alpha + foc->U_beta * foc->U_beta) / voltage_power_supply; // 限制最大参考电压 if (foc->Uref > 0.577f) foc->Uref = 0.577f; if (foc->Uref < -0.577f) foc->Uref = -0.577f; // 标准化电角度值,并根据Uq确定扇区 if (foc->Uq > 0) foc->angle_el = _normalizeAngle(foc->angle_el + _PI_2); else foc->angle_el = _normalizeAngle(foc->angle_el - _PI_2); foc->sector = (foc->angle_el / _PI_3) + 1; // 计算作用时间 foc->T1 = SQRT_3 * arm_sin_f32(foc->sector * _PI_3 - foc->angle_el) * foc->Uref; foc->T2 = SQRT_3 * arm_sin_f32(foc->angle_el - (foc->sector - 1.0f) * _PI_3) * foc->Uref; foc->T0 = 1 - foc->T1 - foc->T2; // 根据扇区计算占空比 switch (foc->sector) { case 1: foc->Ta = foc->T1 + foc->T2 + foc->T0 / 2; foc->Tb = foc->T2 + foc->T0 / 2; foc->Tc = foc->T0 / 2; break; case 2: foc->Ta = foc->T1 + foc->T0 / 2; foc->Tb = foc->T1 + foc->T2 + foc->T0 / 2; foc->Tc = foc->T0 / 2; break; case 3: foc->Ta = foc->T0 / 2; foc->Tb = foc->T1 + foc->T2 + foc->T0 / 2; foc->Tc = foc->T2 + foc->T0 / 2; break; case 4: foc->Ta = foc->T0 / 2; foc->Tb = foc->T1 + foc->T0 / 2; foc->Tc = foc->T1 + foc->T2 + foc->T0 / 2; break; case 5: foc->Ta = foc->T2 + foc->T0 / 2; foc->Tb = foc->T0 / 2; foc->Tc = foc->T1 + foc->T2 + foc->T0 / 2; break; case 6: foc->Ta = foc->T1 + foc->T2 + foc->T0 / 2; foc->Tb = foc->T0 / 2; foc->Tc = foc->T1 + foc->T0 / 2; break; default: // 错误情况 foc->Ta = 0; foc->Tb = 0; foc->Tc = 0; break; } // 输出PWM信号 TIM1->CCR1 = foc->Ta * PWM_PERIOD; TIM1->CCR2 = foc->Tb * PWM_PERIOD; TIM1->CCR3 = foc->Tc * PWM_PERIOD;}这是PID控制的代码
float PID_Loc(float SetValue, float ActualValue, PID_LocTypeDef* pidHandle){pidHandle->error = SetValue - ActualValue;/* Proportional Item */float p = pidHandle->kp * pidHandle->error;/* Integral Item */float i = pidHandle->ki * (pidHandle->error - pidHandle->ka * pidHandle->saturation) + pidHandle->integral;// i = _constrain(i, MIN(0.f, -pidHandle->limit), MAX(0.f, pidHandle->limit));i = _constrain(i, -pidHandle->limit, pidHandle->limit);pidHandle->integral = i;/* Differential Item */float d = pidHandle->kd * pidHandle->ns * (pidHandle->error - pidHandle->errorLast) -pidHandle->differ * (pidHandle->ns - 1.0f);pidHandle->errorLast = pidHandle->error;pidHandle->differ = d;/* Output value update and saturation value calculation */float val = p + i + d + pidHandle->feedforward;float out = _constrain(val, -pidHandle->limit, pidHandle->limit);pidHandle->saturation = val - out;return out;}这是计算Iq和Id的值部分
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc){GetCurrent(&cur);float I_alpha = cur.CurA;float I_beta = (cur.CurB - cur.CurC) * SQRT_3 / 2;cur.Id = I_alpha * arm_cos_f32(foc.angle_el) + I_beta * arm_sin_f32(foc.angle_el);cur.Iq = I_beta * arm_cos_f32(foc.angle_el) - I_alpha * arm_sin_f32(foc.angle_el);/* 低通滤波 */cur.Id = LowPassFilter_Update(&LPF_Id, cur.Id);cur.Iq = LowPassFilter_Update(&LPF_Iq, cur.Iq);}这是使用上位机观察到了UV两项的电流波形。

在调试中观察的数值变化