Skip to content

Commit e1c859c

Browse files
committed
Current controller windup protection improvement
1 parent 5df9246 commit e1c859c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+30
-20
lines changed

CHANGELOG

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* App balance updates. See https://github.com/vedderb/bldc/pull/138.
44
* Changed FOC time constant back to 1000 us.
55
* Do not count AS5047 all ones as fault.
6+
* Improved axis decoupling and integrator windup protection. Should prevent wobbles.
67

78
=== FW 4.01 ===
89
* Leave debug mode on NRF5x after disconnect to avoid excess power consumption before power cycle.

build_all/100_250/VESC_default.bin

0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.

build_all/100_250/VESC_servoout.bin

0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.
Binary file not shown.
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.

build_all/46_o_47/VESC_0005ohm.bin

0 Bytes
Binary file not shown.

build_all/46_o_47/VESC_33k.bin

0 Bytes
Binary file not shown.

build_all/46_o_47/VESC_default.bin

0 Bytes
Binary file not shown.

build_all/46_o_47/VESC_servoout.bin

0 Bytes
Binary file not shown.

build_all/46_o_47/VESC_ws2811.bin

0 Bytes
Binary file not shown.

build_all/46_o_47/VESC_ws2811_33k.bin

0 Bytes
Binary file not shown.

build_all/48/VESC_0005ohm.bin

0 Bytes
Binary file not shown.

build_all/48/VESC_default.bin

0 Bytes
Binary file not shown.

build_all/48/VESC_servoout.bin

0 Bytes
Binary file not shown.

build_all/48/VESC_ws2811.bin

0 Bytes
Binary file not shown.

build_all/60/VESC_default.bin

0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.

build_all/60/VESC_servoout.bin

0 Bytes
Binary file not shown.

build_all/60/VESC_ws2811.bin

0 Bytes
Binary file not shown.

build_all/60_MK3/VESC_default.bin

0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.

build_all/60_MK3/VESC_servoout.bin

0 Bytes
Binary file not shown.

build_all/60_MK3/VESC_ws2811.bin

0 Bytes
Binary file not shown.

build_all/75_300/VESC_default.bin

0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.

build_all/75_300/VESC_servoout.bin

0 Bytes
Binary file not shown.

build_all/75_300/VESC_ws2811.bin

0 Bytes
Binary file not shown.

build_all/75_300_R2/VESC_default.bin

0 Bytes
Binary file not shown.
Binary file not shown.

build_all/75_300_R2/VESC_servoout.bin

0 Bytes
Binary file not shown.

build_all/75_300_R2/VESC_ws2811.bin

0 Bytes
Binary file not shown.

build_all/A200S_V21/VESC_default.bin

0 Bytes
Binary file not shown.

build_all/A200S_V22/VESC_default.bin

0 Bytes
Binary file not shown.

build_all/AXIOM/VESC_default.bin

0 Bytes
Binary file not shown.

build_all/DAS_RS/VESC_default.bin

0 Bytes
Binary file not shown.

build_all/HD/VESC_default.bin

0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.

build_all/HD/VESC_servoout.bin

0 Bytes
Binary file not shown.

build_all/HD/VESC_ws2811.bin

0 Bytes
Binary file not shown.

build_all/LUNA_BBSHD/VESC_default.bin

0 Bytes
Binary file not shown.

build_all/UAVC_OMEGA/VESC_default.bin

0 Bytes
Binary file not shown.

mcpwm_foc.c

