|
- /**
- * 函數功能: 主函數.
- * 輸入參數: 無
- * 返 回 值: 無
- * 說 明: 無
- */
- int main(void)
- {
- /* 復位所有外設,初始化Flash接口和系統滴答定時器 */
- HAL_Init();
- /* 配置系統時鐘 */
- SystemClock_Config();
- /* 配置GPIO作為按鍵使用 */
- KEY_GPIO_Init();
- /* 配置串口輸出 */
- USARTx_Init();
- /* 無限循環 */
- while (1)
- {
- if(KEY1_StateRead() == KEY_DOWN)
- {
- /* 計算S型加減速曲線的加速段速度值*/
- CalcSpeed(0,10,4); // 從0加速到10r/min,加速時間是4s
- }
- }
- }
- /**
- * 函數功能:速度表計算函數
- * 輸入參數:V0 初速度,單位:轉/min
- * Vt 末速度,單位:轉/min
- * Time 加速時間 單位: s
- * 返 回 值:無
- * 說 明: 根據速度曲線和加速時間,將數據密集化,即計算每一步的速度值
- */
- void CalcSpeed(int Vo, int Vt, float Time)
- {
- int32_t i = 0;
-
- int32_t Vm =0; // 中間點速度
- float Jerk = 0; // 加加速度
- float Tn = 0; // 時間間隔
- float DeltaV = 0; // 速度的增量dv
- float TimeDel = 0;
- /* 這里采用的數學模型是勻變速直線運動
- * 加速段的曲線有兩部分組成,第一是加速度遞增的加加速段,
- * 第二是加速度遞減的減加速段,兩段曲線可以視為關于中心對稱(中心是中點速度).這兩段曲線所用時間相等
- * 所以中點速度 Vm = (Vt + Vo)/2;
- * 加加速段:
- * 加加速段的加速度曲線是一條過原點的遞增的直線,對加速度積分得到的就是速度的增加量
- * 所以有:Vm - Vo = 1/2 * Jerk * t^2,得到加加速度Jerk.
- * 最后得到位移方程 S = 1/6 Jerk * t^3
- * :分析過程請結合工程文件夾下得曲線圖理解.
- * 由于S型曲線是V-t曲線,所以這里對時間進行等分,然后根據每一份的時間計算出速度表
- */
- Speed.Vo = ROUNDPS_2_STEPPS(Vo); // 起速:Step/s
- Speed.Vt = ROUNDPS_2_STEPPS(Vt); // 末速:Step/s
- Time = ACCEL_TIME(Time); // 得到加加速段的時間
- Vm = MIDDLEVELOCITY( Speed.Vo , Speed.Vt ); // 計算中點速度
- Jerk = ACCELL_INCREASE( Speed.Vo, Vm, Time ); // 根據中點速度計算加加速度
- Speed.AcceleratingStep = (int32_t)ACCEL_DISPLACEMENT(Jerk,Time);// 加加速需要的步數
-
- /* 申請內存空間存放速度表 */
- Speed.AcceleratingStep = abs(Speed.AcceleratingStep ); // 減速計算的時候防止出現負數
- if( Speed.AcceleratingStep % 2 != 0) // 由于浮點型數據轉換成整形數據帶來了誤差,所以這里加1
- Speed.AcceleratingStep += 1;
- Speed.AccelStep = Speed.AcceleratingStep * 2; // 加速段的步數
- Speed.VelocityTab = (float*)(malloc( Speed.AccelStep * sizeof(float) + 1 ));//申請內存
- if(Speed.VelocityTab == NULL)
- {
- printf("內存不足!請修改曲線參數!\n");
- return ;
- }
-
- /* 目標的速度曲線是對時間的方程,所以這里對時間等分成Speed.S份,根據時間,計算出對應的速度 */
- TimeDel = Time / Speed.AcceleratingStep;
- for(i = 0; i <= Speed.AcceleratingStep; i++)
- {
- Tn = i * TimeDel; // 計算第n個時刻t
- DeltaV = 0.5 * Jerk * pow(Tn,2); // dv = 1/2 * Jerk * t^2;
- Speed.VelocityTab[i] = Speed.Vo + DeltaV; // 得到每一時刻對應的速度 // 加加速過程與減加速是中心對稱,可以直接求出后半段速度
- Speed.VelocityTab [ Speed.AccelStep - i] = Speed.Vt - DeltaV ; // 減加速過程對稱點的速度
- }
-
- /* 串口打印輸出速度表 */
- for(i = 0; i <= Speed.AccelStep ; i++)
- {
- printf("VelocityTab[%d] = %.3f\n",i,Speed.VelocityTab[i]);
- }
- free((void*)Speed.VelocityTab);
- Speed.VelocityTab = NULL;
- }
- /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式開發團隊 *****END OF FILE****/
復制代碼
|
|