诊断系列之—无感FOC控制的堵转检测

安全诊断一直都是汽车小电机控制中非常重要的功能。因此笔者特别整理了小电机驱动所涉及到的一些诊断功能。
第一篇从无感FOC控制的堵转检测开始。

这个话题就公开的资料而言,笔者在2019年就发表过一篇《基于S12ZVM的车用无传感器BLDC堵转检测方法探讨》,目前应该是在网上流传相对比较多的一种方法。
通过校验观测器反电动势的输出与速度的线性关系来验证是否发生堵转,该方法简单可靠,在很多的用户那边也得到了量产验证,这次的重写,主要是弥补之前的一些不足,另外增加AlphaBeta轴反电动势观测器的处理办法。

反电动势校验法
目前反电动势校验法是检测无传感器 FOC 方案的主流方案。接下来会重点介绍该方法的原理、代码实现等。该方法来自NXP的专利 US20170126153A1。

1.原理

对于无传感器的FOC控制,目前比较常用的是反电动势观测器,其框图如图1所示。该观测器将αβ坐标系的电压和电流通过Park变换到垂直的γδ坐标系。而γδ坐标系和同步坐标系dq之间的角度差是θerr。后面的Position Tracking Controller实际上就是个PLL,目标是锁定θerr=0;从而确保输出的θestim和转子真实的位置重合。图2为γδ坐标示意图。

在这里插入图片描述

图1 反电动势观测器和PLL框图

在这里插入图片描述图2 γδ坐标示意图

由图1可以看到 back-EMF State Filter 的输出是γδ坐标系的反电动势。当 γδ 坐标系与dq 坐标系重合的时候,Eδ实际上就是Eq。如果观测器正常工作,Eδ的输出是和转速成正比例的,转速稳定的情况下,Eδ 也是平稳的。从另一个角度来看,对于 q 轴反电动势,如果知道反电动势系数和转速,也是可以根据公式来计算得到的。这样就会有两种途径来获得q轴的反电动势,一个是从观测器输出得到,另一个是从转速和反电动势系数得到。如果两个途径得到的反电动Eq相差比较大,超出了阈值,就可以判定为堵转事件。原理框图如图3所示。

在这里插入图片描述

图3 反电动势校验法原理框图

当然,如果使用的是在alpha-beta轴上的反电动势观测器,可以使用下面的策略。先求出|e|,然后和观测器输出的速度×反电动势系数去比较。这个过程也可以先拟合一个直线方程,再去做合理性判定。本质和d-q轴上的方法没有差别。给出的框图如图4所示。
在这里插入图片描述

图4 静止坐标系下反电动势校验法的原理

2.实现

接下来讲一下如何在代码上的实现。
上面的图3原理框图中,ε 为允许偏差范围百分比;如果允许20%偏差,那么ε=0.2;Ke 与Ke_offset 可以通过实验的方法得到。举例说明如下,比如恩智浦配套的演示电机,可以分别让其跑在1000RPM、2000RPM、3000RPM 以及4000RPM 稳定转速下,分别得到其Eq 值和转速值。然后做一个线性方程就可以解出Ke 和 Ke_offset,理论上两个点就可以了。然后设置一个合理的ε 值,比如 20%。这样就可以算出来 Eq 的变化范围,然后去比较Eδ 和Eq的范围边界,如果出界,ErrorCounter 加 1。如果在一定的Counter 范围内,ErrorCounter超出设置阈值,则判断为堵转事件发生。图5 对 Eδ 的允许范围做了很清晰的描述,如果Eδ 不在蓝色的范围带内,就说明观测器输出是异常的,积累一定次数后就可以判定堵转事件。然后就可以进入到堵转故障处理程序了,通常是停机,然后尝试重新启动。
在这里插入图片描述
图5 反电动势Eδ允许范围示意图

3.代码示例

本文给出了一种实现的方法,是基于F16定点格式的,读者也可以根据前文自己来实现。
其初始化代码如下:

#include "stallDetection.h"
#include "motor_structure.h"

extern   pmsmDrive_t       drvFOC;
extern   tPos_mode         pos_mode;

