Skip to content

Commit

Permalink
Remade of Kalman observer on XY axes, new DTC.
Browse files Browse the repository at this point in the history
  • Loading branch information
rombrew committed Sep 1, 2024
1 parent d8226b9 commit 9c834dc
Show file tree
Hide file tree
Showing 47 changed files with 1,478 additions and 1,342 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ There are a few videos about PMC on [youtube](https://www.youtube.com/@romblv).

- Sensorless vector control of PMSM by measurement of currents and voltages.
- Robust ORTEGA observer with gain scheduling against speed.
- Accurate KALMAN observer having convergence at HF injection.
- Accurate KALMAN observer having convergence at HF injection (**EXPERIMENTAL**).
- Flux weakening and MTPA control (**EXPERIMENTAL**).
- Three and two phases machine connection.
- Hardware abstraction layer (HAL) over STM32F4 and STM32F7.
Expand All @@ -41,6 +41,7 @@ There are a few videos about PMC on [youtube](https://www.youtube.com/@romblv).
with inline or low-side placement.
- Self-adjustment of all onboard measurements (current and voltage) along
symmetrical channels.
- Dead-Time Compensation (DTC) based on currents polatity (**EXPERIMENTAL**).

- Advanced SVPWM scheme provides:
- Reduced switching losses and fully utilised DC link voltage.
Expand All @@ -49,14 +50,13 @@ There are a few videos about PMC on [youtube](https://www.youtube.com/@romblv).
- Prevent bootstrap circuit undervoltage condition.

- Terminal voltage measurements (TVM):
- Compensation of the voltage distortion caused by dead-time insertion.
- Back EMF voltage tracking to catch an already running machine.
- Self-test of the power stages integrity and machine wiring.
- Self-test of bootstrap retention time.

- Automated machine parameters identification (with no external tools):
- Automated machine parameters identification:
- Stator DC resistance (Rs).
- Stator AC impedance in DQ frame (L1, L2, R).
- Stator AC impedance in DQ frame (Ld, Lq, R).
- Rotor flux linkage constant (lambda).
- Mechanical moment of inertia (Ja).

Expand All @@ -82,15 +82,15 @@ There are a few videos about PMC on [youtube](https://www.youtube.com/@romblv).

- Adjustable constraints:
- Phase current (forward and reverse, on HFI current, weakening D current).
- Hardware overtemperature protection (decrease phase current or halt).
- Hardware overtemperature protection (derate phase current or halt).
- Machine voltage applied from VSI.
- DC link current consumption and regeneration.
- DC link overvoltage and undervoltage.
- Maximal speed and acceleration (forward and reverse).
- Absolute location limits in servo operation.

- Input control interfaces:
- Analog input knob with brake signal.
- Analog input knob and brake signal.
- RC servo pulse width modulation.
- CAN bus flexible configurable data transfers.
- STEP/DIR (or CW/CCW) interface (**EXPERIMENTAL**).
Expand All @@ -105,7 +105,7 @@ There are a few videos about PMC on [youtube](https://www.youtube.com/@romblv).
- Flexible configurable data transfers.

- Available information:
- Machine state (electrical position, speed, load torque, etc.)
- Machine state (angle, speed, torque, current, etc.)
- DC link voltage and current consumption.
- Information from temperature sensors.
- Total distance traveled.
Expand Down
88 changes: 42 additions & 46 deletions bench/bench.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,15 +144,10 @@ tlm_plot_grab()
fmt_GP(pm.vsi_BF, 0);
fmt_GP(pm.vsi_CF, 0);
fmt_GP(pm.vsi_IF, 0);
fmt_GP(pm.vsi_SF, 0);
fmt_GP(pm.vsi_UF, 0);

fmt_GP(pm.tvm_A, "V");
fmt_GP(pm.tvm_B, "V");
fmt_GP(pm.tvm_C, "V");

fmt_GP(pm.tvm_X0, "V");
fmt_GP(pm.tvm_Y0, "V");
fmt_GP(pm.dtc_uX, "V");
fmt_GP(pm.dtc_uY, "V");

fmt_GP(pm.lu_MODE, 0);
fmk_GP(pm.lu_mq_produce, pm.const_Zp, "Nm");
Expand All @@ -177,8 +172,8 @@ tlm_plot_grab()
sym_GP(atan2(pm.flux_F[1], pm.flux_F[0]) * kDEG, "pm.flux_F", "deg");
fmk_GP(pm.flux_wS, kRPM, "rpm");

fmt_GP(pm.kalman_residual_D, "A");
fmt_GP(pm.kalman_residual_Q, "A");
fmt_GP(pm.kalman_E[0], "A");
fmt_GP(pm.kalman_E[1], "A");
fmt_GP(pm.kalman_bias_Q, "V");
fmk_GP(pm.kalman_lpf_wS, kRPM, "rpm");

Expand Down Expand Up @@ -379,60 +374,61 @@ void bench_script()

tlm_restart();

/*m.Rs = 8.1E-3;
m.Ld = 3.2E-6;
m.Lq = 4.8E-6;
m.Udc = 48.;
m.Rdc = 0.1;
m.Zp = 21;
m.lambda = blm_Kv_lambda(&m, 109.);
m.Jm = 5.39E-3;*/

m.Rs = 28.E-3;
m.Ld = 14.E-6;
m.Lq = 22.E-6;
m.Udc = 48.;
m.Rdc = 0.1;
m.Zp = 14;
m.lambda = blm_Kv_lambda(&m, 87.);
m.Jm = 0.82E-3;

/*m.Rs = 257.E-3;
m.Ld = 1.1E-3;
m.Lq = 1.5E-3;
m.Udc = 48.;
m.Rs = 7.E-3;
m.Ld = 37.E-6;
m.Lq = 57.E-6;
m.Udc = 49.;
m.Rdc = 0.1;
m.Zp = 1;
m.lambda = blm_Kv_lambda(&m, 55.);
m.Jm = 5.39E-3;*/
m.Zp = 5;
m.lambda = blm_Kv_lambda(&m, 58.);
m.Jm = 17.E-3;

ts_script_default();
ts_script_base();
blm_restart(&m);

ts_adjust_sensor_hall();
blm_restart(&m);

pm.config_LU_ESTIMATE = PM_FLUX_KALMAN;
pm.config_LU_SENSOR = PM_SENSOR_HALL;
pm.config_HFI_WAVETYPE = PM_HFI_SINE;
//pm.config_DTC_VOLTAGE = PM_DISABLED;

pm.watt_wA_maximal = 80.f;
pm.watt_wA_reverse = 80.f;

pm.zone_threshold *= 2.f;

pm.hall_gain_IF = 0.1f;
pm.flux_gain_IF = 0.1f;

m.Jm = 17.E-3 * 48. / 10.;

/*pm.const_im_Ld /= 1.2f;
pm.const_im_Lq /= 1.2f;*/

pm.fsm_req = PM_STATE_LU_STARTUP;
ts_wait_IDLE();

pm.s_setpoint_speed = 4000.f;
pm.s_setpoint_speed = 10.f;
sim_runtime(1.0);

//m.Udc = 30.;
//m.Rdc = 50.;
pm.s_setpoint_speed = 100.f;
sim_runtime(2.0);

pm.s_setpoint_speed = 2000.f;
sim_runtime(1.0);

pm.watt_wP_reverse = 1000.f;
pm.watt_uDC_maximal = 48.f;
//pm.watt_uDC_tol = 10.f;
pm.s_setpoint_speed = - 2000.f;
sim_runtime(2.0);

sim_runtime(0.2);
pm.s_setpoint_speed = 2000.f;
sim_runtime(2.0);

pm.s_setpoint_speed = 0.f;
//pm.s_track = 0.f;
sim_runtime(0.3);


//m.Rdc = 1.;
sim_runtime(0.5);
sim_runtime(3.0);

tlm_PWM_grab();
}
Expand Down
56 changes: 29 additions & 27 deletions bench/blm.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ void blm_enable(blm_t *m)
m->sol_dT = 5.E-6; /* ODE solver step (Second) */

m->pwm_dT = 35.E-6; /* PWM cycle (Second) */
m->pwm_deadtime = 170.E-9; /* PWM deadtime (Second) */
m->pwm_deadtime = 90.E-9; /* PWM deadtime (Second) */
m->pwm_minimal = 50.E-9; /* PWM minimal (Second) */
m->pwm_resolution = 2940; /* PWM resolution */

Expand All @@ -61,7 +61,7 @@ void blm_enable(blm_t *m)

/* Winding resistance (Ohm).
* */
m->Rs = 0.007;
m->Rs = 0.011;

/* Winding inductance (Henry).
* */
Expand Down Expand Up @@ -100,14 +100,14 @@ void blm_enable(blm_t *m)
* */
m->Cdc = 940.E-6;

/* Moment of inertia.
/* Moment of inertia (Kilogram Metre squared).
* */
m->Jm = 5.E-3;

/* Load torque constants.
/* Load torque polynom.
* */
m->Mq[0] = 0.E-3;
m->Mq[1] = 5.E-5;
m->Mq[1] = 5.E-4;
m->Mq[2] = 5.E-7;
m->Mq[3] = 5.E-2;

Expand All @@ -125,7 +125,7 @@ void blm_enable(blm_t *m)
m->range_A = 165.; /* (Ampere) */
m->range_B = 60.; /* (Volt) */

/* Hall sensor installation angles.
/* Hall Sensor installation angles (Degree).
* */
m->hall[0] = 30.7;
m->hall[1] = 150.1;
Expand Down Expand Up @@ -228,7 +228,7 @@ blm_equation(const blm_t *m, const double state[7], double y[7])
* */
mS = state[2] / m->Zp;
mQ = m->Mq[0] - mS * (m->Mq[1] + fabs(mS) * m->Mq[2]);
mQ += (mS < 0.) ? m->Mq[3] : - m->Mq[3];
mQ += - mS / (1.f + fabs(mS)) * m->Mq[3];

/* Mechanical equations.
* */
Expand All @@ -244,47 +244,49 @@ blm_equation(const blm_t *m, const double state[7], double y[7])
static void
blm_ode_step(blm_t *m, double dT)
{
double x2[7], y1[7], y2[7];
double iA, iB, iC, uA, uB, uC, kA, kB, uMIN;
double x0[7], y0[7], y1[7];

double iA, iB, iC, uA, uB, uC;
double kA, kB, uMIN;

/* Second-order ODE solver.
* */

blm_equation(m, m->state, y1);
blm_equation(m, m->state, y0);

if (m->pwm_Z != BLM_Z_DETACHED) {

x2[0] = m->state[0] + y1[0] * dT;
x2[1] = m->state[1] + y1[1] * dT;
x0[0] = m->state[0] + y0[0] * dT;
x0[1] = m->state[1] + y0[1] * dT;
}
else {
x2[0] = 0.;
x2[1] = 0.;
x0[0] = 0.;
x0[1] = 0.;
}

x2[2] = m->state[2] + y1[2] * dT;
x2[3] = m->state[3] + y1[3] * dT;
x2[4] = m->state[4] + y1[4] * dT;
x2[5] = m->state[5] + y1[5] * dT;
x2[6] = m->state[6] + y1[6] * dT;
x0[2] = m->state[2] + y0[2] * dT;
x0[3] = m->state[3] + y0[3] * dT;
x0[4] = m->state[4] + y0[4] * dT;
x0[5] = m->state[5] + y0[5] * dT;
x0[6] = m->state[6] + y0[6] * dT;

blm_equation(m, x2, y2);
blm_equation(m, x0, y1);

if (m->pwm_Z != BLM_Z_DETACHED) {

m->state[0] += (y1[0] + y2[0]) * dT / 2.;
m->state[1] += (y1[1] + y2[1]) * dT / 2.;
m->state[0] += (y0[0] + y1[0]) * dT / 2.;
m->state[1] += (y0[1] + y1[1]) * dT / 2.;
}
else {
m->state[0] = 0.;
m->state[1] = 0.;
}

m->state[2] += (y1[2] + y2[2]) * dT / 2.;
m->state[3] += (y1[3] + y2[3]) * dT / 2.;
m->state[4] += (y1[4] + y2[4]) * dT / 2.;
m->state[5] += (y1[5] + y2[5]) * dT / 2.;
m->state[6] += (y1[6] + y2[6]) * dT / 2.;
m->state[2] += (y0[2] + y1[2]) * dT / 2.;
m->state[3] += (y0[3] + y1[3]) * dT / 2.;
m->state[4] += (y0[4] + y1[4]) * dT / 2.;
m->state[5] += (y0[5] + y1[5]) * dT / 2.;
m->state[6] += (y0[6] + y1[6]) * dT / 2.;

/* Sensor transient (FAST).
* */
Expand Down
Loading

0 comments on commit 9c834dc

Please sign in to comment.