Added configurable PID loop rate and more AUX port modes

This commit is contained in:
Benjamin Vedder 2021-07-12 14:31:01 +02:00
parent 804f49b2a8
commit 3c88ecb7aa
8 changed files with 114 additions and 12 deletions

View File

@ -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.

View File

@ -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"

View File

@ -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;

View File

@ -8,7 +8,7 @@
#include <stdbool.h>
// Constants
#define MCCONF_SIGNATURE 2236691136
#define MCCONF_SIGNATURE 3706516163
#define APPCONF_SIGNATURE 2302012416
// Functions

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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;