|
|
@@ -35,12 +35,13 @@ static shark_timer_t _led_off_timer = TIMER_INIT(_led_off_timer, _led_off_timer_
|
|
|
m_contrl_t motor = {
|
|
|
.s_direction = POSITIVE,
|
|
|
.n_gear = 0,
|
|
|
- .b_is96Mode = false,
|
|
|
+ .b_high_vol_mode = false,
|
|
|
.mode = CTRL_MODE_OPEN,
|
|
|
.mos_lim = 0,
|
|
|
.motor_lim = 0,
|
|
|
.b_ind_start = false,
|
|
|
.s_target_speed = MAX_S16,
|
|
|
+ .s_force_torque = MAX_S16,
|
|
|
.u_set.idc_lim = IDC_USER_LIMIT_NONE,
|
|
|
.u_set.rpm_lim = RPM_USER_LIMIT_NONE,
|
|
|
.u_set.ebrk_lvl = 0,
|
|
|
@@ -175,13 +176,13 @@ static u32 _self_check_task(void *p) {
|
|
|
}
|
|
|
|
|
|
static bool mc_detect_vbus_mode(void) {
|
|
|
-#ifdef CONFIG_FORCE_96V_MODE
|
|
|
- motor.b_is96Mode = true;
|
|
|
+#ifdef CONFIG_FORCE_HIGH_VOL_MODE
|
|
|
+ motor.b_high_vol_mode = true;
|
|
|
return false;
|
|
|
#else
|
|
|
- bool is_96mode = motor.b_is96Mode;
|
|
|
- motor.b_is96Mode = get_vbus_int() >= CONFIG_96V_MODE_VOL;
|
|
|
- return (is_96mode != motor.b_is96Mode);
|
|
|
+ bool is_96mode = motor.b_high_vol_mode;
|
|
|
+ motor.b_high_vol_mode = get_vbus_int() >= CONFIG_HIGH_VOL_MODE_MIN_VOL;
|
|
|
+ return (is_96mode != motor.b_high_vol_mode);
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
@@ -211,8 +212,8 @@ static void _led_off_timer_handler(shark_timer_t *t) {
|
|
|
}
|
|
|
|
|
|
|
|
|
-static void mc_gear_vmode_changed(void) {
|
|
|
- gear_t *gears = mc_get_gear_config();
|
|
|
+static void mc_gear_mode_set(void) {
|
|
|
+ gear_t *gears = mc_gear_conf();
|
|
|
if (gears != &sensorless_gear) {
|
|
|
sensorless_gear.max_torque = gears->max_torque;
|
|
|
}else { //slowly changed
|
|
|
@@ -222,7 +223,6 @@ static void mc_gear_vmode_changed(void) {
|
|
|
mot_contrl_set_vel_limit(&motor.controller, (float)min(gears->max_speed, motor.u_set.rpm_lim));
|
|
|
mot_contrl_set_dccurr_limit(&motor.controller, (float)min(gears->max_idc, motor.u_set.idc_lim));
|
|
|
mot_contrl_set_torque_limit(&motor.controller, (float)gears->max_torque);
|
|
|
- sys_debug("change %d, %d, %d\n", gears->max_idc, gears->max_speed, gears->max_torque);
|
|
|
}
|
|
|
|
|
|
void mc_init(void) {
|
|
|
@@ -248,12 +248,12 @@ m_contrl_t * mc_params(void) {
|
|
|
return &motor;
|
|
|
}
|
|
|
|
|
|
-gear_t *mc_get_gear_config_by_gear(u8 n_gear) {
|
|
|
+gear_t *mc_gear_conf_by_gear(u8 n_gear) {
|
|
|
gear_t *gears;
|
|
|
if (!foc_observer_is_encoder()) { //无感模式,受限运行
|
|
|
return &sensorless_gear;
|
|
|
}
|
|
|
- if (motor.b_is96Mode) {
|
|
|
+ if (motor.b_high_vol_mode) {
|
|
|
gears = &mc_conf()->g_n[0];
|
|
|
}else {
|
|
|
gears = &mc_conf()->g_l[0];
|
|
|
@@ -261,42 +261,33 @@ gear_t *mc_get_gear_config_by_gear(u8 n_gear) {
|
|
|
return &gears[n_gear];
|
|
|
}
|
|
|
|
|
|
-gear_t *mc_get_gear_config(void) {
|
|
|
- return mc_get_gear_config_by_gear(motor.n_gear);
|
|
|
+gear_t *mc_gear_conf(void) {
|
|
|
+ return mc_gear_conf_by_gear(motor.n_gear);
|
|
|
}
|
|
|
|
|
|
static __INLINE float gear_rpm_2_torque(u8 torque, s16 max) {
|
|
|
return (float)torque/100.0f * max;
|
|
|
}
|
|
|
|
|
|
-float mc_get_max_torque_with_gear_vel(s16 vel, u8 gear) {
|
|
|
- gear_t *_current_gear = mc_get_gear_config_by_gear(gear);
|
|
|
- if (_current_gear == NULL) {
|
|
|
+float mc_gear_max_torque(s16 vel, u8 gear_n) {
|
|
|
+ gear_t *gear = mc_gear_conf_by_gear(gear_n);
|
|
|
+ if (gear == NULL) {
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- if (vel > _current_gear->max_speed) {
|
|
|
- vel = _current_gear->max_speed;
|
|
|
- }
|
|
|
vel = ABS(vel);
|
|
|
if (vel <= 1000) {
|
|
|
- return gear_rpm_2_torque(_current_gear->torque[0], _current_gear->max_torque);
|
|
|
+ return gear_rpm_2_torque(gear->torque[0], gear->max_torque);
|
|
|
}
|
|
|
-
|
|
|
- for (int i = 1; i < CONFIG_GEAR_SPEED_TRQ_NUM; i++) {
|
|
|
- if (vel <= 1000 * (i + 1)) { //线性插值
|
|
|
- float trq1 = gear_rpm_2_torque(_current_gear->torque[i-1], _current_gear->max_torque);
|
|
|
- float min_rpm = (i * 1000);
|
|
|
- float trq2 = gear_rpm_2_torque(_current_gear->torque[i], _current_gear->max_torque);
|
|
|
- float max_rpm = (i + 1) * 1000;
|
|
|
- if (trq1 > trq2) {
|
|
|
- return f_map_inv((float)vel, min_rpm, max_rpm, trq2, trq1);
|
|
|
- }else {
|
|
|
- return f_map((float)vel, min_rpm, max_rpm, trq1, trq2);
|
|
|
- }
|
|
|
- }
|
|
|
+ int vel_idx = vel / 1000;
|
|
|
+ if (vel_idx >= CONFIG_GEAR_SPEED_TRQ_NUM -1 ) {
|
|
|
+ return gear_rpm_2_torque(gear->torque[CONFIG_GEAR_SPEED_TRQ_NUM-1], gear->max_torque);
|
|
|
}
|
|
|
- return gear_rpm_2_torque(_current_gear->torque[CONFIG_GEAR_SPEED_TRQ_NUM-1], _current_gear->max_torque);
|
|
|
+ float torque_1 = gear_rpm_2_torque(gear->torque[vel_idx-1], gear->max_torque);
|
|
|
+ float min_rpm = vel_idx * 1000;
|
|
|
+ float torque_2 = gear_rpm_2_torque(gear->torque[vel_idx], gear->max_torque);
|
|
|
+ float max_rpm = min_rpm + 1000;
|
|
|
+ return f_map((float)vel, min_rpm, max_rpm, torque_1, torque_2);
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -348,6 +339,7 @@ bool mc_start(u8 mode) {
|
|
|
#ifdef CONFIG_DQ_STEP_RESPONSE
|
|
|
mode = CTRL_MODE_CURRENT;
|
|
|
#endif
|
|
|
+ motor.s_force_torque = MAX_S16;
|
|
|
mc_detect_vbus_mode();
|
|
|
etcs_enable(&motor.controller.etcs, motor.u_set.b_tcs);
|
|
|
if (motor.b_lock_motor) {
|
|
|
@@ -372,16 +364,20 @@ bool mc_start(u8 mode) {
|
|
|
mot_contrl_set_error(&motor.controller, FOC_Throttle_Err);
|
|
|
return false;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
pwm_up_enable(false);
|
|
|
|
|
|
- _mc_internal_init(mode, true);
|
|
|
+ u32 mask = cpu_enter_critical();
|
|
|
|
|
|
+ _mc_internal_init(mode, true);
|
|
|
throttle_torque_reset();
|
|
|
- mc_gear_vmode_changed();
|
|
|
- mot_contrl_set_torque_ramp_time(&motor.controller, mc_get_gear_config()->zero_accl, mc_conf()->c.thro_dec_time);
|
|
|
motor_encoder_start(true);
|
|
|
mot_contrl_start(&motor.controller, mode);
|
|
|
+ mot_contrl_set_torque_ramp_time(&motor.controller, mc_gear_conf()->zero_accl, mc_conf()->c.thro_dec_time);
|
|
|
+ mc_set_ebrk_level(motor.u_set.ebrk_lvl);
|
|
|
+ mc_gear_mode_set();
|
|
|
+ cpu_exit_critical(mask);
|
|
|
+
|
|
|
pwm_turn_on_low_side();
|
|
|
delay_ms(10);
|
|
|
phase_current_offset_calibrate();
|
|
|
@@ -401,7 +397,6 @@ bool mc_start(u8 mode) {
|
|
|
if (mc_detect_hwbrake()) {
|
|
|
mot_contrl_set_hw_brake(&motor.controller, true);
|
|
|
}
|
|
|
- gpio_beep(200);
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
@@ -459,7 +454,7 @@ bool mc_set_gear(u8 gear) {
|
|
|
if (motor.n_gear != gear) {
|
|
|
u32 mask = cpu_enter_critical();
|
|
|
motor.n_gear = gear;
|
|
|
- mc_gear_vmode_changed();
|
|
|
+ mc_gear_mode_set();
|
|
|
cpu_exit_critical(mask);
|
|
|
}
|
|
|
return true;
|
|
|
@@ -505,6 +500,18 @@ bool mc_set_target_vel(s16 vel) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+bool mc_set_force_torque(s16 torque) {
|
|
|
+ if (motor.mode != CTRL_MODE_TRQ) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (torque == MAX_S16) {
|
|
|
+ motor.s_force_torque = MAX_S16;
|
|
|
+ }else {
|
|
|
+ motor.s_force_torque = fclamp(torque, -mc_gear_conf()->max_torque, mc_gear_conf()->max_torque);
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
bool mc_is_cruise_enabled(void) {
|
|
|
return motor.b_cruise;
|
|
|
}
|
|
|
@@ -528,7 +535,7 @@ void mc_set_idc_limit(s16 limit) {
|
|
|
return;
|
|
|
}
|
|
|
motor.u_set.idc_lim = limit;
|
|
|
- mc_gear_vmode_changed();
|
|
|
+ mc_gear_mode_set();
|
|
|
}
|
|
|
|
|
|
void mc_set_rpm_limit(s16 limit) {
|
|
|
@@ -536,7 +543,7 @@ void mc_set_rpm_limit(s16 limit) {
|
|
|
return;
|
|
|
}
|
|
|
motor.u_set.rpm_lim = limit;
|
|
|
- mc_gear_vmode_changed();
|
|
|
+ mc_gear_mode_set();
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -592,7 +599,7 @@ bool mc_set_foc_mode(u8 mode) {
|
|
|
bool ret = false;
|
|
|
if (mot_contrl_request_mode(&motor.controller, mode)) {
|
|
|
motor.mode = mode;
|
|
|
- if (mode == CTRL_MODE_OPEN || mode == CTRL_MODE_CURRENT) {
|
|
|
+ if ((mode == CTRL_MODE_OPEN || mode == CTRL_MODE_CURRENT) && !mot_contrl_is_start(&motor.controller)) {
|
|
|
mot_contrl_start(&motor.controller, motor.mode);
|
|
|
pwm_enable_channel();
|
|
|
}
|
|
|
@@ -636,7 +643,7 @@ bool mc_start_epm(bool epm) {
|
|
|
mot_contrl_request_mode(&motor.controller, CTRL_MODE_TRQ);
|
|
|
mot_contrl_set_torque_limit_rttime(&motor.controller, CONFIG_LIMIT_RAMP_TIME);
|
|
|
mot_contrl_set_vel_rttime(&motor.controller, CONFIG_CRUISE_RAMP_TIME);
|
|
|
- mc_gear_vmode_changed();
|
|
|
+ mc_gear_mode_set();
|
|
|
}
|
|
|
cpu_exit_critical(mask);
|
|
|
|
|
|
@@ -670,7 +677,7 @@ bool mc_start_epm_move(epm_dir_t dir, bool is_command) {
|
|
|
|
|
|
if (!mot_contrl_is_start(&motor.controller)) {
|
|
|
mot_contrl_start(&motor.controller, motor.mode);
|
|
|
- mc_gear_vmode_changed();
|
|
|
+ mc_gear_mode_set();
|
|
|
pwm_enable_channel();
|
|
|
}else if (mot_contrl_is_auto_holdding(&motor.controller)) {
|
|
|
mc_auto_hold(false);
|
|
|
@@ -993,6 +1000,9 @@ u32 mc_get_critical_error(void) {
|
|
|
}
|
|
|
|
|
|
bool mc_throttle_released(void) {
|
|
|
+ if (motor.s_force_torque != MAX_S16) {
|
|
|
+ return motor.s_force_torque == 0;
|
|
|
+ }
|
|
|
if (motor.b_ignor_throttle) {
|
|
|
return motor.u_throttle_ration == 0;
|
|
|
}
|
|
|
@@ -1352,7 +1362,7 @@ static void mc_process_epm_move(void) {
|
|
|
target_vel = -mc_conf()->c.max_epm_back_rpm;
|
|
|
target_trq = mc_conf()->c.max_epm_back_torque;
|
|
|
}else if (!motor.b_epm_cmd_move) {
|
|
|
- target_vel = throttle_vol_to_open_ration(throttle_get_signal()) * 2.0f * (float)target_vel;
|
|
|
+ target_vel = throttle_vol_to_opening(throttle_get_signal()) * 2.0f * (float)target_vel;
|
|
|
}
|
|
|
motor.f_epm_trq = target_trq;
|
|
|
motor.f_epm_vel = target_vel;
|
|
|
@@ -1471,7 +1481,7 @@ static void mc_motor_runstop(void) {
|
|
|
if (!mot_contrl_is_start(&motor.controller) && mc_can_restart_foc()) {
|
|
|
mask = cpu_enter_critical();
|
|
|
mot_contrl_start(&motor.controller, motor.mode);
|
|
|
- mc_gear_vmode_changed();
|
|
|
+ mc_gear_mode_set();
|
|
|
throttle_torque_reset();
|
|
|
pwm_enable_channel();
|
|
|
g_meas_foc.first = true;
|
|
|
@@ -1518,7 +1528,7 @@ static void mc_process_throttle_torque(float vol) {
|
|
|
}
|
|
|
}
|
|
|
/*FOC 的部分处理,比如速度环,状态机,转把采集等*/
|
|
|
-measure_time_t g_meas_MCTask;
|
|
|
+measure_time_t g_meas_MCTask = {.exec_max_time = 100, .intval_max_time = 1000, .intval_low_err = 0, .intval_hi_err = 0, .first = true,};
|
|
|
#define mc_TaskStart time_measure_start(&g_meas_MCTask)
|
|
|
#define mc_TaskEnd time_measure_end(&g_meas_MCTask)
|
|
|
void Sched_MC_mTask(void) {
|
|
|
@@ -1536,7 +1546,6 @@ void Sched_MC_mTask(void) {
|
|
|
mc_process_curise();
|
|
|
#endif
|
|
|
u8 runMode = mot_contrl_mode(&motor.controller);
|
|
|
-
|
|
|
/*保护功能*/
|
|
|
u8 limted = mot_contrl_protect(&motor.controller);
|
|
|
/* 母线电流,实际采集的相电流矢量大小的计算 */
|
|
|
@@ -1560,7 +1569,7 @@ void Sched_MC_mTask(void) {
|
|
|
}
|
|
|
bool sensor_less = !foc_observer_is_encoder();
|
|
|
if (mc_detect_vbus_mode() || (limted == FOC_LIM_CHANGE_L) || (_sensorless_run != sensor_less)) {
|
|
|
- mc_gear_vmode_changed();
|
|
|
+ mc_gear_mode_set();
|
|
|
if (sensor_less && foc_observer_sensorless_stable()) {//unstable 记录在ADC中断处理中
|
|
|
if (motor_encoder_may_error() == ENCODER_PWM_ERR) {
|
|
|
mc_set_critical_error(FOC_CRIT_Encoder_Err);
|
|
|
@@ -1579,7 +1588,7 @@ void Sched_MC_mTask(void) {
|
|
|
/* 如果取消高温,欠压等限流需要释放转把后才生效,确保不会突然加速 */
|
|
|
if (motor.b_limit_pending && mc_throttle_released()) {
|
|
|
motor.b_limit_pending = false;
|
|
|
- mc_gear_vmode_changed();
|
|
|
+ mc_gear_mode_set();
|
|
|
}
|
|
|
/* 堵转处理 */
|
|
|
if (mc_run_stall_process(runMode) || (motor.mode == CTRL_MODE_CURRENT)) {
|
|
|
@@ -1611,12 +1620,16 @@ void Sched_MC_mTask(void) {
|
|
|
mot_contrl_set_target_vel(&motor.controller, motor.s_target_speed);
|
|
|
}
|
|
|
}else {
|
|
|
- float thro = throttle_get_signal();
|
|
|
- if (motor.b_ignor_throttle) {
|
|
|
- float r = (float)motor.u_throttle_ration/100.0f;
|
|
|
- thro = throttle_open_ration_to_vol(r);
|
|
|
+ if (motor.s_force_torque != MAX_S16) {
|
|
|
+ mot_contrl_set_force_torque(&motor.controller, motor.s_force_torque);
|
|
|
+ }else {
|
|
|
+ float thro = throttle_get_signal();
|
|
|
+ if (motor.b_ignor_throttle) {
|
|
|
+ float r = (float)motor.u_throttle_ration/100.0f;
|
|
|
+ thro = throttle_opening_to_vol(r);
|
|
|
+ }
|
|
|
+ mc_process_throttle_torque(thro);
|
|
|
}
|
|
|
- mc_process_throttle_torque(thro);
|
|
|
}
|
|
|
mot_contrl_slow_task(&motor.controller);
|
|
|
}
|