mirror of https://github.com/rusefi/bldc.git
Added configurable PID loop rate and more AUX port modes
This commit is contained in:
parent
804f49b2a8
commit
3c88ecb7aa
|
@ -30,6 +30,8 @@
|
|||
* Added kill switch support.
|
||||
* Added process derivative term to position controller.
|
||||
* Added position PID-controller angle offset.
|
||||
* Configurable PID controller rate.
|
||||
* Added several AUX port modes.
|
||||
|
||||
=== FW 5.02 ===
|
||||
* IMU calibration improvement.
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#define FW_VERSION_MAJOR 5
|
||||
#define FW_VERSION_MINOR 03
|
||||
// Set to 0 for building a release and iterate during beta test builds
|
||||
#define FW_TEST_VERSION_NUMBER 44
|
||||
#define FW_TEST_VERSION_NUMBER 45
|
||||
|
||||
#include "datatypes.h"
|
||||
|
||||
|
|
|
@ -133,6 +133,7 @@ int32_t confgenerator_serialize_mcconf(uint8_t *buffer, const mc_configuration *
|
|||
buffer_append_float16(buffer, conf->gpd_current_filter_const, 10000, &ind);
|
||||
buffer_append_float32_auto(buffer, conf->gpd_current_kp, &ind);
|
||||
buffer_append_float32_auto(buffer, conf->gpd_current_ki, &ind);
|
||||
buffer[ind++] = conf->sp_pid_loop_rate;
|
||||
buffer_append_float32_auto(buffer, conf->s_pid_kp, &ind);
|
||||
buffer_append_float32_auto(buffer, conf->s_pid_ki, &ind);
|
||||
buffer_append_float32_auto(buffer, conf->s_pid_kd, &ind);
|
||||
|
@ -495,6 +496,7 @@ bool confgenerator_deserialize_mcconf(const uint8_t *buffer, mc_configuration *c
|
|||
conf->gpd_current_filter_const = buffer_get_float16(buffer, 10000, &ind);
|
||||
conf->gpd_current_kp = buffer_get_float32_auto(buffer, &ind);
|
||||
conf->gpd_current_ki = buffer_get_float32_auto(buffer, &ind);
|
||||
conf->sp_pid_loop_rate = buffer[ind++];
|
||||
conf->s_pid_kp = buffer_get_float32_auto(buffer, &ind);
|
||||
conf->s_pid_ki = buffer_get_float32_auto(buffer, &ind);
|
||||
conf->s_pid_kd = buffer_get_float32_auto(buffer, &ind);
|
||||
|
@ -853,6 +855,7 @@ void confgenerator_set_defaults_mcconf(mc_configuration *conf) {
|
|||
conf->gpd_current_filter_const = MCCONF_GPD_CURRENT_FILTER_CONST;
|
||||
conf->gpd_current_kp = MCCONF_GPD_CURRENT_KP;
|
||||
conf->gpd_current_ki = MCCONF_GPD_CURRENT_KI;
|
||||
conf->sp_pid_loop_rate = MCCONF_SP_PID_LOOP_RATE;
|
||||
conf->s_pid_kp = MCCONF_S_PID_KP;
|
||||
conf->s_pid_ki = MCCONF_S_PID_KI;
|
||||
conf->s_pid_kd = MCCONF_S_PID_KD;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include <stdbool.h>
|
||||
|
||||
// Constants
|
||||
#define MCCONF_SIGNATURE 2236691136
|
||||
#define MCCONF_SIGNATURE 3706516163
|
||||
#define APPCONF_SIGNATURE 2302012416
|
||||
|
||||
// Functions
|
||||
|
|
20
datatypes.h
20
datatypes.h
|
@ -72,6 +72,12 @@ typedef enum {
|
|||
OUT_AUX_MODE_UNUSED,
|
||||
OUT_AUX_MODE_ON_WHEN_RUNNING,
|
||||
OUT_AUX_MODE_ON_WHEN_NOT_RUNNING,
|
||||
OUT_AUX_MODE_MOTOR_50,
|
||||
OUT_AUX_MODE_MOSFET_50,
|
||||
OUT_AUX_MODE_MOTOR_70,
|
||||
OUT_AUX_MODE_MOSFET_70,
|
||||
OUT_AUX_MODE_MOTOR_MOSFET_50,
|
||||
OUT_AUX_MODE_MOTOR_MOSFET_70,
|
||||
} out_aux_mode;
|
||||
|
||||
// Temperature sensor type
|
||||
|
@ -285,6 +291,18 @@ typedef struct {
|
|||
bool is_charge_allowed;
|
||||
} bms_soc_soh_temp_stat;
|
||||
|
||||
typedef enum {
|
||||
PID_RATE_25_HZ = 0,
|
||||
PID_RATE_50_HZ,
|
||||
PID_RATE_100_HZ,
|
||||
PID_RATE_250_HZ,
|
||||
PID_RATE_500_HZ,
|
||||
PID_RATE_1000_HZ,
|
||||
PID_RATE_2500_HZ,
|
||||
PID_RATE_5000_HZ,
|
||||
PID_RATE_10000_HZ,
|
||||
} PID_RATE;
|
||||
|
||||
typedef struct {
|
||||
// Limits
|
||||
float l_current_max;
|
||||
|
@ -409,6 +427,8 @@ typedef struct {
|
|||
float gpd_current_kp;
|
||||
float gpd_current_ki;
|
||||
|
||||
PID_RATE sp_pid_loop_rate;
|
||||
|
||||
// Speed PID
|
||||
float s_pid_kp;
|
||||
float s_pid_ki;
|
||||
|
|
|
@ -2323,6 +2323,9 @@ static void run_timer_tasks(volatile motor_if_state_t *motor) {
|
|||
|
||||
// Update auxiliary output
|
||||
switch (motor->m_conf.m_out_aux_mode) {
|
||||
case OUT_AUX_MODE_UNUSED:
|
||||
break;
|
||||
|
||||
case OUT_AUX_MODE_OFF:
|
||||
AUX_OFF();
|
||||
break;
|
||||
|
@ -2361,7 +2364,30 @@ static void run_timer_tasks(volatile motor_if_state_t *motor) {
|
|||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
case OUT_AUX_MODE_MOTOR_50:
|
||||
if (mc_interface_temp_motor_filtered() > 50.0) {AUX_ON();} else {AUX_OFF();}
|
||||
break;
|
||||
|
||||
case OUT_AUX_MODE_MOSFET_50:
|
||||
if (mc_interface_temp_fet_filtered() > 50.0) {AUX_ON();} else {AUX_OFF();}
|
||||
break;
|
||||
|
||||
case OUT_AUX_MODE_MOTOR_70:
|
||||
if (mc_interface_temp_motor_filtered() > 70.0) {AUX_ON();} else {AUX_OFF();}
|
||||
break;
|
||||
|
||||
case OUT_AUX_MODE_MOSFET_70:
|
||||
if (mc_interface_temp_fet_filtered() > 70.0) {AUX_ON();} else {AUX_OFF();}
|
||||
break;
|
||||
|
||||
case OUT_AUX_MODE_MOTOR_MOSFET_50:
|
||||
if (mc_interface_temp_motor_filtered() > 50.0 ||
|
||||
mc_interface_temp_fet_filtered() > 50.0) {AUX_ON();} else {AUX_OFF();}
|
||||
break;
|
||||
|
||||
case OUT_AUX_MODE_MOTOR_MOSFET_70:
|
||||
if (mc_interface_temp_motor_filtered() > 70.0 ||
|
||||
mc_interface_temp_fet_filtered() > 70.0) {AUX_ON();} else {AUX_OFF();}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -117,6 +117,11 @@
|
|||
#define MCCONF_L_DUTY_START 1.0 // Start limiting current at this duty cycle
|
||||
#endif
|
||||
|
||||
// Common PID-parameters
|
||||
#ifndef MCCONF_SP_PID_LOOP_RATE
|
||||
#define MCCONF_SP_PID_LOOP_RATE PID_RATE_1000_HZ // PID loop rate
|
||||
#endif
|
||||
|
||||
// Speed PID parameters
|
||||
#ifndef MCCONF_S_PID_KP
|
||||
#define MCCONF_S_PID_KP 0.004 // Proportional gain
|
||||
|
|
64
mcpwm_foc.c
64
mcpwm_foc.c
|
@ -201,7 +201,7 @@ static void control_current(volatile motor_all_state_t *motor, float dt);
|
|||
static void update_valpha_vbeta(volatile motor_all_state_t *motor, float mod_alpha, float mod_beta);
|
||||
static void svm(float alpha, float beta, uint32_t PWMHalfPeriod,
|
||||
uint32_t* tAout, uint32_t* tBout, uint32_t* tCout, uint32_t *svm_sector);
|
||||
static void run_pid_control_pos(float angle_now, float angle_set, float dt, volatile motor_all_state_t *motor);
|
||||
static void run_pid_control_pos(float dt, volatile motor_all_state_t *motor);
|
||||
static void run_pid_control_speed(float dt, volatile motor_all_state_t *motor);
|
||||
static void stop_pwm_hw(volatile motor_all_state_t *motor);
|
||||
static void start_pwm_hw(volatile motor_all_state_t *motor);
|
||||
|
@ -223,6 +223,10 @@ static THD_WORKING_AREA(hfi_thread_wa, 1024);
|
|||
static THD_FUNCTION(hfi_thread, arg);
|
||||
static volatile bool hfi_thd_stop;
|
||||
|
||||
static THD_WORKING_AREA(pid_thread_wa, 512);
|
||||
static THD_FUNCTION(pid_thread, arg);
|
||||
static volatile bool pid_thd_stop;
|
||||
|
||||
// Macros
|
||||
#ifdef HW_HAS_3_SHUNTS
|
||||
#define TIMER_UPDATE_DUTY_M1(duty1, duty2, duty3) \
|
||||
|
@ -660,6 +664,9 @@ void mcpwm_foc_init(volatile mc_configuration *conf_m1, volatile mc_configuratio
|
|||
hfi_thd_stop = false;
|
||||
chThdCreateStatic(hfi_thread_wa, sizeof(hfi_thread_wa), NORMALPRIO, hfi_thread, NULL);
|
||||
|
||||
pid_thd_stop = false;
|
||||
chThdCreateStatic(pid_thread_wa, sizeof(pid_thread_wa), NORMALPRIO, pid_thread, NULL);
|
||||
|
||||
// Check if the system has resumed from IWDG reset
|
||||
if (timeout_had_IWDG_reset()) {
|
||||
mc_interface_fault_stop(FAULT_CODE_BOOTING_FROM_WATCHDOG_RESET, false, false);
|
||||
|
@ -697,6 +704,11 @@ void mcpwm_foc_deinit(void) {
|
|||
chThdSleepMilliseconds(1);
|
||||
}
|
||||
|
||||
pid_thd_stop = true;
|
||||
while (pid_thd_stop) {
|
||||
chThdSleepMilliseconds(1);
|
||||
}
|
||||
|
||||
TIM_DeInit(TIM1);
|
||||
TIM_DeInit(TIM2);
|
||||
TIM_DeInit(TIM8);
|
||||
|
@ -3334,13 +3346,6 @@ static THD_FUNCTION(timer_thread, arg) {
|
|||
|
||||
input_current_offset_measurement();
|
||||
|
||||
run_pid_control_speed(dt, &m_motor_1);
|
||||
run_pid_control_pos(m_motor_1.m_pos_pid_now, m_motor_1.m_pos_pid_set, dt, &m_motor_1);
|
||||
#ifdef HW_HAS_DUAL_MOTORS
|
||||
run_pid_control_speed(dt, &m_motor_2);
|
||||
run_pid_control_pos(m_motor_2.m_pos_pid_now, m_motor_2.m_pos_pid_set, dt, &m_motor_2);
|
||||
#endif
|
||||
|
||||
chThdSleepMilliseconds(1);
|
||||
}
|
||||
}
|
||||
|
@ -3489,6 +3494,43 @@ static THD_FUNCTION(hfi_thread, arg) {
|
|||
}
|
||||
}
|
||||
|
||||
static THD_FUNCTION(pid_thread, arg) {
|
||||
(void)arg;
|
||||
|
||||
chRegSetThreadName("foc pid");
|
||||
|
||||
uint32_t last_time = timer_time_now();
|
||||
|
||||
for(;;) {
|
||||
if (pid_thd_stop) {
|
||||
pid_thd_stop = false;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (m_motor_1.m_conf->sp_pid_loop_rate) {
|
||||
case PID_RATE_25_HZ: chThdSleepMicroseconds(1000000 / 25); break;
|
||||
case PID_RATE_50_HZ: chThdSleepMicroseconds(1000000 / 50); break;
|
||||
case PID_RATE_100_HZ: chThdSleepMicroseconds(1000000 / 100); break;
|
||||
case PID_RATE_250_HZ: chThdSleepMicroseconds(1000000 / 250); break;
|
||||
case PID_RATE_500_HZ: chThdSleepMicroseconds(1000000 / 500); break;
|
||||
case PID_RATE_1000_HZ: chThdSleepMicroseconds(1000000 / 1000); break;
|
||||
case PID_RATE_2500_HZ: chThdSleepMicroseconds(1000000 / 2500); break;
|
||||
case PID_RATE_5000_HZ: chThdSleepMicroseconds(1000000 / 5000); break;
|
||||
case PID_RATE_10000_HZ: chThdSleepMicroseconds(1000000 / 10000); break;
|
||||
}
|
||||
|
||||
float dt = timer_seconds_elapsed_since(last_time);
|
||||
last_time = timer_time_now();
|
||||
|
||||
run_pid_control_pos(dt, &m_motor_1);
|
||||
run_pid_control_speed(dt, &m_motor_1);
|
||||
#ifdef HW_HAS_DUAL_MOTORS
|
||||
run_pid_control_pos(dt, &m_motor_2);
|
||||
run_pid_control_speed(dt, &m_motor_2);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// See http://cas.ensmp.fr/~praly/Telechargement/Journaux/2010-IEEE_TPEL-Lee-Hong-Nam-Ortega-Praly-Astolfi.pdf
|
||||
void observer_update(float v_alpha, float v_beta, float i_alpha, float i_beta,
|
||||
float dt, volatile float *x1, volatile float *x2, volatile float *phase, volatile motor_all_state_t *motor) {
|
||||
|
@ -4108,8 +4150,12 @@ static void svm(float alpha, float beta, uint32_t PWMHalfPeriod,
|
|||
*svm_sector = sector;
|
||||
}
|
||||
|
||||
static void run_pid_control_pos(float angle_now, float angle_set, float dt, volatile motor_all_state_t *motor) {
|
||||
static void run_pid_control_pos(float dt, volatile motor_all_state_t *motor) {
|
||||
volatile mc_configuration *conf_now = motor->m_conf;
|
||||
|
||||
float angle_now = motor->m_pos_pid_now;
|
||||
float angle_set = motor->m_pos_pid_set;
|
||||
|
||||
float p_term;
|
||||
float d_term;
|
||||
float d_term_proc;
|
||||
|
|
Loading…
Reference in New Issue