基质喷涂
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

525 lines
15 KiB

  1. //
  2. // Created by iflyt on 2025/3/3.
  3. //
  4. #include "elc_motor.h"
  5. #include <base/apphal.hpp>
  6. #include <base/apphardware.hpp>
  7. #include <can_control/can_protocol_factory.h>
  8. #include <cmath>
  9. #include "elc_motor_helper.h"
  10. #define TEST 1
  11. #define TAG "ECL MOTOR"
  12. #define TIMER_IS_FINE 0
  13. using namespace iflytop;
  14. // 定时器回调函数
  15. void ECLMotor::readTimerCallback(void *arg) {
  16. ECLMotor *motor = static_cast<ECLMotor *>(arg);
  17. motor->readMotorPosition();
  18. }
  19. // 读取电机位置
  20. void ECLMotor::readMotorPosition() {
  21. // 清除标志位
  22. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  23. if (motor == nullptr) {
  24. return;
  25. }
  26. osMutexAcquire(mutex_, osWaitForever);
  27. bool last_is_move_finished = is_move_finished_;
  28. osMutexRelease(mutex_);
  29. int32_t x_actual = 0;
  30. int32_t enc_val = 0;
  31. int32_t rt_speed = 0;
  32. enc_val = motor->getEncVal(); // 获取编码器值
  33. x_actual = motor->getXACTUAL(); // 获取实时位置
  34. rt_speed = motor->getVACTUAL(); // 获取实时速度
  35. TMC5130RampStat ramp_stat = motor->getRampStat();
  36. bool is_move_finished = motor->isReachTarget(&ramp_stat);
  37. int32_t postion = 0;
  38. if (0 == enc_val) {
  39. postion = x_actual;
  40. } else {
  41. postion = enc_val;
  42. }
  43. // 移动中
  44. osMutexAcquire(mutex_, osWaitForever);
  45. is_move_finished_ = is_move_finished;
  46. x_actual_ = x_actual;
  47. enc_val_ = enc_val;
  48. rt_speed_ = rt_speed;
  49. osMutexRelease(mutex_);
  50. if (!last_is_move_finished && is_move_finished) {
  51. //处理移动结束的问题
  52. if (!isHomeSuc()) {
  53. ZLOGI(TAG, "[TIMER] HOMING EVENT_MOTOR_MOVE_FINISHED");
  54. osMutexAcquire(mutex_, osWaitForever);
  55. home_event_.event_type = EVENT_MOTOR_MOVE_FINISHED;
  56. osMutexRelease(mutex_);
  57. osMessageQueuePut(homeEventQueue, &home_event_, 0U, 0U);
  58. }
  59. // 发送CAN 消息
  60. {
  61. #if CAN_MODULE_ENABLE
  62. CanMessage msg = CanProtocolFactory::createUploadEvent(seq_id_move_finished_, Motor_Move_Finished, index_);
  63. AppHardware::ins()->can0Controller.sendMessage(msg);
  64. #endif
  65. }
  66. ZLOGI(TAG, "【FIRST DETECT】 MOVE FINISHED");
  67. }
  68. }
  69. // 设置读取速率
  70. void ECLMotor::startReadTimer() {
  71. osTimerStart(readTimer, 50); // // 50毫秒
  72. }
  73. ECLMotor::ECLMotor() {
  74. // 创建互斥锁
  75. mutex_ = osMutexNew(NULL);
  76. if (mutex_ == NULL) {
  77. // 处理互斥锁创建失败
  78. ZLOGI(TAG, "mutex_ create failed");
  79. }
  80. // 初始化电机位置和目标位置
  81. x_actual_ = 0;
  82. target_pos_ = 0;
  83. target_speed_ = 10; // 10 / 60 * 6s ==== 6 S 可以转一圈
  84. is_move_finished_ = false;
  85. enc_val_ = 0;
  86. is_home_init_ = false;
  87. is_home_suc_ = false;
  88. home_state_ = STATE_INIT;
  89. isRunHomingTask = true;
  90. // 创建定时器
  91. osTimerAttr_t timerAttr = {
  92. .name = "MotorReadTimer",
  93. .attr_bits = 0U,
  94. .cb_mem = NULL,
  95. .cb_size = 0U
  96. };
  97. readTimer = osTimerNew(readTimerCallback, osTimerPeriodic, this, &timerAttr);
  98. if (readTimer == NULL) {
  99. // 处理定时器创建失败
  100. }
  101. // 创建消息队列
  102. homeEventQueue = osMessageQueueNew(10, sizeof(HomeEvent), NULL);
  103. if (homeEventQueue == NULL) {
  104. // 处理消息队列创建失败的情况
  105. ZLOGE(TAG, "Failed to create home event message queue");
  106. }
  107. // 创建任务并获取线程句柄
  108. home_task_attr.name = "HomeStateTask";
  109. home_task_attr.stack_size = 256 * 8;
  110. home_task_attr.priority = osPriorityHigh;
  111. homingStateMachineThreadId = osThreadNew(homingTask, this, &home_task_attr);
  112. if (homingStateMachineThreadId == NULL) {
  113. // 处理线程创建失败的情况
  114. ZLOGE(TAG, "THREAD INDEX %d Create Failed", index_);
  115. }
  116. // 启动定时器
  117. startReadTimer();
  118. }
  119. ECLMotor::~ECLMotor() {
  120. isRunHomingTask = false;
  121. if (homingStateMachineThreadId != NULL) {
  122. osThreadTerminate(homingStateMachineThreadId);
  123. }
  124. if (homeEventQueue != NULL) {
  125. osMessageQueueDelete(homeEventQueue);
  126. }
  127. osMutexDelete(mutex_);
  128. osTimerDelete(readTimer);
  129. }
  130. // 读取电机的位置
  131. int32_t ECLMotor::getPosition() {
  132. osMutexAcquire(mutex_, osWaitForever);
  133. int32_t pos = x_actual_;
  134. osMutexRelease(mutex_);
  135. return pos;
  136. }
  137. // 设置电机的目标位置
  138. void ECLMotor::setTargetPosition(int32_t target) {
  139. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  140. if (motor == nullptr) {
  141. return;
  142. }
  143. if (ELCMotorHelper::isFlip(index_)) {
  144. target = -target;
  145. ZLOGI(TAG, "【MOTOR 【%d】TARGET FLIP】", index_);
  146. }
  147. motor->moveTo(target, this->target_speed_);
  148. osMutexAcquire(mutex_, osWaitForever);
  149. target_pos_ = target;
  150. osMutexRelease(mutex_);
  151. }
  152. void ECLMotor::setShiftPosition(int32_t shift_target) {
  153. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  154. if (motor == nullptr) {
  155. return;
  156. }
  157. if (ELCMotorHelper::isFlip(index_)) {
  158. shift_target = -shift_target;
  159. ZLOGI(TAG, "【MOTOR 【%d】SHIFT TARGET FLIP】", index_);
  160. }
  161. motor->moveBy(shift_target, abs(target_speed_));
  162. osMutexAcquire(mutex_, osWaitForever);
  163. target_pos_ = target_pos_ + shift_target;
  164. osMutexRelease(mutex_);
  165. }
  166. void ECLMotor::moveToWithSpeed(int32_t target, int32_t speed) {
  167. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  168. if (motor == nullptr) {
  169. return;
  170. }
  171. if (ELCMotorHelper::isFlip(index_)) {
  172. target = -target;
  173. ZLOGI(TAG, "【MOTOR 【%d】TARGET FLIP】", index_);
  174. }
  175. motor->moveTo(target, abs(speed));
  176. osMutexAcquire(mutex_, osWaitForever);
  177. target_pos_ = target;
  178. osMutexRelease(mutex_);
  179. }
  180. // 设置电机速度
  181. void ECLMotor::setSpeed(int32_t speed) {
  182. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  183. if (motor == nullptr) {
  184. return;
  185. }
  186. osMutexAcquire(mutex_, osWaitForever);
  187. this->target_speed_ = speed;
  188. // 当前正在移动
  189. if (!is_move_finished_) {
  190. motor->setVMax(this->target_speed_);
  191. }
  192. osMutexRelease(mutex_);
  193. }
  194. // 获取电机速度
  195. int32_t ECLMotor::getRTSpeed() {
  196. osMutexAcquire(mutex_, osWaitForever);
  197. const int32_t spd = rt_speed_;
  198. osMutexRelease(mutex_);
  199. return spd;
  200. }
  201. // 获取电机运动状态
  202. bool ECLMotor::isMoveFinished() {
  203. osMutexAcquire(mutex_, osWaitForever);
  204. bool is_move_finshed = is_move_finished_;
  205. osMutexRelease(mutex_);
  206. return is_move_finshed;
  207. }
  208. // 获取编码器位置
  209. int32_t ECLMotor::getEncoderPosition() {
  210. osMutexAcquire(mutex_, osWaitForever);
  211. int32_t encPos = enc_val_;
  212. osMutexRelease(mutex_);
  213. return encPos;
  214. }
  215. // 设置编码器位置
  216. void ECLMotor::setEncoderPosition(int32_t encoderPos) {
  217. osMutexAcquire(mutex_, osWaitForever);
  218. enc_val_ = encoderPos;
  219. osMutexRelease(mutex_);
  220. }
  221. void ECLMotor::setMotorIndex(int32_t index) {
  222. this->index_ = index;
  223. }
  224. bool ECLMotor::isHomeInit() {
  225. return is_home_init_;
  226. }
  227. bool ECLMotor::isHomeSuc() {
  228. osMutexAcquire(mutex_, osWaitForever);
  229. bool is_home_suc = is_home_suc_;
  230. osMutexRelease(mutex_);
  231. return is_home_suc;
  232. }
  233. void ECLMotor::runhomeSuc() {
  234. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  235. if (motor == nullptr) {
  236. return;
  237. }
  238. // 发送 CAN 信息
  239. motor->setEncVal(0);
  240. motor->setXACTUAL(0);
  241. // 置标志位
  242. osMutexAcquire(mutex_, osWaitForever);
  243. this->is_home_init_ = true;
  244. this->is_home_suc_ = true;
  245. this->home_state_ = STATE_INIT;
  246. osMutexRelease(mutex_);
  247. ZLOGI(TAG, "【 MOVE TO HOME SUC 】");
  248. {
  249. #if CAN_MODULE_ENABLE
  250. CanMessage msg = CanProtocolFactory::createUploadEvent(seq_id_home_, Motor_Home_Finished, index_);
  251. AppHardware::ins()->can0Controller.sendMessage(msg);
  252. #endif
  253. }
  254. }
  255. void ECLMotor::startMoveHome() {
  256. home_start_tick_ = 0;
  257. osMutexAcquire(mutex_, osWaitForever);
  258. this->is_home_suc_ = false;
  259. osMutexRelease(mutex_);
  260. const bool isAtOrigin = ELCMotorHelper::isAtOrigin(this->index_);
  261. // 当前是否在原点
  262. if (isAtOrigin) {
  263. home_event_.event_type = EVENT_IN_ORIGIN;
  264. ZLOGI(TAG, "[PUT] EVENT IN ORIGIN");
  265. osStatus_t status = osMessageQueuePut(homeEventQueue, &home_event_, 0U, 0U);
  266. if (status != osOK) {
  267. ZLOGE(TAG, "EVENT IN ORIGIN SEND FAIL, status: %d", status);
  268. }
  269. } else {
  270. home_event_.event_type = EVENT_START_HOMING;
  271. ZLOGI(TAG, "[PUT] EVENT_START_HOMING");
  272. osStatus_t status = osMessageQueuePut(homeEventQueue, &home_event_, 0U, 0U);
  273. if (status != osOK) {
  274. ZLOGE(TAG, "EVENT_START_HOMING SEND FAIL, status: %d", status);
  275. }
  276. }
  277. }
  278. void ECLMotor::setHomeSeqId(uint8_t seq_id) {
  279. this->seq_id_home_ = seq_id;
  280. }
  281. void ECLMotor::setMoveFinishSeqId(uint8_t seq_id) {
  282. this->seq_id_move_ = seq_id;
  283. }
  284. void ECLMotor::homingTask(void *arg) {
  285. ECLMotor *eclMotor = static_cast<ECLMotor *>(arg);
  286. HomeEvent home_event;
  287. while (eclMotor->isRunHomingTask) {
  288. osStatus status = osMessageQueueGet(eclMotor->homeEventQueue, &home_event, NULL, osWaitForever);
  289. if (status == osOK) {
  290. TMC51X0 *motor = AppHardware::ins()->getPump(eclMotor->index_);
  291. if (motor == nullptr) {
  292. return;
  293. }
  294. #if 1
  295. switch (home_event.event_type) {
  296. case EVENT_START_HOMING: {
  297. osMutexAcquire(eclMotor->mutex_, osWaitForever);
  298. eclMotor->home_state_ = STATE_BACK_TO_ORIGIN_MIDDLE;
  299. osMutexRelease(eclMotor->mutex_);
  300. // 中速倒转
  301. int speed = ELCMotorHelper::getRPerMinMiddleSpeed(eclMotor->index_);
  302. int absSpeed = abs(speed);
  303. eclMotor->ECL_Rotate(-absSpeed);
  304. ZLOGI(TAG, "【HOME】 BACK TO ORIGIN MIDDLE");
  305. break;
  306. }
  307. case EVENT_ORIGIN_ENTER: {
  308. // if first enter
  309. if(eclMotor->home_state_ == STATE_BACK_TO_ORIGIN_MIDDLE) {
  310. // 停止
  311. // 中速向前10mm
  312. osMutexAcquire(eclMotor->mutex_, osWaitForever);
  313. eclMotor->home_state_ = STATE_LEAVE_ORIGIN_MIDDLE;
  314. osMutexRelease(eclMotor->mutex_);
  315. // 位置清零
  316. motor->setEncVal(0);
  317. motor->setXACTUAL(0);
  318. const int32_t speed = ELCMotorHelper::getRPerMinMiddleSpeed(eclMotor->index_);
  319. eclMotor->moveToWithSpeed(ELCMotorHelper::getForwordMoveStep(eclMotor->index_), speed);
  320. // 4000 4 圈
  321. ZLOGI(TAG, "【HOME】 [EVENT_ORIGIN_ENTER] FORWARD TO ORIGIN MIDDLE");
  322. }
  323. // if second enter
  324. if (eclMotor->home_state_ == STATE_BACK_TO_ORIGIN_LOW) {
  325. // 位置清零
  326. // 电机停止
  327. // 回归原点成功
  328. eclMotor->runhomeSuc();
  329. }
  330. break;
  331. }
  332. case EVENT_IN_ORIGIN: {
  333. ZLOGI(TAG, "[]EVENT IN ORIGIN");
  334. // 中速向前10mm
  335. motor->setEncVal(0);
  336. motor->setXACTUAL(0);
  337. // 前向移动 1mm
  338. osMutexAcquire(eclMotor->mutex_, osWaitForever);
  339. eclMotor->home_state_ = STATE_LEAVE_ORIGIN_MIDDLE;
  340. osMutexRelease(eclMotor->mutex_);
  341. const int32_t speed = ELCMotorHelper::getRPerMinMiddleSpeed(eclMotor->index_);
  342. eclMotor->moveToWithSpeed(ELCMotorHelper::getForwordMoveStep(eclMotor->index_), speed);
  343. ZLOGI(TAG, "【HOME】 FORWARD TO ORIGIN MIDDLE");
  344. break;
  345. }
  346. case EVENT_MOTOR_MOVE_FINISHED: {
  347. ZLOGI(TAG, "[]EVENT MOTOR MOVE FINISHED");
  348. if (eclMotor->home_state_ == STATE_LEAVE_ORIGIN_MIDDLE) {
  349. // 低速回归
  350. osMutexAcquire(eclMotor->mutex_, osWaitForever);
  351. eclMotor->home_state_ = STATE_BACK_TO_ORIGIN_LOW;
  352. osMutexRelease(eclMotor->mutex_);
  353. const int speed = ELCMotorHelper::getRPerMinLowSpeed(eclMotor->index_);
  354. eclMotor->ECL_Rotate(-speed);
  355. ZLOGI(TAG, "【HOME】 BACK TO ORIGIN LOW");
  356. }
  357. break;
  358. }
  359. default:
  360. break;
  361. }
  362. #endif
  363. } else {
  364. ZLOGI(TAG, "GET MESSAGE FAILED");
  365. }
  366. }
  367. }
  368. void ECLMotor::moveToHome() {
  369. this->startMoveHome();
  370. }
  371. void ECLMotor::runZeroLimit(bool isEnter) {
  372. // 处理回home 位逻辑
  373. if (!isHomeSuc()) {
  374. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  375. if (motor == nullptr) {
  376. return;
  377. }
  378. if (isEnter) {
  379. home_event_.event_type = EVENT_ORIGIN_ENTER;
  380. motor->stop();
  381. osDelay(10);
  382. ZLOGI(TAG, "[PUT] EVENT_ORIGIN_ENTER");
  383. } else {
  384. home_event_.event_type = EVENT_ORIGIN_LEAVE;
  385. ZLOGI(TAG, "[PUT] EVENT_ORIGIN_LEAVE");
  386. }
  387. osMessageQueuePut(homeEventQueue, &home_event_, 0U, 0U);
  388. return;
  389. }
  390. if (!isEnter) {
  391. return;
  392. }
  393. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  394. if (motor == nullptr) {
  395. return;
  396. }
  397. motor->stop();
  398. {
  399. #if CAN_MODULE_ENABLE
  400. CanMessage msg = CanProtocolFactory::createUploadEvent(seq_id_move_, Motor_Move_Finished, index_);
  401. AppHardware::ins()->can0Controller.sendMessage(msg);
  402. #endif
  403. }
  404. // 重置编码器 和 位置
  405. motor->setXACTUAL(0);
  406. motor->setEncVal(0);
  407. osMutexAcquire(mutex_, osWaitForever);
  408. this->x_actual_ = 0;
  409. this->enc_val_ = 0;
  410. this->target_pos_ = 0;
  411. osMutexRelease(mutex_);
  412. ZLOGI("ECL", "MOTOR [%d] runZeroLimit", this->index_);
  413. }
  414. void ECLMotor::runEndLimit(bool isEnter) {
  415. // 发送CAN 消息
  416. if (!isEnter) {
  417. return;
  418. }
  419. this->runStop();
  420. }
  421. void ECLMotor::runE_Stop() {
  422. // 发送CAN 消息
  423. osMutexAcquire(mutex_, osWaitForever);
  424. this->is_home_suc_ = false;
  425. osMutexRelease(mutex_);
  426. this->runStop();
  427. }
  428. void ECLMotor::runPause() {
  429. // 发送CAN 消息
  430. this->runStop();
  431. }
  432. void ECLMotor::runStop() {
  433. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  434. if (motor == nullptr) {
  435. return;
  436. }
  437. motor->stop();
  438. // 发送CAN 消息
  439. #if CAN_MODULE_ENABLE
  440. CanMessage msg = CanProtocolFactory::createUploadEvent(seq_id_home_, Motor_Move_Finished, index_);
  441. AppHardware::ins()->can0Controller.sendMessage(msg);
  442. #endif
  443. }
  444. void ECLMotor::ECL_Rotate(int32_t speed, const bool is_flip) {
  445. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  446. if (motor == nullptr) {
  447. return;
  448. }
  449. if (ELCMotorHelper::isFlip(index_) && is_flip) {
  450. speed = -speed;
  451. ZLOGI(TAG, "ECL MOTOR ECL REAL INDEX 【%d】 FLIP", index_);
  452. }
  453. motor->rotate(speed);
  454. ZLOGI(TAG, "ECL MOTOR %d SPEED %d", index_, speed);
  455. }