src/main/java/com/zy/asrs/controller/CrnController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/asrs/domain/vo/CrnMsgTableVo.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/asrs/domain/vo/CrnStateTableVo.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/asrs/utils/Utils.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/common/service/CommonService.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/core/model/protocol/StaProtocol.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/core/thread/CrnThread.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/core/thread/DevpThread.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/resources/application.yml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/resources/mapper/WrkMastMapper.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/webapp/views/crn.html | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/main/java/com/zy/asrs/controller/CrnController.java
@@ -113,6 +113,7 @@ vo.setLev(crnProtocol.getLevel()); // 层 vo.setXOrigin(crnProtocol.getBay()==1?"是":"否"); // 走行原点 vo.setYOrigin(crnProtocol.getLevel()==1?"是":"否"); // 升降原点 vo.setForkOffset(crnProtocol.getForkPosType().desc); // 货叉位置 vo.setXLocation(crnProtocol.getWalkPos() == 1?"是":"否"); // 走行定位 vo.setYLocation(crnProtocol.getLiftPosType().equals(CrnLiftPosType.NONE)?"否":"是"); // 升降定位 vo.setStop(crnProtocol.getCrnTemp1().stop?"是":"否"); // 急停 @@ -156,6 +157,13 @@ } else { vo.setStatus(crnProtocol.modeType.equals(CrnModeType.AUTO)? CrnStatusType.MACHINE_AUTO.getDesc(): CrnStatusType.MACHINE_UN_AUTO.getDesc()); // 模式状态 } vo.setXspeed(crnProtocol.getXSpeed()); // 走行速度(m/min) vo.setYspeed(crnProtocol.getYSpeed()); // 升降速度(m/min) vo.setZspeed(crnProtocol.getZSpeed()); // 叉牙速度(m/min) vo.setXdistance(crnProtocol.getXDistance()); // 走行距离(Km) vo.setYdistance(crnProtocol.getYDistance()); // 升降距离(Km) vo.setXduration(crnProtocol.getXDuration()); // 走行时长(H) vo.setYduration(crnProtocol.getYDuration()); // 升降时长(H) list.add(vo); } @@ -395,15 +403,15 @@ throw new CoolException("堆垛机不在线"); } // 空闲判断 if (crnProtocol.getStatusType().equals(com.zy.core.enums.CrnStatusType.IDLE) && crnProtocol.getTaskNo() == 0) { // if (crnProtocol.getStatusType().equals(com.zy.core.enums.CrnStatusType.IDLE) && crnProtocol.getTaskNo() == 0) { if (MessageQueue.offer(SlaveType.Crn, crn.getId(), new Task(2, command))) { return true; } else { throw new CoolException("命令下发失败"); } } else { throw new CoolException("堆垛机不在空闲状态"); } // } else { // throw new CoolException("堆垛机不在空闲状态"); // } } } return false; src/main/java/com/zy/asrs/domain/vo/CrnMsgTableVo.java
@@ -1,6 +1,9 @@ package com.zy.asrs.domain.vo; import com.zy.asrs.utils.Utils; import lombok.Data; import java.text.DecimalFormat; /** * Created by vincent on 2020-06-02 @@ -38,4 +41,52 @@ // 命令 private String command = ""; // 走行速度(m/min) private Float xspeed; // 升降速度(m/min) private Float yspeed; // 叉牙速度(m/min) private Float zspeed; // 走行距离(Km) private Float xdistance; // 升降距离(Km) private Float ydistance; // 走行时长(H) private Float xduration; // 升降时长(H) private Float yduration; public void setXspeed(Float xspeed) { this.xspeed = Utils.scale(xspeed); } public void setYspeed(Float yspeed) { this.yspeed = Utils.scale(yspeed); } public void setZspeed(Float zspeed) { this.zspeed = Utils.scale(zspeed); } public void setXdistance(Float xdistance) { this.xdistance = Utils.scale(xdistance); } public void setYdistance(Float ydistance) { this.ydistance = Utils.scale(ydistance); } public void setXduration(Float xduration) { this.xduration = Utils.scale(xduration); } public void setYduration(Float yduration) { this.yduration = Utils.scale(yduration); } } src/main/java/com/zy/asrs/domain/vo/CrnStateTableVo.java
@@ -62,6 +62,4 @@ // 异常码 private String warnCode; } src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -543,6 +543,8 @@ // 出库 + 拣料/盘点/并板出库中:12.吊车出库中 ==> 14.出库完成 } else if (wrkMast.getWrkSts() == 12) { wrkMast.setWrkSts(14L); } else { continue; } Date now = new Date(); wrkMast.setCrnEndTime(now); @@ -550,9 +552,11 @@ // 修改成功后复位堆垛机 if (wrkMastMapper.updateById(wrkMast) > 0) { // 命令下发区 ------------------------------------------------------------------------- // 堆垛机复位 if (!MessageQueue.offer(SlaveType.Crn, crn.getId(), new Task(3, new CrnCommand()))) { log.error("堆垛机复位命令下发失败,工作号={}", wrkMast.getWrkNo()); if (crnProtocol.getStatusType().equals(CrnStatusType.WAITING)) { // 堆垛机复位 if (!MessageQueue.offer(SlaveType.Crn, crn.getId(), new Task(3, new CrnCommand()))) { log.error("堆垛机复位命令下发失败,工作号={}", wrkMast.getWrkNo()); } } } @@ -587,7 +591,7 @@ DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId()); StaProtocol staProtocol = devpThread.getStation().get(emptyInSta.getStaNo()); // 站点条件判断 if (staProtocol.isAutoing() && staProtocol.isLoading() && !staProtocol.isInreq1() if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.isInEnable() && staProtocol.isEmptyMk() && staProtocol.getWorkNo() == 0 && staProtocol.isPakMk()) { // 工作号 int workNo = commonService.getWorkNo(0); @@ -637,6 +641,7 @@ throw new CoolException("更新plc站点信息失败"); } staProtocol.setPakMk(false); } src/main/java/com/zy/asrs/utils/Utils.java
New file @@ -0,0 +1,22 @@ package com.zy.asrs.utils; import com.core.common.Arith; import java.math.BigDecimal; import java.text.DecimalFormat; /** * Created by vincent on 2020/8/27 */ public class Utils { private static final DecimalFormat fmt = new DecimalFormat("##0.00"); public static float scale(Float f){ if (f == null || f == 0f || Float.isNaN(f)) { return 0f; } return (float) Arith.multiplys(2, f, 1); } } src/main/java/com/zy/common/service/CommonService.java
@@ -169,7 +169,7 @@ } BasDevp staNo = basDevpService.selectById(staDesc.getCrnStn()); int inQty = staNo.getInQty()==null?0:staNo.getInQty(); if (staNo.getInEnable().equals("Y") && staNo.getAutoing().equals("Y") && inQty<2) { if (staNo.getAutoing().equals("Y") && inQty<2) { // 查找库位 if (locMast == null) { locMast = locMastService.queryFreeLocMast(curRow); src/main/java/com/zy/core/model/protocol/StaProtocol.java
@@ -41,7 +41,7 @@ private boolean inreq1; // 锁定标记 private boolean pakMk; private boolean pakMk = true; public BasDevp toSqlModel(){ BasDevp basDevp = new BasDevp(); src/main/java/com/zy/core/thread/CrnThread.java
@@ -12,6 +12,7 @@ import com.zy.core.ThreadHandler; import com.zy.core.cache.MessageQueue; import com.zy.core.cache.OutputQueue; import com.zy.core.enums.CrnStatusType; import com.zy.core.enums.CrnTaskModeType; import com.zy.core.enums.SlaveType; import com.zy.core.model.CrnSlave; @@ -35,6 +36,7 @@ private MelsecMcNet melsecMcNet; private CrnSlave slave; private CrnProtocol crnProtocol; private boolean resetFlag = false; public CrnThread(CrnSlave slave) { this.slave = slave; @@ -178,13 +180,21 @@ OutputQueue.CRN.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId())); // if (crnProtocol.getStatusType().equals(CrnStatusType.WAITING)) { // if (resetFlag) { // if (melsecMcNet.Write("D2218", 1).IsSuccess) { // resetFlag = false; // } // } // } // 根据实时信息更新数据库 BasCrnpService basCrnpService = SpringUtils.getBean(BasCrnpService.class); BasCrnp basCrnp = new BasCrnp(); basCrnp.setCrnNo(slave.getId()); if (!basCrnpService.updateById(crnProtocol.toSqlModel(basCrnp))){ log.error("堆垛机plc数据库更新失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort()); } // BasCrnpService basCrnpService = SpringUtils.getBean(BasCrnpService.class); // BasCrnp basCrnp = new BasCrnp(); // basCrnp.setCrnNo(slave.getId()); // if (!basCrnpService.updateById(crnProtocol.toSqlModel(basCrnp))){ // log.error("堆垛机plc数据库更新失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort()); // } } @@ -199,15 +209,33 @@ command.setCrnNo(slave.getId()); /* 方法 1 */ do { if (!melsecMcNet.Write("D2218", command.getAckFinish()).IsSuccess) { break; } if (!melsecMcNet.Write("D2218", command.getAckFinish()).IsSuccess) { break; } if (!melsecMcNet.Write("D2216", command.getTaskMode()).IsSuccess) { break; } if (!melsecMcNet.Write("D2214", command.getSourcePosX()).IsSuccess) { break; } if (!melsecMcNet.Write("D2212", command.getSourcePosY()).IsSuccess) { break; } if (!melsecMcNet.Write("D2210", command.getSourcePosZ()).IsSuccess) { break; } if (!melsecMcNet.Write("D2208", command.getDestinationPosX()).IsSuccess) { break; } if (!melsecMcNet.Write("D2204", command.getDestinationPosY()).IsSuccess) { break; } if (!melsecMcNet.Write("D2202", command.getDestinationPosZ()).IsSuccess) { break; } if (command.getDestinationPosZ() != null) { if (!melsecMcNet.Write("D2202", command.getDestinationPosZ()).IsSuccess) { break; } } if (command.getDestinationPosY() != null) { if (!melsecMcNet.Write("D2204", command.getDestinationPosY()).IsSuccess) { break; } } if (command.getDestinationPosX() != null) { if (!melsecMcNet.Write("D2208", command.getDestinationPosX()).IsSuccess) { break; } } if (command.getSourcePosZ() != null) { if (!melsecMcNet.Write("D2210", command.getSourcePosZ()).IsSuccess) { break; } } if (command.getSourcePosY() != null) { if (!melsecMcNet.Write("D2212", command.getSourcePosY()).IsSuccess) { break; } } if (command.getDestinationPosX() != null) { if (!melsecMcNet.Write("D2214", command.getSourcePosX()).IsSuccess) { break; } } if (command.getTaskMode() != null) { if (!melsecMcNet.Write("D2216", command.getTaskMode()).IsSuccess) { break; } } if (command.getTaskNo() != null) { if (!melsecMcNet.Write("D2217", command.getTaskNo()).IsSuccess) { break; } } if (command.getAckFinish() != null) { if (!melsecMcNet.Write("D2218", command.getAckFinish()).IsSuccess) { break; } } System.out.println(MessageFormat.format("【{0}】[id:{1}] >>>>> {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command))); OutputQueue.CRN.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command))); @@ -262,7 +290,6 @@ crnThread.connect(); crnThread.readStatus(); System.out.println(JSON.toJSONString(crnThread.crnProtocol)); Thread.sleep(3000L); // 1.入库 源和目标都发 // CrnCommand command = new CrnCommand(); @@ -335,19 +362,19 @@ // command.setDestinationPosZ((short) 0); // 目标库位层 // crnThread.write(command); // // 7.坐标移行 目标发 pass // CrnCommand command = new CrnCommand(); // command.setCrnNo(1); // 堆垛机编号 // command.setTaskNo((short) 0); // 工作号 // command.setAckFinish((short) 0); // 任务完成确认位 // command.setTaskMode(CrnTaskModeType.OFFSET_MOVE); // 任务模式 // command.setSourcePosX((short) 0); // 源库位排 // command.setSourcePosY((short) 0); // 源库位列 // command.setSourcePosZ((short) 0); // 源库位层 // command.setDestinationPosX((short) 2); // 目标库位排 // command.setDestinationPosY((short) 1); // 目标库位列 // command.setDestinationPosZ((short) 1); // 目标库位层 // crnThread.write(command); // 7.坐标移行 目标发 pass CrnCommand command = new CrnCommand(); command.setCrnNo(1); // 堆垛机编号 command.setTaskNo((short) 0); // 工作号 command.setAckFinish((short) 0); // 任务完成确认位 command.setTaskMode(CrnTaskModeType.OFFSET_MOVE); // 任务模式 command.setSourcePosX((short) 0); // 源库位排 command.setSourcePosY((short) 0); // 源库位列 command.setSourcePosZ((short) 0); // 源库位层 command.setDestinationPosX((short) 1); // 目标库位排 command.setDestinationPosY((short) 3); // 目标库位列 command.setDestinationPosZ((short) 3); // 目标库位层 crnThread.write(command); // 只有出现指定异常才进行复位 // if (crnThread.crnProtocol.getCrnError2().leftTakeNoneErr src/main/java/com/zy/core/thread/DevpThread.java
@@ -128,6 +128,10 @@ staProtocol.setInEnable(result1.Content[(i-1)*8+2]); // 可入 staProtocol.setOutEnable(result1.Content[(i-1)*8+3]);// 可出 staProtocol.setEmptyMk(result1.Content[(i-1)*8+4]); // 空板信号 if (!staProtocol.isPakMk() && !staProtocol.isLoading()) { staProtocol.setPakMk(true); } } } if (result.IsSuccess && result1.IsSuccess) { @@ -173,6 +177,9 @@ // status[4] = staProtocol.isEmptyMk(); // OperateResult write2 = siemensS7Net.Write("DB100." + ((staProtocol.getSiteId() - 1) + 40), status); // 状态 if (!write.IsSuccess || !write1.IsSuccess) { if (staProtocol.getWorkNo() == 0 && staProtocol.getStaNo() ==0) { staProtocol.setPakMk(true); } OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线站点数据失败。输送线plc编号={1},站点数据={2}", slave.getId(), JSON.toJSON(staProtocol))); log.error("写入输送线站点数据失败。输送线plc编号={},站点数据={}", slave.getId(), JSON.toJSON(staProtocol)); } else { src/main/resources/application.yml
@@ -22,8 +22,8 @@ mybatis-plus: mapper-locations: classpath:mapper/*.xml global-config: field-strategy: 0 # global-config: # field-strategy: 0 logging: path: /stock/out/logs @@ -36,7 +36,7 @@ # 下位机配置 wcs-slave: # 堆垛机 # 堆垛机1 crn[0]: id: 1 ip: 192.168.3.39 @@ -48,17 +48,40 @@ # 堆垛机入库站点 crnInStn[0]: devpPlcId: ${wcs-slave.devp[0].id} staNo: 5 staNo: 4 row: 2 bay: 1 lev: 1 # 堆垛机出库站点 crnOutStn[0]: devpPlcId: ${wcs-slave.devp[0].id} staNo: 6 staNo: 2 row: 1 bay: 1 lev: 1 # 堆垛机2 #crn[1]: id: 1 ip: 192.168.3.40 port: 5015 rack: 0 slot: 0 # 偏移量,当堆垛机站点列号=1时,偏移量=0 offset: 1 # 堆垛机入库站点 crnInStn[0]: devpPlcId: ${wcs-slave.devp[0].id} staNo: 8 row: 2 bay: 1 lev: 1 # 堆垛机出库站点 crnOutStn[0]: devpPlcId: ${wcs-slave.devp[0].id} staNo: 6 row: 1 bay: 1 lev: 1 # 输送线 devp[0]: id: 1 @@ -66,16 +89,26 @@ port: 6000 rack: 0 slot: 1 # 入库口 # 入库口1 inSta[0]: staNo: 2 staNo: 3 barcode: ${wcs-slave.barcode[0].id} # 空板入库口 # 入库口2 inSta[1]: staNo: 7 barcode: ${wcs-slave.barcode[0].id} # 空板入库口1 emptyInSta[0]: staNo: 2 # 出库口 staNo: 3 # 空板入库口2 emptyInSta[1]: staNo: 7 # 出库口1 outSta[0]: staNo: 6 staNo: 1 # 出库口2 outSta[1]: staNo: 5 # 拣料入库口 pickSta[0]: staNo: 2 src/main/resources/mapper/WrkMastMapper.xml
@@ -84,7 +84,7 @@ </select> <select id="selectPakInStep3" resultMap="BaseResultMap"> select top 1 from dbo.asr_wrk_mast where wrk_no=#{workNo} select top 1 * from dbo.asr_wrk_mast where wrk_no=#{workNo} </select> <select id="selectPickStep" resultMap="BaseResultMap"> src/main/webapp/views/crn.html
@@ -47,6 +47,7 @@ <th>层</th> <th>走行原点</th> <th>升降原点</th> <th>货叉位置</th> <th>走行定位</th> <th>升降定位</th> <th>急停</th> @@ -71,6 +72,13 @@ <th>源库位</th> <th>目标库位</th> <th>异常</th> <th>走行速度(m/min)</th> <th>升降速度(m/min)</th> <th>叉牙速度(m/min)</th> <th>走行距离(Km)</th> <th>升降距离(Km)</th> <th>走行时长(H)</th> <th>升降时长(H)</th> </tr> </thead> <tbody> @@ -257,10 +265,11 @@ setVal(tr.children("td").eq(6), table[i-1].lev); setVal(tr.children("td").eq(7), table[i-1].xorigin); setVal(tr.children("td").eq(8), table[i-1].yorigin); setVal(tr.children("td").eq(9), table[i-1].xlocation); setVal(tr.children("td").eq(10), table[i-1].ylocation); setVal(tr.children("td").eq(11), table[i-1].stop); setVal(tr.children("td").eq(12), table[i-1].warnCode); setVal(tr.children("td").eq(9), table[i-1].forkOffset); setVal(tr.children("td").eq(10), table[i-1].xlocation); setVal(tr.children("td").eq(11), table[i-1].ylocation); setVal(tr.children("td").eq(12), table[i-1].stop); setVal(tr.children("td").eq(13), table[i-1].warnCode); } } else if (res.code === 403){ window.location.href = baseUrl+"/login"; @@ -294,7 +303,14 @@ setVal(tr.children("td").eq(4), table[i-1].staNo); setVal(tr.children("td").eq(5), table[i-1].sourceLocNo); setVal(tr.children("td").eq(6), table[i-1].locNo); setVal(tr.children("td").eq(6), table[i-1].error); setVal(tr.children("td").eq(7), table[i-1].error); setVal(tr.children("td").eq(8), table[i-1].xspeed); setVal(tr.children("td").eq(9), table[i-1].yspeed); setVal(tr.children("td").eq(10), table[i-1].zspeed); setVal(tr.children("td").eq(11), table[i-1].xdistance); setVal(tr.children("td").eq(12), table[i-1].ydistance); setVal(tr.children("td").eq(13), table[i-1].xduration); setVal(tr.children("td").eq(14), table[i-1].yduration); } } else if (res.code === 403){ window.location.href = baseUrl+"/login"; @@ -463,6 +479,7 @@ " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " </tr>\n"; } $('#crn-state-table tbody').after(html); @@ -492,6 +509,13 @@ " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " </tr>\n"; } $('#crn-msg-table tbody').after(html);