#include "acim_ttc_comp.h" #include "commands.h" #include "hal.h" #include "math.h" #include "defines.h" #include "angle.h" HAL_COMP(acim_ttc); HAL_PIN(mode); // 0 = slip, 1 = mtpa, 2 = u/f HAL_PIN(sensorless); // motor values HAL_PIN(torque_n); HAL_PIN(cur_n); HAL_PIN(slip_n); HAL_PIN(polecount); HAL_PIN(freq_n); HAL_PIN(vel_n); HAL_PIN(u_n); HAL_PIN(u_boost); HAL_PIN(t_boost); HAL_PIN(s_boost); // torque cmd in HAL_PIN(torque); HAL_PIN(vel_m); // cur cmd out HAL_PIN(d_cmd); HAL_PIN(q_cmd); HAL_PIN(cmd_mode); HAL_PIN(pos); HAL_PIN(vel_e); HAL_PIN(slip); HAL_PIN(t_min); HAL_PIN(t_max); HAL_PIN(scale); HAL_PIN(ki); HAL_PIN(duty); HAL_PIN(duty_setpoint); static void nrt_init(void *ctx_ptr, hal_pin_inst_t *pin_ptr) { struct acim_ttc_pin_ctx_t *pins = (struct acim_ttc_pin_ctx_t *)pin_ptr; PIN(polecount) = 2; PIN(vel_n) = 1745.0 / 60.0 * 2.0 * M_PI; PIN(torque_n) = 23.0; PIN(cur_n) = 17.0; PIN(freq_n) = 60.0; PIN(u_n) = 80.0; PIN(u_boost) = 7.0; PIN(t_boost) = 1.3; PIN(s_boost) = 2.5; PIN(mode) = 0; PIN(sensorless) = 0; PIN(scale) = 1.0; PIN(ki) = 50.0; PIN(duty_setpoint) = 0.9; } static void rt_func(float period, void *ctx_ptr, hal_pin_inst_t *pin_ptr) { // struct acim_ttc_ctx_t * ctx = (struct acim_ttc_ctx_t *)ctx_ptr; struct acim_ttc_pin_ctx_t *pins = (struct acim_ttc_pin_ctx_t *)pin_ptr; float poles = MAX(PIN(polecount), 1.0); float vel_n = PIN(vel_n) * poles; float t_n = MAX(PIN(torque_n), 0.001); float freq_n = MAX(PIN(freq_n), 1.0); float slip_n = freq_n * 2.0 * M_PI - vel_n; float cur_n = PIN(cur_n); float u_n = PIN(u_n); float u_boost = PIN(u_boost); float t_boost = PIN(t_boost); float torque = PIN(torque); float vel = 0.0; if(PIN(sensorless) > 0.0){ vel = PIN(vel_e); } else{ vel = PIN(vel_m) * poles; } float d_cmd = 0.0; float q_cmd = 0.0; float slip = 0.0; float cmd_mode = 0; float id_n = cur_n / sqrtf(2.0); PIN(scale) += (PIN(duty_setpoint) - PIN(duty)) * PIN(ki) * period; PIN(scale) = CLAMP(PIN(scale), 0.01, 1); switch((int)PIN(mode)) { case 0: // slip control cmd_mode = 1.0; // cur cmd // d_cmd = MIN(id_n, id_n * freq_n * 2.0 * M_PI * v_boost / vel); // constant flux d_cmd = id_n * PIN(scale); q_cmd = id_n / t_n * torque / PIN(scale); slip = slip_n * q_cmd / d_cmd; // id = id_n // slip = slip_n * iq / id // torque = 3/2 * p * K * iq * id // id = id_n * scale // // iq = toruqe / t_n * id_n * id_n / id // iq = toruqe / t_n * id_n / scale // slip = slip_n * iq / id // torque = 3/2 * p * K * iq * id // torque = t_n / id_n / id_n * id * iq // iq = toruqe / t_n * id_n * id_n / id break; case 1: // mtpa cmd_mode = 1.0; // cur cmd d_cmd = 0.0; q_cmd = cur_n / t_n * torque; slip = slip_n * SIGN(torque); // constant slip break; case 2: // u/f slip cmd_mode = 0; // volt cmd slip = slip_n / t_n * torque; d_cmd = MAX(u_n / freq_n * ABS(vel / 2.0 / M_PI), u_boost); q_cmd = 0.0; break; default: cmd_mode = 1.0; // cur cmd d_cmd = 0; q_cmd = 0; slip = 0.0; } float t_min = 0; float t_max = 0; if(PIN(vel_m) > 0.0){ t_max = t_n * t_boost * PIN(scale); t_min = -t_max; } else{ t_min = -t_n * t_boost * PIN(scale); t_max = -t_min; } slip = LIMIT(slip, slip_n * PIN(s_boost)); if(PIN(sensorless) > 0.0){ vel -= slip; PIN(vel_m) = vel * poles; } else{ vel += slip; PIN(vel_e) = vel; } PIN(t_min) = t_min; PIN(t_max) = t_max; PIN(cmd_mode) = cmd_mode; PIN(d_cmd) = d_cmd; PIN(q_cmd) = q_cmd; PIN(slip_n) = slip_n; PIN(slip) = slip; PIN(pos) = mod(PIN(pos) + vel * period); } hal_comp_t acim_ttc_comp_struct = { .name = "acim_ttc", .nrt = 0, .rt = rt_func, .frt = 0, .nrt_init = nrt_init, .rt_start = 0, .frt_start = 0, .rt_stop = 0, .frt_stop = 0, .ctx_size = 0, .pin_count = sizeof(struct acim_ttc_pin_ctx_t) / sizeof(struct hal_pin_inst_t), };