天天看點

電機速度曲線規劃1:梯形速度曲線設計與實作

  電機驅動是很常見的應用,在很多系統中我們都會碰到需要改變電機的速度以實作相應的控制功能,這就涉及到電機速度曲線規劃的問題。在這篇中我們就來簡單讨論一下電機的梯形曲線規劃的問題。

1、基本原理

  梯形速度曲線控制算法是工業控制領域應用最為廣泛的加減速控制政策之一。所謂梯形速度曲線将整個運動過程分為勻加速、勻速和勻減速三個階段,在變速過程中加速度保持不變。

電機速度曲線規劃1:梯形速度曲線設計與實作

  從變速過程中加速度保持不變這特點來說,其加減速過程其實是一個線性過程。我們可以采用一個線性函數來描述它。

電機速度曲線規劃1:梯形速度曲線設計與實作

  這一線性函數,具體到我們的加減速過程中就是速度與時間的函數關系,函數結果就是我們某一時刻的速度,變量就是時間,斜率就是加速度,初始速度就是截距,具體如下:

電機速度曲線規劃1:梯形速度曲線設計與實作

  這一函數表達的是連續的,但實際使用中我們需要離散化處理,我們必定以一定的時間間隔來處理速度的增加問題。這樣實際的速度變化就不可能是連續的,而是階梯狀的,具體如下:

電機速度曲線規劃1:梯形速度曲線設計與實作

  為了速度的變化盡量平緩,我們需要盡可能地讓時間間隔小一些,這其實是我們在考慮編寫程式時需要處理的一個參數。

2、設計與實作

  我們已經簡單描述了S型速度規劃曲線的數學原理及應用表達式。接下來我們來考慮怎麼實作它。

  考慮到在同一個驅動器中可能因為應用場景的需要存在多條的速度規劃曲線。是以我們以基于對象的思路來考慮它,這樣我們在更換不同的曲線就隻需要更換不同的曲線實力就可以了。是以我們先來分析一下曲線對象的屬性和操作。

  鑒于前面的分析,我們認為作為一個調速曲線對象至少要記錄:開始調速時的初始速度、目前速度、目标速度、加速度、最大速度、最小速度、調速時間、調速時間跨度、曲線類型等,我們将這些記為對象的屬性。據此我們可以定義電機速度曲線的對象類型為:

/* 定義電機速度曲線對象 */
typedef struct CurveObject {
  float startSpeed;    //開始調速時的初始速度
  float currentSpeed;   //目前速度
  float targetSpeed;    //目标速度
  float stepSpeed;     //加速度
  float speedMax;     //最大速度
  float speedMin;     //最小速度
  uint32_t aTimes;     //調速時間
  uint32_t maxTimes;    //調速跨度
  SpeedCurveType curveMode;  //曲線類型
}CurveObjectType;
           

 我們已經定義了一個速度曲線對象類型,接下來我們就來分析如何實作一個T型調速曲線。我們已經描述過,速度其實就是時間的函數,根據我們前面分析的速度時間的函數表達式,我們實作如下:

void (*pCalCurve[])(CurveObjectType *curve)={CalCurveNone,CalCurveTRAP,CalCurveSPTA};
 
/* 電機曲線加減速操作-------------------------------------------------------- */
void MotorVelocityCurve(CurveObjectType *curve)
{
  float temp=0;
  
  if(curve->targetSpeed>curve->speedMax)
  {
    curve->targetSpeed=curve->speedMax;
  }
  
  if(curve->targetSpeed<curve->speedMin)
  {
    curve->targetSpeed=curve->speedMin;
  }
 
  if((fabs(curve->currentSpeed-curve->startSpeed)<=curve->stepSpeed)&&(curve->maxTimes==0))
  {
    if(curve->startSpeed<curve->speedMin)
    {
      curve->startSpeed=curve->speedMin;
    }
    
    temp=fabs(curve->targetSpeed-curve->startSpeed);
    temp=temp/curve->stepSpeed;
    curve->maxTimes=(uint32_t)(temp)+1;
    curve->aTimes=0;
  }
  
  if(curve->aTimes<curve->maxTimes)
  {
    pCalCurve[curve->curveMode](curve);
    curve->aTimes++;
  }
  else
  {
    curve->currentSpeed=curve->targetSpeed;
    curve->maxTimes=0;
    curve->aTimes=0;
  }
}
 
/*梯形曲線速度計算*/
static void CalCurveTRAP(CurveObjectType *trap)
{
  float slope=0.0;
  
  slope=(trap->targetSpeed-trap->startSpeed)/trap->maxTimes;
    
  trap->currentSpeed=trap->startSpeed+slope*trap->aTimes;
 
  if(trap->currentSpeed>trap->speedMax)
  {
    trap->currentSpeed=trap->speedMax;
  }
  
  if(trap->currentSpeed<trap->speedMin)
  {
    trap->currentSpeed=trap->speedMin;
  }
}
           

  在這個實作中,我們出于更普遍的實用性考慮,将各種曲線的相同操作內建在一起,然後将它們差異的部分通過曲線類型屬性以回調函數的方式內建。

3、應用與驗證

  我們實作了T形電機速度規劃曲線的基本設計與實作。接下來,我們就是用這一調速曲線來實作一個電機調速的執行個體。我們定義速度規劃曲線時,是及與對象的思想來實作的,是以我們先聲明一條曲線對象執行個體。

  CurveObjectType curve; //電機調速曲線

  在聲明了這一曲線對象後,我們需要對其初始化指派才能正确的使用。大多數的屬性直接根據應用對象的要求給予初始值就可以了。需要注意的是曲線類型這一屬性,這将決定使用什麼樣的速度規劃曲線。該屬性為SpeedCurveType枚舉,該枚舉定義如下:

/* 定義電機速度曲線類型枚舉 */
typedef enum SpeedCurve {
  CURVE_NONE=0,  //直啟
  CURVE_TRAP=1,  //梯形曲線
  CURVE_SPTA=2   //S型曲線
}SpeedCurveType;
           

  在這裡我們需要将曲線類型初始化為T形速度規劃曲線。具體操作如下:

  curve.curveMode=CURVE_TRAP;

  初始化完成之後就可以使用曲線對象來實作電機速度的調節了。使用也很簡單,隻要按一定的時間周期調用我們前面實作的MotorVelocityCurve函數就可以實作整個調速過程。具體如下:

  MotorVelocityCurve(&curve);

  在每次調速開始之前都需要設定取下的開始速度和目标速度,這樣函數就會按照設定的起始速度和目标速度實作速度調整。

4、小結

  我們實作了梯形加減速曲線,并使用其實作了具體的應用。總體來說,當我們将參數設定的合适時,所起到的效果也是非常明顯的。在我們的實際使用過程中,梯形曲線對大多數的應用基本都合适。不僅是在啟動和停車過程,在運作過程中如果速度設定發生改變,也會調用曲線實作加減速過程。

  梯形速度曲線雖說實作簡單,在一般的應用場合也能有不錯的效果,但實際上還是有一定的問題。梯形速度曲線的加速度是一個常量,這就造成加速度的變化過程并不連續,在加減速階段和勻速運動階段的連接配接部分,加速度會發生突變,而這種突變可能會對控制目标産生沖擊,而有些應用場合這種沖擊是不允許的。

歡迎關注:

如果閱讀這篇文章讓您略有所得,還請點選下方的【好文要頂】按鈕。

當然,如果您想及時了解我的部落格更新,不妨點選下方的【關注我】按鈕。

如果您希望更友善且及時的閱讀相關文章,也可以掃描上方二維碼關注我的微信公衆号【木南創智】

繼續閱讀