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