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

527 lines
15 KiB

3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
  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. const int32_t pos = x_actual_;
  134. osMutexRelease(mutex_);
  135. const int32_t py_pos = ELCMotorHelper::isFlip(index_) ? -pos : pos;
  136. return py_pos;
  137. }
  138. // 设置电机的目标位置
  139. void ECLMotor::setTargetPosition(int32_t target) {
  140. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  141. if (motor == nullptr) {
  142. return;
  143. }
  144. if (ELCMotorHelper::isFlip(index_)) {
  145. target = -target;
  146. ZLOGI(TAG, "【MOTOR 【%d】TARGET FLIP】", index_);
  147. }
  148. motor->moveTo(target, this->target_speed_);
  149. osMutexAcquire(mutex_, osWaitForever);
  150. target_pos_ = target;
  151. osMutexRelease(mutex_);
  152. }
  153. void ECLMotor::setShiftPosition(int32_t shift_target) {
  154. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  155. if (motor == nullptr) {
  156. return;
  157. }
  158. if (ELCMotorHelper::isFlip(index_)) {
  159. shift_target = -shift_target;
  160. ZLOGI(TAG, "【MOTOR 【%d】SHIFT TARGET FLIP】", index_);
  161. }
  162. motor->moveBy(shift_target, abs(target_speed_));
  163. osMutexAcquire(mutex_, osWaitForever);
  164. target_pos_ = target_pos_ + shift_target;
  165. osMutexRelease(mutex_);
  166. }
  167. void ECLMotor::moveToWithSpeed(int32_t target, int32_t speed) {
  168. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  169. if (motor == nullptr) {
  170. return;
  171. }
  172. if (ELCMotorHelper::isFlip(index_)) {
  173. target = -target;
  174. ZLOGI(TAG, "【MOTOR 【%d】TARGET FLIP】", index_);
  175. }
  176. motor->moveTo(target, abs(speed));
  177. osMutexAcquire(mutex_, osWaitForever);
  178. target_pos_ = target;
  179. osMutexRelease(mutex_);
  180. }
  181. // 设置电机速度
  182. void ECLMotor::setSpeed(int32_t speed) {
  183. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  184. if (motor == nullptr) {
  185. return;
  186. }
  187. osMutexAcquire(mutex_, osWaitForever);
  188. this->target_speed_ = speed;
  189. // 当前正在移动
  190. if (!is_move_finished_) {
  191. motor->setVMax(this->target_speed_);
  192. }
  193. osMutexRelease(mutex_);
  194. }
  195. // 获取电机速度
  196. int32_t ECLMotor::getRTSpeed() {
  197. osMutexAcquire(mutex_, osWaitForever);
  198. const int32_t spd = rt_speed_;
  199. osMutexRelease(mutex_);
  200. return spd;
  201. }
  202. // 获取电机运动状态
  203. bool ECLMotor::isMoveFinished() {
  204. osMutexAcquire(mutex_, osWaitForever);
  205. bool is_move_finshed = is_move_finished_;
  206. osMutexRelease(mutex_);
  207. return is_move_finshed;
  208. }
  209. // 获取编码器位置
  210. int32_t ECLMotor::getEncoderPosition() {
  211. osMutexAcquire(mutex_, osWaitForever);
  212. int32_t encPos = enc_val_;
  213. osMutexRelease(mutex_);
  214. const int32_t py_pos = ELCMotorHelper::isFlip(index_) ? -encPos : encPos;
  215. return py_pos;
  216. }
  217. // 设置编码器位置
  218. void ECLMotor::setEncoderPosition(int32_t encoderPos) {
  219. osMutexAcquire(mutex_, osWaitForever);
  220. enc_val_ = encoderPos;
  221. osMutexRelease(mutex_);
  222. }
  223. void ECLMotor::setMotorIndex(int32_t index) {
  224. this->index_ = index;
  225. }
  226. bool ECLMotor::isHomeInit() {
  227. return is_home_init_;
  228. }
  229. bool ECLMotor::isHomeSuc() {
  230. osMutexAcquire(mutex_, osWaitForever);
  231. bool is_home_suc = is_home_suc_;
  232. osMutexRelease(mutex_);
  233. return is_home_suc;
  234. }
  235. void ECLMotor::runhomeSuc() {
  236. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  237. if (motor == nullptr) {
  238. return;
  239. }
  240. // 发送 CAN 信息
  241. motor->setEncVal(0);
  242. motor->setXACTUAL(0);
  243. // 置标志位
  244. osMutexAcquire(mutex_, osWaitForever);
  245. this->is_home_init_ = true;
  246. this->is_home_suc_ = true;
  247. this->home_state_ = STATE_INIT;
  248. osMutexRelease(mutex_);
  249. ZLOGI(TAG, "【 MOVE TO HOME SUC 】");
  250. {
  251. #if CAN_MODULE_ENABLE
  252. CanMessage msg = CanProtocolFactory::createUploadEvent(seq_id_home_, Motor_Home_Finished, index_);
  253. AppHardware::ins()->can0Controller.sendMessage(msg);
  254. #endif
  255. }
  256. }
  257. void ECLMotor::startMoveHome() {
  258. home_start_tick_ = 0;
  259. osMutexAcquire(mutex_, osWaitForever);
  260. this->is_home_suc_ = false;
  261. osMutexRelease(mutex_);
  262. const bool isAtOrigin = ELCMotorHelper::isAtOrigin(this->index_);
  263. // 当前是否在原点
  264. if (isAtOrigin) {
  265. home_event_.event_type = EVENT_IN_ORIGIN;
  266. ZLOGI(TAG, "[PUT] EVENT IN ORIGIN");
  267. osStatus_t status = osMessageQueuePut(homeEventQueue, &home_event_, 0U, 0U);
  268. if (status != osOK) {
  269. ZLOGE(TAG, "EVENT IN ORIGIN SEND FAIL, status: %d", status);
  270. }
  271. } else {
  272. home_event_.event_type = EVENT_START_HOMING;
  273. ZLOGI(TAG, "[PUT] EVENT_START_HOMING");
  274. osStatus_t status = osMessageQueuePut(homeEventQueue, &home_event_, 0U, 0U);
  275. if (status != osOK) {
  276. ZLOGE(TAG, "EVENT_START_HOMING SEND FAIL, status: %d", status);
  277. }
  278. }
  279. }
  280. void ECLMotor::setHomeSeqId(uint8_t seq_id) {
  281. this->seq_id_home_ = seq_id;
  282. }
  283. void ECLMotor::setMoveFinishSeqId(uint8_t seq_id) {
  284. this->seq_id_move_ = seq_id;
  285. }
  286. void ECLMotor::homingTask(void *arg) {
  287. ECLMotor *eclMotor = static_cast<ECLMotor *>(arg);
  288. HomeEvent home_event;
  289. while (eclMotor->isRunHomingTask) {
  290. osStatus status = osMessageQueueGet(eclMotor->homeEventQueue, &home_event, NULL, osWaitForever);
  291. if (status == osOK) {
  292. TMC51X0 *motor = AppHardware::ins()->getPump(eclMotor->index_);
  293. if (motor == nullptr) {
  294. return;
  295. }
  296. #if 1
  297. switch (home_event.event_type) {
  298. case EVENT_START_HOMING: {
  299. osMutexAcquire(eclMotor->mutex_, osWaitForever);
  300. eclMotor->home_state_ = STATE_BACK_TO_ORIGIN_MIDDLE;
  301. osMutexRelease(eclMotor->mutex_);
  302. // 中速倒转
  303. int speed = ELCMotorHelper::getRPerMinMiddleSpeed(eclMotor->index_);
  304. int absSpeed = abs(speed);
  305. eclMotor->ECL_Rotate(-absSpeed);
  306. ZLOGI(TAG, "【HOME】 BACK TO ORIGIN MIDDLE");
  307. break;
  308. }
  309. case EVENT_ORIGIN_ENTER: {
  310. // if first enter
  311. if(eclMotor->home_state_ == STATE_BACK_TO_ORIGIN_MIDDLE) {
  312. // 停止
  313. // 中速向前10mm
  314. osMutexAcquire(eclMotor->mutex_, osWaitForever);
  315. eclMotor->home_state_ = STATE_LEAVE_ORIGIN_MIDDLE;
  316. osMutexRelease(eclMotor->mutex_);
  317. // 位置清零
  318. motor->setEncVal(0);
  319. motor->setXACTUAL(0);
  320. const int32_t speed = ELCMotorHelper::getRPerMinMiddleSpeed(eclMotor->index_);
  321. eclMotor->moveToWithSpeed(ELCMotorHelper::getForwordMoveStep(eclMotor->index_), speed);
  322. // 4000 4 圈
  323. ZLOGI(TAG, "【HOME】 [EVENT_ORIGIN_ENTER] FORWARD TO ORIGIN MIDDLE");
  324. }
  325. // if second enter
  326. if (eclMotor->home_state_ == STATE_BACK_TO_ORIGIN_LOW) {
  327. // 位置清零
  328. // 电机停止
  329. // 回归原点成功
  330. eclMotor->runhomeSuc();
  331. }
  332. break;
  333. }
  334. case EVENT_IN_ORIGIN: {
  335. ZLOGI(TAG, "[]EVENT IN ORIGIN");
  336. // 中速向前10mm
  337. motor->setEncVal(0);
  338. motor->setXACTUAL(0);
  339. // 前向移动 1mm
  340. osMutexAcquire(eclMotor->mutex_, osWaitForever);
  341. eclMotor->home_state_ = STATE_LEAVE_ORIGIN_MIDDLE;
  342. osMutexRelease(eclMotor->mutex_);
  343. const int32_t speed = ELCMotorHelper::getRPerMinMiddleSpeed(eclMotor->index_);
  344. eclMotor->moveToWithSpeed(ELCMotorHelper::getForwordMoveStep(eclMotor->index_), speed);
  345. ZLOGI(TAG, "【HOME】 FORWARD TO ORIGIN MIDDLE");
  346. break;
  347. }
  348. case EVENT_MOTOR_MOVE_FINISHED: {
  349. ZLOGI(TAG, "[]EVENT MOTOR MOVE FINISHED");
  350. if (eclMotor->home_state_ == STATE_LEAVE_ORIGIN_MIDDLE) {
  351. // 低速回归
  352. osMutexAcquire(eclMotor->mutex_, osWaitForever);
  353. eclMotor->home_state_ = STATE_BACK_TO_ORIGIN_LOW;
  354. osMutexRelease(eclMotor->mutex_);
  355. const int speed = ELCMotorHelper::getRPerMinLowSpeed(eclMotor->index_);
  356. eclMotor->ECL_Rotate(-speed);
  357. ZLOGI(TAG, "【HOME】 BACK TO ORIGIN LOW");
  358. }
  359. break;
  360. }
  361. default:
  362. break;
  363. }
  364. #endif
  365. } else {
  366. ZLOGI(TAG, "GET MESSAGE FAILED");
  367. }
  368. }
  369. }
  370. void ECLMotor::moveToHome() {
  371. this->startMoveHome();
  372. }
  373. void ECLMotor::runZeroLimit(bool isEnter) {
  374. // 处理回home 位逻辑
  375. if (!isHomeSuc()) {
  376. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  377. if (motor == nullptr) {
  378. return;
  379. }
  380. if (isEnter) {
  381. home_event_.event_type = EVENT_ORIGIN_ENTER;
  382. motor->stop();
  383. osDelay(10);
  384. ZLOGI(TAG, "[PUT] EVENT_ORIGIN_ENTER");
  385. } else {
  386. home_event_.event_type = EVENT_ORIGIN_LEAVE;
  387. ZLOGI(TAG, "[PUT] EVENT_ORIGIN_LEAVE");
  388. }
  389. osMessageQueuePut(homeEventQueue, &home_event_, 0U, 0U);
  390. return;
  391. }
  392. if (!isEnter) {
  393. return;
  394. }
  395. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  396. if (motor == nullptr) {
  397. return;
  398. }
  399. motor->stop();
  400. {
  401. #if CAN_MODULE_ENABLE
  402. CanMessage msg = CanProtocolFactory::createUploadEvent(seq_id_move_, Motor_Move_Finished, index_);
  403. AppHardware::ins()->can0Controller.sendMessage(msg);
  404. #endif
  405. }
  406. // 重置编码器 和 位置
  407. motor->setXACTUAL(0);
  408. motor->setEncVal(0);
  409. osMutexAcquire(mutex_, osWaitForever);
  410. this->x_actual_ = 0;
  411. this->enc_val_ = 0;
  412. this->target_pos_ = 0;
  413. osMutexRelease(mutex_);
  414. ZLOGI("ECL", "MOTOR [%d] runZeroLimit", this->index_);
  415. }
  416. void ECLMotor::runEndLimit(bool isEnter) {
  417. // 发送CAN 消息
  418. if (!isEnter) {
  419. return;
  420. }
  421. this->runStop();
  422. }
  423. void ECLMotor::runE_Stop() {
  424. // 发送CAN 消息
  425. osMutexAcquire(mutex_, osWaitForever);
  426. this->is_home_suc_ = false;
  427. osMutexRelease(mutex_);
  428. this->runStop();
  429. }
  430. void ECLMotor::runPause() {
  431. // 发送CAN 消息
  432. this->runStop();
  433. }
  434. void ECLMotor::runStop() {
  435. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  436. if (motor == nullptr) {
  437. return;
  438. }
  439. motor->stop();
  440. // 发送CAN 消息
  441. #if CAN_MODULE_ENABLE
  442. CanMessage msg = CanProtocolFactory::createUploadEvent(seq_id_home_, Motor_Move_Finished, index_);
  443. AppHardware::ins()->can0Controller.sendMessage(msg);
  444. #endif
  445. }
  446. void ECLMotor::ECL_Rotate(int32_t speed, const bool is_flip) {
  447. TMC51X0 *motor = AppHardware::ins()->getPump(index_);
  448. if (motor == nullptr) {
  449. return;
  450. }
  451. if (ELCMotorHelper::isFlip(index_) && is_flip) {
  452. speed = -speed;
  453. ZLOGI(TAG, "ECL MOTOR ECL REAL INDEX 【%d】 FLIP", index_);
  454. }
  455. motor->rotate(speed);
  456. ZLOGI(TAG, "ECL MOTOR %d SPEED %d", index_, speed);
  457. }