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.

519 lines
20 KiB

5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
  1. package com.qyft.ms.app.service;
  2. import cn.hutool.json.JSONUtil;
  3. import com.alibaba.fastjson.JSON;
  4. import com.qyft.ms.app.common.constant.WebSocketMessageType;
  5. import com.qyft.ms.app.common.generator.PathGenerator;
  6. import com.qyft.ms.app.common.result.CMDResultCode;
  7. import com.qyft.ms.app.model.entity.OperationLog;
  8. import com.qyft.ms.app.model.entity.SysSettings;
  9. import com.qyft.ms.app.model.form.CMDForm;
  10. import com.qyft.ms.app.model.vo.ExecutionResult;
  11. import com.qyft.ms.device.service.DeviceTcpCMDService;
  12. import lombok.RequiredArgsConstructor;
  13. import lombok.extern.slf4j.Slf4j;
  14. import org.springframework.stereotype.Service;
  15. import java.util.*;
  16. import java.util.List;
  17. import java.util.function.Supplier;
  18. import static com.qyft.ms.app.common.generator.PathGenerator.generatePathPoints;
  19. @Slf4j
  20. @RequiredArgsConstructor
  21. @Service
  22. public class CMDService {
  23. private final WebSocketService webSocketService;
  24. private final DeviceTcpCMDService deviceTcpCMDService;
  25. private final OperationLogService operationLogService;
  26. private final MatrixCraftService matrixCraftService;
  27. private final ISysSettingsService sysSettingsService;
  28. private void initExecutorThread(List<Supplier<Boolean>> cmdList, CMDForm form) {
  29. new Thread(() -> run(cmdList, form)).start();
  30. }
  31. // 电机移动
  32. public boolean moveMotorToPosition(CMDForm form) {
  33. Map<String, Object> params = form.getParams();
  34. if (params == null || !params.containsKey("axis") || !params.containsKey("position")) {
  35. return false;
  36. }
  37. List<Supplier<Boolean>> cmdList = new ArrayList<>();
  38. String axis = (String) params.get("axis");
  39. double position = Optional.ofNullable(params.get("position"))
  40. .filter(Number.class::isInstance)
  41. .map(Number.class::cast)
  42. .map(Number::doubleValue)
  43. .orElse(0.0);
  44. cmdList.add(() -> deviceTcpCMDService.moveMotorToPosition(axis, position));
  45. initExecutorThread(cmdList, form);
  46. return true;
  47. };
  48. // 切换清洗管路/喷涂管路
  49. public boolean switchThreeWayValve(CMDForm form) {
  50. Map<String, Object> params = form.getParams();
  51. if (params == null || !params.containsKey("type")) {
  52. return false;
  53. }
  54. List<Supplier<Boolean>> cmdList = new ArrayList<>();
  55. String type = (String) params.get("type");
  56. if (type.equals("clean")) {
  57. cmdList.add(deviceTcpCMDService::switchThreeWayValveToSubstrate);
  58. } else if (type.equals("spray")) {
  59. cmdList.add(deviceTcpCMDService::switchThreeWayValveToSpray);
  60. }else {
  61. return false;
  62. }
  63. initExecutorThread(cmdList, form);
  64. return true;
  65. }
  66. // 除湿阀、清洗阀、喷嘴阀控制方法
  67. public boolean controlValve(CMDForm form) {
  68. Map<String, Object> params = form.getParams();
  69. if (params == null || !params.containsKey("valveType") || !params.containsKey("isOpen")) {
  70. return false;
  71. }
  72. List<Supplier<Boolean>> cmdList = new ArrayList<>();
  73. if(params.get("valveType") !=null && params.get("isOpen") !=null) {
  74. String valveType = (String) params.get("valveType");
  75. boolean isOpen = (boolean) params.get("isOpen");
  76. cmdList.add(() -> deviceTcpCMDService.controlValve(valveType,isOpen));
  77. }
  78. initExecutorThread(cmdList, form);
  79. return true;
  80. }
  81. // 以指定电压值开启高压电
  82. public boolean turnOnHighVoltage(CMDForm form) {
  83. Map<String, Object> params = form.getParams();
  84. if (params == null || !params.containsKey("voltage")) {
  85. return false;
  86. }
  87. List<Supplier<Boolean>> cmdList = new ArrayList<>();
  88. double voltage = Optional.ofNullable(params.get("voltage"))
  89. .filter(Number.class::isInstance)
  90. .map(Number.class::cast)
  91. .map(Number::doubleValue)
  92. .orElse(0.0);
  93. cmdList.add(() -> deviceTcpCMDService.turnOnHighVoltage(voltage));
  94. initExecutorThread(cmdList, form);
  95. return true;
  96. }
  97. // 关闭高压电
  98. public boolean turnOffHighVoltage(CMDForm form) {
  99. Map<String, Object> params = form.getParams();
  100. if (params == null) {
  101. return false;
  102. }
  103. List<Supplier<Boolean>> cmdList = new ArrayList<>();
  104. cmdList.add(deviceTcpCMDService::turnOffHighVoltage);
  105. initExecutorThread(cmdList, form);
  106. return true;
  107. }
  108. // 以指定转速、时间开启注射泵
  109. public boolean turnOnSyringePump(CMDForm form) {
  110. Map<String, Object> params = form.getParams();
  111. if (params == null || !params.containsKey("rotationSpeed") || !params.containsKey("time")) {
  112. return false;
  113. }
  114. List<Supplier<Boolean>> cmdList = new ArrayList<>();
  115. double rotationSpeed = Optional.ofNullable(params.get("rotationSpeed"))
  116. .filter(Number.class::isInstance)
  117. .map(Number.class::cast)
  118. .map(Number::doubleValue)
  119. .orElse(0.0);
  120. double time = Optional.ofNullable(params.get("time"))
  121. .filter(Number.class::isInstance)
  122. .map(Number.class::cast)
  123. .map(Number::doubleValue)
  124. .orElse(0.0);
  125. cmdList.add(() -> deviceTcpCMDService.turnOnSyringePump(rotationSpeed, time));
  126. initExecutorThread(cmdList, form);
  127. return true;
  128. }
  129. // 停止注射泵
  130. public boolean turnOffSyringePump(CMDForm form) {
  131. Map<String, Object> params = form.getParams();
  132. if (params == null) {
  133. return false;
  134. }
  135. List<Supplier<Boolean>> cmdList = new ArrayList<>();
  136. cmdList.add(deviceTcpCMDService::turnOffSyringePump);
  137. initExecutorThread(cmdList, form);
  138. return true;
  139. }
  140. // 设置指定轴的电机运行时电流
  141. public boolean setMotorRunningCurrent(CMDForm form) {
  142. Map<String, Object> params = form.getParams();
  143. if (params == null || !params.containsKey("axis") || !params.containsKey("current")) {
  144. return false;
  145. }
  146. List<Supplier<Boolean>> cmdList = new ArrayList<>();
  147. String axis = (String) params.get("axis");
  148. double current = Optional.ofNullable(params.get("current"))
  149. .filter(Number.class::isInstance)
  150. .map(Number.class::cast)
  151. .map(Number::doubleValue)
  152. .orElse(0.0);
  153. cmdList.add(() -> deviceTcpCMDService.setMotorRunningCurrent(axis, current));
  154. initExecutorThread(cmdList, form);
  155. return true;
  156. }
  157. // 开始喷涂
  158. public String startWork(CMDForm form) {
  159. Map<String, Object> params = form.getParams();
  160. if (
  161. params == null ||
  162. !params.containsKey("position") ||
  163. !params.containsKey("space") ||
  164. !params.containsKey("routeType") ||
  165. !params.containsKey("movementSpeed") ||
  166. !params.containsKey("height") ||
  167. !params.containsKey("matrixFlowVelocity")
  168. ) {
  169. return "参数错误";
  170. }
  171. if ( operationLogService.getIng() != null) {
  172. return "当前有正在运行的任务";
  173. }
  174. List<Supplier<Boolean>> cmdList = new ArrayList<>();
  175. // 托盘位置
  176. List<SysSettings> slidePositionList = sysSettingsService.getSlidePositionList();
  177. List<Map<String, Integer>> position = (List<Map<String, Integer>>) params.get("position");
  178. if (position == null) {
  179. return "position参数错误";
  180. }
  181. for (int i = 0; i < position.size(); i++) {
  182. Map<String, Integer> p = position.get(i);
  183. if (p.get("x1") == null || p.get("y1") == null || p.get("x2") == null || p.get("y2") == null || p.get("index") == null) {
  184. return "position参数错误";
  185. }
  186. // 玻片的位置
  187. String p1 = slidePositionList.get(p.get("index")).getValue();
  188. String[] p1s = p1.split(",");
  189. double x = Double.parseDouble(p1s[0]);
  190. double y = Double.parseDouble(p1s[1]);
  191. double z = Double.parseDouble(p1s[2]);
  192. // 玻片范围的实际位置
  193. // 托盘点位 x y z
  194. double left =x+ p.get("x1");
  195. double right = x+ p.get("x2");
  196. double top = y+ p.get("y1");
  197. double bottom = y+ p.get("y2");
  198. int space = (Integer) params.get("space");
  199. int routeType = (Integer) params.get("routeType");
  200. List<PathGenerator.Points> horizontalPath = generatePathPoints(
  201. left, right, top, bottom, space, routeType == 1 ? PathGenerator.MoveMode.HORIZONTAL_ZIGZAG_TOP_DOWN : PathGenerator.MoveMode.VERTICAL_ZIGZAG_LEFT_RIGHT
  202. );
  203. log.info("horizontalPath:{}", horizontalPath);
  204. if(horizontalPath.isEmpty()) {
  205. return "路径规划失败";
  206. }
  207. // 将三通阀转至喷涂管路
  208. cmdList.add(deviceTcpCMDService::switchThreeWayValveToSpray);
  209. // 设置指定轴的电机的运行速度
  210. int movementSpeed = (Integer) params.get("movementSpeed");
  211. cmdList.add(() -> deviceTcpCMDService.setMotorSpeed("x", movementSpeed));
  212. cmdList.add(() -> deviceTcpCMDService.setMotorSpeed("y", movementSpeed));
  213. cmdList.add(() -> deviceTcpCMDService.setMotorSpeed("z", movementSpeed));
  214. // 移动到指定高度(位置)
  215. int height = (Integer) params.get("height");
  216. if(z - height < 6.5) {
  217. return "高度设置太低,有撞针的风险";
  218. }
  219. cmdList.add(() -> deviceTcpCMDService.moveMotorToPosition("Z",z - height ));
  220. cmdList.add(() -> deviceTcpCMDService.moveMotorToPosition("X", left));
  221. cmdList.add(() -> deviceTcpCMDService.moveMotorToPosition("Y", top));
  222. // 是否加电 电压
  223. Object voltage = params.get("voltage");
  224. if (voltage instanceof Integer) {
  225. cmdList.add(() -> deviceTcpCMDService.turnOnHighVoltage( (Integer) voltage));
  226. }
  227. // 开启喷嘴阀
  228. cmdList.add(() -> deviceTcpCMDService.controlValve("Nozzle", true));
  229. // 推注射泵
  230. // TODO 这里不管
  231. // int matrixFlowVelocity = (int) params.get("matrixFlowVelocity");
  232. cmdList.add(deviceTcpCMDService::syringePumpStart);
  233. // 插入日志
  234. if(i == 0) {
  235. cmdList.add( () -> {
  236. OperationLog operationLog = new OperationLog();
  237. operationLog.setStatus(0);
  238. operationLog.setMatrixId((Long) params.get("matrixCraftId"));
  239. operationLog.setMatrixInfo(JSON.toJSONString(params));
  240. operationLogService.add(operationLog);
  241. return true;
  242. });
  243. cmdList.add(() -> {
  244. sysSettingsService.updateWorkStatus("spraying");
  245. return true;
  246. });
  247. }
  248. // 执行轨迹
  249. for (PathGenerator.Points point : horizontalPath) {
  250. double nextX = (int) point.getX();
  251. double nextY = (int) point.getY();
  252. log.info("当前喷针位置x:{}, y:{}", nextX, nextY );
  253. cmdList.add(() -> deviceTcpCMDService.moveMotorToPosition("X", nextX));
  254. cmdList.add(() -> deviceTcpCMDService.moveMotorToPosition("Y", nextY));
  255. }
  256. // 停止喷涂
  257. cmdList.add(deviceTcpCMDService::syringePumpStop);
  258. // 关闭喷嘴阀
  259. cmdList.add(() -> deviceTcpCMDService.controlValve("Nozzle", true));
  260. }
  261. // 回到原点
  262. cmdList.add(() -> deviceTcpCMDService.motorMoveToHome("X"));
  263. cmdList.add(() -> deviceTcpCMDService.motorMoveToHome("Y"));
  264. cmdList.add(() -> deviceTcpCMDService.motorMoveToHome("Z"));
  265. // 结束日志
  266. cmdList.add( () -> {
  267. OperationLog operationLog = operationLogService.getIng();
  268. operationLog.setStatus(1);
  269. operationLogService.updateById(operationLog);
  270. return true;
  271. });
  272. cmdList.add(() -> {
  273. sysSettingsService.updateWorkStatus("idle");
  274. return true;
  275. });
  276. initExecutorThread(cmdList, form);
  277. return "ok";
  278. }
  279. // 结束喷涂
  280. public boolean stopWork(CMDForm form) {
  281. List<Supplier<Boolean>> cmdList = new ArrayList<>();
  282. // 停止喷涂
  283. cmdList.add(deviceTcpCMDService::turnOffSyringePump);
  284. // 关闭喷嘴阀
  285. cmdList.add(() -> deviceTcpCMDService.controlValve("Nozzle", true));
  286. // 回到原点
  287. cmdList.add(() -> deviceTcpCMDService.motorMoveToHome("X"));
  288. cmdList.add(() -> deviceTcpCMDService.motorMoveToHome("Z"));
  289. // 结束日志
  290. cmdList.add( () -> {
  291. OperationLog operationLog = operationLogService.getIng();
  292. operationLog.setStatus(1);
  293. operationLogService.updateById(operationLog);
  294. return true;
  295. });
  296. cmdList.add(() -> {
  297. sysSettingsService.updateWorkStatus("idle");
  298. return true;
  299. });
  300. initExecutorThread(cmdList, form);
  301. return true;
  302. }
  303. // 测试轴转动
  304. public boolean rotate(CMDForm form) {
  305. Map<String, Object> params = form.getParams();
  306. List<Supplier<Boolean>> cmdList = new ArrayList<>();
  307. String axis = (String) params.get("axis");
  308. double rotationSpeed = Optional.ofNullable(params.get("rotationSpeed"))
  309. .filter(Number.class::isInstance)
  310. .map(Number.class::cast)
  311. .map(Number::doubleValue)
  312. .orElse(0.0);
  313. int time = (Integer) params.get("time");
  314. cmdList.add(() -> deviceTcpCMDService.rotateMotor(axis, rotationSpeed, time));
  315. initExecutorThread(cmdList, form);
  316. return true;
  317. }
  318. // 轴停止转动
  319. public boolean stopMotor(CMDForm form) {
  320. Map<String, Object> params = form.getParams();
  321. List<Supplier<Boolean>> cmdList = new ArrayList<>();
  322. String axis = (String) params.get("axis");
  323. cmdList.add(() -> deviceTcpCMDService.stopMotor(axis));
  324. initExecutorThread(cmdList, form);
  325. return true;
  326. }
  327. // 开始清洗
  328. public boolean startWash(CMDForm form) {
  329. List<Supplier<Boolean>> cmdList = new ArrayList<>();
  330. cmdList.add(deviceTcpCMDService::switchThreeWayValveToSubstrate);
  331. cmdList.add(() -> deviceTcpCMDService.controlValve("Cleaning", true));
  332. cmdList.add(() -> {
  333. sysSettingsService.updateWorkStatus("washing");
  334. return true;
  335. });
  336. initExecutorThread(cmdList, form);
  337. return true;
  338. }
  339. // 结束清洗
  340. public boolean stopWash(CMDForm form) {
  341. List<Supplier<Boolean>> cmdList = new ArrayList<>();
  342. cmdList.add(() -> deviceTcpCMDService.controlValve("Cleaning", false));
  343. cmdList.add(() -> {
  344. sysSettingsService.updateWorkStatus("idle");
  345. return true;
  346. });
  347. initExecutorThread(cmdList, form);
  348. return true;
  349. }
  350. // 照明灯板控制方法
  351. /**
  352. * 以指定亮度开启照明灯板
  353. * brightness 亮度值范围 0 - 100
  354. * @return 操作是否成功
  355. */
  356. public boolean turnOnLightPanel(CMDForm form) {
  357. Map<String, Object> params = form.getParams();
  358. List<Supplier<Boolean>> cmdList = new ArrayList<>();
  359. int brightness = (int) params.get("brightness");
  360. cmdList.add(() -> deviceTcpCMDService.turnOnLightPanel(brightness));
  361. initExecutorThread(cmdList, form);
  362. return true;
  363. }
  364. /**
  365. * 关闭照明灯板
  366. * @return 操作是否成功
  367. */
  368. public boolean turnOffLightPanel(CMDForm form) {
  369. List<Supplier<Boolean>> cmdList = new ArrayList<>();
  370. cmdList.add(deviceTcpCMDService::turnOffLightPanel);
  371. initExecutorThread(cmdList, form);
  372. return true;
  373. }
  374. // 开始预充
  375. public boolean startPrefill(CMDForm form) {
  376. List<Supplier<Boolean>> cmdList = new ArrayList<>();
  377. cmdList.add(deviceTcpCMDService::switchThreeWayValveToSpray);
  378. cmdList.add(() -> deviceTcpCMDService.controlValve("Nozzle", true));
  379. cmdList.add(() -> {
  380. sysSettingsService.updateWorkStatus("prefilling");
  381. return true;
  382. });
  383. initExecutorThread(cmdList, form);
  384. return true;
  385. }
  386. // 停止预充
  387. public boolean stopPrefill(CMDForm form) {
  388. List<Supplier<Boolean>> cmdList = new ArrayList<>();
  389. cmdList.add(() -> deviceTcpCMDService.controlValve("Nozzle", false));
  390. cmdList.add(() -> {
  391. sysSettingsService.updateWorkStatus("idle");
  392. return true;
  393. });
  394. initExecutorThread(cmdList, form);
  395. return true;
  396. }
  397. // 电机回到原点
  398. public boolean motorMoveToHome(CMDForm form) {
  399. List<Supplier<Boolean>> cmdList = new ArrayList<>();
  400. Map<String, Object> params = form.getParams();
  401. String axis = (String) params.get("axis");
  402. cmdList.add(() -> deviceTcpCMDService.motorMoveToHome(axis));
  403. initExecutorThread(cmdList, form);
  404. return true;
  405. }
  406. // 开始除湿
  407. public boolean startDehumidify(CMDForm form) {
  408. List<Supplier<Boolean>> cmdList = new ArrayList<>();
  409. Map<String, Object> params = form.getParams();
  410. cmdList.add(() -> {
  411. sysSettingsService.updateWorkStatus("dehumidifying");
  412. return true;
  413. });
  414. double humidity = Optional.ofNullable(params.get("humidity"))
  415. .filter(Number.class::isInstance)
  416. .map(Number.class::cast)
  417. .map(Number::doubleValue)
  418. .orElse(0.0);
  419. cmdList.add(() -> deviceTcpCMDService.startDehumidify(humidity));
  420. cmdList.add(() -> {
  421. sysSettingsService.updateWorkStatus("idle");
  422. return true;
  423. });
  424. initExecutorThread(cmdList, form);
  425. return true;
  426. }
  427. // 设置电机速度
  428. public boolean setMotorSpeed(CMDForm form) {
  429. List<Supplier<Boolean>> cmdList = new ArrayList<>();
  430. Map<String, Object> params = form.getParams();
  431. String axis = (String) params.get("axis");
  432. double speed = Optional.ofNullable(params.get("speed"))
  433. .filter(Number.class::isInstance)
  434. .map(Number.class::cast)
  435. .map(Number::doubleValue)
  436. .orElse(0.0);
  437. cmdList.add(() -> deviceTcpCMDService.setMotorSpeed(axis, speed));
  438. initExecutorThread(cmdList, form);
  439. return true;
  440. }
  441. public boolean trayOut(CMDForm form) {
  442. List<Supplier<Boolean>> cmdList = new ArrayList<>();
  443. cmdList.add(() -> deviceTcpCMDService.moveMotorToPosition("Y", 150));
  444. initExecutorThread(cmdList, form);
  445. return true;
  446. }
  447. public boolean trayIn(CMDForm form) {
  448. List<Supplier<Boolean>> cmdList = new ArrayList<>();
  449. cmdList.add(() -> deviceTcpCMDService.moveMotorToPosition("Y", 0));
  450. initExecutorThread(cmdList, form);
  451. return true;
  452. }
  453. public void run(List<Supplier<Boolean>> cmdList, CMDForm form) {
  454. ExecutionResult executionResult = new ExecutionResult();
  455. executionResult.setCommandId(form.getCommandId());
  456. executionResult.setCommandName(form.getCommandName());
  457. // 执行所有命令
  458. for (Supplier<Boolean> command : cmdList) {
  459. boolean result = command.get();
  460. if (!result) {
  461. log.error("指令执行异常: {}", JSONUtil.toJsonStr(form));
  462. executionResult.setStatus(CMDResultCode.FAILURE.getCode());
  463. executionResult.setMessage(CMDResultCode.FAILURE.getMsg());
  464. webSocketService.pushMsg(WebSocketMessageType.CMD, executionResult);
  465. return;
  466. }
  467. }
  468. log.info("指令执行成功: {}", JSONUtil.toJsonStr(form));
  469. executionResult.setStatus(CMDResultCode.SUCCESS.getCode());
  470. executionResult.setMessage(CMDResultCode.SUCCESS.getMsg());
  471. webSocketService.pushMsg(WebSocketMessageType.CMD, executionResult);
  472. }
  473. }