Commit 19ed1274 sunke

料架分配逻辑修改

1 个父辈 423c514e
package com.myproject.bean.qisda;
import com.google.common.collect.Lists;
import com.myproject.bean.update.DataLog;
import com.myproject.bean.update.qisda.OutItem;
import com.myproject.util.StorageConstants;
......@@ -53,25 +54,6 @@ public class InquiryShelfBean {
}
}
/**
* 清理需求单中的A料架(主要是分盘料和紧急料)
*/
public static void clearCutUrgentPackageShelf(String cutOrUrgentAShelfKey){
Map<String, ShelfInfo> shelfMap = hSerialShelfMap.get(cutOrUrgentAShelfKey);
if(shelfMap != null){
Collection<ShelfInfo> allShelf = shelfMap.values();
for (ShelfInfo shelfInfo : allShelf) {
if(shelfInfo.isAShelf() && shelfInfo.isFull()){
log.info("清理已放满紧急料或分盘料的包装A料架["+shelfInfo.tempRfid()+"]");
shelfMap.remove(shelfInfo.tempRfid());
}
}
hSerialShelfMap.put(cutOrUrgentAShelfKey,shelfMap);
QisdaCache.saveShelfMap(hSerialShelfMap);
}
}
public static boolean clearShelf(String hSerial, String rfid){
boolean clearResult = false;
if(hSerial != null){
......@@ -91,140 +73,6 @@ public class InquiryShelfBean {
return clearResult;
}
private static List<ShelfInfo> getSortedCAndDShelfList(DataLog task){
AppendInfo taskAppendInfo = task.getAppendInfo();
String hSerial = taskAppendInfo.gethSerial();
Map<String, ShelfInfo> shelfMap = hSerialShelfMap.get(hSerial);
//C和D料架列表
List<ShelfInfo> cAndDShelfList = new ArrayList<>();
for (ShelfInfo shelfInfo : shelfMap.values()) {
if(shelfInfo.isDShelf() || shelfInfo.isCShelf()) {
cAndDShelfList.add(shelfInfo);
}
}
//排序1D=>3D=>6D=>2C=>4C=5C
cAndDShelfList.sort(new Comparator<ShelfInfo>() {
public int compare(ShelfInfo shelf1, ShelfInfo shelf2) {
if(shelf1.getShelfType().equals(shelf2.getShelfType())){
int diff = shelf1.getRfidIndex() - shelf2.getRfidIndex();
return diff;
}else{
return shelf2.getShelfType().compareTo(shelf1.getShelfType());
}
}
});
return cAndDShelfList;
}
public static boolean canCheckOutTailActionTask(DataLog task, int unFinishedBigTaskCount){
AppendInfo taskAppendInfo = task.getAppendInfo();
if(taskAppendInfo.isTailAction()){
if(task.isSmallReel()){
return true;
}else{
//大料任务,只有当小料架只剩下一个未满时才可以出
List<ShelfInfo> cAndDShelfList = getSortedCAndDShelfList(task);
for (int i = 0; i < cAndDShelfList.size(); i++) {
ShelfInfo shelfInfo = cAndDShelfList.get(i);
if(!shelfInfo.isFull()){
if(shelfInfo.isCShelf()){
//小料架已经放满,大料可以随便出
return true;
}else if(shelfInfo.isDShelf()){
//小料架还未放满
if(i+1<cAndDShelfList.size()){
ShelfInfo nextShelf = cAndDShelfList.get(i + 1);
if(nextShelf.isDShelf()){
//下一个料架如果是小料架,不允许出
//log.info("还有两个小料架["+shelfInfo.tempRfid()+"," + nextShelf.tempRfid()+"]未放满,大料任务["+task.getBarcode()+"]暂停出库");
return false;
}else{
//下一个料架是大料架,最多只能出一个料架的大料
int emptyLocCount = nextShelf.getEmptyLocCount();
boolean canOut = unFinishedBigTaskCount + 1 <= emptyLocCount;
if(!canOut){
//log.info("未完成的大料数量["+unFinishedBigTaskCount+"]已可放满下一料架"+nextShelf.tempRfid()+"["+emptyLocCount+"],大料任务["+task.getBarcode()+"]暂停出库");
}
return canOut;
}
}
}
break;
}
}
}
}
return false;
}
/**
* 判断首盘任务是否可以出库
*/
public static boolean canCheckOutFistActionTask(DataLog task){
//保证双层线上最多只能有两个料架
List<ShelfInfo> cAndDShelfList = getSortedCAndDShelfList(task);
AppendInfo taskAppendInfo = task.getAppendInfo();
if(taskAppendInfo.isFirstReelAction() && !task.isLessSendReel()){
//如果任务是在最小(有空位)和次小的料架当中,可以出库
ShelfInfo firstEmptyShelf = null;
ShelfInfo secondEmptyShelf = null;
for (int i = 0; i < cAndDShelfList.size(); i++) {
ShelfInfo shelfInfo = cAndDShelfList.get(i);
if(!shelfInfo.isFull()){
firstEmptyShelf = shelfInfo;
if(i+1<cAndDShelfList.size()){
secondEmptyShelf = cAndDShelfList.get(i + 1);
}
break;
}
}
String shelfNameStr = "";
if(firstEmptyShelf != null){
if(firstEmptyShelf.tempRfid().equals(task.getTempRfid())){
//与最小的料架号相同,可以出库
return true;
};
shelfNameStr = firstEmptyShelf.tempRfid();
}
if(secondEmptyShelf != null){
if(secondEmptyShelf.tempRfid().equals(task.getTempRfid())){
//与最次小的料架号相同,可以出库
return true;
};
shelfNameStr = shelfNameStr + "," + secondEmptyShelf.tempRfid();
}
log.info("任务"+task.getBarcode()+"["+task.getTempRfid()+"]不在两个料架"+shelfNameStr+"当中,暂不出库");
}
return false;
}
/**
* 添加限制库位(即库位中只能放入某个条码)
* @param task
* @param outItem
* @return
*/
public static DataLog addLimitLoc(DataLog task, OutItem outItem){
return addLoc(task, outItem, task.getBarcode());
}
/**
* 首盘料时,缺料站位空出一个架位
*/
public static void addEmptyLoc(OutItem outItem, String shelfType){
String hSerial = outItem.gethSerial();
ShelfInfo emptyShelfInfo = getOrAddShelfInfo(hSerial,shelfType, outItem.gethSerial());
if(emptyShelfInfo != null){
int loc = emptyShelfInfo.addEmptyLoc();
log.info("工单"+outItem.getSo()+"["+outItem.getSlotlocation()+"]"+outItem.getPn()+"预留架位"+emptyShelfInfo.tempRfid()+"["+ loc +"]");
updateShelfInfo(emptyShelfInfo);
}
}
/**
* 添加不限制的库位,即库位对条码不作限制
* @param task
......@@ -232,81 +80,18 @@ public class InquiryShelfBean {
* @return
*/
public static DataLog addUnlimitLoc(DataLog task, OutItem outItem){
return addLoc(task, outItem, "");
return addLoc(task, outItem);
}
public static String getShelfType(DataLog task){
//空位预留
if(task == null){
//根据尺寸确定预留种架位
return StorageConstants.SHEFL_TYPE.D;
}
String shelfType = "";
//包装料架
if(task.isPackageReel()){
shelfType = StorageConstants.SHEFL_TYPE.A;
}else {
//需要分盘的料或紧急料或者缺料补发的料,且不是包装料,统一都放到料串上
if(task.isCutReel() || task.isUrgentReel() || task.isLessSendReel() || task.getAppendInfo().isUrgentAction()){
//B料串
return StorageConstants.SHEFL_TYPE.B;
}else{
if(task.isSmallReel()){
//D料架
shelfType = StorageConstants.SHEFL_TYPE.D;
}else{
shelfType = StorageConstants.SHEFL_TYPE.C;
}
}
}
return shelfType;
public static DataLog addUrgentUnlimitLoc(DataLog task){
return addLoc(task, null);
}
/**
* 获取未达最大数量的料架,或者添加一个新的料架
* @param shelfType
* @return
*/
private static ShelfInfo getOrAddShelfInfo(String hSerial, String shelfType, String sourceHSerial){
Map<String, ShelfInfo> shelfMap = hSerialShelfMap.get(hSerial);
int rfidIndex = 0;
if(shelfMap != null){
for (ShelfInfo shelfInfo : shelfMap.values()) {
if(StorageConstants.SHEFL_TYPE.judgeType(shelfInfo.getShelfType(), shelfType)){
if(shelfInfo != null && !shelfInfo.reachMaxLoc()){
if(hSerial.equals(sourceHSerial)){
//工单料
return shelfInfo;
}else{
//不是包装仓的分盘料或紧急料,使用同一个料架;包装料架按需求单号进行区分
if(!shelfInfo.isAShelf()){
return shelfInfo;
}
}
}
}
}
rfidIndex = shelfMap.size();
public static String getShelfType(DataLog task){
return StorageConstants.SHEFL_TYPE.F;
}
ShelfInfo newShelf = null;
if(StorageConstants.SHEFL_TYPE.isAShelf(shelfType)){
newShelf = ShelfInfo.newAShelf();
}else if(StorageConstants.SHEFL_TYPE.isBShelf(shelfType)){
newShelf = ShelfInfo.newBShelf();
}if(StorageConstants.SHEFL_TYPE.isCShelf(shelfType)){
newShelf = ShelfInfo.newCShelf();
}else if(StorageConstants.SHEFL_TYPE.isDShelf(shelfType)){
newShelf = ShelfInfo.newDShelf();
}
if(newShelf != null){
newShelf.setRfidIndex(rfidIndex);
newShelf.sethSerial(hSerial,sourceHSerial);
log.info("添加新料架["+newShelf.tempRfid() + "]");
updateShelfInfo(newShelf);
}
return newShelf;
}
/**
* 更新料架缓存信息
......@@ -322,9 +107,16 @@ public class InquiryShelfBean {
QisdaCache.saveShelfMap(hSerialShelfMap);
}
private static synchronized DataLog addLoc(DataLog task, OutItem outItem, String barcode){
private static synchronized DataLog addLoc(DataLog task,OutItem outItem){
AppendInfo appendInfo = task.getAppendInfo();
String shelfType = getShelfType(task);
String hSerial = outItem.gethSerial();
String soInfoStr = "";
String hSerial = appendInfo.gethSerial();
String sourceHSerial = appendInfo.gethSerial();
if(outItem != null){
hSerial = outItem.gethSerial();
soInfoStr = "工单"+outItem.getSo()+"["+outItem.getSlotlocation()+"]"+outItem.getPn()+"为";
}
if(task.isUrgentReel()){
//紧急料放在同一个料串或包装料架上,需求单号使用1
......@@ -334,49 +126,50 @@ public class InquiryShelfBean {
hSerial = CUT_SHELF_MAP_KEY;
}
ShelfInfo emptyShelfInfo = getOrAddShelfInfo(hSerial,shelfType,outItem.gethSerial());
if(emptyShelfInfo != null){
if(task != null){
int loc = -1;
AppendInfo appendInfo = task.getAppendInfo();
if(task.isPackageReel()){
//包装料,固定库位
loc = emptyShelfInfo.addLimitLoc(task.getBarcode(),task.getReelType());
appendInfo.setRfidLoc(loc);
}else{
loc = emptyShelfInfo.addLimitLoc(barcode,task.getReelType());
ShelfInfo targetShelf = null;
int targetLoc = -1;
Map<String, ShelfInfo> shelfMap = hSerialShelfMap.get(hSerial);
int maxIndex = 0;
if(shelfMap != null){
for (ShelfInfo shelfInfo : shelfMap.values()) {
if(shelfInfo.getRfidIndex() > maxIndex){
maxIndex = shelfInfo.getRfidIndex();
}
targetLoc = shelfInfo.addUnLimitLoc(task);
if(targetLoc != -1){
//添加成功
log.info(soInfoStr + "为["+task.getBarcode()+"]添加架位["+shelfInfo.tempRfid() + "]["+ targetLoc +"]");
targetShelf = shelfInfo;
break;
}
}
}
log.info("工单"+outItem.getSo()+"["+outItem.getSlotlocation()+"]"+outItem.getPn()+"为["+task.getBarcode()+"]添加架位["+emptyShelfInfo.tempRfid() + "]["+ loc +"]=" + barcode);
appendInfo.setRfidIndex(emptyShelfInfo.getRfidIndex());
appendInfo.setShelfType(shelfType);
appendInfo.sethSerial(outItem.gethSerial());
if(barcode != null && !barcode.isEmpty()){
appendInfo.setRfidLoc(loc);
if(targetShelf == null){
targetShelf = ShelfInfo.newFShelf();
if(targetShelf != null){
targetShelf.setRfidIndex(maxIndex + 1);
targetShelf.sethSerial(hSerial,sourceHSerial);
targetLoc = targetShelf.addUnLimitLoc(task);
log.info(soInfoStr + "为["+task.getBarcode()+"]添加新料架["+targetShelf.tempRfid()+"]架位["+targetShelf.tempRfid() + "]["+ targetLoc +"]");
}
String location = shelfType;
if(outItem.isFirstReelAction() && !task.isLessSendReel()){
location = emptyShelfInfo.getRfidIndex() + shelfType + "_" + loc;
}else if(task.isLessSendReel()){
int showLoc = task.resolveRfidLoc(loc+"");
location = shelfType + "_" + showLoc;
}
appendInfo.setRfidIndex(targetShelf.getRfidIndex());
appendInfo.setShelfType(shelfType);
appendInfo.sethSerial(sourceHSerial);
String location = shelfType;
// if(outItem.isFirstReelAction() && !task.isLessSendReel()){
// location = targetShelf.getRfidIndex() + shelfType + "_" + targetLoc;
// }else if(task.isLessSendReel()){
// int showLoc = task.resolveRfidLoc(targetLoc+"");
// location = shelfType + "_" + showLoc;
// }
task.setSubSourceInfo(location);
task.setAppendInfo(appendInfo);
//非分盘和非紧急料和非缺料补发的包装料需要在C型料架上预留位置
if(task.isPackageReel() && !task.isCutReel() && !task.isUrgentReel() && !task.isLessSendReel()){
String cShelf = StorageConstants.SHEFL_TYPE.C;
ShelfInfo packageCShelf = getOrAddShelfInfo(hSerial, cShelf, outItem.gethSerial());
int packageCLoc = packageCShelf.addLimitLoc(barcode, StorageConstants.REEL_TYPE.PACKAGE);
log.info("包装料["+barcode+"]预留C型料架:工单"+outItem.getSo()+"["+outItem.getSlotlocation()+"]"+outItem.getPn()+"添加架位["+packageCShelf.tempRfid() + "]["+ packageCLoc +"]=["+emptyShelfInfo.tempRfid() + "]["+ loc +"]=" + barcode);
}
}else{
int loc = emptyShelfInfo.addEmptyLoc();
log.info("工单"+outItem.getSo()+"["+outItem.getSlotlocation()+"]"+outItem.getPn()+"预留架位"+emptyShelfInfo.tempRfid()+"["+ loc +"]");
}
updateShelfInfo(emptyShelfInfo);
}
updateShelfInfo(targetShelf);
return task;
}
......@@ -433,48 +226,6 @@ public class InquiryShelfBean {
return null;
}
/**
* 查找料架相同RFID的料架,用于AGV判断是否还有任务
*/
public static ShelfInfo findShelf(String rfid){
if(Strings.isEmpty(rfid)){
return null;
}
//ShelfInfo minIndexShelf = null;
for (Map<String, ShelfInfo> shelfInfoMap : hSerialShelfMap.values()) {
for (ShelfInfo shelf : shelfInfoMap.values()) {
String shelfRFID = shelf.getRealRfid();
if(shelfRFID.equals(rfid)){
//已经绑定过该Temp料架
return shelf;
}
}
}
return null;
}
/**
* 3号机器人放入时查找包装料架上的物料信息(肯定会存在)
* @param packageRfid
* @return
*/
public static ShelfInfo findPackageShelf(String hSerial, String packageRfid){
if(packageRfid == null || packageRfid.isEmpty()){
return null;
}
Map<String, ShelfInfo> shSerialShelfInfoMap = hSerialShelfMap.get(hSerial);
if(shSerialShelfInfoMap == null ){
return null;
}
for (ShelfInfo shelf : shSerialShelfInfoMap.values()) {
String shelfRFID = shelf.getRealRfid();
if(shelfRFID.equals(packageRfid)){
//已经绑定过该Temp料架
return shelf;
}
}
return null;
}
/**
* 获取某个需求单已经绑定的RFID
......@@ -494,145 +245,58 @@ public class InquiryShelfBean {
return usedRfidList;
}
/**
* 首套料,获取分配好的库位
*/
public static ShelfLoc getLimitLoc(DataLog task){
AppendInfo appendInfo = task.getAppendInfo();
String barcode = task.getBarcode();
String hSerial = appendInfo.gethSerial();
Map<String, ShelfInfo> shelfMap = hSerialShelfMap.get(hSerial);
if(shelfMap != null){
for (ShelfInfo shelfInfo : shelfMap.values()) {
int loc = shelfInfo.getBarcodeLoc(barcode, appendInfo.getShelfType());
if(loc != -1){
ShelfLoc shelfLoc = new ShelfLoc();
shelfLoc.setLoc(loc);
shelfLoc.setTempRfid(shelfInfo.tempRfid());
shelfLoc.setRealRfid(shelfInfo.getRealRfid());
log.info("查找到["+barcode+"]分配的库位" + shelfInfo.tempRfid()+"["+loc+"] Task库位"+appendInfo.getRfid()+"["+appendInfo.getRfidLoc()+"]");
return shelfLoc;
}
}
}
return null;
}
/**
* 获取需求单使用的所有D料架
*/
public static List<ShelfInfo> getAllDShelf(String hSerial){
List<ShelfInfo> shelfInfos = new ArrayList<>();
Map<String, ShelfInfo> shelfMap = hSerialShelfMap.get(hSerial);
if(shelfMap != null){
for (ShelfInfo shelf : shelfMap.values()) {
if(shelf.isDShelf()){
shelfInfos.add(shelf);
}
}
}
return shelfInfos;
}
public static ShelfInfo findMaxUsedShelf(String hSerial, String shelfType){
Map<String, ShelfInfo> shelfMap = hSerialShelfMap.get(hSerial);
if(shelfMap == null){
return null;
}
ShelfInfo minIndexShelf = null;
for (ShelfInfo shelf : shelfMap.values()) {
if(StorageConstants.SHEFL_TYPE.judgeType(shelfType, shelf.getShelfType())){
if(shelf.isFull()){
//已经放满,查找下一个
continue;
}
//同一种料架
if(minIndexShelf == null){
minIndexShelf = shelf;
}
if(shelf.getRfidIndex() < minIndexShelf.getRfidIndex()){
minIndexShelf = shelf;
}
}
}
if(minIndexShelf != null){
log.info("找到类型为["+shelfType+"]最小序号未绑定同种料架["+minIndexShelf.tempRfid()+"]");
}else{
log.info("已没有与["+shelfType+"]类型相同的料架");;
}
return minIndexShelf;
}
/**
* 锁定架位
*/
public static synchronized ShelfLoc lockShelfLoc(DataLog task, String rfid, String robotIndex){
public static synchronized ShelfLoc lockShelfLoc(DataLog task, String rfidStr){
AppendInfo appendInfo = task.getAppendInfo();
String hSerial = appendInfo.gethSerial();
ShelfInfo shelfInfo = null;
List<String> rfidList = Lists.newArrayList(rfidStr.split(";"));
ShelfLoc lockLoc = null;
if(hSerial != null){
Map<String, ShelfInfo> shelfMap = hSerialShelfMap.get(hSerial);
if(shelfMap != null){
//先判断任务料架是否与双层线上的实际料架类型是否一致,如果不一致,直接使用新的料架
if(rfid != null && !rfid.isEmpty()){
if(StorageConstants.SHEFL_TYPE.judgeType(rfid, task.getAppendInfo().getShelfType())){
//任务与当前料架一致,使用已经绑定过的料架
shelfInfo = findSameShelf(hSerial, rfid);
}
}
if(shelfInfo != null){
//找到与实际料架相同的料架,但料架上已经满了,查找其他同类型料架
if(shelfInfo.isFull()){
log.info("料架["+shelfInfo.getRealRfid()+"]="+shelfInfo.tempRfid()+"已满,查找新的料架");
shelfInfo = null;
}
}
//未找到已经有实际RFID的料架,查找库位最多的料架
if(shelfInfo == null){
log.info(task.getBarcode() + "未找到实际绑定的["+rfid+"]料架,开始查找序号最小的同种料架["+task.getAppendInfo().getShelfType()+"]");
ShelfInfo minIndexShelf = null;
for (ShelfInfo shelf : shelfMap.values()) {
if(StorageConstants.SHEFL_TYPE.judgeType(task.getAppendInfo().getShelfType(), shelf.getShelfType())){
if(shelf.isFull()){
//已经放满,查找下一个
continue;
}
//同一种料架
if(minIndexShelf == null){
minIndexShelf = shelf;
//已经放了此需求单的料架
if(rfidList.contains(shelf.getRealRfid())){
lockLoc = shelf.lockOneEmptyLoc(task);
if(lockLoc != null){
shelfInfo = shelf;
break;
}
if(shelf.getRfidIndex() < minIndexShelf.getRfidIndex()){
}else{
if(minIndexShelf == null || shelf.getRfidIndex() < minIndexShelf.getRfidIndex()){
minIndexShelf = shelf;
}
}
}
shelfInfo = minIndexShelf;
if(shelfInfo != null){
log.info(task.getBarcode() + "["+ task.getTempRfid()+"]未找到rfid=["+rfid+"]的空料架,使用序号最小的同种料架["+shelfInfo.tempRfid()+"]");
if(lockLoc == null){
if(minIndexShelf == null){
log.error("任务条码["+task.getBarcode()+"]已无料架可放");
return null;
}else{
log.info("已没有与["+rfid+"]类型相同的料架");;
}
lockLoc = minIndexShelf.lockOneEmptyLoc(task);
if (lockLoc != null){
shelfInfo = minIndexShelf;
}
}
}
if(shelfInfo == null){
log.error("任务条码["+task.getBarcode()+"]未找到对应的料架" + rfid);
return null;
}
}
ShelfLoc lockLoc = shelfInfo.lockOneEmptyLoc(task.getBarcode(), task.getReelType(), robotIndex);
if(lockLoc != null){
log.info("为["+task.getBarcode()+"]锁定架位:" + shelfInfo.tempRfid() + "[" +shelfInfo.getRealRfid()+"]["+lockLoc.getLoc()+"]原来分配架位:" + task.getTempRfid() + "[" + appendInfo.getRfidLoc() + "]");
// ShelfLoc shelfLoc = new ShelfLoc();
// shelfLoc.setLoc(lockLoc);
// shelfLoc.setRfid(rfid);
if(shelfInfo.getRealRfid() == null || shelfInfo.getRealRfid().isEmpty()){
//未绑定过的,使用TempRFID
lockLoc.setTempRfid(shelfInfo.tempRfid());
......@@ -710,64 +374,6 @@ public class InquiryShelfBean {
}
}
/**
* 紧急料/分盘料放入料架或料串
*/
public static synchronized ShelfLoc putInCutReel(DataLog task, String rfid, int loc){
String barcode = task.getBarcode();
String shelfMapKey = task.getShelfMapKey();
Map<String, ShelfInfo> shelfMap = hSerialShelfMap.get(shelfMapKey);
if(shelfMap != null){
//该料架是否已经绑定过
ShelfInfo bindedShelf = findSameShelf(shelfMapKey,rfid);
if(bindedShelf != null){
if(task.isPackageReel()){
//包装料架
}else{
//料串
loc = bindedShelf.addLimitLoc(barcode, task.getReelType());
}
boolean putInResult = bindedShelf.putInLimitLoc(rfid,loc,barcode);
if(putInResult){
updateShelfInfo(bindedShelf);
log.info("紧急/分盘料["+task.getBarcode()+"]放入料架" + rfid +"["+loc+"]缓存更新成功");
return new ShelfLoc(rfid,loc);
}
}else{
if(task.isPackageReel()){
//包装料架
for (ShelfInfo shelfInfo : shelfMap.values()) {
boolean putInResult = shelfInfo.putInLimitLoc(rfid,loc, barcode);
if(putInResult){
updateShelfInfo(shelfInfo);
log.info("紧急/分盘料["+task.getBarcode()+"]使用新料架" + rfid +"["+loc+"]缓存更新成功");
return new ShelfLoc(rfid,loc);
}
}
}else{
//添加一个新的料串,并放入
ShelfInfo newBShelf = ShelfInfo.newBShelf();
int rfidIndex = shelfMap.size();
newBShelf.setRfidIndex(rfidIndex);
newBShelf.sethSerial(shelfMapKey,task.getAppendInfo().gethSerial());
log.info("添加新料架["+newBShelf.tempRfid() + "]");
loc = newBShelf.addLimitLoc(barcode, task.getReelType());
boolean putInResult = newBShelf.putInLimitLoc(rfid,loc,barcode);
if(putInResult){
updateShelfInfo(newBShelf);
log.info("紧急/分盘料["+task.getBarcode()+"]放入料架" + rfid +"["+loc+"]缓存更新成功");
return new ShelfLoc(rfid,loc);
}
}
}
}else{
log.info("未找到["+shelfMapKey+"]相关料架");
}
log.error("物料["+task.getBarcode()+"]("+task.getTempRfid()+"["+task.getAppendInfo().getRfidLoc()+"])料架" + rfid +"["+loc+"]缓存更新失败");
return null;
}
public static synchronized boolean putInShelf(DataLog task, String rfid, int loc){
AppendInfo appendInfo = task.getAppendInfo();
String barcode = task.getBarcode();
......
package com.myproject.bean.qisda;
import com.myproject.bean.update.DataLog;
import com.myproject.util.StorageConstants;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
......@@ -40,6 +41,19 @@ public class ShelfInfo {
}
/**
* F料架最多放26个小料
*/
private static int MAX_F_SMALL_NUM = 26;
/**
* F料架1-26放小料, 27-31放大料
* @return
*/
public static ShelfInfo newFShelf(){
return new ShelfInfo(StorageConstants.SHEFL_TYPE.F,31);
}
/**
* 需求单号
*/
private String hSerial;
......@@ -93,12 +107,7 @@ public class ShelfInfo {
return emptyLocCount;
}
/**
* 库位数
*/
public int getUsedLocCount(){
return locMap.size();
}
public void setLocMap(Map<Integer, ShelfLoc> locMap) {
this.locMap = locMap;
......@@ -131,6 +140,29 @@ public class ShelfInfo {
}
/**
* 是否到达可放小料的最大数量,F料架1-26放小料, 27-31放大料
*/
public boolean reachMaxSmallLoc(){
int smallCount = 0;
for (ShelfLoc loc : locMap.values()) {
if(loc.getLoc() <= MAX_F_SMALL_NUM){
smallCount++;
}
}
return smallCount >= MAX_F_SMALL_NUM;
}
public boolean reachMaxBigLoc(){
int bigCount = 0;
for (ShelfLoc loc : locMap.values()) {
if(loc.getLoc() > MAX_F_SMALL_NUM){
bigCount++;
}
}
return bigCount >= maxLocCount - MAX_F_SMALL_NUM;
}
/**
* 料架是否放满
*/
public boolean isFull(){
......@@ -222,14 +254,13 @@ public class ShelfInfo {
/**
* 为补料取消一个库位
*/
public boolean cancelLoc(String rfidType, String barcode){
public boolean cancelLoc(String rfidType, DataLog task){
if(rfidType.equals(this.getShelfType())){
int usedCount = getUsedLocCount();
for(int i=usedCount; i> 0; i--){
for(int i=maxLocCount; i> 0; i--){
ShelfLoc shelfLoc = locMap.get(i);
if(shelfLoc != null && shelfLoc.isEmpty() && !shelfLoc.isLock()){
if(shelfLoc != null && shelfLoc.isEmpty() && !shelfLoc.isLock() && shelfLoc.getReelType() == task.getReelType()){
//未放过料,且未锁定
shelfLoc.putIn(barcode);
shelfLoc.putIn(task.getBarcode());
return true;
}
}
......@@ -299,176 +330,75 @@ public class ShelfInfo {
}
/**
* 为包装料锁定架位
* @param shelfLoc 架位信息
* @param packageReelId 包装料条码
* @return
*/
public boolean lockForPackage(ShelfLoc shelfLoc, String packageReelId){
ShelfLoc emptyLoc = locMap.get(shelfLoc.getLoc());
if(!emptyLoc.isEmpty()){
log.info("为包装料["+packageReelId+"]锁定C型料架"+tempRfid()+"["+shelfLoc.getLoc()+"]失败,位置为不空");
return false;
}
log.info("为包装料["+packageReelId+"]锁定架位"+tempRfid()+"["+shelfLoc.getLoc()+"]");
emptyLoc.setBarcode(packageReelId);
return true;
}
/**
* 为不需要按顺序摆放的料盘锁定一个架位,如果已经锁定过,返回对应的架位
*/
public ShelfLoc lockOneEmptyLoc(String barcode, int reelType, String robotIndex){
//if(rfid.contains(shelfType)) {
//不是同一种料架的忽略
public ShelfLoc lockOneEmptyLoc(DataLog task){
//先看看此条码是否已经锁定过
for (ShelfLoc shelfLoc : locMap.values()) {
if(shelfLoc.isLock() && shelfLoc.getBarcode().equals(barcode)){
log.info("找到条码["+barcode+"]锁定的架位["+shelfLoc.getLoc()+"]");
return shelfLoc;
}
}
int usedCount = getUsedLocCount();
//1号机器人从大到小, 2号机器人从小到大,且71,72,73位不分配给2号机器人
if(robotIndex.equals("1")){
//1号机器人优先放70,71,72三个位置
ShelfLoc shelfLoc = lockLocation(72,barcode,reelType);
if(shelfLoc == null){
shelfLoc = lockLocation(71,barcode,reelType);
if(shelfLoc == null){
shelfLoc = lockLocation(70,barcode,reelType);
}
}
if(shelfLoc == null){
for(int i=usedCount; i> 0; i--){
//大料12号位不分配给1号机器人
if(StorageConstants.SHEFL_TYPE.isCShelf(shelfType)){
if(i == 12){
continue;
}
}
shelfLoc = lockLocation(i,barcode,reelType);
if(shelfLoc != null){
return shelfLoc;
}
}
}
if(shelfLoc == null && StorageConstants.SHEFL_TYPE.isCShelf(shelfType)){
//如果执行到这里还有空,说明另一个机器人停掉了只能分配了
for(int i=usedCount; i> 0; i--){
shelfLoc = lockLocation(i,barcode,reelType);
if(shelfLoc != null){
return shelfLoc;
}
}
}
return shelfLoc;
}else if(robotIndex.equals("2")){
ShelfLoc shelfLoc = null;
if(StorageConstants.SHEFL_TYPE.isCShelf(shelfType)){
//大料12号位分给2号机器人
shelfLoc = lockLocation(12,barcode,reelType);
}
if(shelfLoc == null){
for(int i=1; i<= usedCount; i++){
//小料70,71,72位不分配给2号机器人
if(StorageConstants.SHEFL_TYPE.isDShelf(shelfType)){
if(i==70 || i == 71 || i==72){
continue;
}
}
shelfLoc = lockLocation(i,barcode,reelType);
if(shelfLoc != null){
if(shelfLoc.isLock() && shelfLoc.getBarcode().equals(task.getBarcode())){
log.info("找到条码["+task.getBarcode()+"]锁定的架位["+shelfLoc.getLoc()+"]");
return shelfLoc;
}
}
}
if(shelfLoc == null && StorageConstants.SHEFL_TYPE.isDShelf(shelfType)){
//如果执行到这里还有空,说明另一个机器人停掉了只能分配了
for(int i=usedCount; i> 0; i--){
shelfLoc = lockLocation(i,barcode,reelType);
if(shelfLoc != null){
return shelfLoc;
}
}
}
return shelfLoc;
}else {
//包装料
for(int i=1; i<= usedCount; i++){
ShelfLoc shelfLoc = lockLocation(i,barcode,reelType);
for(int i=1; i<= maxLocCount; i++){
ShelfLoc shelfLoc = lockLocation(i,task);
if(shelfLoc != null){
return shelfLoc;
}
}
}
//}
return null;
}
/**
* 锁定库位,如果成功返回库位,如果失败返回null
*/
private ShelfLoc lockLocation(int loc,String barcode, int reelType){
private ShelfLoc lockLocation(int loc, DataLog task){
ShelfLoc shelfLoc = locMap.get(loc);
if(shelfLoc != null && shelfLoc.isEmpty() && !shelfLoc.isLock()){
log.info("为[" + barcode + "]锁定架位"+tempRfid() + "["+loc+"]");
if(shelfLoc != null && shelfLoc.isEmpty() && !shelfLoc.isLock() && task.getReelType() == shelfLoc.getReelType()){
log.info("为[" + task.getBarcode() + "]锁定架位"+tempRfid() + "["+loc+"]");
//未放过料,且未锁定
shelfLoc.setBarcode(barcode);
shelfLoc.setReelType(reelType);
shelfLoc.setBarcode(task.getBarcode());
shelfLoc.setReelType(task.getReelType());
locMap.put(loc, shelfLoc);
return shelfLoc;
}
return null;
}
/**
* 添加缺料空位
*/
public int addEmptyLoc(){
return addShelfLoc(null, 0);
}
/**
* 添加一个库位
*/
public int addLimitLoc(String barcode, int reelType){
if(barcode == null){
barcode = "";
}
return addShelfLoc(barcode, reelType);
}
/**
* 添加一个库位,库位固定放某个条码,不限制库位时,设为空字符串,缺料库位设置为null
* @param barcode
*/
private int addShelfLoc(String barcode, int reelType){
public int addUnLimitLoc(DataLog task){
for(int i=1; i<= maxLocCount; i++){
ShelfLoc shelfLoc = locMap.get(i);
if(shelfLoc == null){
shelfLoc = new ShelfLoc();
if(barcode == null){
barcode = "no code";
shelfLoc.setEmpty(false);
boolean addThis = false;
if(task.isSmallReel()){
if(i<= MAX_F_SMALL_NUM){
addThis = true;
}
}else{
if(i> MAX_F_SMALL_NUM){
addThis = true;
}
}
if(addThis){
shelfLoc = new ShelfLoc();
shelfLoc.setLoc(i);
shelfLoc.setBarcode(barcode);
shelfLoc.setReelType(reelType);
shelfLoc.setBarcode("");
shelfLoc.setReelType(task.getReelType());
locMap.put(i, shelfLoc);
return i;
}
}
}
return -1;
}
public int getMaxLocCount() {
return maxLocCount;
}
......
......@@ -575,9 +575,7 @@ public class DataLog extends BaseMongoBean /*implements Comparable<DataLog>*/ {
* @return
*/
public int getReelType(){
if(isPackageReel()){
return StorageConstants.REEL_TYPE.PACKAGE;
}else if(isSmallReel()){
if(isSmallReel()){
return StorageConstants.REEL_TYPE.SMALL;
}else{
return StorageConstants.REEL_TYPE.BIG;
......
......@@ -203,76 +203,9 @@ public final class DateUtil {
}
public static void main(String args[]) throws Exception {
List<DataLog> list = new ArrayList<>();
list.add(newDataLog(14,2000));
list.add(newDataLog(14,4000));
list.add(newDataLog(2,3000));
list.add(newDataLog(2,1000));
list.add(newDataLog(2,2000));
list.add(newDataLog(2,4000));
list.add(newDataLog(3,2000));
list.add(newDataLog(1,1000));
list.add(newDataLog(1,2000));
list.add(newDataLog(1,3000));
List<DataLog> sortList = sortTailTasks(list);
sortList.sort(new Comparator<DataLog>() {
@Override
public int compare(DataLog o1, DataLog o2) {
return o1.getOutOrder() - o2.getOutOrder();
}
});
for (DataLog d : sortList) {
System.out.println("["+d.getOutOrder()+"]" +d.getAppendInfo().getSlotIndex()+ " - " + d.getNum());
}
}
/**
* 对补料任务进行出库排序
*/
private static List<DataLog> sortTailTasks(List<DataLog> tailTasks){
Multimap<Integer,DataLog> slotTaskMap = HashMultimap.create();
Set<Integer> slotSet = new HashSet<>();
for (DataLog dataLog : tailTasks) {
slotTaskMap.put(dataLog.getAppendInfo().getSlotIndex(), dataLog);
slotSet.add(dataLog.getAppendInfo().getSlotIndex());
}
List<DataLog> sortList = new ArrayList<>();
int outOrder = 0;
while(outOrder < tailTasks.size()){
for (Integer slot : slotSet) {
Collection<DataLog> slotTasks = slotTaskMap.get(slot);
DataLog maxNumtask = null;
for (DataLog slotTask : slotTasks) {
if(maxNumtask == null || slotTask.getNum() > maxNumtask.getNum()){
maxNumtask = slotTask;
}
}
if(maxNumtask != null){
outOrder = outOrder + 1;
maxNumtask.setOutOrder(outOrder);
sortList.add(maxNumtask);
slotTaskMap.remove(slot,maxNumtask);
}
}
}
return sortList;
}
private static DataLog newDataLog(int slotIndex, int num){
DataLog d1 = new DataLog();
AppendInfo appendInfo = new AppendInfo();
appendInfo.setSlotIndex(slotIndex);
d1.setAppendInfo(appendInfo);
d1.setNum(num);
return d1;
}
}
......@@ -645,6 +645,11 @@ public class StorageConstants {
public static String E = "E";
/**
* F料架1-26放小料, 27-31放大料
*/
public static String F = "F";
/**
* 带包装料架
*/
public static boolean isAShelf(String type){
......@@ -668,6 +673,12 @@ public class StorageConstants {
public static boolean isDShelf(String type){
return judgeType(type, D);
}
/**
* 混合料架
*/
public static boolean isFShelf(String type){
return judgeType(type, F);
}
public static boolean judgeType(String type, String targetType){
if(type != null && type.contains(targetType)){
......
......@@ -369,6 +369,7 @@ public class OutInfoCache {
* 将需求单加入到缓存
*/
public void addOutInfo(OutInfo outInfo){
if(outInfo != null){
//先把缓存清理掉,从数据库中查询
String hserial =outInfo.gethSerial();
if(!hserial.isEmpty() && !outInfo.isSendEnd() && !outInfo.isClosed()){
......@@ -386,6 +387,7 @@ public class OutInfoCache {
}
}
}
}
......@@ -985,12 +987,6 @@ public class OutInfoCache {
List<DataLog> tasks = new ArrayList<>();
List<String> allreadyOutPosIdList = new ArrayList<>();
// if(outInfo.isTailAction()){
// //尾料单独处理
//
//
// }else{
List<OutItem> itemList = outInfo.getOutItems();
itemList.sort(new Comparator<OutItem>(){
......@@ -1019,7 +1015,6 @@ public class OutInfoCache {
if(itemTasks != null && !itemTasks.isEmpty()){
for (DataLog itemTask : itemTasks) {
allreadyOutPosIdList.add(itemTask.getPosId());
tasks.add(itemTask);
}
boolean needAddToTotal = false;
......@@ -1034,8 +1029,7 @@ public class OutInfoCache {
int outReelNum = tasks.size();
if(outReelNum > 0){
//补料出库,且不是缺料重发,需要重新排序,按站位序号循环出,每次出最大的盘
if(outInfo.isTailAction() && !outInfoExecuted){
tasks = fixDShelf(outInfo, allreadyOutPosIdList, tasks);
if(!outInfoExecuted){
tasks = sortTailTasks(tasks);
outReelNum = tasks.size();
}
......@@ -1079,199 +1073,6 @@ public class OutInfoCache {
/**
* 补满或删除料架逻辑
*/
private List<DataLog> fixDShelf(OutInfo outInfo, List<String> allreadyOutPosIdList, List<DataLog> tasks){
String lineHasBindShelf = QisdaApi.GetSerialData(outInfo.getLine(),outInfo.gethSerial());
int shelfCountToLine = shelfCountToLine(outInfo.getSoseq(),lineHasBindShelf);
List<ShelfInfo> allDShelfs = InquiryShelfBean.getAllDShelf(outInfo.gethSerial());
try{
log.info("产线可放料架数:"+shelfCountToLine+" 需求单["+outInfo.gethSerial()+"]分配小料架数:" + allDShelfs.size());
if(shelfCountToLine > 0 && shelfCountToLine < allDShelfs.size()){
//产线不可放下那么多料架,需要删减一车
int dShelfToRemove = allDShelfs.size() - shelfCountToLine;
tasks = removeTailDShelf(outInfo,allDShelfs,tasks,dShelfToRemove);
}else{
tasks = fillTailDShelf(outInfo,allDShelfs, allreadyOutPosIdList,tasks);
}
}catch (Exception e){
log.error("料架修正逻辑出错",e);
}
return tasks;
}
/**
* 清除多出来的料架
*/
private List<DataLog> removeTailDShelf(OutInfo outInfo, List<ShelfInfo> allDShelfs, List<DataLog> tasks, int removeDShelfCount){
List<ShelfInfo> dShelfToRemoveList = new ArrayList<>();
while(dShelfToRemoveList.size() < removeDShelfCount){
ShelfInfo dShelfToRemove = null;
for (ShelfInfo dShelf : allDShelfs) {
if(!dShelfToRemoveList.contains(dShelf)){
if(dShelfToRemove == null || dShelfToRemove.getRfidIndex()< dShelf.getRfidIndex()){
dShelfToRemove = dShelf;
}
}
}
if(dShelfToRemove != null){
dShelfToRemoveList.add(dShelfToRemove);
}else{
break;
}
}
boolean hasTaskCancel = false;
for(ShelfInfo dShelfToRemove : dShelfToRemoveList){
int needRemoveReelCount = dShelfToRemove.getUsedLocCount();
if(needRemoveReelCount > 0){
log.info("需求单["+outInfo.gethSerial()+"]的料架["+dShelfToRemove.tempRfid()+"]超出产线可容纳数量,开启删减D料架逻辑,数量:" + needRemoveReelCount);
//站位料盘数统计
Map<Integer,Integer> slotReelCountMap = new HashMap<>();
for (DataLog task : tasks) {
if(task.getAppendInfo().isDShelfTask()){
int slotIndex = task.getAppendInfo().getSlotIndex();
Integer reelCount = slotReelCountMap.get(slotIndex);
if(reelCount == null){
reelCount = 0;
}
reelCount = reelCount + 1;
slotReelCountMap.put(slotIndex,reelCount);
}
}
while(needRemoveReelCount > 0){
Map.Entry<Integer, Integer> maxCountEntry = null;
for (Map.Entry<Integer, Integer> entry : slotReelCountMap.entrySet()) {
if(maxCountEntry == null || entry.getValue() > maxCountEntry.getValue()){
maxCountEntry = entry;
}
}
DataLog taskToRemove = null;
for (DataLog task : tasks) {
AppendInfo appendInfo = task.getAppendInfo();
if(appendInfo.isDShelfTask() && appendInfo.getSlotIndex() == maxCountEntry.getKey()){
//与料盘数最多的站位相同的D料架任务,找最小的一盘
if(taskToRemove == null || task.getNum() < taskToRemove.getNum()){
taskToRemove = task;
}
}
}
if(taskToRemove != null){
hasTaskCancel = true;
taskToRemove.setStatus(StorageConstants.OP_STATUS.CANCEL.name());
dataLogDao.save(taskToRemove);
tasks.remove(taskToRemove);
needRemoveReelCount = needRemoveReelCount -1;
log.info(taskToRemove.getBarcode()+"任务取消,剩余待取消任务数量:" + needRemoveReelCount);
InquiryShelfBean.cancelReelTask(taskToRemove);
int taskSlotIndex = taskToRemove.getAppendInfo().getSlotIndex();
int slotReelCount = slotReelCountMap.get(taskSlotIndex);
slotReelCount = slotReelCount -1;
slotReelCountMap.put(taskSlotIndex,slotReelCount);
}else{
break;
}
}
}
}
if(hasTaskCancel && outInfo.isEndOutInfo()){
String soseq = outInfo.getSoseq();
log.info("需求单["+outInfo.gethSerial()+"]是工单序号["+soseq+"]最后一个补料单,删减料架后更新补料单状态,同时更新Qisda补料单状态");
boolean endOutInfo = false;
outInfo.setEndOutInfo(endOutInfo);
outInfoDao.updateEndOutInfo(outInfo.gethSerial(),endOutInfo);
outInfoMap.put(outInfo.gethSerial(), outInfo);
QisdaApi.UpdateBatchRefillMark(soseq);
}
return tasks;
}
/**
* 把料架填满
*/
private List<DataLog> fillTailDShelf(OutInfo outInfo, List<ShelfInfo> allDShelfs, List<String> allreadyOutPosIdList, List<DataLog> tasks){
//补满一车
ShelfInfo dShelfToFill = null;
for (ShelfInfo dShelf : allDShelfs) {
if(!dShelf.reachMaxLoc()){
dShelfToFill = dShelf;
break;
}
}
if(dShelfToFill != null){
int reelCountToFill = dShelfToFill.getMaxLocCount() - dShelfToFill.getUsedLocCount();
log.info("需求单["+outInfo.gethSerial()+"]的料架["+dShelfToFill.tempRfid()+"]还差["+reelCountToFill+"]盘料未放满,开启补满逻辑");
//是否已放满,未放满的话,每个站别补一盘补满
List<StoragePos> allBindPosList = storagePosDao.listSoSeqBindPos(outInfo.getSoseq());
Map<Integer,OutItemBindBean> itemBindMap = new HashMap<>();
for (StoragePos pos : allBindPosList) {
if(!allreadyOutPosIdList.contains(pos.getId()) && pos.getBarcode().isSmallReel()){
//正常流程未出料盘
int slotIndex = pos.getBarcode().getAppendInfo().getSlotIndex();
OutItem outItem = outInfo.findOutItem(slotIndex);
if(outItem != null){
//必须包含才能出,不然出库完成时会有问题
OutItemBindBean itemBindBean = itemBindMap.get(slotIndex);
if(itemBindBean == null){
itemBindBean =new OutItemBindBean(outItem);
}
itemBindBean.addBindPos(pos);
itemBindMap.put(slotIndex,itemBindBean);
}
}
}
if(!itemBindMap.isEmpty()){
List<OutItemBindBean> itemBindBeanList = new ArrayList<>(itemBindMap.values());
itemBindBeanList.sort(new Comparator<OutItemBindBean>() {
@Override
public int compare(OutItemBindBean o1, OutItemBindBean o2) {
return o2.getBindReelCount().compareTo(o1.getBindReelCount());
}
});
while (reelCountToFill > 0){
int remainBindCount = 0;
for (OutItemBindBean outItemBindBean : itemBindBeanList) {
StoragePos pos = outItemBindBean.takeOnePos();
if(pos != null){
reelCountToFill--;
OutItem outItem = outItemBindBean.getOutItem();
DataLog task = newTask(outItem, pos);
task = InquiryShelfBean.addUnlimitLoc(task, outItem);
task = dataLogDao.save(task);
tasks.add(task);
boolean needAddToTotal = false;
boolean outInfoExecuted = false;
resetTaskNum(outItem.gethSerial(), tasks.size(),outInfoExecuted,needAddToTotal);
updateOutItem(outItem.getId());
}
remainBindCount = remainBindCount + outItemBindBean.getBindReelCount();
if(reelCountToFill<=0){
break;
}
}
if(remainBindCount == 0 || reelCountToFill <= 0){
break;
}
}
}
}
return tasks;
}
/**
* 对补料任务进行出库排序
*/
private List<DataLog> sortTailTasks(List<DataLog> tailTasks){
......@@ -1482,38 +1283,15 @@ public class OutInfoCache {
DataLog task = newTask(outItem, maxQtyPos);
if(lessSend){
task.setLessSendReel(lessSend);
InquiryShelfBean.addUnlimitLoc(task, outItem);
//InquiryShelfBean.addUnlimitLoc(task, outItem);
}else{
task = InquiryShelfBean.addLimitLoc(task, outItem);
//task = InquiryShelfBean.addLimitLoc(task, outItem);
}
task = InquiryShelfBean.addUnlimitLoc(task, outItem);
task = dataLogDao.save(task);
tasks.add(task);
}else{
//缺料重发不需要保留位置
if(!lessSend){
//缺料,查看是否有本工单,同PN的,如果有抢一个过来
//缺料,料架留空
boolean hasBigSizePn = false;
List<Component> pnList = componentManager.listByPn(outItem.getPn());
for (Component c : pnList) {
if(c.getPlateSize() > 7 || c.getHeight() > 12){
hasBigSizePn = true;
break;
}
}
if(pnList.isEmpty()){
log.error("未找到物料["+outItem.getPn()+"]的尺寸信息,保留C类型架位");
InquiryShelfBean.addEmptyLoc(outItem, StorageConstants.SHEFL_TYPE.C);
}else if(hasBigSizePn){
log.info(outItem.getSlotlocation() + "["+outItem.getPn()+"]缺料,且PN数据中有大料,保留C类型架位");
InquiryShelfBean.addEmptyLoc(outItem, StorageConstants.SHEFL_TYPE.C);
}else {
log.info(outItem.getSlotlocation() + "["+outItem.getPn()+"]缺料,保留D类型架位");
InquiryShelfBean.addEmptyLoc(outItem, StorageConstants.SHEFL_TYPE.D);
}
}
log.error("物料["+outItem.getPn()+"]无库存");
}
return tasks;
}
......
......@@ -62,41 +62,13 @@ public class QisdaDeviceController extends BaseController {
protected final static Logger log = LogManager.getLogger(QisdaDeviceController.class);
/**
* 第一台机器人缓存位置信息(流水线扫码后获取尺寸时更新)
*/
private DataLog firstRobotTask = null;
private DataLog firstScanTask = null;
/**
* 第二台机器人缓存位置信息(流水线扫码后获取尺寸时更新)
*/
private DataLog secondRobotTask = null;
private DataLog secondScanTask = null;
/**
* 流水线根据条码及机器人工位获取尺寸信息,同时为料盘锁定架位
*/
@RequestMapping(value = "/getSize")
@ResponseBody
public ResultBean getSize(HttpServletRequest request) {
try{
String robotIndex = request.getParameter("robotIndex");
String barcodeStr = request.getParameter("barcode");
log.info("料盘到达机器人["+robotIndex+"]扫码位置,开始获取["+ barcodeStr +"]的尺寸信息");
if(robotIndex == null){
return ResultBean.newErrorResult(-2, "参数错误:无robotIndex参数");
}
if(!robotIndex.equals("1") && !robotIndex.equals("2")){
return ResultBean.newErrorResult(-2, "参数错误:robotIndex参数只能为1或2");
}
//清空扫码缓存信息
updateScanTask(robotIndex, null);
//Barcode barcode = dataCache.resolveOneValideBarcode(barcodeStr);
Collection<CodeBean> codeBeans = dataCache.resolveCodeStr(barcodeStr);
Barcode barcode = null;
for (CodeBean codeBean : codeBeans) {
......@@ -107,7 +79,6 @@ public class QisdaDeviceController extends BaseController {
}else{
barcode = codeBean.getBarcode();
}
}
}
if(barcode == null){
......@@ -135,18 +106,10 @@ public class QisdaDeviceController extends BaseController {
String msg = "料盘["+barcode.getBarcode()+"]任务的需求单号与当前正在执行的需求单号不一致,不返回尺寸信息";
return ResultBean.newErrorResult(106, msg);
}
boolean firstRobtoSame = isSameTask(barcode,firstRobotTask);
boolean secondRobtoSame = isSameTask(barcode,secondRobotTask);
if (firstRobtoSame || secondRobtoSame){
String msg = "机器人正在将料盘["+barcode.getBarcode()+"]的放上料架,不返回尺寸信息";
return ResultBean.newErrorResult(107, msg);
}
}
}
updateScanTask(robotIndex, task);
log.info("返回机器人["+robotIndex+"]barcode=["+task.getBarcode()+"]的尺寸:" + task.getW());
log.info("返回barcode=["+task.getBarcode()+"]的尺寸:" + task.getW());
return ResultBean.newOkResult(task.getW() + "");
}catch(ValidateException e){
......@@ -158,21 +121,7 @@ public class QisdaDeviceController extends BaseController {
}
}
/**
* 更新相机扫码任务
* @param robotIndex
* @param task
*/
private void updateScanTask(String robotIndex, DataLog task){
if(robotIndex != null){
if(robotIndex.equals("1")){
//1号位机器人
firstScanTask = task;
}else if(robotIndex.equals("2")){
secondScanTask = task;
}
}
}
/**
* 判断条码是否与扫码和机器人工位的条码一致
......@@ -192,47 +141,9 @@ public class QisdaDeviceController extends BaseController {
@RequestMapping(value = "/arrive3fRobotLocation")
@ResponseBody
public Object arrive3fRobotLocation(HttpServletRequest request){
String robotIndex = request.getParameter("robotIndex");
String codeStr = request.getParameter("barcode");
//更新位置任务,清空扫码任务
log.info("料盘["+codeStr+"]到达机器人["+robotIndex+"]取料位置,更新位置任务");
if(robotIndex != null){
try{
Barcode barcode = dataCache.resolveOneValideBarcode(codeStr);
DataLog task = taskService.getFinishedTask(barcode.getBarcode());
if(task == null){
String msg = "未找到待分配位置的条码["+barcode.getBarcode()+"]任务信息";
return ResultBean.newErrorResult(203, msg);
}else {
if (task.isFinished()) {
String msg = "条码[" + barcode.getBarcode() + "]的任务已完成";
return ResultBean.newErrorResult(204, msg);
} else if (task.isStopSendToQisda()) {
//被取消的出库任务,不可再放上料架
String msg = "条码[" + barcode.getBarcode() + "]的任务已被取消";
return ResultBean.newErrorResult(207, msg);
} else {
String hSerial = task.getAppendInfo().gethSerial();
String executingHSerial = QisdaCache.getCurrentOrderHSerial();
if (!executingHSerial.equals(hSerial)) {
String msg = "料盘[" + barcode.getBarcode() + "]任务的需求单号与当前正在执行的需求单号不一致";
return ResultBean.newErrorResult(206, msg);
}
}
}
if(robotIndex.equals("1")){
//1号位机器人
firstRobotTask = task;
log.info("将扫码任务["+firstRobotTask.getBarcode()+"]设置到机器人["+robotIndex+"]取料任务");
}else if(robotIndex.equals("2")){
secondRobotTask = task;
log.info("将扫码任务["+secondRobotTask.getBarcode()+"]设置到机器人["+robotIndex+"]取料任务");
}
}catch(Exception e){
log.error("料盘到达机器人出错:",e);
return ResultBean.newErrorResult(-1, "Error:" + e.getMessage());
}
}
log.info("料盘["+codeStr+"]到达取料位置");
return ResultBean.newOkResult("OK");
}
......@@ -243,239 +154,51 @@ public class QisdaDeviceController extends BaseController {
@RequestMapping(value = "/arriveRobotLocation")
@ResponseBody
public Object arriveRobot(HttpServletRequest request){
String robotIndex = request.getParameter("robotIndex");
String codeStr = request.getParameter("barcode");
//更新位置任务,清空扫码任务
log.info("料盘["+codeStr+"]到达机器人["+robotIndex+"]取料位置,更新位置任务,清空扫码任务");
if(robotIndex != null){
try{
Barcode barcode = dataCache.resolveOneValideBarcode(codeStr);
if(robotIndex.equals("1")){
//1号位机器人
boolean firstRobtoSame = isSameTask(barcode,firstRobotTask);
if(firstRobtoSame){
//已经到达过一次,直接忽略
log.info("机器人["+robotIndex+"]当前取料任务与条码["+barcode.getBarcode()+"]一致,不再更新位置任务");
return "OK";
}
firstRobotTask = firstScanTask;
log.info("将扫码任务["+firstRobotTask.getBarcode()+"]设置到机器人["+robotIndex+"]取料任务");
}else if(robotIndex.equals("2")){
boolean secondRobtoSame = isSameTask(barcode,secondRobotTask);
if(secondRobtoSame){
//已经到达过一次,直接忽略
log.info("机器人["+robotIndex+"]当前取料任务与条码["+barcode.getBarcode()+"]一致,不再更新位置任务");
return "OK";
}
secondRobotTask = secondScanTask;
log.info("将扫码任务["+secondRobotTask.getBarcode()+"]设置到机器人["+robotIndex+"]取料任务");
}
updateScanTask(robotIndex, null);
}catch(Exception e){
log.error("料盘到达机器人出错:",e);
return "Error:" + e.getMessage();
}
}
log.info("料盘["+codeStr+"]到达取料位置");
return "OK";
}
/**
* 3号机器人获取摆放位置信息
*/
@RequestMapping(value = "/getPackageLocation")
@ResponseBody
public Object getPackageLocation(HttpServletRequest request) {
try{
String bigRfid = request.getParameter("bigRfid");
//包装料RFID
String packageRfid = request.getParameter("packageRfid");
String hSerial = QisdaCache.getCurrentOrderHSerial();
if(hSerial.isEmpty()){
return ResultBean.newErrorResult(-2, "未找到大料架["+bigRfid+"]");
}
List<DataLog> allTasks = taskService.getAllTasks();
for (DataLog task : allTasks) {
//如果还有小料任务未完成,说明换了需求单了,放行大料架
if(task.isCheckOutTask() && task.isSmallReel() && !task.isPackageReel() && !task.isLessSendReel()){
AppendInfo appendInfo = task.getAppendInfo();
if(appendInfo.isFirstReelAction() || appendInfo.isTailAction()){
return ResultBean.newErrorResult(-3, "还有小料任务,需求单已更换,大料架["+bigRfid+"]放行");
}
}
}
log.info("收到机器人[3]获取包装料摆放位置信息请求:[packageRfid=" + packageRfid + "]bigRfid=" + bigRfid + "当前工单料需求:["+hSerial+"]");
ShelfInfo packageShelf = InquiryShelfBean.findPackageShelf(hSerial, packageRfid);
ShelfInfo bigShelf = InquiryShelfBean.findSameShelf(hSerial,bigRfid);
//未找到,说明是未绑定过的新料架,找相同类型的进行绑定
//未找到已经有实际RFID的料架,查找库位最多的料架
if(bigShelf == null){
log.info("未找到实际绑定的["+bigRfid+"]料架,开始查找序号最小的C型料架");
ShelfInfo maxLocShelf = InquiryShelfBean.findMaxUsedShelf(hSerial, StorageConstants.SHEFL_TYPE.C);
if(maxLocShelf != null){
bigShelf = maxLocShelf;
}else{
log.info(hSerial + "已没有C型料架");
}
}
if(bigShelf != null){
//剩余包装料任务
int packageTask = 0;
for (DataLog task : allTasks) {
if(!task.isFinished() && !task.isCancel() && task.isCheckOutTask()){
if(task.isPackageReel()){
if(!task.isCutReel()){
packageTask = packageTask + 1;
}
}
}
}
String barcode = "";
int packageLoc = -1;
int reelInPackage = 0;
if(packageShelf == null){
log.info("机器人[3]获取包装料摆放位置信息,未找到包装料架["+packageRfid+"]的信息");
}else{
//查找包装料架上的物料
Map<Integer, ShelfLoc> packageLocMap = packageShelf.getLocMap();
for (ShelfLoc shelfLoc : packageLocMap.values()) {
if(!shelfLoc.isEmpty()){
reelInPackage = reelInPackage + 1;
if(barcode.isEmpty()){
barcode = shelfLoc.getBarcode();
packageLoc = shelfLoc.getLoc();
}
}
}
}
AppendInfo taskAppendInfo = null;
if(!barcode.isEmpty()){
//包装料架上有料,且大料架有空位,从大料架上查找空位
DataLog task = taskService.getFinishedTask(barcode);
if(task == null){
String msg = "机器人[3]获取包装料摆放位置信息,未找到条码["+barcode+"]的任务";
log.error(msg);
return ResultBean.newErrorResult(103, msg);
}
taskAppendInfo = task.getAppendInfo();
}
//当前大料架上空位数
int emptyInBig = 0;
int bigLoc = -1;
Map<Integer, ShelfLoc> bigShelfLocMap = bigShelf.getLocMap();
for (ShelfLoc shelfLoc : bigShelfLocMap.values()) {
//这里不能使用包装料的数量(补料盘的料架没有固定位置,不是包装料类型)
if(shelfLoc.isEmpty()){
emptyInBig = emptyInBig + 1;
if(taskAppendInfo != null){
//找到了包装料架上物料的任务才能查找位置
if(bigLoc <= 0){
if(taskAppendInfo.isFirstReelAction()){
//首套料,需要固定位置
if(shelfLoc.isInThisLoc(barcode)){
bigLoc = shelfLoc.getLoc();
}
}else{
//尾料,不需要固定位置,返回机器人架位的同时,锁定此位置
bigShelf.lockForPackage(shelfLoc,barcode);
InquiryShelfBean.updateShelfInfo(bigShelf);
bigLoc = shelfLoc.getLoc();
}
}
}
}
}
if(packageTask == 0){
//log.info("已无包装料任务,更改料架可放包装料数量"+ emptyInBig + "为0");
//emptyInBig = 0;
}
Map<String,Object> resultMap = new HashMap<>();
resultMap.put("barcode", barcode);
//大料架上可放包装料数量
resultMap.put("emptyInBig", emptyInBig);
//包装料架上剩余的包装料数量(包含当前获取的物料)
resultMap.put("reelInPackage", reelInPackage);
resultMap.put("packageTask", packageTask);
resultMap.put("packageRfid", packageRfid);
resultMap.put("packageLoc", packageLoc);
resultMap.put("bigRfid", bigShelf.tempRfid());
resultMap.put("realBigRfid",bigShelf.getRealRfid());
resultMap.put("bigLoc", bigLoc);
log.info("机器人[3]获取包装料摆放位置信息返回:"+resultMap);
return ResultBean.newOkResult(resultMap);
}else{
return ResultBean.newErrorResult(-2, "未找到大料架["+bigRfid+"]");
}
}catch(Exception e){
log.error("包装料摆放位置信息获取出错",e);
return ResultBean.newErrorResult(-1,"包装料摆放位置信息获取出错:" + e.getMessage());
}
}
/**
* 1号2号机器人根据工位获取摆放位置信息
*/
@RequestMapping(value = "/getLocation")
@ResponseBody
public Object getLocation(HttpServletRequest request) {
try{
String robotIndex = request.getParameter("robotIndex");
String rfid = request.getParameter("rfid");
log.info("收到机器人["+robotIndex+"]获取摆放位置信息请求:rfid=" + rfid);
if(robotIndex == null){
return ResultBean.newErrorResult(-2, "参数错误:无robotIndex参数");
}
if(!robotIndex.equals("1") && !robotIndex.equals("2")){
return ResultBean.newErrorResult(-2, "参数错误:robotIndex参数只能为1或2");
}
if(rfid == null){
return ResultBean.newErrorResult(-2, "参数错误:无rfid参数");
}
DataLog task = null;
if(robotIndex != null){
if(robotIndex.equals("1")){
//1号位机器人
task = firstRobotTask;
}else if(robotIndex.equals("2")){
task = secondRobotTask;
String rfid = request.getParameter("rfid");
String codeStr = request.getParameter("barcode");
Barcode barcode = dataCache.resolveOneValideBarcode(codeStr);
DataLog task = taskService.getFinishedTask(barcode.getBarcode());
if(task == null){
String msg = "未找到待分配位置的条码["+barcode.getBarcode()+"]任务信息";
return ResultBean.newErrorResult(203, msg);
}else {
if (task.isFinished()) {
String msg = "条码[" + barcode.getBarcode() + "]的任务已完成";
return ResultBean.newErrorResult(204, msg);
} else if (task.isStopSendToQisda()) {
//被取消的出库任务,不可再放上料架
String msg = "条码[" + barcode.getBarcode() + "]的任务已被取消";
return ResultBean.newErrorResult(207, msg);
} else {
// String hSerial = task.getAppendInfo().gethSerial();
// String executingHSerial = QisdaCache.getCurrentOrderHSerial();
// if (!executingHSerial.equals(hSerial)) {
// String msg = "料盘[" + barcode.getBarcode() + "]任务的需求单号与当前正在执行的需求单号不一致";
// return ResultBean.newErrorResult(206, msg);
// }
}
}
if(task == null){
String msg = "机器人["+robotIndex+"]无缓存位置信息";
log.info(msg);
return ResultBean.newErrorResult(201, msg);
}
AppendInfo appendInfo = task.getAppendInfo();
ShelfLoc shelfLoc = null;
if(appendInfo.isFirstReelAction()){
//首盘料已经固定好库位了
shelfLoc = InquiryShelfBean.getLimitLoc(task);
}else{
shelfLoc = InquiryShelfBean.lockShelfLoc(task, rfid, robotIndex);
}
ShelfLoc shelfLoc = InquiryShelfBean.lockShelfLoc(task, rfid);
if(shelfLoc == null){
String msg = "机器人["+robotIndex+"]获取料架["+rfid+"]位置信息失败";
String msg = "获取料架["+rfid+"]位置信息失败";
log.info(msg);
return ResultBean.newErrorResult(202, msg);
}
......@@ -491,7 +214,7 @@ public class QisdaDeviceController extends BaseController {
task.setAppendInfo(appendInfo);
task.setStatus(StorageConstants.OP_STATUS.INROBOT.name());
task.setLocInfo(robotIndex);
task.setLocInfo("");
task = dataLogDao.save(task);
taskService.updateFinishedTask(task);
......@@ -510,7 +233,7 @@ public class QisdaDeviceController extends BaseController {
resultMap.put("usedRfidList",String.join(",",usedRfidList));
resultMap.put("rfidLoc", shelfLoc.getLoc() + "");
log.info("机器人["+robotIndex+"]位置信息返回:[realRfid="+shelfLoc.getRealRfid()+",rfid=[" + shelfLoc.getTempRfid() + "]["+shelfLoc.getLoc()+"] barcode=["+task.getBarcode()+"]尺寸"+task.getW()+"x"+task.getH());
log.info("位置信息返回:[realRfid="+shelfLoc.getRealRfid()+",rfid=[" + shelfLoc.getTempRfid() + "]["+shelfLoc.getLoc()+"] barcode=["+task.getBarcode()+"]尺寸"+task.getW()+"x"+task.getH());
return ResultBean.newOkResult(resultMap);
}catch(Exception e){
......@@ -553,31 +276,7 @@ public class QisdaDeviceController extends BaseController {
return task;
}
/**
* 查找包装料架的剩余任务数
*/
@RequestMapping(value = "/packageShelfTask")
@ResponseBody
public ResultBean packageShelfTask(HttpServletRequest request) {
String rfid = request.getParameter("rfid");
if(rfid == null){
rfid = "";
}
//InquiryShelfBean.findSameShelf()
ShelfInfo shelfInfo = InquiryShelfBean.findSameShelf(InquiryShelfBean.URGENT_SHELF_MAP_KEY,rfid);
if(shelfInfo == null){
shelfInfo = InquiryShelfBean.findSameShelf(InquiryShelfBean.CUT_SHELF_MAP_KEY,rfid);
}
String tempRfid = "";
if(shelfInfo != null){
tempRfid = shelfInfo.tempRfid();
}
Map<String,Object> resultMap = new HashMap<>();
resultMap.put("tempRfid", tempRfid);
return ResultBean.newOkResult(resultMap);
}
/**
......@@ -724,11 +423,10 @@ public class QisdaDeviceController extends BaseController {
DataLog task = findFinishedTask(barcode);
String tempRfid = "";
if(task != null && !task.isCancel()){
ShelfLoc shelfLoc = InquiryShelfBean.putInCutReel(task,rfid, Integer.valueOf(rfidLoc));
if(shelfLoc != null){
boolean putResult = InquiryShelfBean.putInShelf(task,rfid, Integer.valueOf(rfidLoc));
if(putResult){
log.info("["+cid+"]紧急/分盘料[" + barcode + "]放入"+rfid+"[" + rfidLoc + "]成功");
task.setStatus(StorageConstants.OP_STATUS.FINISHED.name());
rfidLoc = shelfLoc.getLoc() + "";
}else{
if(task.isLessSendReel()){
task.setStatus(StorageConstants.OP_STATUS.FINISHED.toString());
......@@ -846,21 +544,21 @@ public class QisdaDeviceController extends BaseController {
task.setStatus(statusStr);
task.setLocInfo(locInfo);
if(task.isInBelt() || task.isPackageReel()){
//已经放上皮带线
AppendInfo appendInfo = task.getAppendInfo();
if(Strings.isBlank(appendInfo.gethSerial())){
log.info("手动出库料盘["+barcode+"]放上皮带线或包装料架,结束任务");
task.setStatus(StorageConstants.OP_STATUS.FINISHED.name());
}else if(appendInfo.isCheckAction()){
log.info("盘点料盘["+barcode+"]放上皮带线或包装料架,结束任务");
task.setStatus(StorageConstants.OP_STATUS.FINISHED.name());
//盘点料,出到皮带线上即算完成
int slotSeq = appendInfo.getSlotIndex();
int sendQty = task.getNum();
outInfoCache.incTaskFinishNum(appendInfo.gethSerial(),slotSeq, sendQty);
}
}
// if(task.isInBelt() || task.isPackageReel()){
// //已经放上皮带线
// AppendInfo appendInfo = task.getAppendInfo();
// if(Strings.isBlank(appendInfo.gethSerial())){
// //log.info("手动出库料盘["+barcode+"]放上皮带线或包装料架,结束任务");
// //task.setStatus(StorageConstants.OP_STATUS.FINISHED.name());
// }else if(appendInfo.isCheckAction()){
// log.info("盘点料盘["+barcode+"]放上皮带线或包装料架,结束任务");
// task.setStatus(StorageConstants.OP_STATUS.FINISHED.name());
// //盘点料,出到皮带线上即算完成
// int slotSeq = appendInfo.getSlotIndex();
// int sendQty = task.getNum();
// outInfoCache.incTaskFinishNum(appendInfo.gethSerial(),slotSeq, sendQty);
// }
// }
task = dataLogDao.save(task);
......@@ -869,50 +567,6 @@ public class QisdaDeviceController extends BaseController {
taskService.updateFinishedTask(task);
}
//包装料
if(task.isPackageReel()){
String[] infos = locInfo.split("@");
String rfid = infos[0];
String rfidLoc = infos[1];
InquiryShelfBean.putInShelf(task,rfid, Integer.valueOf(rfidLoc));
//剩余任务数
String taskCid = task.getCid();
Date taskDate = task.getCreateDate();
Collection<DataLog> waitTasks = taskService.getQueueTasks();
int taskCount = 0;
int packageCutShelf = 0;
int packageUrgentTask = 0;
//同一个料仓的出库任务(等待中和正在执行的)
for (DataLog waitTask : waitTasks) {
String waitCid = waitTask.getCid();
Date waitTaskDate = waitTask.getCreateDate();
if(waitTask.isCheckOutTask() && waitCid != null && waitCid.equals(taskCid) && waitTaskDate.equals(taskDate)){
taskCount = taskCount + 1;
}
if(waitTask.isCheckOutTask() && waitTask.isPackageReel()){
if(waitTask.isCutReel()){
packageCutShelf = packageCutShelf + 1;
}else if(waitTask.isUrgentReel() || waitTask.isLessSendReel() || waitTask.getAppendInfo().isCheckAction()){
packageUrgentTask = packageUrgentTask + 1;
}
}
}
InquiryShelfBean.clearCutUrgentPackageShelf(InquiryShelfBean.CUT_SHELF_MAP_KEY);
InquiryShelfBean.clearCutUrgentPackageShelf(InquiryShelfBean.URGENT_SHELF_MAP_KEY);
Map<String,Object> resultMap = new HashMap<>();
resultMap.put("taskCount",taskCount+"");
return ResultBean.newOkResult(resultMap);
}
return ResultBean.newOkResult("");
}
......@@ -983,51 +637,6 @@ public class QisdaDeviceController extends BaseController {
}
return false;
}
/**
* 包装线机器人从A包装料架放到C大料架上barcode
*/
@RequestMapping(value = "/putPackageFinished")
@ResponseBody
public Object putPackageFinished(HttpServletRequest request) {
//A料架肯定要存在
String packageRfid = request.getParameter("packageRfid");
String bigRfid = request.getParameter("bigRfid");
String packageLoc = request.getParameter("packageLoc");
String bigLoc = request.getParameter("bigLoc");
String barcode = request.getParameter("barcode");
String msg = "机器人[3]将包装料盘["+barcode+"]从"+packageRfid+"["+packageLoc+"]放入料架=>"+bigRfid+"["+bigLoc+"]";
log.info(msg);
if(Strings.isNotBlank(barcode)) {
DataLog cacheTask = taskService.getFinishedTask(barcode);
if (cacheTask == null) {
return ResultBean.newErrorResult(501,msg+"失败, 料盘[" + barcode + "]的任务不存在");
} else {
boolean putInResult = reelPutInFinished(cacheTask,bigRfid, bigLoc);
if(putInResult){
//清理包装料架的位置
ShelfInfo packageShelf = InquiryShelfBean.findPackageShelf(cacheTask.getAppendInfo().gethSerial(), packageRfid);
if(packageShelf != null){
log.info(msg + "成功,清空包装料架信息");
Map<Integer, ShelfLoc> packageLocMap = packageShelf.getLocMap();
for (ShelfLoc shelfLoc : packageLocMap.values()) {
if(shelfLoc.isInThisLoc(barcode)){
shelfLoc.setEmpty(true);
packageLocMap.put(shelfLoc.getLoc(), shelfLoc);
packageShelf.setLocMap(packageLocMap);
InquiryShelfBean.updateShelfInfo(packageShelf);
return ResultBean.newOkResult(null);
}
}
}else{
return ResultBean.newErrorResult(502,msg + "失败,未找到包装料架["+packageRfid+"]的缓存信息");
}
}
}
}
String errorMsg = "包装线机器人放置料盘["+barcode+"]从"+packageRfid+"["+packageLoc+"]=>"+bigRfid+"["+bigLoc+"]失败";
return ResultBean.newErrorResult(501,errorMsg);
}
/**
* 放置到料架动作完成,返回当前料架还可放置的数量,用任务总数
......@@ -1035,7 +644,6 @@ public class QisdaDeviceController extends BaseController {
@RequestMapping(value = "/putShelfFinished")
@ResponseBody
public Object putShelfFinished(HttpServletRequest request) {
String robotIndex = request.getParameter("robotIndex");
String rfid = request.getParameter("rfid");
String rfidLoc = request.getParameter("rfidLoc");
String barcode = request.getParameter("barcode");
......@@ -1049,25 +657,6 @@ public class QisdaDeviceController extends BaseController {
if (cacheTask == null) {
log.error("料盘[" + barcode + "]的任务不存在");
} else {
if(Strings.isNotBlank(robotIndex)){
if(robotIndex.equals("1") && firstRobotTask != null){
if(firstRobotTask.getBarcode().equals(barcode)){
log.info("机器人["+robotIndex+"]将料盘["+barcode+"]放入料架["+rfid+"]["+rfidLoc+"]完成,任务一致,清空机器人任务");
//1号位机器人
firstRobotTask = null;
}else{
log.info("机器人["+robotIndex+"]将料盘["+barcode+"]放入料架["+rfid+"]["+rfidLoc+"]完成,与当前任务["+firstRobotTask.getBarcode()+"]不一致,不清空");
}
}else if(robotIndex.equals("2") && secondRobotTask != null){
if(secondRobotTask.getBarcode().equals(barcode)){
//1号位机器人
log.info("机器人["+robotIndex+"]将料盘["+barcode+"]放入料架["+rfid+"]["+rfidLoc+"]完成,任务一致,清空机器人任务");
secondRobotTask = null;
}else{
log.info("机器人["+robotIndex+"]将料盘["+barcode+"]放入料架["+rfid+"]["+rfidLoc+"]完成,与当前任务["+secondRobotTask.getBarcode()+"]不一致,不清空");
}
}
}
reelPutInFinished(cacheTask,rfid, rfidLoc);
}
}
......@@ -1186,7 +775,7 @@ public class QisdaDeviceController extends BaseController {
return ResultBean.newOkResult(resultMap);
}catch(Exception e){
log.error("机器人放料完成信息出错robotIndex="+robotIndex+";rfid="+rfid+";rfidLoc="+rfidLoc+";barcode="+barcode,e);
log.error("机器人放料完成信息出错rfid="+rfid+";rfidLoc="+rfidLoc+";barcode="+barcode,e);
}
return "";
......@@ -1222,68 +811,7 @@ public class QisdaDeviceController extends BaseController {
}
/**
* 包装料仓空闲仓位数量
*/
@RequestMapping(value = "/emptyStoragePosCount")
@ResponseBody
public ResultBean emptyStoragePosCount(HttpServletRequest request) {
Map<String,Object> resultMap = new HashMap<>();
try {
Map<String, Storage> allStorage = dataCache.getAllStorage();
for (Storage storage : allStorage.values()) {
if(storage.isPackage()){
String cidTaskCountKey = storage.getCid() + "-taskCount";
//包装料仓
resultMap.put(storage.getCid(), storage.getEmptySlots()+"");
resultMap.put(cidTaskCountKey, 0);
}
}
try{
Collection<DataLog> queueTasks = taskService.getQueueTasks();
for (DataLog queueTask : queueTasks) {
if(queueTask.isPackageReel()){
String cidTaskCountKey = queueTask.getCid() + "-taskCount";
Object cidTaskCountObj = resultMap.get(cidTaskCountKey);
Integer cidTaskCount = Integer.valueOf(cidTaskCountObj.toString());
cidTaskCount = cidTaskCount + 1;
resultMap.put(cidTaskCountKey, cidTaskCount);
}
}
}catch (Exception e){
log.error("获取包装料空闲仓位时,计算任务数出错",e);
}
}catch (Exception e){
log.error("获取包装料仓空闲仓位出错",e);
}
return ResultBean.newOkResult(resultMap);
}
/**
* 包装线AGV获取料架中的任务数,如果当前料架的任务数不为0,需要用当前料架去其他包装仓继续放料
*/
@RequestMapping(value = "/shelfTaskCount")
@ResponseBody
public ResultBean taskInShelf(HttpServletRequest request){
String rfid = request.getParameter("rfid");
ShelfInfo shelfInfo = InquiryShelfBean.findShelf(rfid);
int taskCount = 0;
String msg = "ok";
if(shelfInfo != null){
taskCount = shelfInfo.getEmptyLocCount();
}else{
log.info("AGV获取料架["+rfid+"]中的剩余任务数时未找到包装料架");
msg = "未找到包装料架"+rfid;
}
Map<String,Object> resultMap = new HashMap<>();
resultMap.put("taskCount",taskCount);
resultMap.put("rfid",rfid);
log.info("AGV获取料架["+rfid+"]中的剩余任务数:" + taskCount);
return ResultBean.newOkResult(msg, resultMap);
}
/**
* 库位物料检测接口
......@@ -1425,35 +953,7 @@ public class QisdaDeviceController extends BaseController {
}
}
/**
* AGV锁定包装仓入库料架, AGV从VMI拉上包装料架准备入库时,调用此接口,用于包装仓判断料架是否是入库料架
*/
@RequestMapping("/lockPutInAShelf")
@ResponseBody
public ResultBean lockPutInAShelf(HttpServletRequest request) {
String rfid = request.getParameter("rfid");
try {
log.info("AGV锁定料架["+rfid+"]为入库料架");
ReelLockPosInfo reelLocInfo = new ReelLockPosInfo();
reelLocInfo.setBarcode(rfid);
reelLocInfo.setCid(rfid);
reelLocInfo.setLockPosName(rfid);
reelLocInfo.setLockPosId(rfid);
reelLocInfo.setRfid(rfid);
reelLocInfo.setRfidLoc("0");
reelLocInfo = QisdaCache.addReelLockPosInfo(reelLocInfo);
if(reelLocInfo == null){
return ResultBean.newErrorResult(5201,"库位锁定失败");
}else{
ResultBean.newOkResult("");
}
return ResultBean.newOkResult("");
}catch (Exception e){
log.error("锁定包装仓入库料架出错",e);
return ResultBean.newErrorResult(5202,"锁定包装仓入库料架出错:" + e.getMessage());
}
}
/**
* 点料机解析条码,用于获取料盘尺寸
......
......@@ -56,9 +56,6 @@ public class TaskService implements ITaskService {
@Autowired
private IBarcodeManager barcodeManager;
//@Autowired
//private IComponentManager componentManager;
@Autowired
private IDataLogDao dataLogDao;
......@@ -939,15 +936,6 @@ public class TaskService implements ITaskService {
}
}
if(storage.isPackage()){
//包装料按生成顺序进行出库
DataLog packageTask = findEarliestPackageTask(storage);
if(packageTask != null){
log.info("出库最早生成的包装料任务:" + packageTask.getBarcode()+"["+packageTask.getPosName()+"]");
}
return packageTask;
}
//if(DataCache.isProductionFor(DataCache.CUSTOMER.QISDA)){
//分盘料,按时间顺序进行出库
......@@ -962,299 +950,33 @@ public class TaskService implements ITaskService {
}
}
}
if(urgentTask != null){
log.info("出库最先生成的分盘/紧急任务"+urgentTask.getBarcode()+"["+urgentTask.getPosName()+"]");
return urgentTask;
}
//按料架顺序,从小盘开始出库
boolean hasFirstReelAction = false;
//编号最小的料架
int minCRfidIndex = -1;
int minDRfidIndex = -1;
int minARfidIndex = -1;
DataLog outTask = null;
for (DataLog task : waitTasks) {
if(task.isCheckOutTask()) {
AppendInfo appendInfo = task.getAppendInfo();
if(appendInfo.isFirstReelAction() && !task.isLessSendReel()){
//首盘料
hasFirstReelAction = true;
}
int rfidIndex = appendInfo.getRfidIndex();
boolean isAShelf = appendInfo.isAShelfTask();
if(isAShelf){
//包装料最小的料架编号
if(minARfidIndex == -1 || rfidIndex < minARfidIndex){
minARfidIndex = rfidIndex;
}
}
boolean isDShelf = appendInfo.isDShelfTask();;
if(isDShelf){
//小料架
if(minDRfidIndex == -1 || rfidIndex < minDRfidIndex){
minDRfidIndex = rfidIndex;
}
}
boolean isCShelf = appendInfo.isCShelfTask();
if(isCShelf){
//大料架
if(minCRfidIndex == -1 || rfidIndex < minCRfidIndex){
minCRfidIndex = rfidIndex;
}
}
}
}
if(hasFirstReelAction){
return findFirstActionask(storage, minARfidIndex,minDRfidIndex, minCRfidIndex);
}else{
//补料
return findTailActionTask(storage, minARfidIndex,minDRfidIndex, minCRfidIndex);
}
//}
}
/**
* 查找最早生成的且料架号最小的包装料任务
* @return
*/
private DataLog findEarliestPackageTask(Storage storage){
Collection<DataLog> waitTasks = taskMap.values();
DataLog earliestTask = null;
for (DataLog waitTask : waitTasks) {
if(waitTask.isCheckOutTask() && waitTask.isPackageReel()) {
if(earliestTask == null){
earliestTask = waitTask;
}else{
if(earliestTask.getCreateDate().after(waitTask.getCreateDate())){
//时间比当前的任务早
earliestTask = waitTask;
}else if(earliestTask.getCreateDate().equals(waitTask.getCreateDate())){
AppendInfo appendInfo = waitTask.getAppendInfo();
int rfidIndex = appendInfo.getRfidIndex();
if(rfidIndex < earliestTask.getAppendInfo().getRfidIndex()){
earliestTask = waitTask;
}
}
}
}
}
DataLog storageTask = null;
//创建最早,且与最小料架号一致的才出库
if(earliestTask != null){
// if(storage.getCid().equals(earliestTask.getCid())){
// return earliestTask;
// }
for (DataLog waitTask : waitTasks) {
if (storage.getCid().equals(waitTask.getCid()) && waitTask.isPackageReel() && waitTask.isCheckOutTask()) {
if(waitTask.getCreateDate().equals(earliestTask.getCreateDate())){
//与创建最早的任务同时创建的
AppendInfo appendInfo = waitTask.getAppendInfo();
int rfidIndex = appendInfo.getRfidIndex();
if(rfidIndex <= earliestTask.getAppendInfo().getRfidIndex()){
storageTask = waitTask;
break;
}
}
}
//与最小料架号一样的紧急料,修改其他紧急料的时间
// if(earliestTask.isUrgentReel() || earliestTask.isCutReel()){
// if(waitTask.isPackageReel() && waitTask.isWait()){
// if(waitTask.getTempRfid().equals(earliestTask.getTempRfid())){
// Date earliestTaskDate = earliestTask.getCreateDate();
// if(!waitTask.getCreateDate().equals(earliestTaskDate)){
// log.info("修改紧急包装料["+waitTask.getBarcode()+"]的任务创建时间与["+earliestTask.getBarcode()+"]保持一致");
// waitTask.setCreateDate(earliestTaskDate);
// taskMap.put(waitTask.getId(), waitTask);
// }
// }
// }
// }
}
}
return storageTask;
}
/**
* 查找包装料最小料架的任务
*/
private DataLog findPackageMinTask(Storage storage, int minARfidIndex){
DataLog storageTask = null;
if(storage.isPackage()){
//找当前料仓最小料架,最小架位的
for (DataLog task : taskMap.values()) {
if (storage.getCid().equals(task.getCid()) && task.isCheckOutTask() && task.isWait()) {
//按料架顺序
if(minARfidIndex != -1){
AppendInfo appendInfo = task.getAppendInfo();
int rfidIndex = appendInfo.getRfidIndex();
boolean isAShelf = StorageConstants.SHEFL_TYPE.isAShelf(appendInfo.getShelfType());
if(isAShelf && rfidIndex <= minARfidIndex){
if(storageTask == null || appendInfo.getRfidLoc() < storageTask.getAppendInfo().getRfidLoc()){
storageTask = task;
}
}
}
}
}
if(storageTask != null){
log.info("出库首盘料任务[包装料]"+storageTask.getBarcode()+"["+storageTask.getPosName()+"]" + storageTask.getAppendInfo());
}
}
return storageTask;
}
/**
* 查找首盘料出库任务
*/
private DataLog findFirstActionask(Storage storage, int minARfidIndex, int minDRfidIndex, int minCRfidIndex){
DataLog storageTask = null;
//包装料仓
if(storage.isPackage()){
//包装料仓的最小料架的任务
return findPackageMinTask(storage, minARfidIndex);
}else{
//首套料需要先出D料架,再出C料架,并且要按料架顺序
//架位顺序随机,保证左右机器人均衡
boolean locAsc = RandomUtils.nextBoolean();
for (DataLog task : taskMap.values()) {
if(storage.getCid().equals(task.getCid()) && task.isCheckOutTask() && task.isWait()){
AppendInfo appendInfo = task.getAppendInfo();
int rfidIndex = appendInfo.getRfidIndex();
if(minDRfidIndex != -1){
//有小料架(D),出最小的D料架
boolean isDShelf = StorageConstants.SHEFL_TYPE.isDShelf(appendInfo.getShelfType());
if(isDShelf && rfidIndex <= minDRfidIndex){
if(storageTask == null){
storageTask = task;
}else{
if(locAsc){
//升序,取最小的架位
if(appendInfo.getRfidLoc() < storageTask.getAppendInfo().getRfidLoc()){
storageTask = task;
}
}else{
//降序,取最大的架位
if(appendInfo.getRfidLoc() > storageTask.getAppendInfo().getRfidLoc()){
storageTask = task;
}
}
}
}
}else{
//没有小料架(D),那么可以出C料架了
boolean isCShelf = StorageConstants.SHEFL_TYPE.isCShelf(appendInfo.getShelfType());
if(isCShelf && rfidIndex <= minCRfidIndex){
if(storageTask == null){
storageTask = task;
}else{
if(locAsc){
//升序,取最小的架位
if(appendInfo.getRfidLoc() < storageTask.getAppendInfo().getRfidLoc()){
storageTask = task;
}
}else{
//降序,取最大的架位
if(appendInfo.getRfidLoc() > storageTask.getAppendInfo().getRfidLoc()){
storageTask = task;
}
}
}
}
}
}
}
}
if(storageTask != null){
//如果双层线上有两个料架,但任务不属于这两个料架,不允许出库
if(InquiryShelfBean.canCheckOutFistActionTask(storageTask)){
log.info("出库首盘料任务"+storageTask.getBarcode()+"["+storageTask.getPosName()+"]" + storageTask.getAppendInfo());
return storageTask;
}
}
return null;
}
/**
* 查找补料任务
* @return
*/
private DataLog findTailActionTask(Storage storage, int minARfidIndex, int minDRfidIndex, int minCRfidIndex){
//包装料仓,不按顺序,可以同时出
if(storage.isPackage()){
return findPackageMinTask(storage, minARfidIndex);
if(cid.equals(task.getCid()) && task.isCheckOutTask() && task.isWait()) {
//工单料按生成时间顺序,如果生成时间一样,按料架序号和架位号出库
if(outTask == null){
outTask = task;
}else{
//一次性把D料架出完,再出C料架,包装料可以同时出
List<DataLog> waitTasks = new ArrayList<>(taskMap.values());
List<DataLog> allTaskList = new ArrayList<>();
if(!waitTasks.isEmpty()){
allTaskList.addAll(waitTasks);
waitTasks.sort(new Comparator<DataLog>() {
@Override
public int compare(DataLog o1, DataLog o2) {
return o1.getOutOrder() - o2.getOutOrder();
}
});
}
//还有小料架出库任务,出小料架
if(minDRfidIndex != -1){
for (DataLog task : waitTasks) {
if(storage.getCid().equals(task.getCid()) && task.isCheckOutTask() && task.isWait()){
if(task.isSmallReel()){
log.info("出库小料任务"+task.getBarcode()+"["+task.getPosName()+"] outOrder=" + task.getOutOrder());
return task;
}
if(task.getCreateDate().before(outTask.getCreateDate())){
outTask = task;
}else if(task.getCreateDate().equals(outTask.getCreateDate())){
if(task.getOutOrder() < outTask.getOutOrder()){
outTask = task;
}
}
}else{
Collection<DataLog> finishedTasks = finishedTaskMap.values();
if(!finishedTasks.isEmpty()){
allTaskList.addAll(finishedTasks);
}
//未完成的大料数量(正在执行和未放上料架的)
int unFinishedBigTaskCount = 0;
for (DataLog task : allTaskList) {
////非包装料大料任务还未完成(未放入料架),暂时不出大料
if(task.isCheckOutTask() && task.getAppendInfo().isCShelfTask()){
if(!task.isFinished() && !task.isWait() && !task.isCancel()){
unFinishedBigTaskCount = unFinishedBigTaskCount + 1;
}
}
}
for (DataLog task : waitTasks) {
if(storage.getCid().equals(task.getCid()) && task.isCheckOutTask() && task.isWait()){
//开始出大料架,不需要按顺序
if(!task.isSmallReel()){
if(InquiryShelfBean.canCheckOutTailActionTask(task, unFinishedBigTaskCount)){
log.info("出库大料任务"+task.getBarcode()+"["+task.getPosName()+"]");
return task;
}
}
}
}
return outTask;
}
}
return null;
}
@Override
......@@ -1640,13 +1362,18 @@ public class TaskService implements ITaskService {
//手动出库的当做是工单料,放到皮带线上
task.setUrgentReel(true);
AppendInfo appendInfo = task.getAppendInfo();
appendInfo.setShelfType(StorageConstants.SHEFL_TYPE.B);
appendInfo.sethSerial(InquiryShelfBean.URGENT_SHELF_MAP_KEY);
task.setAppendInfo(appendInfo);
task.setType(StorageConstants.OP.CHECKOUT);
task.setStatus(StorageConstants.OP_STATUS.WAIT.name());
task.setSingleOut(isSingleOut);
task = InquiryShelfBean.addUrgentUnlimitLoc(task);
//task.setAppendInfo(pos.getBarcode().getAppendInfo());
//工单出库任务
if(!Strings.isNullOrEmpty(subSourceId)){
......@@ -2062,7 +1789,7 @@ public class TaskService implements ITaskService {
log.error(task.getBarcode()+"的出库任务["+task.getId()+"]清除失败");
}
}catch (Exception e){
log.error(e);
}
finishedTaskMap.put(task.getBarcode(),task);
......@@ -2099,9 +1826,9 @@ public class TaskService implements ITaskService {
if (outLatest.equals("L")) {
log.info("工单[" + outItem.getSo() + "]需求单["+outItem.gethSerial()+"]的最后一盘出库完成,发送缺料通知");
List<OutItem> outItemList = outItemDao.findByHSerial(outItem.gethSerial());
boolean lessBind = false;
QisdaApi.VMILocationOutFeedback(outItemList, lessBind);
//List<OutItem> outItemList = outItemDao.findByHSerial(outItem.gethSerial());
//boolean lessBind = false;
//QisdaApi.VMILocationOutFeedback(outItemList, lessBind);
}
}
}else{
......
......@@ -29,10 +29,6 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-mongodb:1.8.0.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.mongodb:mongo-java-driver:2.12.5" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.slf4j:jcl-over-slf4j:1.7.11" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:1.10.2.RELEASE" level="project" />
<orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-orm:4.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:4.1.6.RELEASE" level="project" />
......
......@@ -30,6 +30,7 @@
<build>
<finalName>smdbox</finalName>
<defaultGoal>install</defaultGoal>
<plugins>
<plugin>
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!