position_task.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  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)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.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 = 100;
  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. movementPhase = speedUpPhase;
  138. timeLeftMS = 0;
  139. moveCmdTimeoutCounter = 0;
  140. } else {
  141. movementPhase = idlePhase;
  142. #ifdef DBG_POSITION
  143. printf ("Axe %c idle phase\n", posCtrlTaskArg->axe);
  144. #endif
  145. }
  146. break;
  147. case speedUpPhase:
  148. if ((abs ((*posCtrlTaskArg->currentPosition + *posCtrlTaskArg->positionOffset) - startPosition) >= ANGLE_RANGE_FOR_MOTOR_SPEED_LIMIT) || (timeLeftMS >= TIME_MS_FOR_MOTOR_SPEED_LIMIT)) {
  149. pwmValue = MOTOR_HIGH_SPEED_PWM_VALUE;
  150. motorStatus = MotorControl (posCtrlTaskArg->htim, posCtrlTaskArg->motorTimerConfigOC, posCtrlTaskArg->channel1, posCtrlTaskArg->channel2, posCtrlTaskArg->motorTimerHandle,
  151. sign * pwmValue, -1, *posCtrlTaskArg->switchLimiterUpStat, *posCtrlTaskArg->switchLimiterDownStat);
  152. *posCtrlTaskArg->motorStatus = motorStatus;
  153. movementPhase = movePhase;
  154. #ifdef DBG_POSITION
  155. printf ("Axe %c move phase\n", posCtrlTaskArg->axe);
  156. #endif
  157. }
  158. break;
  159. case movePhase:
  160. if (abs ((*posCtrlTaskArg->currentPosition + *posCtrlTaskArg->positionOffset) - *posCtrlTaskArg->positionSetting) <= ANGLE_RANGE_FOR_MOTOR_SPEED_LIMIT) {
  161. movementPhase = slowDownPhase;
  162. #ifdef DBG_POSITION
  163. printf ("Axe %c slow down phase\n", posCtrlTaskArg->axe);
  164. #endif
  165. }
  166. break;
  167. case slowDownPhase:
  168. pwmValue = MOTOR_START_STOP_PWM_VALUE;
  169. motorStatus = MotorControl (posCtrlTaskArg->htim, posCtrlTaskArg->motorTimerConfigOC, posCtrlTaskArg->channel1, posCtrlTaskArg->channel2, posCtrlTaskArg->motorTimerHandle,
  170. sign * pwmValue, -1, *posCtrlTaskArg->switchLimiterUpStat, *posCtrlTaskArg->switchLimiterDownStat);
  171. *posCtrlTaskArg->motorStatus = motorStatus;
  172. movementPhase = stopPhase;
  173. timeLeftMS = 0;
  174. #ifdef DBG_POSITION
  175. printf ("Axe %c stop phase\n", posCtrlTaskArg->axe);
  176. #endif
  177. break;
  178. case stopPhase:
  179. float posDiff = sign > 0 ? posCtrlData.positionSettingValue - (*posCtrlTaskArg->currentPosition + *posCtrlTaskArg->positionOffset) : (*posCtrlTaskArg->currentPosition + *posCtrlTaskArg->positionOffset) - posCtrlData.positionSettingValue;
  180. if ((posDiff <= 0) || (timeLeftMS >= TIME_MS_FOR_MOTOR_SPEED_LIMIT)) {
  181. motorStatus = MotorControl (posCtrlTaskArg->htim, posCtrlTaskArg->motorTimerConfigOC, posCtrlTaskArg->channel1, posCtrlTaskArg->channel2, posCtrlTaskArg->motorTimerHandle,
  182. 0, 0, *posCtrlTaskArg->switchLimiterUpStat, *posCtrlTaskArg->switchLimiterDownStat);
  183. *posCtrlTaskArg->motorStatus = motorStatus;
  184. movementPhase = idlePhase;
  185. #ifdef DBG_POSITION
  186. printf ("Axe %c idle phase\n", posCtrlTaskArg->axe);
  187. #endif
  188. }
  189. break;
  190. default: break;
  191. }
  192. } else {
  193. if ((*posCtrlTaskArg->motorStatus == 0) && (movementPhase != idlePhase)) {
  194. movementPhase = idlePhase;
  195. #ifdef DBG_POSITION
  196. printf ("Axe %c idle phase\n", posCtrlTaskArg->axe);
  197. #endif
  198. }
  199. }
  200. osMutexRelease (sensorsInfoMutex);
  201. }
  202. }
  203. }
  204. }