搜索
bottom↓
回复: 15

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

[复制链接]

出0入4汤圆

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

阿莫论坛20周年了!感谢大家的支持与爱护!!

如果想吃一顿饺子,就得从冰箱里取出肉,剁馅儿,倒面粉、揉面、醒面,擀成皮儿,下锅……
一整个繁琐流程,就是为了出锅时那一嘴滚烫流油的热饺子。

如果这个过程,禁不住饿,零食下肚了,饺子出锅时也就不香了……《非诚勿扰3》

出0入420汤圆

发表于 2021-10-11 11:57:56 | 显示全部楼层
有了编码器,就可以得到电角度,还要什么估算器

出0入0汤圆

发表于 2021-10-11 13:43:10 | 显示全部楼层
hameyou 发表于 2021-10-11 11:57
有了编码器,就可以得到电角度,还要什么估算器

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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

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

老兄研究的蛮深

出0入0汤圆

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

vesc都有源码了

出0入4汤圆

 楼主| 发表于 2021-10-11 14:03:28 | 显示全部楼层

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

出30入16汤圆

发表于 2021-10-11 14:26:57 来自手机 | 显示全部楼层
hameyou 发表于 2021-10-11 11:57
有了编码器,就可以得到电角度,还要什么估算器

你确定?

出105入79汤圆

发表于 2021-10-11 14:40:13 | 显示全部楼层
本帖最后由 qwe2231695 于 2021-10-11 14:47 编辑

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

出105入79汤圆

发表于 2021-10-11 14:42:35 | 显示全部楼层
韩国的Junggi Lee 的论文用PI滤波器估算角度,兼容性不错的,实现很简单在VESC里面就1个函数,效果不输SMO滑膜。

出0入0汤圆

发表于 2021-10-11 15:46:11 | 显示全部楼层

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

出0入4汤圆

 楼主| 发表于 2021-10-11 15:49:20 | 显示全部楼层
TINXPST 发表于 2021-10-11 15:46
VESC和Odrive的源码都有了,论文也有了,可是我还没看懂,数学基础不够。

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

出0入4汤圆

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

谢谢大神解答~~~

出0入0汤圆

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

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

出0入4汤圆

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

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

出10入0汤圆

发表于 2021-10-11 20:29:31 | 显示全部楼层
https://github.com/odriverobotic ... rless_estimator.cpp
贴出来等待高手讲解,我顺道学习下
#include "odrive_main.h"

void SensorlessEstimator::reset() {
    pll_pos_ = 0.0f;
    vel_estimate_ = 0.0f;
    V_alpha_beta_memory_[0] = 0.0f;
    V_alpha_beta_memory_[1] = 0.0f;
    flux_state_[0] = 0.0f;
    flux_state_[1] = 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/Telec ... a-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[2] = {
        current_meas->phA,
        one_by_sqrt3 * (current_meas->phB - current_meas->phC)};

    // alpha-beta vector operations
    float eta[2];
    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[0] * eta[0] + eta[1] * eta[1];
    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_[0] = axis_->motor_.current_control_.final_v_alpha_;
    V_alpha_beta_memory_[1] = 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[1], eta[0]);
    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;
};

出0入4汤圆

 楼主| 发表于 2021-10-11 22:00:42 | 显示全部楼层
blackcafe 发表于 2021-10-11 20:29
https://github.com/odriverobotics/ODrive/blob/master/Firmware/MotorControl/sensorless_estimator.cpp
...

期待
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-28 18:03

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表