電機速度曲線規划2:S形速度曲線設計與實現


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

1、基本原理

  S型速度曲線控制算法是工業控制領域另一種常用的加減速控制策略,S型曲線很好的克服了T型曲線加速度不連續的問題。

  S型曲線實際就是實現一個加速度的T型變化過程,具體來說就是加速度增加、加速度恆定、將速度減小的過程。在整個速度調節規程中,加速度是連續變化的,而反映到速度的變化就是一條平滑的S型曲線。如下圖所示:

  這是比較常見的S曲線的形式,其函數表達式如下:

  這一函數是這類函數的一個特例,其並不具有普遍性。在我們應用中,我們可能會需要根據應用的要求對S型曲線在橫軸和縱軸兩個方向平移或拉伸。所以這一函數更為普遍的描述如下:

  在這一表達式中,A表示在縱軸方向的平移,B表示在縱軸方向的拉伸,a表示在橫軸方向的拉伸,b表示在橫軸方向的平移。具體反映到函數圖形上就是如下圖所示:

  那么究竟如何使用這一S曲線函數來對電機進行調速呢?我們考慮到,所謂電機調速實際就是電機速度與運行時間之間存在一定的函數關系。很顯然,縱軸就是電機速度,橫軸就是運行時間。於是我們就可以得到電機的S型速度曲線的函數關系如下:

  可能大家會發現,這個速度曲線的函數似乎與前面的數學函數有些許差別。這是為了更好的適應調速的區別。在數學上,數軸都是對稱的,但在速度調節過程中,速度和時間都不可能存在負數的情況,所以我們需要對其進行平移。但是平移之后,S曲線的圖形就不對稱了,所以我們以整個調速過程的調速時間的中間點為軸就是對稱的了,所以就有了上述的函數表達式。

2、設計與實現

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

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

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

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

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

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;
  }
}
 
/*S型曲線速度計算*/
static void CalCurveSPTA(CurveObjectType *spta)
{
  float power=0.0;
  float speed=0.0;
  
  power=(2*((float)spta->aTimes)-((float)spta->maxTimes))/((float)spta->maxTimes);
  power=(0.0-spta->flexible)*power;
  
  speed=1+expf(power);
  speed=(spta->targetSpeed-spta->startSpeed)/speed;
  spta->currentSpeed=speed+spta->startSpeed;
  
  if(spta->currentSpeed>spta->speedMax)
  {
     spta->currentSpeed=spta->speedMax;
  }
  
  if(spta->currentSpeed<spta->speedMin)
  {
     spta->currentSpeed=spta->speedMin;
  }
}

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

3、應用與驗證

  我們實現了S型電機速度規划曲線的基本設計與實現。接下來,我們就是用這一調速曲線來實現一個電機調速的實例。我們定義速度規划曲線時,是及與對象的思想來實現的,所以我們先聲明一條曲線對象實例。

  CurveObjectType curve; //電機調速曲線

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

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

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

  curve.curveMode=CURVE_SPTA;

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

  MotorVelocityCurve(&curve);

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

4、小結

  S型速度曲線將整個運動過程划分為7個階段,即加加速度段、勻加速度段、減加速度段、勻速段、加減速度段、勻減速度段和減減速度段,不同階段速度銜接處加速度是連續的,且加速度的變化率可控,克服了梯形速度曲線中存在的加速度突變的不利影響,這是S型曲線的一大優勢。

  但是相比於T型速度曲線,S型曲線的計算量要大很多,實現起來也比T型曲線更為復雜。不過這些在現在的處理系統中都不再是問題。在使用過程中需要關注參數設定,特別是拉伸系數,必須根據應用場合需要仔細調整。如果太小,中間調速過程會變平坦,起始和結束階段則會相對變化較快;如果太大,其實和結束過程會變得比較平坦,但中間部分會變化較快。具體就要看應用需求了。

歡迎關注:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM