cmdgen.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. /**
  2. * @file cmdgen.c
  3. * @author Zhang, Kai(zhangkai71@midea.com)
  4. * @brief System FSM
  5. * @version 0.1
  6. * @date 2021-09-27
  7. *
  8. * @copyright Copyright (c) 2021
  9. *
  10. */
  11. #include "cmdgen.h"
  12. /******************************
  13. *
  14. * Parameter
  15. *
  16. ******************************/
  17. SLONG cmd_pvt_slAccDeltaInPu; // Q31, Acceleration before acceleration limit
  18. SLONG cmd_pvt_slAccDeltaOutPu; // Q31, Acceleration after acceleration limit
  19. SLONG cmd_pvt_slAccDeltaOutZ1Pu; // Q31, Old Acceleration
  20. SLONG cmd_pvt_slSpdRefZ1Pu;
  21. void cmd_voCmdGenInit(CMD_CONTROL *s)
  22. {
  23. s->Out.swSpdCmdRefPu = 0;
  24. s->Out.swSpdRefPu = 0;
  25. s->Out.slSpdRefPu = 0;
  26. s->Out.swSpdCmdDir = 1;
  27. s->Out.swSpdRefDirNow = 1;
  28. cmd_pvt_slAccDeltaInPu = 33408; // when ACC value is 1500
  29. cmd_pvt_slAccDeltaOutPu = 33408;
  30. cmd_pvt_slAccDeltaOutZ1Pu = 33408;
  31. s->Out.enSpdStatus = Constant;
  32. cmd_pvt_slSpdRefZ1Pu = 0;
  33. }
  34. void cmd_voCmdGenCoef(CMD_GEN_COFIN *in, CMD_CONTROL *s)
  35. {
  36. SLONG slAccLim1Tmp = 0;
  37. SLONG slAccLim2Tmp = 0;
  38. SLONG slAccLim3Tmp = 0;
  39. SLONG slDecLim1Tmp = 0;
  40. SLONG slDecLim2Tmp = 0;
  41. SLONG slDecLim3Tmp = 0;
  42. if (in->uwBaseRpm < 1000)
  43. {
  44. in->uwBaseRpm = 1000;
  45. }
  46. s->Coef.uwBaseRpm = in->uwBaseRpm;
  47. s->Coef.uwBaseRpmInv = ((ULONG)1 << 25) / in->uwBaseRpm; // Q25
  48. if (in->uwFTbsHz < 600)
  49. {
  50. in->uwFTbsHz = 600;
  51. }
  52. s->Coef.uwFTbsHzInv = ((ULONG)1 << 25) / in->uwFTbsHz; // Q25
  53. if (in->uwRefMaxRpm < 20000)
  54. {
  55. in->uwRefMaxRpm = 20000;
  56. }
  57. s->Coef.ulSpdRefMaxPu = ((ULONG)in->uwRefMaxRpm << 15) / in->uwBaseRpm; // Q15
  58. if (in->uwAccSw1Rpm < 10)
  59. {
  60. in->uwAccSw1Rpm = 10;
  61. }
  62. if (in->uwAccSw2Rpm < 20)
  63. {
  64. in->uwAccSw2Rpm = 20;
  65. }
  66. if (in->uwDecSw1Rpm < 10)
  67. {
  68. in->uwDecSw1Rpm = 10;
  69. }
  70. if (in->uwDecSw2Rpm < 20)
  71. {
  72. in->uwDecSw2Rpm = 20;
  73. }
  74. if (in->swAccLim1Rpmps > 5000)
  75. {
  76. in->swAccLim1Rpmps = 5000;
  77. }
  78. else if (in->swAccLim1Rpmps <= 0)
  79. {
  80. in->swAccLim1Rpmps = 1;
  81. }
  82. if (in->swAccLim2Rpmps > 5000)
  83. {
  84. in->swAccLim2Rpmps = 5000;
  85. }
  86. else if (in->swAccLim2Rpmps <= 0)
  87. {
  88. in->swAccLim2Rpmps = 1;
  89. }
  90. if (in->swAccLim3Rpmps > 5000)
  91. {
  92. in->swAccLim3Rpmps = 5000;
  93. }
  94. else if (in->swAccLim3Rpmps <= 0)
  95. {
  96. in->swAccLim3Rpmps = 1;
  97. }
  98. if (in->swDecLim1Rpmps > 5000)
  99. {
  100. in->swDecLim1Rpmps = 5000;
  101. }
  102. else if (in->swDecLim1Rpmps <= 0)
  103. {
  104. in->swDecLim1Rpmps = 1;
  105. }
  106. if (in->swDecLim2Rpmps > 5000)
  107. {
  108. in->swDecLim2Rpmps = 5000;
  109. }
  110. else if (in->swDecLim2Rpmps <= 0)
  111. {
  112. in->swDecLim2Rpmps = 1;
  113. }
  114. if (in->swDecLim3Rpmps > 5000)
  115. {
  116. in->swDecLim3Rpmps = 5000;
  117. }
  118. else if (in->swDecLim3Rpmps <= 0)
  119. {
  120. in->swDecLim3Rpmps = 1;
  121. }
  122. s->Coef.ulAccSpdSw1Pu = (((ULONG)in->uwAccSw1Rpm << 15) / in->uwBaseRpm); // Q15
  123. s->Coef.ulAccSpdSw2Pu = (((ULONG)in->uwAccSw2Rpm << 15) / in->uwBaseRpm); // Q15
  124. s->Coef.ulDecSpdSw1Pu = (((ULONG)in->uwDecSw1Rpm << 15) / in->uwBaseRpm); // Q15
  125. s->Coef.ulDecSpdSw2Pu = (((ULONG)in->uwDecSw2Rpm << 15) / in->uwBaseRpm); // Q15
  126. slAccLim1Tmp = ((SLONG)in->swAccLim1Rpmps << 15) / in->uwBaseRpm;
  127. if (slAccLim1Tmp > 32767)
  128. {
  129. slAccLim1Tmp = 32767;
  130. }
  131. slAccLim2Tmp = ((SLONG)in->swAccLim2Rpmps << 15) / in->uwBaseRpm;
  132. if (slAccLim2Tmp > 32767)
  133. {
  134. slAccLim2Tmp = 32767;
  135. }
  136. slAccLim3Tmp = ((SLONG)in->swAccLim3Rpmps << 15) / in->uwBaseRpm;
  137. if (slAccLim3Tmp > 32767)
  138. {
  139. slAccLim3Tmp = 32767;
  140. }
  141. slDecLim1Tmp = ((SLONG)in->swDecLim1Rpmps << 15) / in->uwBaseRpm;
  142. if (slDecLim1Tmp > 32767)
  143. {
  144. slDecLim1Tmp = 32767;
  145. }
  146. slDecLim2Tmp = ((SLONG)in->swDecLim2Rpmps << 15) / in->uwBaseRpm;
  147. if (slDecLim2Tmp > 32767)
  148. {
  149. slDecLim2Tmp = 32767;
  150. }
  151. slDecLim3Tmp = ((SLONG)in->swDecLim3Rpmps << 15) / in->uwBaseRpm;
  152. if (slDecLim3Tmp > 32767)
  153. {
  154. slDecLim3Tmp = 32767;
  155. }
  156. s->Coef.slAccLim1Pu = (slAccLim1Tmp << 16) / in->uwFTbsHz; // Q31
  157. s->Coef.slAccLim2Pu = (slAccLim2Tmp << 16) / in->uwFTbsHz; // Q31
  158. s->Coef.slAccLim3Pu = (slAccLim3Tmp << 16) / in->uwFTbsHz; // Q31
  159. s->Coef.slDecLim1Pu = (slDecLim1Tmp << 16) / in->uwFTbsHz; // Q31
  160. s->Coef.slDecLim2Pu = (slDecLim2Tmp << 16) / in->uwFTbsHz; // Q31
  161. s->Coef.slDecLim3Pu = (slDecLim3Tmp << 16) / in->uwFTbsHz; // Q31
  162. }
  163. void cmd_voCmdGen(CMD_GEN_IN *in, CMD_CONTROL *s)
  164. {
  165. SLONG slSpdCmdRefPu = 0; // Q31
  166. SLONG slAccDeltaInPuTmp1 = 0;
  167. SLONG slAccDeltaInPuTmp2 = 0;
  168. UWORD uwSpdRefZ1AbsPu = 0;
  169. ULONG ulAccDeltaInAbsPu = 33408; // when ACC value is 1500
  170. s->Out.swSpdRefPu = s->Out.slSpdRefPu >> 16; // Q31-Q16=Q15
  171. s->Out.swSpdCmdRefPu = in->slRefRpm; // Q15
  172. slSpdCmdRefPu = ((SLONG)s->Out.swSpdCmdRefPu << 16); // Q31
  173. if (s->Out.swSpdCmdRefPu >= 0)
  174. {
  175. s->Out.swSpdCmdDir = 1;
  176. }
  177. else
  178. {
  179. s->Out.swSpdCmdDir = -1;
  180. }
  181. slAccDeltaInPuTmp1 = ((SLONG)in->swAccRpmps * s->Coef.uwBaseRpmInv) >> 13; // Q0+Q25-Q13=Q12
  182. if (slAccDeltaInPuTmp1 > 131071) // Q17 = 131072
  183. {
  184. slAccDeltaInPuTmp1 = 131071;
  185. }
  186. slAccDeltaInPuTmp2 = (slAccDeltaInPuTmp1 * s->Coef.uwFTbsHzInv) >> 11; // Q12+Q25-Q11=Q26
  187. if (slAccDeltaInPuTmp2 > 67108863) // Q26 = 67108864
  188. {
  189. slAccDeltaInPuTmp2 = 67108863;
  190. }
  191. cmd_pvt_slAccDeltaInPu = (slAccDeltaInPuTmp2 << 5);
  192. /* Accelaration & decelaration limit */
  193. // uwSpdRefZ1AbsPu = abs(s->Out.swSpdRefPu);
  194. // ulAccDeltaInAbsPu = abs(cmd_pvt_slAccDeltaInPu);
  195. if ((s->Out.swSpdRefPu) >= 0)
  196. {
  197. uwSpdRefZ1AbsPu = (UWORD)s->Out.swSpdRefPu;
  198. }
  199. else
  200. {
  201. uwSpdRefZ1AbsPu = (UWORD)(-(s->Out.swSpdRefPu));
  202. }
  203. if ((cmd_pvt_slAccDeltaInPu) >= 0)
  204. {
  205. ulAccDeltaInAbsPu = (UWORD)cmd_pvt_slAccDeltaInPu;
  206. }
  207. else
  208. {
  209. ulAccDeltaInAbsPu = (UWORD)(-cmd_pvt_slAccDeltaInPu);
  210. }
  211. if (cmd_pvt_slAccDeltaInPu > 0)
  212. {
  213. if ((s->Out.swSpdRefPu - s->Out.swSpdCmdRefPu) < 0)
  214. {
  215. if (s->Out.swSpdRefPu >= 0) // in acceleration
  216. {
  217. s->Out.enSpdStatus = Accelerate;
  218. if (uwSpdRefZ1AbsPu < s->Coef.ulAccSpdSw1Pu) // Q15
  219. {
  220. if (ulAccDeltaInAbsPu > s->Coef.slAccLim1Pu)
  221. {
  222. cmd_pvt_slAccDeltaOutPu = s->Coef.slAccLim1Pu; // Q31
  223. }
  224. else
  225. {
  226. cmd_pvt_slAccDeltaOutPu = cmd_pvt_slAccDeltaInPu;
  227. }
  228. }
  229. else if (uwSpdRefZ1AbsPu < s->Coef.ulAccSpdSw2Pu)
  230. {
  231. if (ulAccDeltaInAbsPu > s->Coef.slAccLim2Pu)
  232. {
  233. cmd_pvt_slAccDeltaOutPu = s->Coef.slAccLim2Pu;
  234. }
  235. else
  236. {
  237. cmd_pvt_slAccDeltaOutPu = cmd_pvt_slAccDeltaInPu;
  238. }
  239. }
  240. else
  241. {
  242. if (ulAccDeltaInAbsPu > s->Coef.slAccLim3Pu)
  243. {
  244. cmd_pvt_slAccDeltaOutPu = s->Coef.slAccLim3Pu; // Q31
  245. }
  246. else
  247. {
  248. cmd_pvt_slAccDeltaOutPu = cmd_pvt_slAccDeltaInPu;
  249. }
  250. }
  251. }
  252. else // in deceleration
  253. {
  254. s->Out.enSpdStatus = Decelerate;
  255. if (uwSpdRefZ1AbsPu < s->Coef.ulDecSpdSw1Pu)
  256. {
  257. if (ulAccDeltaInAbsPu > s->Coef.slDecLim1Pu)
  258. {
  259. cmd_pvt_slAccDeltaOutPu = s->Coef.slDecLim1Pu; // Q31
  260. }
  261. else
  262. {
  263. cmd_pvt_slAccDeltaOutPu = cmd_pvt_slAccDeltaInPu;
  264. }
  265. }
  266. else if (uwSpdRefZ1AbsPu < s->Coef.ulDecSpdSw2Pu)
  267. {
  268. if (ulAccDeltaInAbsPu > s->Coef.slDecLim2Pu)
  269. {
  270. cmd_pvt_slAccDeltaOutPu = s->Coef.slDecLim2Pu; // Q31
  271. }
  272. else
  273. {
  274. cmd_pvt_slAccDeltaOutPu = cmd_pvt_slAccDeltaInPu;
  275. }
  276. }
  277. else
  278. {
  279. if (ulAccDeltaInAbsPu > s->Coef.slDecLim3Pu)
  280. {
  281. cmd_pvt_slAccDeltaOutPu = s->Coef.slDecLim3Pu; // Q31
  282. }
  283. else
  284. {
  285. cmd_pvt_slAccDeltaOutPu = cmd_pvt_slAccDeltaInPu;
  286. }
  287. }
  288. }
  289. }
  290. else if ((s->Out.swSpdRefPu - s->Out.swSpdCmdRefPu) > 0)
  291. {
  292. if (s->Out.swSpdRefPu > 0) // in deceleration
  293. {
  294. s->Out.enSpdStatus = Decelerate;
  295. }
  296. else // in acceleration
  297. {
  298. s->Out.enSpdStatus = Accelerate;
  299. }
  300. if (cmd_pvt_slAccDeltaOutZ1Pu >= 0)
  301. {
  302. cmd_pvt_slAccDeltaOutPu = -cmd_pvt_slAccDeltaOutZ1Pu;
  303. }
  304. else
  305. {
  306. cmd_pvt_slAccDeltaOutPu = cmd_pvt_slAccDeltaOutZ1Pu;
  307. }
  308. // cmd_pvt_slAccDeltaOutPu = -abs(cmd_pvt_slAccDeltaOutZ1Pu);
  309. }
  310. else
  311. {}
  312. }
  313. else if (cmd_pvt_slAccDeltaInPu < 0)
  314. {
  315. if ((s->Out.swSpdRefPu - s->Out.swSpdCmdRefPu) > 0)
  316. {
  317. if (s->Out.swSpdRefPu > 0) // in deceleration
  318. {
  319. s->Out.enSpdStatus = Decelerate;
  320. if (uwSpdRefZ1AbsPu < s->Coef.ulDecSpdSw1Pu)
  321. {
  322. if (ulAccDeltaInAbsPu > s->Coef.slDecLim1Pu)
  323. {
  324. cmd_pvt_slAccDeltaOutPu = s->Coef.slDecLim1Pu; // Q31
  325. }
  326. else
  327. {
  328. cmd_pvt_slAccDeltaOutPu = cmd_pvt_slAccDeltaInPu;
  329. }
  330. }
  331. else if (uwSpdRefZ1AbsPu < s->Coef.ulDecSpdSw2Pu)
  332. {
  333. if (ulAccDeltaInAbsPu > s->Coef.slDecLim2Pu)
  334. {
  335. cmd_pvt_slAccDeltaOutPu = -s->Coef.slDecLim2Pu; // Q31
  336. }
  337. else
  338. {
  339. cmd_pvt_slAccDeltaOutPu = cmd_pvt_slAccDeltaInPu;
  340. }
  341. }
  342. else
  343. {
  344. if (ulAccDeltaInAbsPu > s->Coef.slDecLim3Pu)
  345. {
  346. cmd_pvt_slAccDeltaOutPu = -s->Coef.slDecLim3Pu; // Q31
  347. }
  348. else
  349. {
  350. cmd_pvt_slAccDeltaOutPu = cmd_pvt_slAccDeltaInPu;
  351. }
  352. }
  353. }
  354. else // in acceleration
  355. {
  356. s->Out.enSpdStatus = Accelerate;
  357. if (uwSpdRefZ1AbsPu < s->Coef.ulAccSpdSw1Pu)
  358. {
  359. if (ulAccDeltaInAbsPu > s->Coef.slAccLim1Pu)
  360. {
  361. cmd_pvt_slAccDeltaOutPu = -s->Coef.slAccLim1Pu; // Q31
  362. }
  363. else
  364. {
  365. cmd_pvt_slAccDeltaOutPu = cmd_pvt_slAccDeltaInPu;
  366. }
  367. }
  368. else if (uwSpdRefZ1AbsPu < s->Coef.ulAccSpdSw2Pu)
  369. {
  370. if (ulAccDeltaInAbsPu > s->Coef.slAccLim2Pu)
  371. {
  372. cmd_pvt_slAccDeltaOutPu = -s->Coef.slAccLim2Pu; // Q31
  373. }
  374. else
  375. {
  376. cmd_pvt_slAccDeltaOutPu = cmd_pvt_slAccDeltaInPu;
  377. }
  378. }
  379. else
  380. {
  381. if (ulAccDeltaInAbsPu > s->Coef.slAccLim3Pu)
  382. {
  383. cmd_pvt_slAccDeltaOutPu = -s->Coef.slAccLim3Pu; // Q31
  384. }
  385. else
  386. {
  387. cmd_pvt_slAccDeltaOutPu = cmd_pvt_slAccDeltaInPu;
  388. }
  389. }
  390. }
  391. }
  392. else if ((s->Out.swSpdRefPu - s->Out.swSpdCmdRefPu) < 0)
  393. {
  394. if (s->Out.swSpdRefPu < 0) // in deceleration
  395. {
  396. s->Out.enSpdStatus = Decelerate;
  397. }
  398. else // in acceleration
  399. {
  400. s->Out.enSpdStatus = Accelerate;
  401. }
  402. if (cmd_pvt_slAccDeltaOutZ1Pu >= 0)
  403. {
  404. cmd_pvt_slAccDeltaOutZ1Pu = cmd_pvt_slAccDeltaOutZ1Pu;
  405. }
  406. else
  407. {
  408. cmd_pvt_slAccDeltaOutPu = -cmd_pvt_slAccDeltaOutZ1Pu;
  409. }
  410. // cmd_pvt_slAccDeltaOutPu = abs(cmd_pvt_slAccDeltaOutZ1Pu);
  411. }
  412. else
  413. {}
  414. }
  415. else
  416. {}
  417. cmd_pvt_slAccDeltaOutZ1Pu = cmd_pvt_slAccDeltaOutPu;
  418. if (s->Out.swSpdRefPu > s->Out.swSpdCmdRefPu) // if swSpdRefPu > 0 deceleration, else acceleration
  419. {
  420. s->Out.slSpdRefPu += cmd_pvt_slAccDeltaOutPu; // Q31
  421. if (s->Out.slSpdRefPu <= slSpdCmdRefPu)
  422. {
  423. s->Out.slSpdRefPu = slSpdCmdRefPu;
  424. }
  425. }
  426. else if (s->Out.swSpdRefPu < s->Out.swSpdCmdRefPu) // if swSpdRefPu > 0 acceleration, else deceleration
  427. {
  428. s->Out.slSpdRefPu += cmd_pvt_slAccDeltaOutPu; // Q31
  429. if (s->Out.slSpdRefPu >= slSpdCmdRefPu)
  430. {
  431. s->Out.slSpdRefPu = slSpdCmdRefPu;
  432. }
  433. }
  434. else
  435. {
  436. s->Out.slSpdRefPu = slSpdCmdRefPu;
  437. }
  438. s->Out.swSpdRefPu = s->Out.slSpdRefPu >> 16; // Q31-Q16=Q15
  439. if (cmd_pvt_slSpdRefZ1Pu == s->Out.slSpdRefPu)
  440. {
  441. s->Out.enSpdStatus = Constant;
  442. }
  443. cmd_pvt_slSpdRefZ1Pu = s->Out.slSpdRefPu;
  444. if (s->Out.swSpdRefPu > (SLONG)s->Coef.ulSpdRefMaxPu)
  445. {
  446. s->Out.swSpdRefPu = (SLONG)s->Coef.ulSpdRefMaxPu;
  447. }
  448. else if (s->Out.swSpdRefPu < -(SLONG)s->Coef.ulSpdRefMaxPu)
  449. {
  450. s->Out.swSpdRefPu = -(SLONG)s->Coef.ulSpdRefMaxPu;
  451. }
  452. if (s->Out.swSpdRefPu >= 0)
  453. {
  454. s->Out.swSpdRefDirNow = 1;
  455. }
  456. else
  457. {
  458. s->Out.swSpdRefDirNow = -1;
  459. }
  460. }
  461. void cmd_voCmdDirGen(CMD_GEN_IN *in, CMD_CONTROL *s)
  462. {
  463. if (in->slRefRpm >= 0)
  464. {
  465. s->Out.swSpdCmdDir = 1;
  466. }
  467. else
  468. {
  469. s->Out.swSpdCmdDir = -1;
  470. }
  471. }