关于VESC还有odrive无刷电机方案的位置估算的观测器疑问?
本人以前玩过带霍尔的无刷,目前刚接触无霍尔的,属于超级小白一个,目前在了解FOC方案,关于VESC还有odrive无刷电机方案的位置估算的观测器有疑问?odrive是什么观测器做的?另外一个它两都可以带磁编码器了,位置估算不是直接读取即可,不就可实现换向了,是不是可以直接跳过观测器了,这样摇实现停住不动是不是就很简单了?
谢谢各路大神指点一下!
有了编码器,就可以得到电角度,还要什么估算器 hameyou 发表于 2021-10-11 11:57
有了编码器,就可以得到电角度,还要什么估算器
VESC和Oderive的角度估算算法都是基于这篇论文做出来的。如果数学基础好的话,正好可以研究一下如何用C代码实现这些复杂的运算: TINXPST 发表于 2021-10-11 13:43
VESC和Oderive的角度估算算法都是基于这篇论文做出来的。如果数学基础好的话,正好可以研究一下如何用C代 ...
老兄研究的蛮深 TINXPST 发表于 2021-10-11 13:43
VESC和Oderive的角度估算算法都是基于这篇论文做出来的。如果数学基础好的话,正好可以研究一下如何用C代 ...
vesc都有源码了 霸气侧漏 发表于 2021-10-11 13:57
vesc都有源码了
ODRIVE的源码也是开源的吧?包括观测器? hameyou 发表于 2021-10-11 11:57
有了编码器,就可以得到电角度,还要什么估算器
你确定? 本帖最后由 qwe2231695 于 2021-10-11 14:47 编辑
有了编码器可以得到机械角度,电角度,和实时速度,当前的电流角度Id Iq还是不能得到的,产生的力矩就不得不到,低速可以等效,但特别是高速大电流的情况下要计算得到。 韩国的Junggi Lee 的论文用PI滤波器估算角度,兼容性不错的,实现很简单在VESC里面就1个函数,效果不输SMO滑膜。 霸气侧漏 发表于 2021-10-11 13:57
vesc都有源码了
VESC和Odrive的源码都有了,论文也有了,可是我还没看懂,数学基础不够。 TINXPST 发表于 2021-10-11 15:46
VESC和Odrive的源码都有了,论文也有了,可是我还没看懂,数学基础不够。
{:lol:} 它里面源代码内容太多了,还是要向高手先问一遍,点一点,确定一下有没有,原理方向,然后自己再去深挖,省的淹死了,发现后头一看还是看个皮毛 qwe2231695 发表于 2021-10-11 14:42
韩国的Junggi Lee 的论文用PI滤波器估算角度,兼容性不错的,实现很简单在VESC里面就1个函数,效果不输SMO ...
{:handshake:} 谢谢大神解答~~~ zhanyanqiang 发表于 2021-10-11 15:49
它里面源代码内容太多了,还是要向高手先问一遍,点一点,确定一下有没有,原理方向,然后自己再 ...
角度观测部分就是一个函数,代码只有几十行,就把论文中的内容给实现了。我说的只是这个部分。 TINXPST 发表于 2021-10-11 16:02
角度观测部分就是一个函数,代码只有几十行,就把论文中的内容给实现了。我说的只是这个部分。 ...
哦,明白了,谢谢指点,我是搞了好久才将它源码跑起来,一直在研究它的过程框架,非常遗憾,都没有研究到你说的那个核心,光在看什么chibios系统,又是什么fft,fir之类的杂七杂八的,又是各个硬件版本糅合在一起,眼花缭乱的~~确实方向错了。 https://github.com/odriverobotics/ODrive/blob/master/Firmware/MotorControl/sensorless_estimator.cpp
贴出来等待高手讲解,我顺道学习下
#include "odrive_main.h"
void SensorlessEstimator::reset() {
pll_pos_ = 0.0f;
vel_estimate_ = 0.0f;
V_alpha_beta_memory_ = 0.0f;
V_alpha_beta_memory_ = 0.0f;
flux_state_ = 0.0f;
flux_state_ = 0.0f;
}
bool SensorlessEstimator::update() {
// Algorithm based on paper: Sensorless Control of Surface-Mount Permanent-Magnet Synchronous Motors Based on a Nonlinear Observer
// http://cas.ensmp.fr/~praly/Telechargement/Journaux/2010-IEEE_TPEL-Lee-Hong-Nam-Ortega-Praly-Astolfi.pdf
// In particular, equation 8 (and by extension eqn 4 and 6).
// The V_alpha_beta applied immedietly prior to the current measurement associated with this cycle
// is the one computed two cycles ago. To get the correct measurement, it was stored twice:
// once by final_v_alpha/final_v_beta in the current control reporting, and once by V_alpha_beta_memory.
// PLL
// TODO: the PLL part has some code duplication with the encoder PLL
// Pll gains as a function of bandwidth
float pll_kp = 2.0f * config_.pll_bandwidth;
// Critically damped
float pll_ki = 0.25f * (pll_kp * pll_kp);
// Check that we don't get problems with discrete time approximation
if (!(current_meas_period * pll_kp < 1.0f)) {
error_ |= ERROR_UNSTABLE_GAIN;
reset(); // Reset state for when the next valid current measurement comes in.
return false;
}
// TODO: we read values here which are modified by a higher priority interrupt.
// This is not thread-safe.
auto current_meas = axis_->motor_.current_meas_;
if (!axis_->motor_.is_armed_) {
// While the motor is disarmed the current is not measurable so we
// assume that it's zero.
current_meas = {0.0f, 0.0f};
}
if (!current_meas.has_value()) {
error_ |= ERROR_UNKNOWN_CURRENT_MEASUREMENT;
reset(); // Reset state for when the next valid current measurement comes in.
return false;
}
// Clarke transform
float I_alpha_beta = {
current_meas->phA,
one_by_sqrt3 * (current_meas->phB - current_meas->phC)};
// alpha-beta vector operations
float eta;
for (int i = 0; i <= 1; ++i) {
// y is the total flux-driving voltage (see paper eqn 4)
float y = -axis_->motor_.config_.phase_resistance * I_alpha_beta + V_alpha_beta_memory_;
// flux dynamics (prediction)
float x_dot = y;
// integrate prediction to current timestep
flux_state_ += x_dot * current_meas_period;
// eta is the estimated permanent magnet flux (see paper eqn 6)
eta = flux_state_ - axis_->motor_.config_.phase_inductance * I_alpha_beta;
}
// Non-linear observer (see paper eqn 8):
float pm_flux_sqr = config_.pm_flux_linkage * config_.pm_flux_linkage;
float est_pm_flux_sqr = eta * eta + eta * eta;
float bandwidth_factor = 1.0f / pm_flux_sqr;
float eta_factor = 0.5f * (config_.observer_gain * bandwidth_factor) * (pm_flux_sqr - est_pm_flux_sqr);
// alpha-beta vector operations
for (int i = 0; i <= 1; ++i) {
// add observer action to flux estimate dynamics
float x_dot = eta_factor * eta;
// convert action to discrete-time
flux_state_ += x_dot * current_meas_period;
// update new eta
eta = flux_state_ - axis_->motor_.config_.phase_inductance * I_alpha_beta;
}
// Flux state estimation done, store V_alpha_beta for next timestep
V_alpha_beta_memory_ = axis_->motor_.current_control_.final_v_alpha_;
V_alpha_beta_memory_ = axis_->motor_.current_control_.final_v_beta_;
float phase_vel = phase_vel_.previous().value_or(0.0f);
// predict PLL phase with velocity
pll_pos_ = wrap_pm_pi(pll_pos_ + current_meas_period * phase_vel);
// update PLL phase with observer permanent magnet phase
float phase = fast_atan2(eta, eta);
float delta_phase = wrap_pm_pi(phase - pll_pos_);
pll_pos_ = wrap_pm_pi(pll_pos_ + current_meas_period * pll_kp * delta_phase);
// update PLL velocity
phase_vel += current_meas_period * pll_ki * delta_phase;
// set outputs
phase_ = phase;
phase_vel_ = phase_vel;
vel_estimate_ = phase_vel / (std::max((float)axis_->motor_.config_.pole_pairs, 1.0f) * 2.0f * M_PI);
return true;
}; blackcafe 发表于 2021-10-11 20:29
https://github.com/odriverobotics/ODrive/blob/master/Firmware/MotorControl/sensorless_estimator.cpp
...
{:handshake:} 期待
页:
[1]