|
@@ -8,22 +8,30 @@
|
|
|
#include "libs/logger.h"
|
|
#include "libs/logger.h"
|
|
|
#include "prot/can_foc_msg.h"
|
|
#include "prot/can_foc_msg.h"
|
|
|
|
|
|
|
|
|
|
+static rpm_trq_map_t gear_torques[5][5] = {
|
|
|
|
|
+ [0] = {{500, 100}, {1200, 100}, {1700, 80}, {2200, 75}, {2800, 50},},
|
|
|
|
|
+ [1] = {{800, 130}, {1600, 120}, {2400, 110}, {3200, 80}, {4300, 60},},
|
|
|
|
|
+ [2] = {{1200, 150}, {2200, 140}, {3200, 120}, {4200, 80}, {5300, 70},},
|
|
|
|
|
+ [3] = {{3000, 200}, {4740, 150}, {5050, 110}, {5200, 85}, {5300, 70},},
|
|
|
|
|
+ [4] = {{4500, 200}, {4740, 150}, {5050, 110}, {5200, 85}, {5300, 70},},
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
/*
|
|
/*
|
|
|
通过查表获取对应扭矩和速度时的Id和IQ的分配
|
|
通过查表获取对应扭矩和速度时的Id和IQ的分配
|
|
|
*/
|
|
*/
|
|
|
-static torque_lut_t *_trq_tbl = NULL;
|
|
|
|
|
-static torque_manager_t g_trq_mn;
|
|
|
|
|
|
|
+static torque_lut_t *torque_lkup_table = NULL;
|
|
|
|
|
+static torque_manager_t torque_ctrl;
|
|
|
void torque_init(void) {
|
|
void torque_init(void) {
|
|
|
- _trq_tbl = nv_get_trq_tlb();
|
|
|
|
|
|
|
+ torque_lkup_table = nv_get_trq_tlb();
|
|
|
torque_reset();
|
|
torque_reset();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void torque_reset(void) {
|
|
void torque_reset(void) {
|
|
|
- memset(&g_trq_mn, 0, sizeof(g_trq_mn));
|
|
|
|
|
|
|
+ memset(&torque_ctrl, 0, sizeof(torque_ctrl));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void torque_get_idq(float torque, float rpm, DQ_t *dq_out) {
|
|
void torque_get_idq(float torque, float rpm, DQ_t *dq_out) {
|
|
|
- if ((_trq_tbl == NULL) || (torque < 0 || rpm < 0)) {
|
|
|
|
|
|
|
+ if ((torque_lkup_table == NULL) || (torque < 0 || rpm < 0)) {
|
|
|
dq_out->d = 0;
|
|
dq_out->d = 0;
|
|
|
dq_out->q = torque;
|
|
dq_out->q = torque;
|
|
|
return;
|
|
return;
|
|
@@ -36,16 +44,16 @@ void torque_get_idq(float torque, float rpm, DQ_t *dq_out) {
|
|
|
if (rpm_idx >= MAX_SPD_POINTS) {
|
|
if (rpm_idx >= MAX_SPD_POINTS) {
|
|
|
rpm_idx = MAX_SPD_POINTS -1;
|
|
rpm_idx = MAX_SPD_POINTS -1;
|
|
|
}
|
|
}
|
|
|
- s16 d = _trq_tbl->dq[trq_idx][rpm_idx].d;
|
|
|
|
|
- s16 q = _trq_tbl->dq[trq_idx][rpm_idx].q;
|
|
|
|
|
|
|
+ s16 d = torque_lkup_table->dq[trq_idx][rpm_idx].d;
|
|
|
|
|
+ s16 q = torque_lkup_table->dq[trq_idx][rpm_idx].q;
|
|
|
if (trq_idx < MAX_TRQ_POINTS - 1) {
|
|
if (trq_idx < MAX_TRQ_POINTS - 1) {
|
|
|
trq_idx += 1;
|
|
trq_idx += 1;
|
|
|
}
|
|
}
|
|
|
if (rpm_idx < MAX_SPD_POINTS - 1) {
|
|
if (rpm_idx < MAX_SPD_POINTS - 1) {
|
|
|
rpm_idx += 1;
|
|
rpm_idx += 1;
|
|
|
}
|
|
}
|
|
|
- s16 d_delta = _trq_tbl->dq[trq_idx][rpm_idx].d - d;
|
|
|
|
|
- s16 q_delta = _trq_tbl->dq[trq_idx][rpm_idx].q - q;
|
|
|
|
|
|
|
+ s16 d_delta = torque_lkup_table->dq[trq_idx][rpm_idx].d - d;
|
|
|
|
|
+ s16 q_delta = torque_lkup_table->dq[trq_idx][rpm_idx].q - q;
|
|
|
float comp_ceof = 0.5f * ((torque - torque/TBL_TRQ_INTVAL*TBL_TRQ_INTVAL)/(float)TBL_TRQ_INTVAL + (rpm - rpm/TBL_SPD_INTVAL*TBL_SPD_INTVAL)/(float)TBL_SPD_INTVAL);
|
|
float comp_ceof = 0.5f * ((torque - torque/TBL_TRQ_INTVAL*TBL_TRQ_INTVAL)/(float)TBL_TRQ_INTVAL + (rpm - rpm/TBL_SPD_INTVAL*TBL_SPD_INTVAL)/(float)TBL_SPD_INTVAL);
|
|
|
|
|
|
|
|
dq_out->d = d + d_delta * comp_ceof;
|
|
dq_out->d = d + d_delta * comp_ceof;
|
|
@@ -53,6 +61,35 @@ void torque_get_idq(float torque, float rpm, DQ_t *dq_out) {
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
|
+float torque_max_from_gear_rpm(void) {
|
|
|
|
|
+ u8 gear = mc_get_gear();
|
|
|
|
|
+ if (gear > 4) {
|
|
|
|
|
+ gear = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ rpm_trq_map_t *map = &gear_torques[gear][0];
|
|
|
|
|
+ s16 rpm = (s16)torque_ctrl.spd_filted;
|
|
|
|
|
+ if (rpm <= map[0].rpm) {
|
|
|
|
|
+ return (float)map[0].torque;
|
|
|
|
|
+ }
|
|
|
|
|
+ int map_size = 5;
|
|
|
|
|
+ for (int i = 1; i < map_size; i++) {
|
|
|
|
|
+ if (rpm <= map[i].rpm) { //线性插值
|
|
|
|
|
+ float trq1 = map[i-1].torque;
|
|
|
|
|
+ float min_rpm = map[i-1].rpm;
|
|
|
|
|
+ float trq2 = map[i].torque;
|
|
|
|
|
+ float max_rpm = map[i].rpm;
|
|
|
|
|
+ if (trq1 > trq2) {
|
|
|
|
|
+ return f_map_inv((float)rpm, min_rpm, max_rpm, trq2, trq1);
|
|
|
|
|
+ }else {
|
|
|
|
|
+ return f_map((float)rpm, min_rpm, max_rpm, trq1, trq2);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return (float)map[map_size-1].torque;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
/* 获取油门开度 */
|
|
/* 获取油门开度 */
|
|
|
static float throttle_ration(float f_throttle) {
|
|
static float throttle_ration(float f_throttle) {
|
|
|
if (f_throttle <= nv_get_foc_params()->n_minThroVol) {
|
|
if (f_throttle <= nv_get_foc_params()->n_minThroVol) {
|
|
@@ -79,29 +116,29 @@ float throttle_to_torque(float f_throttle) {
|
|
|
void request_torque(float thro_ration) {
|
|
void request_torque(float thro_ration) {
|
|
|
float curr_rpm = PMSM_FOC_GetSpeed();
|
|
float curr_rpm = PMSM_FOC_GetSpeed();
|
|
|
if (curr_rpm == 0) {
|
|
if (curr_rpm == 0) {
|
|
|
- g_trq_mn.spd_filted = 0;
|
|
|
|
|
|
|
+ torque_ctrl.spd_filted = 0;
|
|
|
}else {
|
|
}else {
|
|
|
- LowPass_Filter(g_trq_mn.spd_filted, curr_rpm, 0.5f);
|
|
|
|
|
|
|
+ LowPass_Filter(torque_ctrl.spd_filted, curr_rpm, 0.01f);
|
|
|
}
|
|
}
|
|
|
- float trq_map = (float)get_max_torque_for_rpm((s16)g_trq_mn.spd_filted);
|
|
|
|
|
- float trq_lim = PMSM_FOC_GetTorqueLimit();
|
|
|
|
|
- float max_trq = min(trq_map, trq_lim);
|
|
|
|
|
- float ref_trq = max_trq * thro_ration;
|
|
|
|
|
|
|
+ float torque_map = torque_max_from_gear_rpm();// (float)get_max_torque_for_rpm((s16)torque_ctrl.spd_filted);
|
|
|
|
|
+ float torque_lim = PMSM_FOC_GetTorqueLimit();
|
|
|
|
|
+ float max_torque = min(torque_map, torque_lim);
|
|
|
|
|
+ float ref_torque = max_torque * thro_ration;
|
|
|
if ((mc_throttle_released()) && eCtrl_enable_eBrake(true)) {
|
|
if ((mc_throttle_released()) && eCtrl_enable_eBrake(true)) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (!mc_throttle_released()) {
|
|
if (!mc_throttle_released()) {
|
|
|
if (curr_rpm <= CONFIG_ZERO_SPEED_RPM) {
|
|
if (curr_rpm <= CONFIG_ZERO_SPEED_RPM) {
|
|
|
- g_trq_mn.torque_req = eCtrl_get_FinalTorque() * FINAL_DQ_CEFO;
|
|
|
|
|
- ref_trq = MAX(eCtrl_get_FinalTorque() * FINAL_DQ_CEFO, ref_trq );
|
|
|
|
|
|
|
+ torque_ctrl.torque_req = eCtrl_get_FinalTorque() * FINAL_DQ_CEFO;
|
|
|
|
|
+ ref_torque = MAX(eCtrl_get_FinalTorque() * FINAL_DQ_CEFO, ref_torque);
|
|
|
}
|
|
}
|
|
|
- if (ref_trq > g_trq_mn.torque_req) { //加扭矩step给定
|
|
|
|
|
- step_towards(&g_trq_mn.torque_req, ref_trq, 1.0f);
|
|
|
|
|
|
|
+ if (ref_torque > torque_ctrl.torque_req) { //加扭矩step给定
|
|
|
|
|
+ step_towards(&torque_ctrl.torque_req, ref_torque, 1.0f);
|
|
|
}else { //减扭矩,直接给定
|
|
}else { //减扭矩,直接给定
|
|
|
- g_trq_mn.torque_req = ref_trq;
|
|
|
|
|
|
|
+ torque_ctrl.torque_req = ref_torque;
|
|
|
}
|
|
}
|
|
|
- PMSM_FOC_Set_Torque(g_trq_mn.torque_req);
|
|
|
|
|
|
|
+ PMSM_FOC_Set_Torque(torque_ctrl.torque_req);
|
|
|
}else if (mc_throttle_released() && eCtrl_get_FinalTorque() != 0){
|
|
}else if (mc_throttle_released() && eCtrl_get_FinalTorque() != 0){
|
|
|
float real_trq = PMSM_FOC_Get_Real_Torque() * REAL_DQ_CEOF;
|
|
float real_trq = PMSM_FOC_Get_Real_Torque() * REAL_DQ_CEOF;
|
|
|
float ref_now = min(real_trq, eCtrl_get_RefTorque());
|
|
float ref_now = min(real_trq, eCtrl_get_RefTorque());
|
|
@@ -119,17 +156,17 @@ void request_speed(float thro_ration) {
|
|
|
|
|
|
|
|
void throttle_process(u8 run_mode, float f_throttle) {
|
|
void throttle_process(u8 run_mode, float f_throttle) {
|
|
|
if (mc_throttle_released()){
|
|
if (mc_throttle_released()){
|
|
|
- g_trq_mn.throttle_value = 0;
|
|
|
|
|
- g_trq_mn.torque_req = 0;
|
|
|
|
|
|
|
+ torque_ctrl.throttle_value = 0;
|
|
|
|
|
+ torque_ctrl.torque_req = 0;
|
|
|
}else {
|
|
}else {
|
|
|
- LowPass_Filter(g_trq_mn.throttle_value, f_throttle, THRO_REF_LP_CEOF);
|
|
|
|
|
|
|
+ LowPass_Filter(torque_ctrl.throttle_value, f_throttle, THRO_REF_LP_CEOF);
|
|
|
}
|
|
}
|
|
|
- g_trq_mn.thro_ration = throttle_ration(f_throttle);
|
|
|
|
|
|
|
+ torque_ctrl.thro_ration = throttle_ration(f_throttle);
|
|
|
|
|
|
|
|
if (run_mode == CTRL_MODE_TRQ) {
|
|
if (run_mode == CTRL_MODE_TRQ) {
|
|
|
- request_torque(g_trq_mn.thro_ration);
|
|
|
|
|
|
|
+ request_torque(torque_ctrl.thro_ration);
|
|
|
}else if (run_mode == CTRL_MODE_SPD) {
|
|
}else if (run_mode == CTRL_MODE_SPD) {
|
|
|
- request_speed(g_trq_mn.thro_ration);
|
|
|
|
|
|
|
+ request_speed(torque_ctrl.thro_ration);
|
|
|
}else if (run_mode == CTRL_MODE_CURRENT_BRK) {
|
|
}else if (run_mode == CTRL_MODE_CURRENT_BRK) {
|
|
|
eCtrl_reset_Torque(0);
|
|
eCtrl_reset_Torque(0);
|
|
|
if (eCtrl_get_FinalCurrent() < 0.0001f && PMSM_FOC_GetSpeed() < CONFIG_MIN_RPM_EXIT_EBRAKE) {
|
|
if (eCtrl_get_FinalCurrent() < 0.0001f && PMSM_FOC_GetSpeed() < CONFIG_MIN_RPM_EXIT_EBRAKE) {
|