stmbl/shared/comps/acim_ttc.c

186 lines
4.1 KiB
C

#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),
};