最近在浏览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 回复