chenged to 2 motor velocity-closed-loop; before testing

This commit is contained in:
2025-11-20 09:50:13 +08:00
parent dd8f7c006f
commit ed09f10c03
13 changed files with 276 additions and 261 deletions

View File

@@ -1,4 +1,5 @@
#include "dfoc.h"
#include "config.h"
#include "delay.h"
#include "lowpass_filter.h"
@@ -15,6 +16,18 @@
#define _1_SQRT3 0.57735026919f
#define _2_SQRT3 1.15470053838f
struct Motor_ M0 = {0};
struct Motor_ M1 = {1};
struct _PID M0_VEL_PID = {0.4, 2, 0};
struct _PID M1_VEL_PID = {0.4, 2, 0};
struct LOWPASS M0_VEL_Filter = {0.1};
struct LOWPASS M1_VEL_Filter = {0.1};
struct AS5600_Sensor Angle_Sensor0 = {0};
struct AS5600_Sensor Angle_Sensor1 = {1};
#define VOLTAGE_POWER_SUPPLY 12.0f
#define VOLTAGE_LIMIT 6
#define PWM_COMPARE_VALUE 750.0f
@@ -22,10 +35,10 @@
volatile float Ua = 0, Ub = 0, Uc = 0, Ualpha, Ubeta = 0, dc_a = 0, dc_b = 0,
dc_c = 0;
volatile float zero_electric_Angle = 0.0;
float M0_zero_elc_Angle = 0, M1_zero_elc_Angle = 0;
extern int pp;
extern int Dir;
extern int M0_PP, M0_DIR;
extern int M1_PP, M1_DIR;
void Motor_en() {}
@@ -40,11 +53,16 @@ float normalizeAngle(float angle) {
return ((a >= 0) ? a : (a + 2 * PI));
}
float electricAngle(void) {
return normalizeAngle((GetAngle_NoTrack() * pp * Dir) - zero_electric_Angle);
float M0_electricAngle(void) {
return normalizeAngle((GetAngle_NoTrack(&Angle_Sensor0) * M0_PP * M0_DIR) -
M0_zero_elc_Angle);
}
void SetPwm(float Ua, float Ub, float Uc) {
float M1_electricAngle(void) {
return normalizeAngle((GetAngle_NoTrack(&Angle_Sensor1) * M1_PP * M1_DIR) -
M1_zero_elc_Angle);
}
void SetPwm(int Mot_num, float Ua, float Ub, float Uc) {
volatile float U_a = 0.0;
volatile float U_b = 0.0;
volatile float U_c = 0.0;
@@ -53,44 +71,54 @@ void SetPwm(float Ua, float Ub, float Uc) {
U_b = constrain(Ub, 0.0f, VOLTAGE_LIMIT);
U_c = constrain(Uc, 0.0f, VOLTAGE_LIMIT);
dc_a = constrain(U_a / VOLTAGE_POWER_SUPPLY, 0.0f, 1.0f);
dc_b = constrain(U_b / VOLTAGE_POWER_SUPPLY, 0.0f, 1.0f);
dc_c = constrain(U_c / VOLTAGE_POWER_SUPPLY, 0.0f, 1.0f);
if (DEBUG_ENABLED & DEBUG_DFOC_ENABLED) {
if (Mot_num == 0) {
M0.dc_a = constrain(U_a / VOLTAGE_POWER_SUPPLY, 0.0f, 1.0f);
M0.dc_b = constrain(U_b / VOLTAGE_POWER_SUPPLY, 0.0f, 1.0f);
M0.dc_c = constrain(U_c / VOLTAGE_POWER_SUPPLY, 0.0f, 1.0f);
printf("dc_a : %f -- dc_b : %f -- dc_c : %f \n", dc_a, dc_b, dc_c);
M0_PWM_A(M0.dc_a * PWM_COMPARE_VALUE); // 频率15k
M0_PWM_B(M0.dc_b * PWM_COMPARE_VALUE);
M0_PWM_C(M0.dc_c * PWM_COMPARE_VALUE);
} else if (Mot_num == 1) {
M1.dc_a = constrain(U_a / VOLTAGE_POWER_SUPPLY, 0.0f, 1.0f);
M1.dc_b = constrain(U_b / VOLTAGE_POWER_SUPPLY, 0.0f, 1.0f);
M1.dc_c = constrain(U_c / VOLTAGE_POWER_SUPPLY, 0.0f, 1.0f);
M1_PWM_A(M1.dc_a * PWM_COMPARE_VALUE); // 频率15k
M1_PWM_B(M1.dc_b * PWM_COMPARE_VALUE);
M1_PWM_C(M1.dc_c * PWM_COMPARE_VALUE);
}
PWM_Channel1((1 - dc_a) * PWM_COMPARE_VALUE); // 频率15k
PWM_Channel2((1 - dc_b) * PWM_COMPARE_VALUE);
PWM_Channel3((1 - dc_c) * PWM_COMPARE_VALUE);
}
// FOC核心算法克拉克逆变换/帕克逆变换
volatile float test_angle = 0.0;
volatile float last_test_angle = 0.0;
void SetPhaseVoltage(float Uq, float Ud, float angle_el) {
void SetPhaseVoltage(struct Motor_ *Motor, float Uq, float angle_el) {
// angle_el = normalizeAngle(angle_el);
test_angle = angle_el - last_test_angle;
Ualpha = -Uq * sin(angle_el);
Ubeta = Uq * cos(angle_el);
Motor->Ualpha = -Uq * sin(angle_el);
Motor->Ubeta = Uq * cos(angle_el);
Ua = Ualpha + VOLTAGE_POWER_SUPPLY / 2;
Ub = (sqrt(3) * Ubeta - Ualpha) / 2 + VOLTAGE_POWER_SUPPLY / 2;
Uc = -(Ualpha + sqrt(3) * Ubeta) / 2 + VOLTAGE_POWER_SUPPLY / 2;
Motor->Ua = Motor->Ualpha + VOLTAGE_POWER_SUPPLY / 2;
Motor->Ub =
(sqrt(3) * Motor->Ubeta - Motor->Ualpha) / 2 + VOLTAGE_POWER_SUPPLY / 2;
Motor->Uc =
-(Motor->Ualpha + sqrt(3) * Motor->Ubeta) / 2 + VOLTAGE_POWER_SUPPLY / 2;
SetPwm(Ua, Ub, Uc);
last_test_angle = angle_el;
SetPwm(Motor->Mot_num, Motor->Ua, Motor->Ub, Motor->Uc);
}
void Check_Sensor(void) {
// SetPhaseVoltage(3, 0, _3PI_2);
// delay_ms(3000);
zero_electric_Angle = electricAngle();
printf("Check_Sensor zero_electric_Angle is %f \n", zero_electric_Angle);
// SetPhaseVoltage(0, 0, _3PI_2);
// delay_ms(500);
SetPhaseVoltage(&M0, 3, _3PI_2);
delay_ms(2000);
M0_zero_elc_Angle = M0_electricAngle();
SetPhaseVoltage(&M0, 0, _3PI_2);
delay_ms(500);
SetPhaseVoltage(&M1, 3, _3PI_2);
delay_ms(2000);
M1_zero_elc_Angle = M1_electricAngle();
SetPhaseVoltage(&M1, 0, _3PI_2);
delay_ms(500);
}
void FOC_Init() {
@@ -100,50 +128,30 @@ void FOC_Init() {
Check_Sensor();
}
// 单角度环
void Set_Angle(float Target) {
volatile float langle = GetAngle();
if (DEBUG_ENABLED & DEBUG_DFOC_ENABLED) {
printf("angle readback in dfoc.c is %f \n", langle);
void Print_Velocity(int Motor_Velocity) {
if (Motor_Velocity == 0) {
printf("Velocity M0 is %f \n", GetVelocity(&Angle_Sensor0));
}
volatile float Uq =
PID_Controller(0.03, 0.01, 0, (Target - Dir * langle) * 180 / PI);
// volatile float Uq = PID_Controller(0.133, 0, 0, (Target - Dir * langle) *
// 180 / PI);
if (DEBUG_ENABLED & DEBUG_DFOC_ENABLED) {
printf("Uq is %f \n", Uq);
if (Motor_Velocity == 1) {
printf("Velocity M1 is %f \n", GetVelocity(&Angle_Sensor1));
}
SetPhaseVoltage(Uq, 0, electricAngle());
}
volatile double openloop_timestamp;
float velocityopenloop(float target) {
volatile float Uq = 0.0;
volatile double Ts = 0.0;
volatile double shaft_angle;
volatile uint32_t now_ts = DL_SYSTICK_getValue();
if (now_ts < openloop_timestamp) {
Ts = (openloop_timestamp - now_ts) / 80.0f * 1e-6f;
} else {
Ts = (0xFFFFFF - now_ts + openloop_timestamp) / 80.0f * 1e-6f;
}
if (Ts < 0 || Ts >= 0.005) {
Ts = 0.001f;
}
shaft_angle = normalizeAngle(shaft_angle + pp * target * Ts);
if (DEBUG_ENABLED) {
printf("shaft_angle : %f -- Ts : %f \n", shaft_angle, Ts);
}
Uq = VOLTAGE_LIMIT;
SetPhaseVoltage(Uq, 0, shaft_angle);
openloop_timestamp = now_ts;
return Uq;
// 单速度环
void M0_Set_Velocity(float Target) {
Angle_Sensor0.velocity =
Lowpassfilter(&M0_VEL_Filter, GetVelocity(&Angle_Sensor0));
SetPhaseVoltage(
&M0,
PID_Controller(&M0_VEL_PID, M0_DIR * (Target - Angle_Sensor0.velocity)),
M0_electricAngle());
}
void M1_Set_Velocity(float Target) {
Angle_Sensor1.velocity =
Lowpassfilter(&M1_VEL_Filter, GetVelocity(&Angle_Sensor1));
SetPhaseVoltage(
&M1,
PID_Controller(&M1_VEL_PID, M1_DIR * (Target - Angle_Sensor1.velocity)),
M1_electricAngle());
}