基质喷涂
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.

710 lines
20 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. #if 0
  23. if(isHoming()) {
  24. if(++home_count_ == max_home_count_) {
  25. // 强制清零
  26. home_count_ = 0;
  27. homeState_ = STATE_INIT;
  28. ZLOGI(TAG, "【HOME STATE COUNT FORCE CLEAR】");
  29. }
  30. }
  31. #endif
  32. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  33. if (motor == nullptr) {
  34. return;
  35. }
  36. bool is_reached = false;
  37. bool is_move_finished = false;
  38. int32_t x_actual = 0;
  39. int32_t enc_val = 0;
  40. int32_t rt_speed = 0;
  41. enc_val = motor->getEncVal(); // 获取编码器值
  42. x_actual = motor->getXACTUAL(); // 获取实时位置
  43. rt_speed = motor->getVACTUAL(); // 获取实时速度
  44. TMC5130RampStat ramp_stat = motor->getRampStat();
  45. is_reached = motor->isReachTarget(&ramp_stat);
  46. int32_t postion = 0;
  47. int32_t distance = 0;
  48. if (0 == enc_val) {
  49. postion = x_actual;
  50. } else {
  51. postion = enc_val;
  52. }
  53. distance = abs(target_pos_ - postion);
  54. if (distance < 50 && is_reached) {
  55. is_move_finished = true;
  56. }
  57. if (is_reached) {
  58. is_move_finished = true;
  59. }
  60. #if 1
  61. #else
  62. if(is_moving)
  63. {
  64. if(0 == enc_val) {
  65. postion = x_actual;
  66. }
  67. else {
  68. postion = enc_val;
  69. }
  70. const bool is_forward = target_pos_ - postion > 0;
  71. distance = abs(target_pos_ - postion);
  72. // 检查目标距离与实际距离是否一致
  73. if(distance < 20 || is_forward != isFoward_) {
  74. // 电机移动停止
  75. motor->stop();
  76. // 发送CAN 消息
  77. is_moving = false;
  78. this->runStop();
  79. ZLOGI(TAG, "MOTOR DETECT STOP!!! ");
  80. #if TIMER_IS_FINE
  81. setReadRate(READ_RATE_LOW);
  82. #endif
  83. }
  84. }
  85. #endif
  86. bool is_moving = false;
  87. // 移动中
  88. osMutexAcquire(mutex_, osWaitForever);
  89. is_moving = is_moving_;
  90. if (is_move_finished) {
  91. is_moving_ = false;
  92. }
  93. x_actual_ = x_actual;
  94. enc_val_ = enc_val;
  95. rt_speed_ = rt_speed;
  96. osMutexRelease(mutex_);
  97. if (is_moving && is_move_finished) {
  98. //处理移动结束的问题
  99. #if 1
  100. if (isHoming()) {
  101. ZLOGI(TAG, "【[TIMER] HOMING EVENT_MOTOR_MOVE_FINISHED】");
  102. #if 1
  103. home_event_.event_type = EVENT_MOTOR_MOVE_FINISHED;
  104. osMessageQueuePut(homeEventQueue, &home_event_, 0U, 0U);
  105. #endif
  106. }
  107. #endif
  108. // 发送CAN 消息
  109. {
  110. CanMessage msg = CanProtocolFactory::createUploadEvent(seq_id_move_finished_, Motor_Move_Finished, index_);
  111. AppHardware::ins()->can0Controller.sendMessage(msg);
  112. }
  113. ZLOGI(TAG, "【FIRST DETECT】 MOVE FINISHED");
  114. }
  115. }
  116. // 设置读取速率
  117. void ECLMotor::setReadRate(ReadRate rate) {
  118. readRate = rate;
  119. uint32_t period;
  120. switch (rate) {
  121. case READ_RATE_LOW:
  122. period = 500; // 1秒
  123. break;
  124. case READ_RATE_MEDIUM:
  125. period = 100; // 500毫秒
  126. break;
  127. case READ_RATE_HIGH:
  128. period = 50; // 50毫秒
  129. break;
  130. default:
  131. period = 1000;
  132. break;
  133. }
  134. osTimerStop(readTimer);
  135. osTimerStart(readTimer, period);
  136. }
  137. ECLMotor::ECLMotor() {
  138. // 创建互斥锁
  139. mutex_ = osMutexNew(NULL);
  140. if (mutex_ == NULL) {
  141. // 处理互斥锁创建失败
  142. ZLOGI(TAG, "mutex_ create failed");
  143. }
  144. // 初始化电机位置和目标位置
  145. x_actual_ = 0;
  146. target_pos_ = 0;
  147. target_speed_ = 10; // 10 / 60 * 6s ==== 6 S 可以转一圈
  148. is_moving_ = 0;
  149. enc_val_ = 0;
  150. isHomed_ = false;
  151. homeState_ = STATE_INIT;
  152. isRunHomingTask = true;
  153. // 初始读取速率
  154. readRate = READ_RATE_HIGH;
  155. // 创建定时器
  156. osTimerAttr_t timerAttr = {
  157. .name = "MotorReadTimer",
  158. .attr_bits = 0U,
  159. .cb_mem = NULL,
  160. .cb_size = 0U
  161. };
  162. readTimer = osTimerNew(readTimerCallback, osTimerPeriodic, this, &timerAttr);
  163. if (readTimer == NULL) {
  164. // 处理定时器创建失败
  165. }
  166. // 创建消息队列
  167. homeEventQueue = osMessageQueueNew(10, sizeof(HomeEvent), NULL);
  168. if (homeEventQueue == NULL) {
  169. // 处理消息队列创建失败的情况
  170. ZLOGE(TAG, "Failed to create home event message queue");
  171. }
  172. // 创建任务并获取线程句柄
  173. home_task_attr.name = "HomeStateTask";
  174. home_task_attr.stack_size = 256 * 8;
  175. home_task_attr.priority = osPriorityHigh;
  176. homingStateMachineThreadId = osThreadNew(homingTask, this, &home_task_attr);
  177. if (homingStateMachineThreadId == NULL) {
  178. // 处理线程创建失败的情况
  179. ZLOGE(TAG, "THREAD INDEX %d Create Failed", index_);
  180. }
  181. // 启动定时器
  182. setReadRate(readRate);
  183. }
  184. ECLMotor::~ECLMotor() {
  185. isRunHomingTask = false;
  186. if (homingStateMachineThreadId != NULL) {
  187. osThreadTerminate(homingStateMachineThreadId);
  188. }
  189. if (homeEventQueue != NULL) {
  190. osMessageQueueDelete(homeEventQueue);
  191. }
  192. osMutexDelete(mutex_);
  193. osTimerDelete(readTimer);
  194. }
  195. // 读取电机的位置
  196. int32_t ECLMotor::getPosition() {
  197. osMutexAcquire(mutex_, osWaitForever);
  198. int32_t pos = x_actual_;
  199. osMutexRelease(mutex_);
  200. return pos;
  201. }
  202. // 设置电机的目标位置
  203. void ECLMotor::setTargetPosition(int32_t target) {
  204. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  205. if (motor == nullptr) {
  206. return;
  207. }
  208. if (ELCMotorHelper::isFlip(index_)) {
  209. target = -target;
  210. ZLOGI(TAG, "【MOTOR 【%d】TARGET FLIP】", index_);
  211. }
  212. motor->moveTo(target, this->target_speed_);
  213. osMutexAcquire(mutex_, osWaitForever);
  214. target_pos_ = target;
  215. is_moving_ = true;
  216. osMutexRelease(mutex_);
  217. #if 0
  218. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  219. if(motor == nullptr) {
  220. return;
  221. }
  222. if(is_Flip[index_]) {
  223. target = -target;
  224. ZLOGI(TAG, "【MOTOR 【%d】TARGET FLIP】", index_);
  225. }
  226. osMutexAcquire(mutex_, osWaitForever);
  227. int32_t postion = 0;
  228. #if 0
  229. if(0 == enc_val_) {
  230. postion = x_actual_;
  231. }
  232. else {
  233. postion = enc_val_;
  234. }
  235. #else
  236. if(0 == enc_val_) {
  237. postion = enc_val_;
  238. }
  239. else {
  240. postion = x_actual_;
  241. }
  242. #endif
  243. const bool is_forward = target - postion > 0;
  244. isFoward_ = is_forward;
  245. target_pos_ = target;
  246. is_moving_ = true;
  247. osMutexRelease(mutex_);
  248. #if TIMER_IS_FINE
  249. this->setReadRate(READ_RATE_HIGH);
  250. #endif
  251. int32_t abs_speed = abs(speed_);
  252. int32_t speed = is_forward ? abs_speed : -abs_speed;
  253. // 运行
  254. this->ECL_Rotate(speed, false);
  255. #endif
  256. }
  257. void ECLMotor::setShiftPosition(int32_t shift_target) {
  258. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  259. if (motor == nullptr) {
  260. return;
  261. }
  262. if (ELCMotorHelper::isFlip(index_)) {
  263. shift_target = -shift_target;
  264. ZLOGI(TAG, "【MOTOR 【%d】SHIFT TARGET FLIP】", index_);
  265. }
  266. motor->moveBy(shift_target, abs(target_speed_));
  267. osMutexAcquire(mutex_, osWaitForever);
  268. target_pos_ = target_pos_ + shift_target;
  269. is_moving_ = true;
  270. osMutexRelease(mutex_);
  271. }
  272. void ECLMotor::moveToWithSpeed(int32_t target, int32_t speed) {
  273. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  274. if (motor == nullptr) {
  275. return;
  276. }
  277. if (ELCMotorHelper::isFlip(index_)) {
  278. target = -target;
  279. ZLOGI(TAG, "【MOTOR 【%d】TARGET FLIP】", index_);
  280. }
  281. motor->moveTo(target, abs(speed));
  282. osMutexAcquire(mutex_, osWaitForever);
  283. target_pos_ = target;
  284. is_moving_ = true;
  285. osMutexRelease(mutex_);
  286. }
  287. // 设置电机速度
  288. void ECLMotor::setSpeed(int32_t speed) {
  289. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  290. if (motor == nullptr) {
  291. return;
  292. }
  293. osMutexAcquire(mutex_, osWaitForever);
  294. this->target_speed_ = speed;
  295. #if 0
  296. if(is_moving_) {
  297. motor->moveTo(target_pos_, this->target_speed_);
  298. }
  299. #else
  300. if (is_moving_) {
  301. motor->setVMax(this->target_speed_);
  302. }
  303. #endif
  304. osMutexRelease(mutex_);
  305. }
  306. // 获取电机速度
  307. int32_t ECLMotor::getRTSpeed() {
  308. osMutexAcquire(mutex_, osWaitForever);
  309. const int32_t spd = rt_speed_;
  310. osMutexRelease(mutex_);
  311. return spd;
  312. }
  313. // 获取电机运动状态
  314. bool ECLMotor::isMoving() {
  315. osMutexAcquire(mutex_, osWaitForever);
  316. bool moving = is_moving_;
  317. osMutexRelease(mutex_);
  318. return moving;
  319. }
  320. // 获取编码器位置
  321. int32_t ECLMotor::getEncoderPosition() {
  322. osMutexAcquire(mutex_, osWaitForever);
  323. int32_t encPos = enc_val_;
  324. osMutexRelease(mutex_);
  325. return encPos;
  326. }
  327. // 设置编码器位置
  328. void ECLMotor::setEncoderPosition(int32_t encoderPos) {
  329. osMutexAcquire(mutex_, osWaitForever);
  330. enc_val_ = encoderPos;
  331. osMutexRelease(mutex_);
  332. }
  333. // 新增设置是否运动的接口
  334. void ECLMotor::setMoving(bool moving) {
  335. osMutexAcquire(mutex_, osWaitForever);
  336. is_moving_ = moving;
  337. osMutexRelease(mutex_);
  338. }
  339. void ECLMotor::setMotorIndex(int32_t index) {
  340. this->index_ = index;
  341. }
  342. bool ECLMotor::isHomed() {
  343. return isHomed_;
  344. }
  345. bool ECLMotor::isHoming() {
  346. bool isDoHome = homeState_ != STATE_INIT;
  347. return isDoHome;
  348. }
  349. void ECLMotor::runhomeSuc() {
  350. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  351. if (motor == nullptr) {
  352. return;
  353. }
  354. // 发送 CAN 信息
  355. motor->setEncVal(0);
  356. motor->setXACTUAL(0);
  357. this->isHomed_ = true;
  358. this->homeState_ = STATE_INIT;
  359. ZLOGI(TAG, "【HOMED】 MOVE TO HOME SUC"); {
  360. CanMessage msg = CanProtocolFactory::createUploadEvent(seq_id_home_, Motor_Home_Finished, index_);
  361. AppHardware::ins()->can0Controller.sendMessage(msg);
  362. }
  363. }
  364. void ECLMotor::startMoveHome() {
  365. // 避免有相同的操作
  366. bool isDoHoming = this->isHoming();
  367. if (isDoHoming) {
  368. ZLOGI(TAG, "MOTOR [%d] HOME FAILED, Current is Homing", this->index_);
  369. // return;
  370. }
  371. home_count_ = 0; // 开始前清零
  372. bool isAtOrigin = ELCMotorHelper::isAtOrigin(this->index_);
  373. ZLOGI(TAG, "START NOT IN HOME")
  374. // 当前是否在原点
  375. if (isAtOrigin) {
  376. home_event_.event_type = EVENT_IN_ORIGIN;
  377. ZLOGI(TAG, "EVENT_IN_ORIGIN");
  378. osStatus_t status = osMessageQueuePut(homeEventQueue, &home_event_, 0U, 0U);
  379. if (status != osOK) {
  380. ZLOGE(TAG, "EVENT_IN_ORIGIN SEND FAIL, status: %d", status);
  381. }
  382. } else {
  383. if (homeState_ == STATE_INIT) {
  384. home_event_.event_type = EVENT_START_HOMING;
  385. ZLOGI(TAG, "EVENT_START_HOMING");
  386. osStatus_t status = osMessageQueuePut(homeEventQueue, &home_event_, 0U, 0U);
  387. if (status != osOK) {
  388. ZLOGE(TAG, "EVENT_START_HOMING SEND FAIL, status: %d", status);
  389. }
  390. }
  391. }
  392. }
  393. void ECLMotor::setHomeSeqId(uint8_t seq_id) {
  394. this->seq_id_home_ = seq_id;
  395. }
  396. void ECLMotor::setMoveFinishSeqId(uint8_t seq_id) {
  397. this->seq_id_move_finished_ = seq_id;
  398. }
  399. void ECLMotor::homingTask(void *arg) {
  400. ECLMotor *eclMotor = static_cast<ECLMotor *>(arg);
  401. HomeEvent home_event;
  402. while (eclMotor->isRunHomingTask) {
  403. osStatus status = osMessageQueueGet(eclMotor->homeEventQueue, &home_event, NULL, osWaitForever);
  404. if (status == osOK) {
  405. TMC51X0 *motor = AppHardware::ins()->getPump(eclMotor->index_);
  406. if (motor == nullptr) {
  407. return;
  408. }
  409. ZLOGI(TAG, "HANDLE NOT HOMED");
  410. #if 1
  411. switch (home_event.event_type) {
  412. case EVENT_START_HOMING: {
  413. ZLOGI(TAG, "[]EVENT_START_HOMING");
  414. if (eclMotor->homeState_ == STATE_INIT) {
  415. eclMotor->homeState_ = STATE_BACK_TO_ORIGIN_MIDDLE;
  416. // 中速倒转
  417. int speed = ELCMotorHelper::getRPerMinMiddleSpeed(eclMotor->index_);
  418. int absSpeed = abs(speed);
  419. eclMotor->ECL_Rotate(-absSpeed);
  420. ZLOGI(TAG, "【HOME】 BACK TO ORIGIN MIDDLE");
  421. }
  422. break;
  423. }
  424. case EVENT_ORIGIN_ENTER: {
  425. // ZLOGI(TAG, "[]EVENT_ORIGIN_ENTER");
  426. // if first enter
  427. if (eclMotor->homeState_ == STATE_BACK_TO_ORIGIN_MIDDLE) {
  428. // 停止
  429. // 中速向前10mm
  430. // int speed = ELCMotorHelper::getRPerMinMiddleSpeed(eclMotor->index_);
  431. // eclMotor->ECL_Rotate(speed);
  432. eclMotor->homeState_ = STATE_LEAVE_ORIGIN_MIDDLE;
  433. // 位置清零
  434. motor->setEncVal(0);
  435. motor->setXACTUAL(0);
  436. const int32_t speed = ELCMotorHelper::getRPerMinMiddleSpeed(eclMotor->index_);
  437. eclMotor->moveToWithSpeed(ELCMotorHelper::getForwordMoveStep(eclMotor->index_), speed);
  438. // 4000 4 圈
  439. ZLOGI(TAG, "【HOME】 [EVENT_ORIGIN_ENTER] FORWARD TO ORIGIN MIDDLE");
  440. }
  441. // if second enter
  442. if (eclMotor->homeState_ == STATE_BACK_TO_ORIGIN_LOW) {
  443. // 位置清零
  444. // 电机停止
  445. // 回归原点成功
  446. eclMotor->runhomeSuc();
  447. }
  448. break;
  449. }
  450. case EVENT_ENCODER_NEAR_ORIGN: {
  451. // ZLOGI(TAG, "[]EVENT_ENCODER_NEAR_ORIGN");
  452. if (eclMotor->homeState_ == STATE_LEAVE_ORIGIN_MIDDLE) {
  453. // 停止
  454. // 低速回归
  455. eclMotor->homeState_ = STATE_BACK_TO_ORIGIN_LOW;
  456. int speed = ELCMotorHelper::getRPerMinLowSpeed(eclMotor->index_);
  457. eclMotor->ECL_Rotate(-speed);
  458. ZLOGI(TAG, "【HOME】 BACK TO ORIGIN LOW");
  459. }
  460. break;
  461. }
  462. case EVENT_IN_ORIGIN: {
  463. // ZLOGI(TAG, "[]EVENT_IN_ORIGIN");
  464. if (eclMotor->homeState_ == STATE_INIT) {
  465. // 中速向前10mm
  466. eclMotor->homeState_ = STATE_FORWARD_TO_ORIGIN_MIDDLE;
  467. int speed = ELCMotorHelper::getRPerMinMiddleSpeed(eclMotor->index_);
  468. eclMotor->ECL_Rotate(speed);
  469. ZLOGI(TAG, "【HOME】 FORWARD TO ORIGIN MIDDLE");
  470. }
  471. break;
  472. }
  473. case EVENT_ORIGIN_LEAVE: {
  474. // ZLOGI(TAG, "[]EVENT_ORIGIN_LEAVE");
  475. if (eclMotor->homeState_ == STATE_FORWARD_TO_ORIGIN_MIDDLE) {
  476. // 停止 前向移动 1mm
  477. eclMotor->homeState_ = STATE_LEAVE_ORIGIN_MIDDLE;
  478. motor->stop();
  479. // 位置清零
  480. motor->setEncVal(0);
  481. motor->setXACTUAL(0);
  482. const int32_t speed = ELCMotorHelper::getRPerMinMiddleSpeed(eclMotor->index_);
  483. eclMotor->moveToWithSpeed(ELCMotorHelper::getForwordMoveStep(eclMotor->index_), speed);
  484. ZLOGI(TAG, "【HOME】 FORWARD TO ORIGIN MIDDLE");
  485. }
  486. break;
  487. }
  488. case EVENT_MOTOR_MOVE_FINISHED: {
  489. ZLOGI(TAG, "[]EVENT_MOTOR_MOVE_FINISHED");
  490. if (eclMotor->homeState_ == STATE_LEAVE_ORIGIN_MIDDLE) {
  491. // 低速回归
  492. eclMotor->homeState_ = STATE_BACK_TO_ORIGIN_LOW;
  493. const int speed = ELCMotorHelper::getRPerMinLowSpeed(eclMotor->index_);
  494. eclMotor->ECL_Rotate(-speed);
  495. ZLOGI(TAG, "【HOME】 BACK TO ORIGIN LOW");
  496. }
  497. break;
  498. }
  499. default:
  500. break;
  501. }
  502. #endif
  503. } else {
  504. ZLOGI(TAG, "GET MESSAGE FAILED");
  505. }
  506. ZLOGI(TAG, "RUN MOTOR [END] %d", eclMotor->index_);
  507. }
  508. }
  509. void ECLMotor::moveToHome() {
  510. #if 0
  511. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  512. if (motor == nullptr) {
  513. return;
  514. }
  515. osMutexAcquire(mutex_, osWaitForever);
  516. is_moving_ = false;
  517. osMutexRelease(mutex_);
  518. int32_t abs_speed = abs(target_speed_);
  519. int32_t roback_speed = -abs_speed;
  520. #if TIMER_IS_FINE
  521. this->setReadRate(READ_RATE_HIGH);
  522. #endif
  523. // 倒转回HOME
  524. this->ECL_Rotate(roback_speed);
  525. ZLOGI(TAG, "ECL MOTOR HOME ROBACK SPEED %d", roback_speed);
  526. #else
  527. this->startMoveHome();
  528. #endif
  529. }
  530. void ECLMotor::runZeroLimit(bool isEnter) {
  531. // 处理回home 位逻辑
  532. if (isHoming()) {
  533. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  534. if (motor == nullptr) {
  535. return;
  536. }
  537. if (isEnter) {
  538. home_event_.event_type = EVENT_ORIGIN_ENTER;
  539. motor->stop();
  540. osDelay(10);
  541. ZLOGI(TAG, "[PUT] EVENT_ORIGIN_ENTER");
  542. } else {
  543. home_event_.event_type = EVENT_ORIGIN_LEAVE;
  544. ZLOGI(TAG, "[PUT] EVENT_ORIGIN_LEAVE");
  545. }
  546. osMessageQueuePut(homeEventQueue, &home_event_, 0U, 0U);
  547. return;
  548. }
  549. if (!isEnter) {
  550. return;
  551. }
  552. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  553. if (motor == nullptr) {
  554. return;
  555. }
  556. motor->stop();
  557. osDelay(10); {
  558. CanMessage msg = CanProtocolFactory::createUploadEvent(seq_id_move_finished_, Motor_Move_Finished, index_);
  559. AppHardware::ins()->can0Controller.sendMessage(msg);
  560. }
  561. osDelay(10);
  562. // 重置编码器 和 位置
  563. motor->setXACTUAL(0);
  564. motor->setEncVal(0);
  565. osMutexAcquire(mutex_, osWaitForever);
  566. this->x_actual_ = 0;
  567. this->enc_val_ = 0;
  568. this->target_pos_ = 0;
  569. this->is_moving_ = false;
  570. osMutexRelease(mutex_);
  571. ZLOGI("ECL", "MOTOR [%d] runZeroLimit", this->index_);
  572. }
  573. void ECLMotor::runEndLimit(bool isEnter) {
  574. // 发送CAN 消息
  575. if (!isEnter) {
  576. return;
  577. }
  578. this->runStop();
  579. }
  580. void ECLMotor::runE_Stop() {
  581. // 发送CAN 消息
  582. this->runStop();
  583. }
  584. void ECLMotor::runPause() {
  585. // 发送CAN 消息
  586. this->runStop();
  587. }
  588. void ECLMotor::runStop() {
  589. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  590. if (motor == nullptr) {
  591. return;
  592. }
  593. motor->stop();
  594. // 发送CAN 消息
  595. CanMessage msg = CanProtocolFactory::createUploadEvent(seq_id_home_, Motor_Move_Finished, index_);
  596. AppHardware::ins()->can0Controller.sendMessage(msg);
  597. osMutexAcquire(mutex_, osWaitForever);
  598. this->is_moving_ = false;
  599. osMutexRelease(mutex_);
  600. }
  601. void ECLMotor::ECL_Rotate(int32_t speed, const bool is_flip) {
  602. #ifdef TEST
  603. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  604. if (motor == nullptr) {
  605. return;
  606. }
  607. if (ELCMotorHelper::isFlip(index_) && is_flip) {
  608. speed = -speed;
  609. ZLOGI(TAG, "ECL MOTOR ECL REAL INDEX 【%d】 FLIP", index_);
  610. }
  611. motor->rotate(speed);
  612. ZLOGI(TAG, "ECL MOTOR %d SPEED %d", index_, speed);
  613. #else
  614. motor->rotate(roback_speed);
  615. #endif
  616. }