void stallDetectionInit(stallDetection_T * params)
{
  params->bEMFObs_Q               = 0.0F;
  params->bEMFObsFilter.fltLambda = BEMFOBSFILTER_LAMBDA;
  params->bEMFObsFilter.fltAcc    = 0.0F;
  params->wRotElFilt              = 0.0F;
  params->wRotElFilter.fltLambda  = ROTELFILTER_LAMBDA;
  params->wRotElFilter.fltAcc     = 0.0F;
  params->bEMFObsFilter_Q         = 0.0F;
  params->bEMFKeCal_Q             = 0.0F;
  params->bEMFKeCalL_Q            = 0.0F;
  params->bEMFKeCalH_Q            = 0.0F;
  params->coeffKE                 = STALLDETECTION_COEFFKE;     //offline test coeff, depend on the motor parameters
  params->coeffKEOFT              = STALLDETECTION_COEFFKEOFT;  
  params->blankCnt                = 0;
  params->stallDetCnt             = 0;
  params->coeffL                  = STALLDETECTION_COEFFL;
  params->coeffH                  = STALLDETECTION_COEFFH;
  params->stallErrFlag            = FALSE;
}

周期性调用代码如下:

tBool stallDetection(stallDetection_T * params)
{
  params->bEMFObs_Q = MLIB_Abs_FLT(drvFOC.pospeSensorless.bEMFObs.pEObsrv.fltArg2);
  params->bEMFObsFilter_Q = GDFLIB_FilterMA(params->bEMFObs_Q, &params->bEMFObsFilter);
  params->wRotElFilt = GDFLIB_FilterMA(drvFOC.pospeControl.wRotEl, &params->wRotElFilter);
  params->bEMFKeCal_Q = MLIB_Mul_FLT(MLIB_Abs_FLT(params->wRotElFilt), params->coeffKE) + params->coeffKEOFT;
  params->bEMFKeCalL_Q = MLIB_Mul_FLT(params->bEMFKeCal_Q, params->coeffL);     //0.75
  params->bEMFKeCalH_Q = MLIB_Mul_FLT(params->bEMFKeCal_Q, params->coeffH);     //1.25
  params->blankCnt++;
  
  params->stallDetCnt++;

  if(params->blankCnt>=STALLDETECTION_BLANKCNT)
  {
    if(pos_mode==sensorless1)
    {
      if((params->bEMFObsFilter_Q > params->bEMFKeCalH_Q) || (params->bEMFObsFilter_Q < params->bEMFKeCalL_Q))
      {
        params->stallDetErrCnt++;
      }
    }  
    params->blankCnt = STALLDETECTION_BLANKCNT;
  }

  if(params->stallDetCnt>STALLDETECTION_CHKCNT)
  {
    if(params->stallDetErrCnt>=STALLDETECTION_CHKERRCNT)
    {
     params->stallErrFlag = TRUE;   
    }
    params->stallDetCnt = 0;
    params->stallDetErrCnt = 0;
  }    
  return params->stallErrFlag;
}

以上合在一起为.c文件,其头文件.h文件如下所示:

#ifndef __STALLDETECTION_H
#define __STALLDETECTION_H

#include "mlib.h"
#include "gdflib.h"

/******************************************************************************
* Type definition
******************************************************************************/
#define STALLDETECTION_BLANKCNT     20000
#define STALLDETECTION_CHKCNT       30
#define STALLDETECTION_CHKERRCNT    STALLDETECTION_CHKCNT-5
#define STALLDETECTION_COEFF        FRAC16(0.30)    //30% range tolerent
#define STALLDETECTION_COEFFKE      0.01672F
#define STALLDETECTION_COEFFKEOFT   -0.3
#define BEMFOBSFILTER_LAMBDA        FRAC16(1.0)
#define ROTELFILTER_LAMBDA          FRAC16(1.0)

