|
|
@@ -163,6 +163,8 @@ static void _mc_internal_init(u8 mode, bool start) {
|
|
|
motor.b_force_run = false;
|
|
|
motor.b_cruise = false;
|
|
|
motor.b_limit_pending = false;
|
|
|
+ motor.f_epm_trq = 0;
|
|
|
+ motor.f_epm_vel = 0;
|
|
|
}
|
|
|
|
|
|
static void _led_off_timer_handler(shark_timer_t *t) {
|
|
|
@@ -177,7 +179,6 @@ static void mc_gear_vmode_changed(void) {
|
|
|
PMSM_FOC_SpeedLimit(gears->n_max_speed);
|
|
|
PMSM_FOC_DCCurrLimit(min(gears->n_max_idc, motor.idc_user_lim));
|
|
|
PMSM_FOC_TorqueLimit(gears->n_max_trq);
|
|
|
- //eCtrl_set_accl_time((u16)gears->n_accl_time); 放到转把处理的地方设置
|
|
|
}
|
|
|
|
|
|
static s16 mc_get_gear_idc_limit(void) {
|
|
|
@@ -360,8 +361,8 @@ bool mc_set_gear(u8 gear) {
|
|
|
return false;
|
|
|
}
|
|
|
if (motor.n_gear != gear) {
|
|
|
- motor.n_gear = gear;
|
|
|
u32 mask = cpu_enter_critical();
|
|
|
+ motor.n_gear = gear;
|
|
|
mc_gear_vmode_changed();
|
|
|
cpu_exit_critical(mask);
|
|
|
}
|
|
|
@@ -467,11 +468,14 @@ bool mc_start_epm(bool epm) {
|
|
|
}
|
|
|
u32 mask = cpu_enter_critical();
|
|
|
motor.b_epm = epm;
|
|
|
+ motor.f_epm_vel = 0.0f;
|
|
|
+ motor.f_epm_trq = 0.0f;
|
|
|
motor_encoder_band_epm(epm);
|
|
|
if (epm) {
|
|
|
eCtrl_set_TgtSpeed(0);
|
|
|
motor.mode = CTRL_MODE_SPD;
|
|
|
- PMSM_FOC_TorqueLimit(nv_get_foc_params()->s_maxEpmTorqueLim);
|
|
|
+ motor.epm_dir = EPM_Dir_None;
|
|
|
+ PMSM_FOC_TorqueLimit(nv_get_foc_params()->s_maxEpmTorqueLimBck);
|
|
|
PMSM_FOC_SetCtrlMode(CTRL_MODE_SPD);
|
|
|
}else {
|
|
|
motor.epm_dir = EPM_Dir_None;
|
|
|
@@ -502,6 +506,10 @@ bool mc_start_epm_move(EPM_Dir_t dir, bool is_command) {
|
|
|
return true;
|
|
|
}
|
|
|
u32 mask = cpu_enter_critical();
|
|
|
+ if (motor.epm_dir != dir) {
|
|
|
+ motor.f_epm_vel = 0.0f;
|
|
|
+ motor.f_epm_trq = 0.0f;
|
|
|
+ }
|
|
|
motor.epm_dir = dir;
|
|
|
if (dir != EPM_Dir_None) {
|
|
|
motor.b_epm_cmd_move = is_command;
|
|
|
@@ -509,13 +517,11 @@ bool mc_start_epm_move(EPM_Dir_t dir, bool is_command) {
|
|
|
if (!PMSM_FOC_Is_Start()) {
|
|
|
PMSM_FOC_Start(motor.mode);
|
|
|
pwm_enable_channel();
|
|
|
+ }else if (PMSM_FOC_AutoHoldding()) {
|
|
|
+ mc_auto_hold(false);
|
|
|
}
|
|
|
- float rpm = nv_get_foc_params()->s_maxEpmRPM;
|
|
|
- if (dir == EPM_Dir_Back) {
|
|
|
- rpm = -rpm;
|
|
|
- }
|
|
|
- sys_debug("rpm %f\n", rpm);
|
|
|
- PMSM_FOC_Set_Speed(rpm);
|
|
|
+ PMSM_FOC_TorqueLimit(motor.f_epm_trq);
|
|
|
+ PMSM_FOC_Set_Speed(motor.f_epm_vel);
|
|
|
}else {
|
|
|
motor.b_epm_cmd_move = false;
|
|
|
PMSM_FOC_Set_Speed(0);
|
|
|
@@ -1036,31 +1042,6 @@ void ADC_IRQHandler(void) {
|
|
|
TIME_MEATURE_END();
|
|
|
}
|
|
|
|
|
|
-#ifndef CONFIG_DQ_STEP_RESPONSE
|
|
|
-static bool mc_can_stop_foc(void) {
|
|
|
- if (mc_critical_can_not_run()) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- if (motor.mode == CTRL_MODE_CURRENT) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- if (mc_throttle_released() && PMSM_FOC_GetSpeed() == 0.0f) {
|
|
|
- if (!PMSM_FOC_AutoHoldding() && motor.epm_dir == EPM_Dir_None) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
- /* 启用无感观测器,同时速度低于观测器允许的最小速度,关闭输出,滑行 */
|
|
|
- if (!foc_observer_is_encoder() && PMSM_FOC_GetSpeed() < foc_observer_sensorless_working_speed()) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- return false;
|
|
|
-}
|
|
|
-
|
|
|
-static bool mc_can_restart_foc(void) {
|
|
|
- return (!PMSM_FOC_Is_Start()) && (!mc_throttle_released()) && (!mc_unsafe_critical_error());
|
|
|
-}
|
|
|
-
|
|
|
-#endif
|
|
|
|
|
|
static bool mc_run_stall_process(u8 run_mode) {
|
|
|
if ((run_mode == CTRL_MODE_TRQ || run_mode == CTRL_MODE_SPD) && !PMSM_FOC_AutoHoldding()) {
|
|
|
@@ -1142,6 +1123,24 @@ static void mc_process_throttle_epm(void) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void mc_process_epm_move(void) {
|
|
|
+ if (!motor.b_epm || (motor.epm_dir == EPM_Dir_None)){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ float target_vel = nv_get_foc_params()->s_maxEpmRPM;
|
|
|
+ float target_trq = nv_get_foc_params()->s_maxEpmTorqueLim;
|
|
|
+ float step = 0.2f;
|
|
|
+ if (motor.epm_dir == EPM_Dir_Back) {
|
|
|
+ target_vel = -nv_get_foc_params()->s_maxEpmRPMBck;
|
|
|
+ target_trq = nv_get_foc_params()->s_maxEpmTorqueLimBck;
|
|
|
+ step = 0.1f;
|
|
|
+ }
|
|
|
+ step_towards(&motor.f_epm_vel, target_vel, step);
|
|
|
+ step_towards(&motor.f_epm_trq, target_trq, 0.05f);
|
|
|
+ PMSM_FOC_TorqueLimit(motor.f_epm_trq);
|
|
|
+ PMSM_FOC_Set_Speed(motor.f_epm_vel);
|
|
|
+}
|
|
|
+
|
|
|
static bool mc_process_force_running(void) {
|
|
|
if (motor.b_calibrate || (motor.mode == CTRL_MODE_OPEN)) {
|
|
|
if (motor.b_force_run) {
|
|
|
@@ -1196,6 +1195,32 @@ static void mc_process_curise(void) {
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+#ifndef CONFIG_DQ_STEP_RESPONSE
|
|
|
+static bool mc_can_stop_foc(void) {
|
|
|
+ if (mc_critical_can_not_run()) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (motor.mode == CTRL_MODE_CURRENT) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (mc_throttle_released() && PMSM_FOC_GetSpeed() == 0.0f) {
|
|
|
+ if (!PMSM_FOC_AutoHoldding() && motor.epm_dir == EPM_Dir_None) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /* 启用无感观测器,同时速度低于观测器允许的最小速度,关闭输出,滑行 */
|
|
|
+ if (!foc_observer_is_encoder() && PMSM_FOC_GetSpeed() < foc_observer_sensorless_working_speed()) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+static bool mc_can_restart_foc(void) {
|
|
|
+ return (!PMSM_FOC_Is_Start()) && (!mc_throttle_released() || (motor.epm_dir != EPM_Dir_None)) && (!mc_unsafe_critical_error());
|
|
|
+}
|
|
|
+
|
|
|
+#endif
|
|
|
+
|
|
|
static void mc_motor_runstop(void) {
|
|
|
u32 mask;
|
|
|
if (mc_can_stop_foc()) {
|
|
|
@@ -1283,6 +1308,7 @@ void Sched_MC_mTask(void) {
|
|
|
eCtrl_Running();
|
|
|
if ((runMode == CTRL_MODE_SPD) && mc_is_epm()) {
|
|
|
mc_process_throttle_epm();
|
|
|
+ mc_process_epm_move();
|
|
|
}else {
|
|
|
float thro = get_throttle_float();
|
|
|
if (motor.b_ignor_throttle) {
|