src/main/java/com/zy/asrs/controller/ShuttleController.java
@@ -6,13 +6,9 @@ import com.core.common.Cools; import com.core.common.R; import com.core.exception.CoolException; import com.zy.asrs.domain.enums.CrnStatusType; import com.zy.asrs.domain.param.ShuttleOperatorParam; import com.zy.asrs.domain.param.SteModeParam; import com.zy.asrs.domain.param.SteOperatorParam; import com.zy.asrs.domain.vo.*; import com.zy.asrs.entity.BasShuttle; import com.zy.asrs.entity.BasSte; import com.zy.asrs.entity.WrkMast; import com.zy.asrs.service.BasShuttleService; import com.zy.asrs.service.WrkMastService; @@ -21,16 +17,12 @@ import com.zy.core.cache.SlaveConnection; import com.zy.core.enums.*; import com.zy.core.model.ShuttleSlave; import com.zy.core.model.SteSlave; import com.zy.core.model.Task; import com.zy.core.model.command.ShuttleAssignCommand; import com.zy.core.model.command.ShuttleCommand; import com.zy.core.model.command.SteCommand; import com.zy.core.model.protocol.ShuttleProtocol; import com.zy.core.model.protocol.SteProtocol; import com.zy.core.properties.SlaveProperties; import com.zy.core.properties.SystemProperties; import com.zy.core.thread.ShuttleThread; import com.zy.core.thread.SteThread; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -38,6 +30,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Random; /** * 四向穿梭车接口 @@ -77,9 +70,6 @@ if (!Cools.isEmpty(shuttleProtocol.getBusyStatus())) { vo.setStatus(shuttleProtocol.getBusyStatusType().desc); // 状态 } vo.setRow(shuttleProtocol.getRow()); vo.setBay(shuttleProtocol.getBay()); vo.setLev(shuttleProtocol.getLev()); vo.setBatteryPower(shuttleProtocol.getBatteryPower() + "%"); vo.setSpeed(shuttleProtocol.getCurrentMoveServoSpeed()); if (!Cools.isEmpty(shuttleProtocol.getErrorCode())) { @@ -127,6 +117,12 @@ vo.setPakMk(shuttleProtocol.getPakMk().toString()); // 作业标记 } return R.ok().add(list); } @PostMapping("/latest/data/shuttle") @ManagerAuth(memo = "四向穿梭车实时数据") public R shuttleLatestData(){ return R.ok(); } @PostMapping("/output/shuttle") @@ -226,7 +222,7 @@ // } // } ShuttleCommand shuttleCommand = new ShuttleCommand(); shuttleCommand.setTaskNo(vo.getWorkNo()); shuttleCommand.setTaskNo(vo.getWorkNo().shortValue()); if (MessageQueue.offer(SlaveType.Shuttle, vo.getShuttleNo(), new Task(2, shuttleCommand))) { } else { throw new CoolException("命令下发失败"); @@ -265,23 +261,16 @@ if (shuttleProtocol == null) { throw new CoolException("四向穿梭车不在线"); } ShuttleTaskModeType shuttleTaskModeType = ShuttleTaskModeType.get(param.getShuttleTaskMode()); ShuttleCommand shuttleCommand = new ShuttleCommand(); shuttleCommand.setShuttleNo(shuttleSlave.getId()); // 四向穿梭车编号 // if (param.getShuttleTaskMode() == 16) { // steCommand.setComplete(true); // } else if (param.getSteTaskMode() == 99) { // steCommand.setControlMode((short) 1); // } else if (param.getSteTaskMode() == 100) { // steCommand.setControlMode((short) 0); // } else { // if (steTaskModeType == null) { // throw new CoolException("任务类型错误"); // } // steCommand.setTaskNo(param.getTaskNo()); // 工作号 // steCommand.setTaskMode(steTaskModeType); // } if (MessageQueue.offer(SlaveType.Shuttle, shuttleSlave.getId(), new Task(2, shuttleCommand))) { ShuttleAssignCommand command = new ShuttleAssignCommand(); command.setShuttleNo(shuttleSlave.getId().shortValue()); // 四向穿梭车编号 command.setTaskMode(shuttleTaskModeType.id.shortValue()); command.setSourceLocNo(param.getSourceLocNo()); command.setDistLocNo(param.getDistLocNo()); command.setTaskNo((short) 9999); if (MessageQueue.offer(SlaveType.Shuttle, shuttleSlave.getId(), new Task(3, command))) { return R.ok(); } else { throw new CoolException("命令下发失败"); src/main/java/com/zy/asrs/domain/param/ShuttleOperatorParam.java
@@ -14,13 +14,10 @@ // 任务号 private Integer taskNo = 0; // 目标库位-排 private Short row; // 启动库位 private String sourceLocNo; // 目标库位-列 private Short bay; // 目标库位-层 private Short lev; // 目标库位 private String distLocNo; } src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -635,7 +635,7 @@ //任务号 assignCommand.setTaskNo(wrkSts.getWrkNo().shortValue()); //入出库模式 assignCommand.setTaskMode(0); assignCommand.setTaskMode((short) 0); //源库位 assignCommand.setSourceLocNo(wrkSts.getSourceLocNo()); //目标库位 src/main/java/com/zy/common/utils/NavigateMapData.java
@@ -2,6 +2,7 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.zy.core.enums.ShuttleTaskModeType; import java.io.*; import java.util.ArrayList; @@ -12,15 +13,17 @@ public class NavigateMapData { public int[][] getData() { return getData("in"); return getData(ShuttleTaskModeType.PAK_IN.id); } public int[][] getData(String mapType) { public int[][] getData(Integer mapType) { try { String mapFilename = ""; if (mapType.equals("in")) { if (mapType == ShuttleTaskModeType.PAK_IN.id) { //入库地图 mapFilename = "mapIn.json"; }else { //出库地图 mapFilename = "mapOut.json"; } src/main/java/com/zy/common/utils/NavigateSolution.java
@@ -21,7 +21,7 @@ this.map = data; } public NavigateSolution(String mapType) { public NavigateSolution(Integer mapType) { //载入地图 NavigateMapData mapData = new NavigateMapData(); int[][] data = mapData.getData(mapType); src/main/java/com/zy/common/utils/NavigateUtils.java
@@ -1,6 +1,7 @@ package com.zy.common.utils; import com.zy.common.model.NavigateNode; import com.zy.core.enums.ShuttleTaskModeType; import java.util.*; @@ -9,7 +10,7 @@ */ public class NavigateUtils { public static List<NavigateNode> calc(String startPoint, String endPoint, String mapType) { public static List<NavigateNode> calc(String startPoint, String endPoint, Integer mapType) { //通过开始编号和结束编号获取对应的xy轴坐标 int[] startArr = NavigatePositionConvert.positionToXY(startPoint);//开始节点 int[] endArr = NavigatePositionConvert.positionToXY(endPoint);//结束节点 @@ -150,7 +151,7 @@ public static void main(String[] args) { //计算路径 List<NavigateNode> calc = calc("1000901", "0201801", "out"); List<NavigateNode> calc = calc("1000901", "0201801", ShuttleTaskModeType.PAK_OUT.id); System.out.println(calc); System.out.println("------------------------"); // List<NavigateNode> calc = calc("0501401", "0201801", "out"); src/main/java/com/zy/core/enums/ShuttleTaskModeType.java
@@ -3,6 +3,14 @@ public enum ShuttleTaskModeType { INIT(0, "初始"), // 初始 PAK_IN(1, "入库"), PAK_OUT(2, "出库"), PALLET_LIFT(3, "托盘顶升"), PALLET_DOWN(4, "托盘下降"), MOVE_LEFT(5, "左移"), MOVE_RIGHT(6, "右移"), MOVE_TOP(7, "前移"), MOVE_BOTTOM(8, "后移"), ; public Integer id; src/main/java/com/zy/core/model/command/ShuttleAssignCommand.java
@@ -17,10 +17,16 @@ /** * 作业类型 * 0: 入库 * 1: 出库 * 1: 入库 * 2: 出库 * 3: 托盘顶升 * 4: 托盘下降 * 5: 左移 * 6: 右移 * 7: 前移 * 8: 后移 */ private Integer taskMode = 0; private Short taskMode = 0; /** * 源库位 src/main/java/com/zy/core/model/command/ShuttleCommand.java
@@ -11,22 +11,17 @@ /** * 四向穿梭车号 */ private Integer shuttleNo = 0; private Short shuttleNo = 0; /** * 任务号 */ private Integer taskNo = 0; private Short taskNo = 0; /** * 作业类型 */ private Short taskMode = 0; /** * 任务确认 false:未确认 true:已确认 */ private Boolean complete = Boolean.FALSE; /** * 控制指令字 src/main/java/com/zy/core/model/protocol/ShuttleProtocol.java
@@ -32,21 +32,6 @@ private String locNo; /** * 排 */ private Short row; /** * 列 */ private Short bay; /** * 层 */ private Short lev; /** * 小车忙状态位 * 1: 忙 * 0: 空闲 src/main/java/com/zy/core/thread/ShuttleThread.java
@@ -66,10 +66,10 @@ case 1: readStatus(); break; // // 写入数据 // case 2: // write((ShuttleCommand) task.getData()); // break; // 写入数据 case 2: write((ShuttleCommand) task.getData()); break; //下发任务 case 3: assignWork((ShuttleAssignCommand) task.getData()); @@ -189,46 +189,77 @@ return false; } command.setShuttleNo(slave.getId()); command.setShuttleNo(slave.getId().shortValue()); // 开始任务 short[] array = new short[17]; //控制指令字 array[0] = command.getCommandWord(); //启始二维编号 array[1] = command.getStartCodeNum(); //中间二维编号 array[2] = command.getMiddleCodeNum(); //目标二维编号 array[3] = command.getDistCodeNum(); if (command.getStartCodeNum() != null) { //启始二维编号 array[1] = command.getStartCodeNum(); } //起点到目标点的距离长度,先将int转为byte数组,再将byte数组转成两个short,分别占用4和5空间 short[] startToDistDistances = CommonUtils.intToShorts(command.getStartToDistDistance()); array[4] = startToDistDistances[0]; array[5] = startToDistDistances[1]; if (command.getMiddleCodeNum() != null) { //中间二维编号 array[2] = command.getMiddleCodeNum(); } //中间点到目标点的距离长度,先将int转为byte数组,再将byte数组转成两个short,分别占用4和5空间 short[] middleToDistDistances = CommonUtils.intToShorts(command.getMiddleToDistDistance()); array[6] = middleToDistDistances[0]; array[7] = middleToDistDistances[1]; if (command.getDistCodeNum() != null) { //目标二维编号 array[3] = command.getDistCodeNum(); } //小车运行方向 array[8] = command.getRunDirection(); //托盘顶升 array[9] = command.getPalletLift(); if (command.getStartToDistDistance() != null) { //起点到目标点的距离长度,先将int转为byte数组,再将byte数组转成两个short,分别占用4和5空间 short[] startToDistDistances = CommonUtils.intToShorts(command.getStartToDistDistance()); array[4] = startToDistDistances[0]; array[5] = startToDistDistances[1]; } //小车强制移动距离,先将int转为byte数组,再将byte数组转成两个short,分别占用4和5空间 short[] forceMoveDistances = CommonUtils.intToShorts(command.getForceMoveDistance()); array[10] = forceMoveDistances[0]; array[11] = forceMoveDistances[1]; if (command.getMiddleToDistDistance() != null) { //中间点到目标点的距离长度,先将int转为byte数组,再将byte数组转成两个short,分别占用4和5空间 short[] middleToDistDistances = CommonUtils.intToShorts(command.getMiddleToDistDistance()); array[6] = middleToDistDistances[0]; array[7] = middleToDistDistances[1]; } //充电开关 array[12] = command.getChargeSwitch(); //小车IO控制 array[13] = command.getIOControl(); //小车运行速度 array[14] = command.getRunSpeed(); //小车雷达备用 array[15] = command.getRadarTmp(); if (command.getRunDirection() != null) { //小车运行方向 array[8] = command.getRunDirection(); } if (command.getPalletLift() != null) { //托盘顶升 array[9] = command.getPalletLift(); } if (command.getForceMoveDistance() != null) { //小车强制移动距离,先将int转为byte数组,再将byte数组转成两个short,分别占用4和5空间 short[] forceMoveDistances = CommonUtils.intToShorts(command.getForceMoveDistance()); array[10] = forceMoveDistances[0]; array[11] = forceMoveDistances[1]; } if (command.getChargeSwitch() != null) { //充电开关 array[12] = command.getChargeSwitch(); } if (command.getIOControl() != null) { //小车IO控制 array[13] = command.getIOControl(); } if (command.getRunSpeed() != null) { //小车运行速度 array[14] = command.getRunSpeed(); } if (command.getRadarTmp() != null) { //小车雷达备用 array[15] = command.getRadarTmp(); } //指令结束位 array[16] = command.getCommandEnd(); @@ -255,23 +286,50 @@ //分配任务 private void assignWork(ShuttleAssignCommand assignCommand) { //计算路径 List<NavigateNode> calc = NavigateUtils.calc(assignCommand.getSourceLocNo(), assignCommand.getDistLocNo(), "in"); //获取分段路径 ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(calc); //将此map存入redis中 HashMap<String, Object> map = new HashMap<>(); //命令执行步序 map.put("commandStep", 0); //路径数据 map.put("path", data); //工作号 map.put("wrk_no", assignCommand.getTaskNo()); //任务数据保存到redis redisUtil.set("wrk_no_" + assignCommand.getTaskNo(), JSON.toJSONString(map)); ShuttleCommand command = new ShuttleCommand(); switch (assignCommand.getTaskMode()) { case 1: case 2: //计算路径 List<NavigateNode> calc = NavigateUtils.calc(assignCommand.getSourceLocNo(), assignCommand.getDistLocNo(), assignCommand.getTaskMode().intValue()); if (calc != null) { //获取分段路径 ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(calc); //将此map存入redis中 HashMap<String, Object> map = new HashMap<>(); //命令执行步序 map.put("commandStep", 0); //路径数据 map.put("path", data); //工作号 map.put("wrk_no", assignCommand.getTaskNo()); //任务数据保存到redis redisUtil.set("wrk_no_" + assignCommand.getTaskNo(), JSON.toJSONString(map)); shuttleProtocol.setTaskNo(assignCommand.getTaskNo()); //执行下发任务 executeWork(assignCommand.getTaskNo()); //执行下发任务 executeWork(assignCommand.getTaskNo()); } break; case 3: case 4: command.setCommandWord((short) 2); command.setPalletLift(assignCommand.getTaskMode() == 3 ? (short)1 : (short)2); command.setCommandEnd((short) 1); write(command); break; case 5: case 6: case 7: case 8: command.setCommandWord((short) 3); command.setForceMoveDistance(1000); command.setRunDirection((short) (assignCommand.getTaskMode() - 4)); command.setCommandEnd((short) 1); write(command); break; } } //执行下发的指令 src/main/webapp/views/index.html
@@ -20,7 +20,7 @@ <ul class="cl-effect-4"> <li><a id="console" onclick="nav(this.id)" class="nav-select" href="#">主控图</a></li> <li><a id="pipeline" onclick="nav(this.id)" class="nav-unselect" href="#">输送设备</a></li> <li><a id="crn" onclick="nav(this.id)" class="nav-unselect" href="#">堆垛机</a></li> <!-- <li><a id="crn" onclick="nav(this.id)" class="nav-unselect" href="#">堆垛机</a></li>--> <!-- <li><a id="ste" onclick="nav(this.id)" class="nav-unselect" href="#">穿梭车</a></li>--> <li><a id="shuttle" onclick="nav(this.id)" class="nav-unselect" href="#">四向穿梭车</a></li> </ul> src/main/webapp/views/shuttle.html
@@ -95,49 +95,17 @@ <!-- 设备任务操作 --> <div class="task-operator"> <div style="display: flex;"> <div class="task-operator" style="height: auto;width: auto;"> <div class="task-operator" style="height: auto;width: 100%;"> <div class="operator-item" style="height: auto"> <span class="select-title">源站/源库位</span> <span class="select-title">源库位/目标库位</span> <div class="select-container" style="height: auto"> <div class="select-container-item"> <span>站</span> <label><input id="sourceStaNo" type="number" name="points" min="0" /></label> <span>源库位</span> <label><input id="sourceLocNo" type="text" name="sourceLocNo" /></label> </div> <div class="select-container-item"> <span>排</span> <label><input id="sourceRow" type="number" name="points" min="1" style="background-color: #a9eeff" value="1" /></label> </div> <div class="select-container-item"> <span>列</span> <label><input id="sourceBay" type="number" name="points" min="0" style="background-color: #a9eeff" value="0" /></label> </div> <div class="select-container-item"> <span>层</span> <label><input id="sourceLev" type="number" name="points" min="1" style="background-color: #a9eeff" value="1" /></label> </div> </div> </div> </div> <div class="task-operator" style="height: auto;width: auto;"> <div class="operator-item" style="height: auto"> <span class="select-title">源站/源库位</span> <div class="select-container" style="height: auto"> <div class="select-container-item"> <span>站</span> <label><input id="distStaNo" type="number" name="points" min="0" /></label> </div> <div class="select-container-item"> <span>排</span> <label><input id="distRow" type="number" name="points" min="1" style="background-color: #a9eeff" value="1" /></label> </div> <div class="select-container-item"> <span>列</span> <label><input id="distBay" type="number" name="points" min="0" style="background-color: #a9eeff" value="0" /></label> </div> <div class="select-container-item"> <span>层</span> <label><input id="distLev" type="number" name="points" min="1" style="background-color: #a9eeff" value="1" /></label> <span>目标库位</span> <label><input id="distLocNo" type="text" name="distLocNo" /></label> </div> </div> </div> @@ -147,14 +115,14 @@ <fieldset style="height: auto;padding-bottom: 20px;"> <legend>手动操作</legend> <div class="button-group"> <button class="item" onclick="shuttleOperator(4)">托盘顶升</button> <button class="item" onclick="shuttleOperator(4)">托盘放下</button> <button class="item" onclick="shuttleOperator(1)">入库</button> <button class="item" onclick="shuttleOperator(2)">出库</button> <button class="item" onclick="shuttleOperator(3)">托盘顶升</button> <button class="item" onclick="shuttleOperator(4)">托盘下降</button> <button class="item" onclick="shuttleOperator(5)">左移</button> <button class="item" onclick="shuttleOperator(6)">右移</button> <button class="item" onclick="shuttleOperator(7)">前移</button> <button class="item" onclick="shuttleOperator(8)">后移</button> <button class="item" onclick="shuttleOperator(9)">强制移动</button> <button class="item" onclick="shuttleOperator(16)">任务完成</button> </div> </fieldset> </div> @@ -696,7 +664,9 @@ function shuttleOperator(shuttleTaskMode) { http.post(baseUrl+"/shuttle/operator/shuttle", { shuttleNo: $('input[name="shuttleSelect"]:checked').val(), shuttleTaskMode: shuttleTaskMode shuttleTaskMode: shuttleTaskMode, sourceLocNo: $("#sourceLocNo").val(), distLocNo: $("#distLocNo").val() }, function (res) { layer.msg(res.msg, {icon: 1}); });