zhanyanqiang 发表于 2021-10-11 11:14:05

关于VESC还有odrive无刷电机方案的位置估算的观测器疑问?

    本人以前玩过带霍尔的无刷,目前刚接触无霍尔的,属于超级小白一个,目前在了解FOC方案,关于VESC还有odrive无刷电机方案的位置估算的观测器有疑问?
odrive是什么观测器做的?另外一个它两都可以带磁编码器了,位置估算不是直接读取即可,不就可实现换向了,是不是可以直接跳过观测器了,这样摇实现停住不动是不是就很简单了?
谢谢各路大神指点一下!

hameyou 发表于 2021-10-11 11:57:56

有了编码器,就可以得到电角度,还要什么估算器

TINXPST 发表于 2021-10-11 13:43:10

hameyou 发表于 2021-10-11 11:57
有了编码器,就可以得到电角度,还要什么估算器

VESC和Oderive的角度估算算法都是基于这篇论文做出来的。如果数学基础好的话,正好可以研究一下如何用C代码实现这些复杂的运算:

霸气侧漏 发表于 2021-10-11 13:57:20

TINXPST 发表于 2021-10-11 13:43
VESC和Oderive的角度估算算法都是基于这篇论文做出来的。如果数学基础好的话,正好可以研究一下如何用C代 ...

老兄研究的蛮深

霸气侧漏 发表于 2021-10-11 13:57:43

TINXPST 发表于 2021-10-11 13:43
VESC和Oderive的角度估算算法都是基于这篇论文做出来的。如果数学基础好的话,正好可以研究一下如何用C代 ...

vesc都有源码了

zhanyanqiang 发表于 2021-10-11 14:03:28

霸气侧漏 发表于 2021-10-11 13:57
vesc都有源码了

ODRIVE的源码也是开源的吧?包括观测器?

洞洞幺 发表于 2021-10-11 14:26:57

hameyou 发表于 2021-10-11 11:57
有了编码器,就可以得到电角度,还要什么估算器

你确定?

qwe2231695 发表于 2021-10-11 14:40:13

本帖最后由 qwe2231695 于 2021-10-11 14:47 编辑

有了编码器可以得到机械角度,电角度,和实时速度,当前的电流角度Id Iq还是不能得到的,产生的力矩就不得不到,低速可以等效,但特别是高速大电流的情况下要计算得到。

qwe2231695 发表于 2021-10-11 14:42:35

韩国的Junggi Lee 的论文用PI滤波器估算角度,兼容性不错的,实现很简单在VESC里面就1个函数,效果不输SMO滑膜。

TINXPST 发表于 2021-10-11 15:46:11

霸气侧漏 发表于 2021-10-11 13:57
vesc都有源码了

VESC和Odrive的源码都有了,论文也有了,可是我还没看懂,数学基础不够。

zhanyanqiang 发表于 2021-10-11 15:49:20

TINXPST 发表于 2021-10-11 15:46
VESC和Odrive的源码都有了,论文也有了,可是我还没看懂,数学基础不够。

{:lol:} 它里面源代码内容太多了,还是要向高手先问一遍,点一点,确定一下有没有,原理方向,然后自己再去深挖,省的淹死了,发现后头一看还是看个皮毛

zhanyanqiang 发表于 2021-10-11 15:51:15

qwe2231695 发表于 2021-10-11 14:42
韩国的Junggi Lee 的论文用PI滤波器估算角度,兼容性不错的,实现很简单在VESC里面就1个函数,效果不输SMO ...

{:handshake:} 谢谢大神解答~~~

TINXPST 发表于 2021-10-11 16:02:29

zhanyanqiang 发表于 2021-10-11 15:49
它里面源代码内容太多了,还是要向高手先问一遍,点一点,确定一下有没有,原理方向,然后自己再 ...

角度观测部分就是一个函数,代码只有几十行,就把论文中的内容给实现了。我说的只是这个部分。

zhanyanqiang 发表于 2021-10-11 16:28:20

TINXPST 发表于 2021-10-11 16:02
角度观测部分就是一个函数,代码只有几十行,就把论文中的内容给实现了。我说的只是这个部分。 ...

哦,明白了,谢谢指点,我是搞了好久才将它源码跑起来,一直在研究它的过程框架,非常遗憾,都没有研究到你说的那个核心,光在看什么chibios系统,又是什么fft,fir之类的杂七杂八的,又是各个硬件版本糅合在一起,眼花缭乱的~~确实方向错了。

blackcafe 发表于 2021-10-11 20:29:31

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;
};

zhanyanqiang 发表于 2021-10-11 22:00:42

blackcafe 发表于 2021-10-11 20:29
https://github.com/odriverobotics/ODrive/blob/master/Firmware/MotorControl/sensorless_estimator.cpp
...

{:handshake:} 期待
页: [1]
查看完整版本: 关于VESC还有odrive无刷电机方案的位置估算的观测器疑问?