typedef struct
{
  //bEMFObs of Q from Observer
  tFrac16                  bEMFObs_Q;
  tFrac16                  bEMFObsFilter_Q;
  tFrac16                  wRotElFilt;
  //bEMFKeCal of Q from KE Calculation
  tFrac16                  bEMFKeCal_Q;
  //bEMFKeCal High Threshold
  tFrac16                  bEMFKeCalH_Q;
  //bEMFKeCal Low Threshold
  tFrac16                  bEMFKeCalL_Q;
  //KE coeff
  tFrac16                  coeffKE;       //coeffKE and coeffKEOFT is from test
  //KE offset
  tFrac16                  coeffKEOFT;   
  //blank count for stall detection
  unsigned int             blankCnt;
  //check count for  reliability
  unsigned int             stallDetCnt;    
  unsigned int             stallDetErrCnt;
  tFrac16                  coeffL;        //usually 0.75 to 0.85    
  tFrac16                  coeffH;    
  GDFLIB_FILTER_MA_T       bEMFObsFilter;
  GDFLIB_FILTER_MA_T       wRotElFilter;
  tBool                    stallErrFlag;
  
} stallDetection_T;

/* Exported function headers */
extern void stallDetectionInit(stallDetection_T * params);
extern tBool stallDetectionUpdate(stallDetection_T * params);

#endif

代码的实现是在NXP的AMMCLIB上实现的,当然也非常容易移植到其他平台,读者可以根据需要自行移植。
以上 .c 和 .h 代码使用起来也非常的简洁。
1)定义结构体变量 stallDetection_T stallDetectionPsrams;
2)初始化堵转检测函数 stallDetectionInit(&stallDetectionPsrams);
3)在StateRun状态机函数中运行堵转检测程序即可

      if(stallDetection(&stallDetectionPsrams)==TRUE)
      {
          permFaults.motor.B.StallError = 1;
      }

以上宏定义的含义说明如下:

STALLDETECTION_BLANKCNT
这个宏用于屏蔽检测,由于该算法的原理是检测观测器的反电动势输出是否与电机的特性相吻合,如果偏离较大,就判定堵转。因此在反电动势观测不准确的阶段,该算法是不成立的,因此需要一个BLANK时间来屏蔽该检测。

STALLDETECTION_CHKCNT
STALLDETECTION_CHKERRCNT
检测堵转的次数 vs 检测堵转的次数中发生偏离的次数。
如果检测堵转的次数 STALLDETECTION_CHKCNT = 20, 那么默认检测堵转错误的次数就是15,也就是说检测20次,出现了15次错误就判定堵转事件。这个比率可以根据需要修改。

STALLDETECTION_COEFFL
STALLDETECTION_COEFFH
堵转检测的阈值,取值区间为0-1.0F。
一般可以选择0.75F或者0.8F,如果选择0.75F也就是意味着观测器的反电动势输出不要超出计算反电动势的值的±25%范围即可,超出的话会累计错误,如果连续检测的次数里,错误次数超过设定值,则报堵转事件。

STALLDETECTION_COEFFKE
STALLDETECTION_COEFFKEOFT
该参数非常重要,是计算反电动势公式的斜率和偏移量,一般通过实际测试来标定,每个电机会不一样。
以LINIX 40电机为例,通过记录特定转速下,测定反电动势观测器的输出,得到一个反电动势与转速的关系表,
比如:1000rpm 为 3.2;2000rpm 为6.7;
有方程 1000a + b = 3.2; 2000a + b = 6.7;
解出方程 a = 0.0035; b = -0.3;
那么有 bemf = speed (rpm) * 0.0035 – 0.3;
又因为速度单位为rad/s,
因此有bemf = speed (rad/s) 60/(2pi*PP) * 0.0035 – 0.3 = speed (rad/s) * 0.1672 – 0.3
最后得到了:
STALLDETECTION_COEFFKE = 0.1672F;
STALLDETECTION_COEFFKEOFT = -0.3F。

BEMFOBSFILTER_LAMBDA
ROTELFILTER_LAMBDA
BEMFOBSFILTER_LAMBDA 为反电动势观测器的MA滤波器的系数,选择范围为0到1.0F;
ROTELFILTER_LAMBDA为电转速的MA滤波器的系数,选择范围为0到1.0F;
该值越大,说明滤波程度越低,越小说明滤波越厉害
以上仅供参考。

大家可以搜索公众号 “汽车电机之芯” 获取更多的信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值