position_task.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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 = 0.0;
  16. float positionYSetting = 0.0;
  17. osMutexId_t positionSettingMutex;
  18. osThreadId_t positionXControlTaskHandle = NULL;
  19. osThreadId_t positionYControlTaskHandle = NULL;
  20. PositionControlTaskInitArg positionXControlTaskInitArg = { 0 };
  21. PositionControlTaskInitArg positionYControlTaskInitArg = { 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)osPriorityNormal;
  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.motorStatus = &(sensorsInfo.motorXStatus);
  42. positionXControlTaskInitArg.motorPeakCurrent = &(sensorsInfo.motorXPeakCurrent);
  43. positionXControlTaskInitArg.positionSetting = &positionXSetting;
  44. positionXControlTaskInitArg.axe = 'X';
  45. positionYControlTaskInitArg.channel1 = TIM_CHANNEL_3;
  46. positionYControlTaskInitArg.channel2 = TIM_CHANNEL_4;
  47. positionYControlTaskInitArg.htim = &htim3;
  48. positionYControlTaskInitArg.motorTimerConfigOC = &motorXYTimerConfigOC;
  49. positionYControlTaskInitArg.motorTimerHandle = motorYTimerHandle;
  50. positionYControlTaskInitArg.positionSettingQueue = osMessageQueueNew (16, sizeof (PositionControlTaskData), NULL);
  51. positionYControlTaskInitArg.switchLimiterCenterStat = &(sensorsInfo.limitYSwitchCenter);
  52. positionYControlTaskInitArg.switchLimiterUpStat = &(sensorsInfo.limitYSwitchUp);
  53. positionYControlTaskInitArg.switchLimiterDownStat = &(sensorsInfo.limitYSwitchDown);
  54. positionYControlTaskInitArg.currentPosition = &(sensorsInfo.currentYPosition);
  55. positionYControlTaskInitArg.motorStatus = &(sensorsInfo.motorYStatus);
  56. positionYControlTaskInitArg.motorPeakCurrent = &(sensorsInfo.motorYPeakCurrent);
  57. positionXControlTaskInitArg.positionSetting = &positionYSetting;
  58. positionYControlTaskInitArg.axe = 'Y';
  59. positionXControlTaskHandle = osThreadNew (PositionControlTask, &positionXControlTaskInitArg, &osThreadAttrPositionControlTask);
  60. positionYControlTaskHandle = osThreadNew (PositionControlTask, &positionYControlTaskInitArg, &osThreadAttrPositionControlTask);
  61. }
  62. void PositionControlTask (void* argument) {
  63. const int32_t PositionControlTaskTimeOut = 100;
  64. PositionControlTaskInitArg* posCtrlTaskArg = (PositionControlTaskInitArg*)argument;
  65. PositionControlTaskData posCtrlData = { 0 };
  66. uint32_t motorStatus = 0;
  67. osStatus_t queueSatus;
  68. int32_t pwmValue = MOTOR_START_STOP_PWM_VALUE;
  69. int32_t sign = 0;
  70. MovementPhases movementPhase = idlePhase;
  71. float startPosition = 0;
  72. float prevPosition = 0;
  73. int32_t timeLeftMS = 0;
  74. int32_t moveCmdTimeoutCounter = 0;
  75. while (pdTRUE) {
  76. queueSatus = osMessageQueueGet (posCtrlTaskArg->positionSettingQueue, &posCtrlData, 0, pdMS_TO_TICKS (PositionControlTaskTimeOut));
  77. if (queueSatus == osOK) {
  78. if (osMutexAcquire (sensorsInfoMutex, osWaitForever) == osOK) {
  79. float posDiff = posCtrlData.positionSettingValue - *posCtrlTaskArg->currentPosition;
  80. if (posDiff != 0) {
  81. sign = posDiff > 0 ? 1 : -1;
  82. startPosition = *posCtrlTaskArg->currentPosition;
  83. movementPhase = startPhase;
  84. moveCmdTimeoutCounter = 0;
  85. timeLeftMS = 0;
  86. #ifdef DBG_POSITION
  87. printf ("Axe %c start phase\n", posCtrlTaskArg->axe);
  88. #endif
  89. }
  90. osMutexRelease (sensorsInfoMutex);
  91. if (osMutexAcquire (positionSettingMutex, osWaitForever) == osOK) {
  92. *positionXControlTaskInitArg.positionSetting = posCtrlData.positionSettingValue;
  93. osMutexRelease (positionSettingMutex);
  94. }
  95. }
  96. } else if (queueSatus == osErrorTimeout) {
  97. if (osMutexAcquire (sensorsInfoMutex, osWaitForever) == osOK) {
  98. if (((*posCtrlTaskArg->motorStatus != 0) && (movementPhase != idlePhase)) || (movementPhase == startPhase) ) {
  99. if (((*posCtrlTaskArg->switchLimiterDownStat == 1) && (*posCtrlTaskArg->switchLimiterUpStat == 1)) ||
  100. ((*posCtrlTaskArg->switchLimiterUpStat == 1) && (*posCtrlTaskArg->switchLimiterCenterStat == 1))) {
  101. movementPhase = idlePhase;
  102. motorStatus = MotorControl (posCtrlTaskArg->htim, posCtrlTaskArg->motorTimerConfigOC, posCtrlTaskArg->channel1, posCtrlTaskArg->channel2, posCtrlTaskArg->motorTimerHandle, 0,
  103. 0, *posCtrlTaskArg->switchLimiterUpStat, *posCtrlTaskArg->switchLimiterDownStat);
  104. *posCtrlTaskArg->motorStatus = motorStatus;
  105. #ifdef DBG_POSITION
  106. printf ("Axe %c limiters wrong state - idle phase\n", posCtrlTaskArg->axe);
  107. #endif
  108. }
  109. timeLeftMS += PositionControlTaskTimeOut;
  110. if (prevPosition == *posCtrlTaskArg->currentPosition) {
  111. moveCmdTimeoutCounter += PositionControlTaskTimeOut;
  112. } else {
  113. moveCmdTimeoutCounter = 0;
  114. }
  115. prevPosition = *posCtrlTaskArg->currentPosition;
  116. if (moveCmdTimeoutCounter > NO_MOVE_TIMEOUT_MS) {
  117. movementPhase = idlePhase;
  118. motorStatus = MotorControl (posCtrlTaskArg->htim, posCtrlTaskArg->motorTimerConfigOC, posCtrlTaskArg->channel1, posCtrlTaskArg->channel2, posCtrlTaskArg->motorTimerHandle, 0,
  119. 0, *posCtrlTaskArg->switchLimiterUpStat, *posCtrlTaskArg->switchLimiterDownStat);
  120. *posCtrlTaskArg->motorStatus = motorStatus;
  121. #ifdef DBG_POSITION
  122. printf ("Axe %c no movement idle phase\n", posCtrlTaskArg->axe);
  123. #endif
  124. }
  125. switch (movementPhase) {
  126. case startPhase:
  127. motorStatus = MotorControl (posCtrlTaskArg->htim, posCtrlTaskArg->motorTimerConfigOC, posCtrlTaskArg->channel1, posCtrlTaskArg->channel2, posCtrlTaskArg->motorTimerHandle,
  128. sign * pwmValue, -1, *posCtrlTaskArg->switchLimiterUpStat, *posCtrlTaskArg->switchLimiterDownStat);
  129. *posCtrlTaskArg->motorStatus = motorStatus;
  130. if (motorStatus == 1) {
  131. *posCtrlTaskArg->motorPeakCurrent = 0.0;
  132. #ifdef DBG_POSITION
  133. printf ("Axe %c speed up phase\n", posCtrlTaskArg->axe);
  134. #endif
  135. movementPhase = speedUpPhase;
  136. timeLeftMS = 0;
  137. moveCmdTimeoutCounter = 0;
  138. } else {
  139. movementPhase = idlePhase;
  140. #ifdef DBG_POSITION
  141. printf ("Axe %c idle phase\n", posCtrlTaskArg->axe);
  142. #endif
  143. }
  144. break;
  145. case speedUpPhase:
  146. if ((abs (*posCtrlTaskArg->currentPosition - startPosition) >= ANGLE_RANGE_FOR_MOTOR_SPEED_LIMIT) || (timeLeftMS >= TIME_MS_FOR_MOTOR_SPEED_LIMIT)) {
  147. pwmValue = MOTOR_HIGH_SPEED_PWM_VALUE;
  148. motorStatus = MotorControl (posCtrlTaskArg->htim, posCtrlTaskArg->motorTimerConfigOC, posCtrlTaskArg->channel1, posCtrlTaskArg->channel2, posCtrlTaskArg->motorTimerHandle,
  149. sign * pwmValue, -1, *posCtrlTaskArg->switchLimiterUpStat, *posCtrlTaskArg->switchLimiterDownStat);
  150. *posCtrlTaskArg->motorStatus = motorStatus;
  151. movementPhase = movePhase;
  152. #ifdef DBG_POSITION
  153. printf ("Axe %c move phase\n", posCtrlTaskArg->axe);
  154. #endif
  155. }
  156. break;
  157. case movePhase:
  158. if (abs (*posCtrlTaskArg->currentPosition - *posCtrlTaskArg->positionSetting) <= ANGLE_RANGE_FOR_MOTOR_SPEED_LIMIT) {
  159. movementPhase = slowDownPhase;
  160. #ifdef DBG_POSITION
  161. printf ("Axe %c slow down phase\n", posCtrlTaskArg->axe);
  162. #endif
  163. }
  164. break;
  165. case slowDownPhase:
  166. pwmValue = MOTOR_START_STOP_PWM_VALUE;
  167. motorStatus = MotorControl (posCtrlTaskArg->htim, posCtrlTaskArg->motorTimerConfigOC, posCtrlTaskArg->channel1, posCtrlTaskArg->channel2, posCtrlTaskArg->motorTimerHandle,
  168. sign * pwmValue, -1, *posCtrlTaskArg->switchLimiterUpStat, *posCtrlTaskArg->switchLimiterDownStat);
  169. *posCtrlTaskArg->motorStatus = motorStatus;
  170. movementPhase = stopPhase;
  171. timeLeftMS = 0;
  172. #ifdef DBG_POSITION
  173. printf ("Axe %c stop phase\n", posCtrlTaskArg->axe);
  174. #endif
  175. break;
  176. case stopPhase:
  177. float posDiff = sign > 0 ? posCtrlData.positionSettingValue - *posCtrlTaskArg->currentPosition : *posCtrlTaskArg->currentPosition - posCtrlData.positionSettingValue;
  178. if ((posDiff <= 0) || (timeLeftMS >= TIME_MS_FOR_MOTOR_SPEED_LIMIT)) {
  179. motorStatus = MotorControl (posCtrlTaskArg->htim, posCtrlTaskArg->motorTimerConfigOC, posCtrlTaskArg->channel1, posCtrlTaskArg->channel2, posCtrlTaskArg->motorTimerHandle,
  180. 0, 0, *posCtrlTaskArg->switchLimiterUpStat, *posCtrlTaskArg->switchLimiterDownStat);
  181. *posCtrlTaskArg->motorStatus = motorStatus;
  182. movementPhase = idlePhase;
  183. #ifdef DBG_POSITION
  184. printf ("Axe %c idle phase\n", posCtrlTaskArg->axe);
  185. #endif
  186. }
  187. break;
  188. default: break;
  189. }
  190. } else {
  191. if ((*posCtrlTaskArg->motorStatus == 0) && (movementPhase != idlePhase)) {
  192. movementPhase = idlePhase;
  193. #ifdef DBG_POSITION
  194. printf ("Axe %c idle phase\n", posCtrlTaskArg->axe);
  195. #endif
  196. }
  197. }
  198. osMutexRelease (sensorsInfoMutex);
  199. }
  200. }
  201. }
  202. }