#include "DengFOC.h" #include "Can.h" #include "Filter.h" #include "Timer.h" #include "adc.h" #include "ang_sensor.h" #include "gd32c10x_dbg.h" #include "initial.h" #include "pid.h" #include "systick.h" #include #include #include #include constexpr double PI = 3.1415926535897932384626433832795f; constexpr float ANGLE_FACTOR = 25.0f / 360.0f * 2.0f * 3.14159265358979323846f; constexpr float _1_SQRT3 = 0.57735026919f; constexpr float _2_SQRT3 = 1.15470053838f; constexpr float _3PI_2 = 4.71238898038f; constexpr u8 PP = 11; constexpr float DIR = 1.0; constexpr float sqrt3 = 1.73205080757f; // sqrt(3)的预计算值 constexpr float zero_electric_angle = 0.0f; extern sampler sampler; extern angle_sensor KTH7823; extern CAN_transmiter CAN0_transmiter; CurrentKalman curU_kalman(0.0f, 0.0026f, 4.8f, 0.0001f, 1e-6f, 0.02f); CurrentKalman curV_kalman(0.0f, 0.0026f, 4.8f, 0.0001f, 1e-6f, 0.02f); CurrentKalman curW_kalman(0.0f, 0.0026f, 4.8f, 0.0001f, 1e-6f, 0.02f); // 初始变量及函数定义 #define _constrain(amt, low, high) \ ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt))) // 三值约束比较函数,用于SVPWM算法 #define _constrain3(a, b, c) \ ((a) < (b) ? ((a) < (c) ? (a) : (c)) : ((b) < (c) ? (b) : (c))) #define constrain(value, min, max, target_min, target_max) \ ((value - min) / (max - min) * (target_max - target_min)) /** * @brief 归一化角度 * * @param angle * @return float */ inline float _normalizeAngle(float angle) { float a = fmod(angle, 2 * PI); // 取余运算可以用于归一化,列出特殊值例子算便知 return a >= 0 ? a : (a + 2 * PI); } inline float _electricalAngle() { return _normalizeAngle((float)(DIR * PP) * KTH7823.read_sensorAngle() * -zero_electric_angle); } /** * @brief 电机控制类构造函数 * */ FOC_Controlroller::FOC_Controlroller() { ; } /** * @brief 设置电机输出,使用优化的SVPWM算法 * * @param Uq: q轴电压 * @param Ud: d轴电压 * @param angle_el: 电机轴角度 */ inline void FOC_Controlroller::setPhaseVoltage(float Uq, float Ud) { // 计算电气角度 float angle_el = _normalizeAngle(shaft_angle * PP + zero_electric_angle); // 帕克逆变换 (直接计算,避免函数调用开销) const float sin_el = sin(angle_el); const float cos_el = cos(angle_el); Ualpha = -Uq * sin_el; Ubeta = Uq * cos_el; // 克拉克逆变换 (预计算常量值) Ua = Ualpha + v_half; Ub = (sqrt3 * Ubeta - Ualpha) * 0.5f + v_half; Uc = (-Ualpha - sqrt3 * Ubeta) * 0.5f + v_half; // 计算占空比 float dc_a = _constrain(Ua / voltage_power_supply, 0.0f, 1.0f); float dc_b = _constrain(Ub / voltage_power_supply, 0.0f, 1.0f); float dc_c = _constrain(Uc / voltage_power_supply, 0.0f, 1.0f); // 设置PWM输出 dc_a = dc_a * limit_voltage / voltage_power_supply; dc_b = dc_b * limit_voltage / voltage_power_supply; dc_c = dc_c * limit_voltage / voltage_power_supply; Set_3Pwm(dc_a, dc_b, dc_c); // std::printf("PWM:%f,%f,%f\n", dc_a, dc_b, dc_c); } /** * @brief 电机关机 * */ void FOC_Controlroller::shut_down() { is_shut_down = 100; gpio_bit_reset(GPIOB, GPIO_PIN_12); } /** * @brief 电机恢复 * */ void FOC_Controlroller::resume() { over_current = 0; temp_error = 0; voltage_error = 0; is_shut_down = 0; gpio_bit_set(GPIOB, GPIO_PIN_12); } /** * @brief 更新电源电压 * */ void FOC_Controlroller::update_power(void) { voltage_power_supply = sampler.get_vbus_voltage(); v_half = voltage_power_supply * 0.5f; } /** * @brief 速度开环控制 * * @param target_velocity: 目标速度 * @return float: q轴电压 */ float FOC_Controlroller::velocity_open_loop() { // 通过时间间隔和目标速度计算需要转动的机械角度,存储在shaft_angle中,在此之前,还需要对轴角度归一化 // 预计算常量 1e-4 = 100微秒控制周期 shaft_angle = _normalizeAngle(shaft_angle + target_velocity * ANGLE_FACTOR * 1e-4f); // 因为在开环控制中,Ud始终为0,只控制Uq const float Uq = voltage_power_supply / 2.0f; setPhaseVoltage(Uq, 0.0f); return limit_voltage; } /** * @brief 电机初始化 * * @param _PP: 电机极队数 */ // void FOC_Controlroller::DFOC_alignSensor(int _PP) { // u8 PP = _PP; // setPhaseVoltage(3, 0, _3PI_2); // delay_1ms(3000); // zero_electric_angle = _electricalAngle(); // setPhaseVoltage(0, 0, _3PI_2); // std::printf("0电角度:%f", zero_electric_angle); // } /** * @brief 角度闭环控制 * * @param target_angle: 目标角度 * @return float: 当前角度 */ float FOC_Controlroller::angle_control(float target_angle) { shaft_angle = KTH7823.getRawAngle() * DEG2RAD; // PID 控制计算 float Uq = angle_loop(shaft_angle - target_angle * ANGLE_FACTOR); CAN0_transmiter.testfloat_union.f = angle_loop(target_angle * ANGLE_FACTOR - shaft_angle); // 设置相电压 setPhaseVoltage(Uq, 0.0f); return shaft_angle; } /** * @brief 角度闭环控制 * * @param target_angle: 目标角度 * @return float: 当前角度 */ float FOC_Controlroller::angle_control_NPID(float target_angle) { shaft_angle = KTH7823.getRawAngle() * DEG2RAD; float Kp = 20.0f; // 控制力矩计算 float Uq = 1.0f - _constrain(Kp * (target_angle * ANGLE_FACTOR - DIR * shaft_angle), -voltage_power_supply, voltage_power_supply); // 设置相电压 setPhaseVoltage(Uq, 0.0f); return shaft_angle; } /** * @brief 速度闭环控制 * * @param target_velocity: 目标速度 * @return float: 当前速度 */ float FOC_Controlroller::velocity_control(float target_velocity) { shaft_angle = KTH7823.getRawAngle() * DEG2RAD; // PID 控制计算 float Uq = vel_loop(rt_velocity - target_velocity); CAN0_transmiter.testfloat_union.f = Uq; // 设置相电压 setPhaseVoltage(Uq, 0.0f); return rt_velocity; }