+29-20
Original file line numberDiff line numberDiff line change
@@ -2804,6 +2804,7 @@ static void control_current(volatile motor_state_t *state_m, float dt) {
28042804
// Decoupling
28052805
float dec_vd = 0.0;
28062806
float dec_vq = 0.0;
2807+
float dec_bemf = 0.0;
28072808

28082809
if (m_control_mode < CONTROL_MODE_HANDBRAKE && m_conf->foc_cc_decoupling != FOC_CC_DECOUPLING_DISABLED) {
28092810
switch (m_conf->foc_cc_decoupling) {
@@ -2813,12 +2814,13 @@ static void control_current(volatile motor_state_t *state_m, float dt) {
28132814
break;
28142815

28152816
case FOC_CC_DECOUPLING_BEMF:
2816-
dec_vq = state_m->speed_rad_s * m_conf->foc_motor_flux_linkage;
2817+
dec_bemf = state_m->speed_rad_s * m_conf->foc_motor_flux_linkage;
28172818
break;
28182819

28192820
case FOC_CC_DECOUPLING_CROSS_BEMF:
28202821
dec_vd = state_m->iq * state_m->speed_rad_s * m_conf->foc_motor_l;
2821-
dec_vq = state_m->id * state_m->speed_rad_s * m_conf->foc_motor_l + state_m->speed_rad_s * m_conf->foc_motor_flux_linkage;
2822+
dec_vq = state_m->id * state_m->speed_rad_s * m_conf->foc_motor_l;
2823+
dec_bemf = state_m->speed_rad_s * m_conf->foc_motor_flux_linkage;
28222824
break;
28232825

28242826
default:
@@ -2827,7 +2829,7 @@ static void control_current(volatile motor_state_t *state_m, float dt) {
28272829
}
28282830

28292831
state_m->vd -= dec_vd;
2830-
state_m->vq += dec_vq;
2832+
state_m->vq += dec_vq + dec_bemf;
28312833

28322834
float max_v_mag = (2.0 / 3.0) * max_duty * SQRT3_BY_2 * state_m->v_bus;
28332835

@@ -2838,23 +2840,30 @@ static void control_current(volatile motor_state_t *state_m, float dt) {
28382840

28392841
// Integrator windup protection
28402842
// This is important, tricky and probably needs improvement.
2841-
// Currently we check if the integrator causes over modulation and decrease the components
2842-
// that contribute to the over modulation.
2843-
float int_over_mod = sqrtf(SQ(state_m->vd_int - dec_vd) + SQ(state_m->vq_int + dec_vq)) - max_v_mag;
2844-
float max_int_over_mod = -0.1;
2845-
if (int_over_mod > max_int_over_mod) {
2846-
float diff_vd = fabsf((state_m->vd_int - dec_vd)) - fabsf(dec_vd);
2847-
float diff_vq = fabsf((state_m->vq_int + dec_vq)) - fabsf(dec_vq);
2848-
int_over_mod -= max_int_over_mod;
2849-
float dec_gain = 0.03;
2850-
2851-
if (diff_vd > 0.0) {
2852-
state_m->vd_int *= 1.0 - dec_gain * int_over_mod;
2853-
}
2854-
if (diff_vq > 0.0) {
2855-
state_m->vq_int *= 1.0 - dec_gain * int_over_mod;
2856-
}
2857-
}
2843+
// Currently we start by truncating the d-axis and then the q-axis with the magnitude that is
2844+
// left. Axis decoupling is taken into account in the truncation. How to do that best is also
2845+
// an open question...
2846+
2847+
// Take both cross and back emf decoupling into consideration. Seems to make the control
2848+
// noisy at full modulation.
2849+
// utils_truncate_number((float*)&state_m->vd_int, -max_v_mag + dec_vd, max_v_mag + dec_vd);
2850+
// float mag_left = sqrtf(SQ(max_v_mag) - SQ(state_m->vd_int - dec_vd));
2851+
// utils_truncate_number((float*)&state_m->vq_int, -mag_left - (dec_vq + dec_bemf), mag_left - (dec_vq + dec_bemf));
2852+
2853+
// Take only back emf decoupling into consideration. Seems to work best.
2854+
utils_truncate_number((float*)&state_m->vd_int, -max_v_mag, max_v_mag);
2855+
float mag_left = sqrtf(SQ(max_v_mag) - SQ(state_m->vd_int));
2856+
utils_truncate_number((float*)&state_m->vq_int, -mag_left - dec_bemf, mag_left - dec_bemf);
2857+
2858+
// Ignore decoupling. Works badly when back emf decoupling is used, probably not
2859+
// the best way to go.
2860+
// utils_truncate_number((float*)&state_m->vd_int, -max_v_mag, max_v_mag);
2861+
// float mag_left = sqrtf(SQ(max_v_mag) - SQ(state_m->vd_int));
2862+
// utils_truncate_number((float*)&state_m->vq_int, -mag_left, mag_left);
2863+
2864+
// This is how anti-windup was done in FW < 4.0. Does not work well when there is too much D axis voltage.
2865+
// utils_truncate_number((float*)&state_m->vd_int, -max_v_mag, max_v_mag);
2866+
// utils_truncate_number((float*)&state_m->vq_int, -max_v_mag, max_v_mag);
28582867

28592868
// TODO: Have a look at this?
28602869
state_m->i_bus = state_m->mod_d * state_m->id + state_m->mod_q * state_m->iq;

0 commit comments

Comments
 (0)