src/main/java/com/zy/asrs/controller/ConsoleController.java
@@ -100,7 +100,6 @@ vo.setSiteId(String.valueOf(entry.getKey())); // 站点编号 vo.setWorkNo(staProtocol.getWorkNo()); // 工作号 vo.setSiteStatus(SiteStatusType.process(staProtocol)); // 状态 vo.setNearbySta(String.valueOf(staProtocol.getPosition())); // 台车位置 vos.add(vo); } return R.ok().add(vos); src/main/java/com/zy/asrs/mapper/LocMastMapper.java
@@ -13,7 +13,7 @@ @Repository public interface LocMastMapper extends BaseMapper<LocMast> { LocMast queryFreeLocMast(@Param("row") Integer row); LocMast queryFreeLocMast(@Param("row") Integer row, @Param("locType1") Short locType1); @Select("select loc_no from asr_loc_mast where 1=1 and loc_sts = 'O' and crn_no = #{crnNo}") List<String> queryGroupEmptyStock(Integer crnNo); src/main/java/com/zy/asrs/service/LocMastService.java
@@ -10,7 +10,7 @@ /** * 检索可用库位 */ LocMast queryFreeLocMast(Integer row); LocMast queryFreeLocMast(Integer row, Short locType1); /** * 获取同组货架的空库位 src/main/java/com/zy/asrs/service/impl/LocMastServiceImpl.java
@@ -13,8 +13,8 @@ public class LocMastServiceImpl extends ServiceImpl<LocMastMapper, LocMast> implements LocMastService { @Override public LocMast queryFreeLocMast(Integer row) { return this.baseMapper.queryFreeLocMast(row); public LocMast queryFreeLocMast(Integer row, Short locType1) { return this.baseMapper.queryFreeLocMast(row, locType1); } @Override src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -12,6 +12,7 @@ import com.zy.asrs.mapper.WrkMastMapper; import com.zy.asrs.service.*; import com.zy.asrs.utils.VersionUtils; import com.zy.common.model.LocTypeDto; import com.zy.common.model.MatDto; import com.zy.common.model.StartupDto; import com.zy.common.service.CommonService; @@ -129,8 +130,9 @@ try { // 检索库位 LocTypeDto locTypeDto = new LocTypeDto(staProtocol); List<String> matNos = waitPakins.stream().map(WaitPakin::getMatnr).distinct().collect(Collectors.toList()); StartupDto startupDto = commonService.getLocNo(1, 1, inSta.getStaNo(), matNos); StartupDto startupDto = commonService.getLocNo(1, 1, inSta.getStaNo(), matNos, locTypeDto); // 工作号 int workNo = startupDto.getWorkNo(); // 插入工作明细档 @@ -848,7 +850,8 @@ if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.isInEnable() && staProtocol.isEmptyMk() && staProtocol.getWorkNo() == 0 && staProtocol.isPakMk()) { // 检索库位 StartupDto startupDto = commonService.getLocNo(1, 10, emptyInSta.getStaNo(), null); LocTypeDto locTypeDto = new LocTypeDto(staProtocol); StartupDto startupDto = commonService.getLocNo(1, 10, emptyInSta.getStaNo(), null, locTypeDto); // 工作号 int workNo = startupDto.getWorkNo(); src/main/java/com/zy/asrs/utils/Utils.java
@@ -1,9 +1,12 @@ package com.zy.asrs.utils; import com.core.common.Arith; import com.core.common.Cools; import com.zy.core.properties.SlaveProperties; import java.math.BigDecimal; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; /** * Created by vincent on 2020/8/27 @@ -33,5 +36,140 @@ } } /** * 判断是否为深库位 */ public static boolean isDeepLoc(SlaveProperties slaveProperties, String locNo){ if (slaveProperties.isDoubleDeep()) { int row = getRow(locNo); return slaveProperties.getDoubleLocs().contains(row); } else { return false; } } /** * 判断是否为深库位 */ public static boolean isDeepLoc(SlaveProperties slaveProperties, Integer row){ if (slaveProperties.isDoubleDeep()) { return slaveProperties.getDoubleLocs().contains(row); } else { return false; } } /** * 判断是否为浅库位 */ public static boolean isShallowLoc(SlaveProperties slaveProperties, String locNo){ if (slaveProperties.isDoubleDeep()) { int row = getRow(locNo); return !slaveProperties.getDoubleLocs().contains(row); } else { return false; } } /** * 判断是否为浅库位 */ public static boolean isShallowLoc(SlaveProperties slaveProperties, Integer row){ if (slaveProperties.isDoubleDeep()) { return !slaveProperties.getDoubleLocs().contains(row); } else { return false; } } /** * 获取 深库位对应的浅库位号 */ public static String getShallowLoc(SlaveProperties slaveProperties, String deepLoc) { int row = getRow(deepLoc); int remainder = (int) Arith.remainder(row, slaveProperties.getGroupCount()); int shallowRow = remainder == 1 ? (row + 1) : (row - 1); return zerofill(String.valueOf(shallowRow), 2) + deepLoc.substring(2); } /** * 获取 深库位排对应的浅库位排 */ public static Integer getShallowRow(SlaveProperties slaveProperties, Integer deepRow) { int remainder = (int) Arith.remainder(deepRow, slaveProperties.getGroupCount()); return remainder == 1 ? (deepRow + 1) : (deepRow - 1); } /** * 获取 浅库位对应的深库位号 */ public static String getDeepLoc(SlaveProperties slaveProperties, String shallowLoc) { int row = getRow(shallowLoc); int remainder = (int) Arith.remainder(row, slaveProperties.getGroupCount()); int targetRow; if (remainder == 2) { targetRow = row - 1; } else if (remainder == 3) { targetRow = row + 1; } else { throw new RuntimeException(shallowLoc + "不是浅库位,系统繁忙"); } return zerofill(String.valueOf(targetRow), 2) + shallowLoc.substring(2); } /** * 获取 浅库位排对应的深库位排 */ public static Integer getDeepRow(SlaveProperties slaveProperties, Integer shallowRow) { int remainder = (int) Arith.remainder(shallowRow, slaveProperties.getGroupCount()); int targetRow; if (remainder == 2) { targetRow = shallowRow - 1; } else if (remainder == 3) { targetRow = shallowRow + 1; } else { throw new RuntimeException(shallowRow + "不是浅库位排,系统繁忙"); } return targetRow; } /** * 通过库位号获取 排 */ public static int getRow(String locNo) { if (!Cools.isEmpty(locNo)) { return Integer.parseInt(locNo.substring(0, 2)); } throw new RuntimeException("库位解析异常"); } /** * 当检索到双深库位的浅库位时,如果深库位无货,则放入对应的深库位 */ public static void toDeepIfEmptyByShallow(String shallowLoc) { int row = getRow(shallowLoc); int remainder = (int) Arith.remainder(row, 4); int targetRow = 0; if (remainder == 2) { targetRow = row - 1; } else if (remainder == 3) { targetRow = row + 1; } else { throw new RuntimeException(shallowLoc + "不是浅库位,系统繁忙"); } String targetLoc = zerofill(String.valueOf(targetRow), 2) + shallowLoc.substring(2); } public static void main(String[] args) { SlaveProperties slaveProperties = new SlaveProperties(); slaveProperties.setDoubleDeep(true); List<Integer> list = new ArrayList<>(); list.add(1);list.add(4);list.add(5);list.add(8);list.add(9);list.add(12); slaveProperties.setDoubleLocs(list); slaveProperties.setGroupCount(4); Integer deepRow = getDeepRow(slaveProperties, 6); System.out.println(deepRow); } } src/main/java/com/zy/common/model/LocTypeDto.java
New file @@ -0,0 +1,52 @@ package com.zy.common.model; import com.core.exception.CoolException; import com.zy.core.model.protocol.StaProtocol; import lombok.Data; /** * Created by vincent on 2020/10/19 */ @Data public class LocTypeDto { // 高低类型{0:未知,1:低库位,2:高库位} private Short locType1; // 宽窄类型{0:未知,1:窄库位,2:宽库位} private Short locType2; // 轻重类型{0:未知,1:轻库位,2:重库位} private Short locType3; public LocTypeDto() { } public LocTypeDto(StaProtocol staProtocol) { if (staProtocol.isHigh() == staProtocol.isLow()) { throw new CoolException("plc高低检测异常"); } if (staProtocol.isLow()) { this.locType1 = 1; // 低库位 } else { this.locType1 = 2; // 高库位 } } /** * 库位类型解析 */ public static LocTypeDto process(StaProtocol staProtocol) { LocTypeDto dto = new LocTypeDto(); if (staProtocol.isHigh() == staProtocol.isLow()) { throw new CoolException("plc高低检测异常"); } if (staProtocol.isLow()) { dto.setLocType1((short) 1); // 低库位 } else { dto.setLocType1((short) 2); // 高库位 } return dto; } } src/main/java/com/zy/common/service/CommonService.java
@@ -5,12 +5,16 @@ import com.core.common.Arith; import com.core.common.Cools; import com.core.exception.CoolException; import com.zy.asrs.domain.enums.WorkNoType; import com.zy.asrs.entity.*; import com.zy.asrs.service.*; import com.zy.asrs.utils.Utils; import com.zy.common.model.LocTypeDto; import com.zy.common.model.Shelves; import com.zy.common.model.StartupDto; import com.zy.core.properties.SlaveProperties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; @@ -35,10 +39,13 @@ private BasDevpService basDevpService; @Autowired private LocMastService locMastService; @Autowired private SlaveProperties slaveProperties; @Autowired private LocDetlService locDetlService; /** * 生成工作号 * @param wrkMk 0:入库 1 - 3000 ; 1:拣料/并板/盘点 3001 - 6000 ; 2: 出库 6001 -9000 ; 3:其他 9001 -9999 * @return workNo(工作号) */ public int getWorkNo(Integer wrkMk) { @@ -75,6 +82,7 @@ return workNo; } /** * 检索库位号 * @param whsType 类型 1:双深式货架 @@ -83,15 +91,19 @@ * @param matNos 物料号集合 * @return locNo 检索到的库位号 */ public StartupDto getLocNo(Integer whsType, Integer staDescId, Integer sourceStaNo, List<String> matNos) { @Transactional public StartupDto getLocNo(Integer whsType, Integer staDescId, Integer sourceStaNo, List<String> matNos, LocTypeDto locTypeDto) { StartupDto startupDto = new StartupDto(); int workNo = getWorkNo(WorkNoType.getWorkNoType(staDescId)); startupDto.setWorkNo(workNo); if (sourceStaNo < 100) { // 生成工作号 int workNo = getWorkNo(0); if (sourceStaNo == 202) { whsType = 2; } else if (sourceStaNo == 205){ whsType = 1; } else { whsType = 2; throw new CoolException("库位排号分配"); } startupDto.setWorkNo(workNo); RowLastno rowLastno = rowLastnoService.selectById(whsType); if (Cools.isEmpty(rowLastno)) { throw new CoolException("数据异常,请联系管理员"); @@ -100,20 +112,85 @@ int curRow = rowLastno.getCurrentRow(); int sRow = rowLastno.getsRow(); int eRow = rowLastno.geteRow(); // 获取目标站所在货架排号 curRow = curRow == sRow ? eRow : sRow; int crn_qty = rowLastno.getCrnQty(); int rowCount = eRow - sRow + 1; // 目标堆垛机号 int crnNo; switch (whsType) { case 1: crnNo = 1; break; case 2: crnNo = 2; break; default: throw new CoolException("检索库位 -- 检索堆垛机号失败"); int crnNo = 0; // 目标库位 LocMast locMast = null; // 靠近摆放规则 --- 同天同规格物料 if (!Cools.isEmpty(matNos)) { List<String> locNos = locDetlService.getSameDetlToday(matNos.get(0)); for (String locNo : locNos) { if (Utils.isShallowLoc(slaveProperties, locNo)) { continue; } String shallowLocNo = Utils.getShallowLoc(slaveProperties, locNo); // 检测目标库位是否为空库位 LocMast shallowLoc = locMastService.selectById(shallowLocNo); if (shallowLoc != null && shallowLoc.getLocSts().equals("O")) { locMast = shallowLoc; crnNo = locMast.getCrnNo(); break; } } } // 靠近摆放规则 --- 空托 if (staDescId == 10) { List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>().eq("loc_sts", "D")); if (locMasts.size() > 0) { for (LocMast loc : locMasts) { if (Utils.isShallowLoc(slaveProperties, loc.getLocNo())) { continue; } String shallowLocNo = Utils.getShallowLoc(slaveProperties, loc.getLocNo()); // 检测目标库位是否为空库位 LocMast shallowLoc = locMastService.selectById(shallowLocNo); if (shallowLoc != null && shallowLoc.getLocSts().equals("O")) { locMast = shallowLoc; crnNo = locMast.getCrnNo(); break; } } } } // 如果没有相近物料,则按规则轮询货架 if (null == locMast) { // 重库位 if (whsType == 1) { // 获取目标站所在货架排号 Shelves shelves = new Shelves(rowCount, crn_qty); curRow = shelves.start(curRow); if (curRow < 0) { throw new CoolException("检索库位失败,请联系管理员"); } for (List<Integer> node : shelves.nodes){ if (node.contains(curRow)) { crnNo = shelves.nodes.indexOf(node) + 1; break; } } // 轻库位 } if (whsType == 2) { // 获取目标站所在货架排号 Shelves shelves = new Shelves(rowCount, crn_qty); curRow = shelves.start(curRow - 4); if (curRow < 0) { throw new CoolException("检索库位失败,请联系管理员"); } for (List<Integer> node : shelves.nodes){ if (node.contains(curRow)) { crnNo = shelves.nodes.indexOf(node) + 1; break; } } // 偏移量补偿 curRow = curRow + 4; crnNo = crnNo + 1; } } basCrnpService.checkSiteStatus(crnNo); @@ -130,8 +207,21 @@ int inQty = staNo.getInQty()==null?0:staNo.getInQty(); if (staNo.getAutoing().equals("Y") && inQty<2) { // 查找库位 LocMast locMast = locMastService.queryFreeLocMast(curRow); if (locMast == null) { if (Utils.isShallowLoc(slaveProperties, curRow)) { Integer deepRow = Utils.getDeepRow(slaveProperties, curRow); locMast = locMastService.queryFreeLocMast(deepRow, locTypeDto.getLocType1()); } if (Cools.isEmpty(locMast)) { locMast = locMastService.queryFreeLocMast(curRow, locTypeDto.getLocType1()); } } if (Cools.isEmpty(locMast)) { // 轻货物找轻库位为空时,可以去找重库位仓 if (locTypeDto.getLocType1() == 1) { locTypeDto.setLocType1((short) 2); return getLocNo(1, staDescId, sourceStaNo, matNos, locTypeDto); } throw new CoolException("没有空库位"); } String locNo = locMast.getLocNo(); src/main/java/com/zy/core/enums/CrnModeType.java
@@ -2,10 +2,11 @@ public enum CrnModeType { STOP(0, "停机状态"), // 停机状态 HAND(1, "手动模式"), // 手动模式中 HALF_AUTO(2, "半自动模式"), // 半自动模式中 AUTO(3, "电脑模式"), // 电脑模式中/自动模式 NONE(0, "未选择"), AUTO(1, "自动"), HALF_AUTO(2, "半自动"), HAND(3, "手动"), STOP(4, "维修"), ; public Integer id; src/main/java/com/zy/core/model/protocol/StaProtocol.java
@@ -37,25 +37,31 @@ // 空板信号 private boolean emptyMk; // 高 private boolean high; // 低 private boolean low; // 需求1 private boolean inreq1; // 锁定标记 private boolean pakMk = true; // 台车位置 private Short position; public BasDevp toSqlModel(){ BasDevp basDevp = new BasDevp(); basDevp.setDevNo(siteId); basDevp.setWrkNo(workNo.intValue()); // 站点 todo:luxiaotao basDevp.setAutoing(autoing?"Y":"N"); basDevp.setLoading(loading?"Y":"N"); basDevp.setInEnable(inEnable?"Y":"N"); basDevp.setOutEnable(outEnable?"Y":"N"); basDevp.setInreq1(inreq1?"Y":"N"); basDevp.setLocType1((short) 0); // 高低类型{0:未知,1:低库位,2:高库位} basDevp.setLocType2((short) 0); // 宽窄类型{0:未知,1:窄库位,2:宽库位} basDevp.setLocType3((short) 0); // 轻重类型{0:未知,1:轻库位,2:重库位} basDevp.setLocType1(high != low && low ? (short) 1 : (short) 2); return basDevp; } src/main/java/com/zy/core/properties/SlaveProperties.java
@@ -19,6 +19,12 @@ @ConfigurationProperties(prefix = "wcs-slave") public class SlaveProperties { private boolean doubleDeep; private List<Integer> doubleLocs = new ArrayList<>(); private int groupCount; private List<CrnSlave> crn = new ArrayList<>(); private List<DevpSlave> devp = new ArrayList<>(); src/main/java/com/zy/core/thread/SiemensDevpThread.java
@@ -130,15 +130,6 @@ } } } // 台车位置 OperateResultExOne<Short> result2 = siemensS7Net.ReadInt16("DB100.48"); if (result2.IsSuccess) { StaProtocol staProtocol = station.get(8); staProtocol.setPosition(result2.Content); } else { OutputQueue.DEVP.offer(MessageFormat.format("【{0}】8号台车获取实时位置失败!!!", DateUtils.convert(new Date()))); log.error("8号台车获取实时位置失败!!!"); } if (result.IsSuccess && result1.IsSuccess) { src/main/resources/application.yml
@@ -35,6 +35,12 @@ # 下位机配置 wcs-slave: # 双深 doubleDeep: true # 双深库位排号 doubleLocs: 1,4,5,8 # 一个堆垛机负责的货架排数 groupCount: 4 # 堆垛机1 crn[0]: id: 1 src/main/resources/mapper/LocMastMapper.xml
@@ -39,7 +39,14 @@ </resultMap> <select id="queryFreeLocMast" resultMap="BaseResultMap"> select top 1 * from asr_loc_mast where row1=#{row} and loc_sts='O' order by loc_sts desc ,lev1 asc,bay1 asc select top 1 * from asr_loc_mast where row1=#{row} and loc_sts='O' <if test="locType1 != null"> and loc_type1 = #{locType1} </if> order by loc_sts desc ,lev1 asc,bay1 asc </select> <select id="queryDemoSourceLoc" resultMap="BaseResultMap"> src/main/webapp/static/css/console.css
@@ -218,7 +218,7 @@ .main-part { position: absolute; top: 100px; left: 300px; left: 500px; } .main-part .lane { /*margin-bottom: 30px;*/ @@ -358,7 +358,7 @@ position: absolute; background-color:#333!important; color: #333 !important; width: 93%; width: 72%; margin-top: 10px; } src/main/webapp/views/console.html
@@ -91,14 +91,6 @@ <!----------- 左输送线 ----------> <!-- 台车轨道 --> <div id="car-track-1" class="car-track"> <div></div> </div> <!-- 台车实例 --> <div id="site-8" class="site car">8</div> <!-- 第一列(宽度 100px) --> <div class="site-row site-row-1"> <div id="site-7" class="site" style="height: 20px;line-height: 20px;margin-bottom: 20px">7</div> @@ -125,10 +117,10 @@ <div class="main-part"> <!--第一组--> <div class="lane"> <span class="row-no">1#</span> <span class="row-no">8#</span> <!-- 货架 --> <div class="stock-group"> <div id="site-6" class="site" style="">6</div> <div id="site-100" class="site" style="">100</div> <button class="item">1</button> <button class="item">2</button> <button class="item">3</button> @@ -161,8 +153,90 @@ <button class="item">30</button> <button class="item">31</button> <button class="item">32</button> <button class="item">33</button> <button class="item">34</button> <div class="site site-none"> </div> </div> <!-- 堆垛机 --> <div class="crn"> <hr class="pathway"> <div id="crn-2" class="machine"></div> </div> <!-- 货架 --> <div class="stock-group"> <div id="site-124" class="site" style="">124</div> <button class="item">1</button> <button class="item">2</button> <button class="item">3</button> <button class="item">4</button> <button class="item">5</button> <button class="item">6</button> <button class="item">7</button> <button class="item">8</button> <button class="item">9</button> <button class="item">10</button> <button class="item">11</button> <button class="item">12</button> <button class="item">13</button> <button class="item">14</button> <button class="item">15</button> <button class="item">16</button> <button class="item">17</button> <button class="item">18</button> <button class="item">19</button> <button class="item">20</button> <button class="item">21</button> <button class="item">22</button> <button class="item">23</button> <button class="item">24</button> <button class="item">25</button> <button class="item">26</button> <button class="item">27</button> <button class="item">28</button> <button class="item">29</button> <button class="item">30</button> <button class="item">31</button> <button class="item">32</button> <div class="site site-none"> </div> </div> <span class="row-no">5#</span> </div> <!--第二组--> <div class="lane"> <span class="row-no">4#</span> <!-- 货架 --> <div class="stock-group"> <div id="site-120" class="site" style="">120</div> <button class="item">1</button> <button class="item">2</button> <button class="item">3</button> <button class="item">4</button> <button class="item">5</button> <button class="item">6</button> <button class="item">7</button> <button class="item">8</button> <button class="item">9</button> <button class="item">10</button> <button class="item">11</button> <button class="item">12</button> <button class="item">13</button> <button class="item">14</button> <button class="item">15</button> <button class="item">16</button> <button class="item">17</button> <button class="item">18</button> <button class="item">19</button> <button class="item">20</button> <button class="item">21</button> <button class="item">22</button> <button class="item">23</button> <button class="item">24</button> <button class="item">25</button> <button class="item">26</button> <button class="item">27</button> <button class="item">28</button> <button class="item">29</button> <button class="item">30</button> <button class="item">31</button> <button class="item">32</button> <div class="site site-none"> </div> </div> <!-- 堆垛机 --> @@ -172,7 +246,7 @@ </div> <!-- 货架 --> <div class="stock-group"> <div id="site-5" class="site" style="">5</div> <div id="site-118" class="site" style="">118</div> <button class="item">1</button> <button class="item">2</button> <button class="item">3</button> @@ -205,79 +279,9 @@ <button class="item">30</button> <button class="item">31</button> <button class="item">32</button> <button class="item">33</button> <button class="item">34</button> <div class="site site-none"> </div> </div> <span class="row-no">2#</span> </div> <!--第二组--> <div class="lane" style="margin-left: 300px"> <span class="row-no">3#</span> <!-- 货架 --> <div class="stock-group"> <div id="site-101" class="site" style="">101</div> <button class="item">2</button> <button class="item">4</button> <button class="item">6</button> <button class="item">8</button> <button class="item">10</button> <button class="item">12</button> <button class="item">14</button> <button class="item">16</button> <button class="item">18</button> <button class="item">20</button> <button class="item">22</button> <button class="item">24</button> <button class="item">26</button> <button class="item">28</button> <button class="item">30</button> <button class="item">32</button> <button class="item">34</button> <button class="item">36</button> <button class="item">38</button> <button class="item">40</button> <button class="item">42</button> <button class="item">44</button> <button class="item">46</button> <button class="item">48</button> <div class="site site-none"> </div> </div> <!-- 堆垛机 --> <div class="crn"> <hr class="pathway" style="width: 67.5%"> <div id="crn-2" class="machine"></div> </div> <!-- 货架 --> <div class="stock-group"> <div id="site-107" class="site" style="">107</div> <button class="item">2</button> <button class="item">4</button> <button class="item">6</button> <button class="item">8</button> <button class="item">10</button> <button class="item">12</button> <button class="item">14</button> <button class="item">16</button> <button class="item">18</button> <button class="item">20</button> <button class="item">22</button> <button class="item">24</button> <button class="item">26</button> <button class="item">28</button> <button class="item">30</button> <button class="item">32</button> <button class="item">34</button> <button class="item">36</button> <button class="item">38</button> <button class="item">40</button> <button class="item">42</button> <button class="item">44</button> <button class="item">46</button> <button class="item">48</button> <div class="site site-none"> </div> </div> <span class="row-no">4#</span> <span class="row-no">1#</span> </div> </div> </main>