position_task.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /*
  2. * position_task.c
  3. *
  4. * Created on: Nov 6, 2024
  5. * Author: jakubski
  6. */
  7. #include "position_task.h"
  8. #include "meas_tasks.h"
  9. #include "measurements.h"
  10. #include "node-red-config.h"
  11. #include "peripherial.h"
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. float positionXSetting __attribute__ ((aligned (32))) = 0.0;
  16. float positionYSetting __attribute__ ((aligned (32))) = 0.0;
  17. //osMutexId_t positionSettingMutex;
  18. osThreadId_t positionXControlTaskHandle = NULL;
  19. osThreadId_t positionYControlTaskHandle = NULL;
  20. PositionControlTaskInitArg positionXControlTaskInitArg __attribute__ ((aligned (32))) = { 0 };
  21. PositionControlTaskInitArg positionYControlTaskInitArg __attribute__ ((aligned (32))) = { 0 };
  22. extern osTimerId_t motorXTimerHandle;
  23. extern osTimerId_t motorYTimerHandle;
  24. extern TIM_HandleTypeDef htim3;
  25. extern TIM_OC_InitTypeDef motorXYTimerConfigOC;
  26. void PositionControlTaskInit (void) {
  27. // positionSettingMutex = osMutexNew (NULL);
  28. osThreadAttr_t osThreadAttrPositionControlTask = { 0 };
  29. osThreadAttrPositionControlTask.stack_size = configMINIMAL_STACK_SIZE * 2;
  30. osThreadAttrPositionControlTask.priority = (osPriority_t)osPriorityHigh;
  31. positionXControlTaskInitArg.channel1 = TIM_CHANNEL_1;
  32. positionXControlTaskInitArg.channel2 = TIM_CHANNEL_2;
  33. positionXControlTaskInitArg.htim = &htim3;
  34. positionXControlTaskInitArg.motorTimerConfigOC = &motorXYTimerConfigOC;
  35. positionXControlTaskInitArg.motorTimerHandle = motorXTimerHandle;
  36. positionXControlTaskInitArg.positionSettingQueue = osMessageQueueNew (16, sizeof (PositionControlTaskData), NULL);
  37. positionXControlTaskInitArg.switchLimiterCenterStat = &(sensorsInfo.limitXSwitchCenter);
  38. positionXControlTaskInitArg.switchLimiterUpStat = &(sensorsInfo.limitXSwitchUp);
  39. positionXControlTaskInitArg.switchLimiterDownStat = &(sensorsInfo.limitXSwitchDown);
  40. positionXControlTaskInitArg.currentPosition = &(sensorsInfo.currentXPosition);
  41. positionXControlTaskInitArg.positionOffset = &(sensorsInfo.positionXOffset);
  42. positionXControlTaskInitArg.motorStatus = &(sensorsInfo.motorXStatus);
  43. positionXControlTaskInitArg.motorPeakCurrent = &(sensorsInfo.motorXPeakCurrent);
  44. positionXControlTaskInitArg.positionSetting = &positionXSetting;
  45. positionXControlTaskInitArg.axe = 'X';
  46. positionYControlTaskInitArg.channel1 = TIM_CHANNEL_3;
  47. positionYControlTaskInitArg.channel2 = TIM_CHANNEL_4;
  48. positionYControlTaskInitArg.htim = &htim3;
  49. positionYControlTaskInitArg.motorTimerConfigOC = &motorXYTimerConfigOC;
  50. positionYControlTaskInitArg.motorTimerHandle = motorYTimerHandle;
  51. positionYControlTaskInitArg.positionSettingQueue = osMessageQueueNew (16, sizeof (PositionControlTaskData), NULL);
  52. positionYControlTaskInitArg.switchLimiterCenterStat = &(sensorsInfo.limitYSwitchCenter);
  53. positionYControlTaskInitArg.switchLimiterUpStat = &(sensorsInfo.limitYSwitchUp);
  54. positionYControlTaskInitArg.switchLimiterDownStat = &(sensorsInfo.limitYSwitchDown);
  55. positionYControlTaskInitArg.currentPosition = &(sensorsInfo.currentYPosition);
  56. positionYControlTaskInitArg.positionOffset = &(sensorsInfo.positionYOffset);
  57. positionYControlTaskInitArg.motorStatus = &(sensorsInfo.motorYStatus);
  58. positionYControlTaskInitArg.motorPeakCurrent = &(sensorsInfo.motorYPeakCurrent);
  59. positionXControlTaskInitArg.positionSetting = &positionYSetting;
  60. positionYControlTaskInitArg.axe = 'Y';
  61. positionXControlTaskHandle = osThreadNew (PositionControlTask, &positionXControlTaskInitArg, &osThreadAttrPositionControlTask);
  62. positionYControlTaskHandle = osThreadNew (PositionControlTask, &positionYControlTaskInitArg, &osThreadAttrPositionControlTask);
  63. }
  64. void PositionControlTask (void* argument) {
  65. const int32_t PositionControlTaskTimeOut = 10;
  66. PositionControlTaskInitArg* posCtrlTaskArg = (PositionControlTaskInitArg*)argument;
  67. PositionControlTaskData posCtrlData __attribute__ ((aligned (32))) = { 0 };
  68. uint32_t motorStatus = 0;
  69. osStatus_t queueSatus;
  70. int32_t pwmValue = MOTOR_START_STOP_PWM_VALUE;
  71. int32_t sign = 0;
  72. MovementPhases movementPhase = idlePhase;
  73. float startPosition = 0;
  74. float prevPosition = 0;
  75. int32_t timeLeftMS = 0;
  76. int32_t moveCmdTimeoutCounter = 0;
  77. while (pdTRUE) {
  78. queueSatus = osMessageQueueGet (posCtrlTaskArg->positionSettingQueue, &posCtrlData, 0, pdMS_TO_TICKS (PositionControlTaskTimeOut));
  79. if (queueSatus == osOK) {
  80. if (osMutexAcquire (sensorsInfoMutex, osWaitForever) == osOK) {
  81. float posDiff = posCtrlData.positionSettingValue - (*posCtrlTaskArg->currentPosition + *posCtrlTaskArg->positionOffset);
  82. if (posDiff != 0) {
  83. sign = posDiff > 0 ? 1 : -1;
  84. startPosition = *posCtrlTaskArg->currentPosition + *posCtrlTaskArg->positionOffset;
  85. movementPhase = startPhase;
  86. moveCmdTimeoutCounter = 0;
  87. timeLeftMS = 0;
  88. #ifdef DBG_POSITION
  89. printf ("Axe %c start phase\n", posCtrlTaskArg->axe);
  90. #endif
  91. }
  92. *(posCtrlTaskArg->positionSetting) = posCtrlData.positionSettingValue;
  93. osMutexRelease (sensorsInfoMutex);
  94. // if (osMutexAcquire (positionSettingMutex, osWaitForever) == osOK) {
  95. // osMutexRelease (positionSettingMutex);
  96. // }
  97. }
  98. } else if (queueSatus == osErrorTimeout) {
  99. if (osMutexAcquire (sensorsInfoMutex, osWaitForever) == osOK) {
  100. if (((*posCtrlTaskArg->motorStatus != 0) && (movementPhase != idlePhase)) || (movementPhase == startPhase) ) {
  101. if (((*posCtrlTaskArg->switchLimiterDownStat == 1) && (*posCtrlTaskArg->switchLimiterUpStat == 1)) ||
  102. ((*posCtrlTaskArg->switchLimiterUpStat == 1) && (*posCtrlTaskArg->switchLimiterCenterStat == 1))) {
  103. movementPhase = idlePhase;
  104. motorStatus = MotorControl (posCtrlTaskArg->htim, posCtrlTaskArg->motorTimerConfigOC, posCtrlTaskArg->channel1, posCtrlTaskArg->channel2, posCtrlTaskArg->motorTimerHandle, 0,
  105. 0, *posCtrlTaskArg->switchLimiterUpStat, *posCtrlTaskArg->switchLimiterDownStat);
  106. *posCtrlTaskArg->motorStatus = motorStatus;
  107. #ifdef DBG_POSITION
  108. printf ("Axe %c limiters wrong state - idle phase\n", posCtrlTaskArg->axe);
  109. #endif
  110. }
  111. timeLeftMS += PositionControlTaskTimeOut;
  112. if (prevPosition == (*posCtrlTaskArg->currentPosition + *posCtrlTaskArg->positionOffset)) {
  113. moveCmdTimeoutCounter += PositionControlTaskTimeOut;
  114. } else {
  115. moveCmdTimeoutCounter = 0;
  116. }
  117. prevPosition = *posCtrlTaskArg->currentPosition + *posCtrlTaskArg->positionOffset;
  118. if (moveCmdTimeoutCounter > NO_MOVE_TIMEOUT_MS) {
  119. movementPhase = idlePhase;
  120. motorStatus = MotorControl (posCtrlTaskArg->htim, posCtrlTaskArg->motorTimerConfigOC, posCtrlTaskArg->channel1, posCtrlTaskArg->channel2, posCtrlTaskArg->motorTimerHandle, 0,
  121. 0, *posCtrlTaskArg->switchLimiterUpStat, *posCtrlTaskArg->switchLimiterDownStat);
  122. *posCtrlTaskArg->motorStatus = motorStatus;
  123. #ifdef DBG_POSITION
  124. printf ("Axe %c no movement idle phase\n", posCtrlTaskArg->axe);
  125. #endif
  126. }
  127. switch (movementPhase) {
  128. case startPhase:
  129. motorStatus = MotorControl (posCtrlTaskArg->htim, posCtrlTaskArg->motorTimerConfigOC, posCtrlTaskArg->channel1, posCtrlTaskArg->channel2, posCtrlTaskArg->motorTimerHandle,
  130. sign * pwmValue, -1, *posCtrlTaskArg->switchLimiterUpStat, *posCtrlTaskArg->switchLimiterDownStat);
  131. *posCtrlTaskArg->motorStatus = motorStatus;
  132. if (motorStatus == 1) {
  133. *posCtrlTaskArg->motorPeakCurrent = 0.0;
  134. #ifdef DBG_POSITION
  135. printf ("Axe %c speed up phase\n", posCtrlTaskArg->axe);
  136. #endif
  137. if (abs (posCtrlData.positionSettingValue - startPosition) > ANGLE_RANGE_FOR_MOTOR_SPEED_LIMIT) {
  138. movementPhase = speedUpPhase;
  139. } else {
  140. movementPhase = slowDownPhase;
  141. }
  142. timeLeftMS = 0;
  143. moveCmdTimeoutCounter = 0;
  144. } else {
  145. movementPhase = idlePhase;
  146. #ifdef DBG_POSITION
  147. printf ("Axe %c idle phase\n", posCtrlTaskArg->axe);
  148. #endif
  149. }
  150. break;
  151. case speedUpPhase:
  152. if ((abs ((*posCtrlTaskArg->currentPosition + *posCtrlTaskArg->positionOffset) - startPosition) >= ANGLE_RANGE_FOR_MOTOR_SPEED_LIMIT) || (timeLeftMS >= TIME_MS_FOR_MOTOR_SPEED_LIMIT)) {
  153. pwmValue = MOTOR_HIGH_SPEED_PWM_VALUE;
  154. motorStatus = MotorControl (posCtrlTaskArg->htim, posCtrlTaskArg->motorTimerConfigOC, posCtrlTaskArg->channel1, posCtrlTaskArg->channel2, posCtrlTaskArg->motorTimerHandle,
  155. sign * pwmValue, -1, *posCtrlTaskArg->switchLimiterUpStat, *posCtrlTaskArg->switchLimiterDownStat);
  156. *posCtrlTaskArg->motorStatus = motorStatus;
  157. movementPhase = movePhase;
  158. #ifdef DBG_POSITION
  159. printf ("Axe %c move phase\n", posCtrlTaskArg->axe);
  160. #endif
  161. }
  162. break;
  163. case movePhase:
  164. if (abs ((*posCtrlTaskArg->currentPosition + *posCtrlTaskArg->positionOffset) - *posCtrlTaskArg->positionSetting) <= ANGLE_RANGE_FOR_MOTOR_SPEED_LIMIT) {
  165. movementPhase = slowDownPhase;
  166. #ifdef DBG_POSITION
  167. printf ("Axe %c slow down phase\n", posCtrlTaskArg->axe);
  168. #endif
  169. }
  170. break;
  171. case slowDownPhase:
  172. pwmValue = MOTOR_START_STOP_PWM_VALUE;
  173. motorStatus = MotorControl (posCtrlTaskArg->htim, posCtrlTaskArg->motorTimerConfigOC, posCtrlTaskArg->channel1, posCtrlTaskArg->channel2, posCtrlTaskArg->motorTimerHandle,
  174. sign * pwmValue, -1, *posCtrlTaskArg->switchLimiterUpStat, *posCtrlTaskArg->switchLimiterDownStat);
  175. *posCtrlTaskArg->motorStatus = motorStatus;
  176. movementPhase = stopPhase;
  177. timeLeftMS = 0;
  178. #ifdef DBG_POSITION
  179. printf ("Axe %c stop phase\n", posCtrlTaskArg->axe);
  180. #endif
  181. break;
  182. case stopPhase:
  183. float posDiff = sign > 0 ? posCtrlData.positionSettingValue - (*posCtrlTaskArg->currentPosition + *posCtrlTaskArg->positionOffset) : (*posCtrlTaskArg->currentPosition + *posCtrlTaskArg->positionOffset) - posCtrlData.positionSettingValue;
  184. if ((posDiff <= 0) || (timeLeftMS >= TIME_MS_FOR_MOTOR_SPEED_LIMIT)) {
  185. motorStatus = MotorControl (posCtrlTaskArg->htim, posCtrlTaskArg->motorTimerConfigOC, posCtrlTaskArg->channel1, posCtrlTaskArg->channel2, posCtrlTaskArg->motorTimerHandle,
  186. 0, 0, *posCtrlTaskArg->switchLimiterUpStat, *posCtrlTaskArg->switchLimiterDownStat);
  187. *posCtrlTaskArg->motorStatus = motorStatus;
  188. movementPhase = idlePhase;
  189. #ifdef DBG_POSITION
  190. printf ("Axe %c idle phase\n", posCtrlTaskArg->axe);
  191. #endif
  192. }
  193. break;
  194. default: break;
  195. }
  196. } else {
  197. if ((*posCtrlTaskArg->motorStatus == 0) && (movementPhase != idlePhase)) {
  198. movementPhase = idlePhase;
  199. #ifdef DBG_POSITION
  200. printf ("Axe %c idle phase\n", posCtrlTaskArg->axe);
  201. #endif
  202. }
  203. }
  204. osMutexRelease (sensorsInfoMutex);
  205. }
  206. }
  207. }
  208. }