最近在浏览VESC代码,看到它使用了一种观测器是基于此论文的,特下载跟大家分享:

一种无传感器非线性观察器(本杰明电调)2010-IEEE_TPEL-Lee-Hong-Nam-Ortega-Praly-Astolfi.pdf
最近看了下源码,做了一部分注解,有兴趣的可以留言一起学习:
// dt:就是调用此函数的时间,例如pwm10k,dt=1/10k=100us = 0.0000001s
void observer_update(float v_alpha, float v_beta, float i_alpha, float i_beta,
float dt, volatile float *x1, volatile float *x2, volatile float *phase) {
const float L = (3.0 / 2.0) * m_conf->foc_motor_l;
const float lambda = m_conf->foc_motor_flux_linkage;
float R = (3.0 / 2.0) * m_conf->foc_motor_r;
// Saturation compensation 饱和补偿电阻?
const float sign = (m_motor_state.iq * m_motor_state.vq) >= 0.0 ? 1.0 : -1.0;
R -= R * sign * m_conf->foc_sat_comp * (m_motor_state.i_abs_filter / m_conf->l_current_max);
// Temperature compensation 温度补偿电阻
const float t = mc_interface_temp_motor_filtered();
if (m_conf->foc_temp_comp && t > -5.0) {
R += R * 0.00386 * (t - m_conf->foc_temp_comp_base_temp);
}
const float L_ia = L * i_alpha;
const float L_ib = L * i_beta;
const float R_ia = R * i_alpha;
const float R_ib = R * i_beta;
const float lambda_2 = SQ(lambda); // 磁链的平方
const float gamma_half = m_gamma_now * 0.5; // 观测器增益的一半,公式8
// Original
// float err = lambda_2 - (SQ(*x1 - L_ia) + SQ(*x2 - L_ib));
// float x1_dot = -R_ia + v_alpha + gamma_half * (*x1 - L_ia) * err;
// float x2_dot = -R_ib + v_beta + gamma_half * (*x2 - L_ib) * err;
// *x1 += x1_dot * dt;
// *x2 += x2_dot * dt;
// Iterative with some trial and error 迭代6次?
const int iterations = 6;
const float dt_iteration = dt / (float)iterations;
for (int i = 0;i < iterations;i++) {
float err = lambda_2 - (SQ(*x1 - L_ia) + SQ(*x2 - L_ib)); // 公式8的减法
float gamma_tmp = gamma_half;
if (utils_truncate_number_abs(&err, lambda_2 * 0.2)) { // 把err限定在 lambda_2*0.2内
gamma_tmp *= 10.0; // 超过范围后放大?相当于 m_gamma_now 放大5倍
}
// 公式4:y=-RsIab + Vab ,则向量 -Ria + va
// - Rib +vb
// 公式8:dx/dt = y + gamma/2*n(x)*err
float x1_dot = -R_ia + v_alpha + gamma_tmp * (*x1 - L_ia) * err;
float x2_dot = -R_ib + v_beta + gamma_tmp * (*x2 - L_ib) * err;
*x1 += x1_dot * dt_iteration;
*x2 += x2_dot * dt_iteration;
}
// Same as above, but without iterations.
// float err = lambda_2 - (SQ(*x1 - L_ia) + SQ(*x2 - L_ib));
// float gamma_tmp = gamma_half;
// if (utils_truncate_number_abs(&err, lambda_2 * 0.2)) {
// gamma_tmp *= 10.0;
// }
// float x1_dot = -R_ia + v_alpha + gamma_tmp * (*x1 - L_ia) * err;
// float x2_dot = -R_ib + v_beta + gamma_tmp * (*x2 - L_ib) * err;
// *x1 += x1_dot * dt;
// *x2 += x2_dot * dt;
// 确保x1 x2不是nan,也可以用 isnan()函数
UTILS_NAN_ZERO(*x1);
UTILS_NAN_ZERO(*x2);
// 最后得到估算角度theta 三角,公式9
// atan2(y, x)是4象限反正切,它的取值不仅取决于正切值y/x,还取决于点 (x, y) 落入哪个象限
*phase = utils_fast_atan2(*x2 - L_ib, *x1 - L_ia);
}
边文清:源码有用到相电压吗?
2022-02-04 23:54:09 回复
易缘天地:老兄,本明杰的高频注入研究过吗,他怎么做的,最近我做了个方波注入的。性看看本明杰怎么做的
2020-07-10 11:00:38 回复
易缘天地:我用simulink仿真了一下,和实际角度一直差45度,关键电机的温度如何获取。
2020-06-30 09:52:50 回复
易缘天地:试了吗这个观测器效果如何
2020-06-30 08:59:23 回复