Commit be279abb sunke

包装料机器人逻辑

1 个父辈 57191c57
...@@ -26,6 +26,16 @@ public class InquiryShelfBean { ...@@ -26,6 +26,16 @@ public class InquiryShelfBean {
public static Map<String,Map<String,ShelfInfo>> hSerialShelfMap = new ConcurrentHashMap<>(); public static Map<String,Map<String,ShelfInfo>> hSerialShelfMap = new ConcurrentHashMap<>();
/** /**
* 清理使用过的料架
*/
public static void clearShelf(String hSerial){
if(hSerial != null){
log.info("清理["+hSerial+"]使用的过料架");
hSerialShelfMap.remove(hSerial);
}
}
/**
* 添加限制库位(即库位中只能放入某个条码) * 添加限制库位(即库位中只能放入某个条码)
* @param task * @param task
* @param outItem * @param outItem
...@@ -241,18 +251,20 @@ public class InquiryShelfBean { ...@@ -241,18 +251,20 @@ public class InquiryShelfBean {
* @param packageRfid * @param packageRfid
* @return * @return
*/ */
public ShelfInfo findPackageShelf(String packageRfid){ public ShelfInfo findPackageShelf(String hSerial, String packageRfid){
if(packageRfid == null){ if(packageRfid == null){
return null; return null;
} }
for (Map<String, ShelfInfo> shelfInfoMap : hSerialShelfMap.values()) { Map<String, ShelfInfo> shSerialShelfInfoMap = hSerialShelfMap.get(hSerial);
for (ShelfInfo shelf : shelfInfoMap.values()) { if(shSerialShelfInfoMap == null ){
String shelfRFID = shelf.getRealRfid(); return null;
if(shelfRFID != null){ }
if(shelfRFID.equals(packageRfid)){ for (ShelfInfo shelf : shSerialShelfInfoMap.values()) {
//已经绑定过该Temp料架 String shelfRFID = shelf.getRealRfid();
return shelf; if(shelfRFID != null){
} if(shelfRFID.equals(packageRfid)){
//已经绑定过该Temp料架
return shelf;
} }
} }
} }
...@@ -284,6 +296,28 @@ public class InquiryShelfBean { ...@@ -284,6 +296,28 @@ public class InquiryShelfBean {
return null; return null;
} }
public ShelfInfo findMaxUsedShelf(String hSerial, String shelfType){
Map<String, ShelfInfo> shelfMap = hSerialShelfMap.get(hSerial);
ShelfInfo maxLocShelf = null;
for (ShelfInfo shelf : shelfMap.values()) {
if(StorageConstants.SHEFL_TYPE.judgeType(shelfType, shelf.getShelfType())){
//同一种料架
if(maxLocShelf == null){
maxLocShelf = shelf;
}
if(shelf.getUsedLocCount() > maxLocShelf.getUsedLocCount()){
maxLocShelf = shelf;
}
}
}
if(maxLocShelf != null){
log.info("找到类型为["+shelfType+"]库位最多的同种料架["+maxLocShelf.tempRfid()+"]");
}else{
log.info("已没有与["+shelfType+"]类型相同的料架");;
}
return maxLocShelf;
}
/** /**
* 锁定架位 * 锁定架位
*/ */
......
...@@ -177,6 +177,14 @@ public class OutInfo extends BaseMongoBean { ...@@ -177,6 +177,14 @@ public class OutInfo extends BaseMongoBean {
return getAction().contains("首盘"); return getAction().contains("首盘");
} }
/**
* 补料需求单
*/
public boolean isTailAction(){
return getAction().contains("补料");
}
public int getTaskFinishNum() { public int getTaskFinishNum() {
return taskFinishNum; return taskFinishNum;
} }
......
...@@ -26,6 +26,22 @@ public class OutInfoCache { ...@@ -26,6 +26,22 @@ public class OutInfoCache {
//定时查询未完成的需求单 //定时查询未完成的需求单
private static Map<String,OutInfo> outInfoMap = new ConcurrentHashMap<>(); private static Map<String,OutInfo> outInfoMap = new ConcurrentHashMap<>();
/**
* 当前正在执行的工单需求单(首盘,补料),未完成时,其他工单需求单不可执行
*/
private static String currentOrderHSerial = "";
public static void setCurrentOrderHSerial(String currentOrderHSerial) {
if(currentOrderHSerial == null){
currentOrderHSerial = "";
}
OutInfoCache.currentOrderHSerial = currentOrderHSerial;
}
public String getCurrentOrderHSerial() {
return currentOrderHSerial;
}
@Autowired @Autowired
private IOutInfoDao outInfoDao; private IOutInfoDao outInfoDao;
......
...@@ -429,17 +429,17 @@ public class QisdaApiController extends BaseController { ...@@ -429,17 +429,17 @@ public class QisdaApiController extends BaseController {
private void realBindReel(OutItem outItem){ private void realBindReel(OutItem outItem){
if(!outItem.isCutMaterial()){ if(!outItem.isCutMaterial()){
//先从预绑定料盘中进行绑定,如果还有缺料的,从未使用的物料中查找,如果还缺料,从预绑定的物料中查找 //先从预绑定料盘中进行绑定,如果还有缺料的,从未使用的物料中查找,如果还缺料,从预绑定的物料中查找
log.info("绑定非分盘料:So=["+outItem.getSo()+"]hSerial=["+outItem.gethSerial()+"]+refno=["+outItem.getRefno()+"]的slotLoction"+outItem.getSlotlocation()+"]pn=["+outItem.getPn()+"]当前绑定数量["+outItem.getRealLockQty()+"/"+outItem.getQty()+"]"); log.info("绑定非分盘料:So=["+outItem.getSo()+"]hSerial=["+outItem.gethSerial()+"]+refno=["+outItem.getRefno()+"]的slotLoction"+outItem.getSlotlocation()+"]pn=["+outItem.getPn()+"]当前绑定数量["+outItem.getRealLockQty()+"/"+outItem.getQty()+"]当前出库/发料数量["+outItem.getOutQty()+"/"+outItem.getSendQty()+"]");
List<StoragePos> preBindPosList = storagePosDao.findPreBindList(outItem.getSo(), outItem.getSlotlocation()); List<StoragePos> preBindPosList = storagePosDao.findPreBindList(outItem.getSo(), outItem.getSlotlocation());
for (StoragePos pos : preBindPosList) { for (StoragePos pos : preBindPosList) {
outItem = tryRealBind(pos, outItem); outItem = tryRealBind(pos, outItem);
} }
log.info("将预绑定转为真实绑定结束,当前数量:"+ outItem.getRealLockQty() +"/" + outItem.getQty()); //所需数量=需求单数量-已发料数量-真实绑定数量
int needNum = outItem.getQty() - outItem.getRealLockQty(); int needNum = outItem.getQty() - outItem.getSendQty() - outItem.getRealLockQty();
log.info("将预绑定转为真实绑定结束,所需数量("+needNum+")=需求单数量("+outItem.getQty()+")-已发料数量("+ outItem.getSendQty()+")-真实绑定数量"+ outItem.getRealLockQty() +")");
if(needNum >= 0){ if(needNum >= 0){
log.info("预绑定数量不足,查找未绑定料盘进行真实绑定结束,当前数量:"+ outItem.getRealLockQty() +"/" + outItem.getQty()); log.info("预绑定数量不足,查找未绑定料盘进行真实绑定结束,当前数量:"+outItem.getSendQty()+"+"+ outItem.getRealLockQty() +"/" + outItem.getQty());
while(needNum >= 0){ while(needNum >= 0){
StoragePos pos = storagePosDao.findNoBindMinQty(outItem.getPn(), outItem.getFacility()); StoragePos pos = storagePosDao.findNoBindMinQty(outItem.getPn(), outItem.getFacility());
OutItem resultOutItem = tryRealBind(pos, outItem); OutItem resultOutItem = tryRealBind(pos, outItem);
...@@ -455,9 +455,9 @@ public class QisdaApiController extends BaseController { ...@@ -455,9 +455,9 @@ public class QisdaApiController extends BaseController {
} }
needNum = outItem.getQty() - outItem.getRealLockQty(); needNum = outItem.getQty() - outItem.getSendQty() - outItem.getRealLockQty();
if(needNum >= 0 ){ if(needNum >= 0 ){
log.info("未绑定料盘数量不足,开始抢其他工单的预绑定物料进行真实绑定,当前数量:"+ outItem.getRealLockQty() +"/" + outItem.getQty()); log.info("未绑定料盘数量不足,开始抢其他工单的预绑定物料进行真实绑定,当前数量:"+outItem.getSendQty()+"+"+ outItem.getRealLockQty() +"/" + outItem.getQty());
//抢其他工单的预绑定 //抢其他工单的预绑定
while(needNum >= 0){ while(needNum >= 0){
StoragePos pos = storagePosDao.findOtherPreBindMinQty(outItem.getPn(), outItem.getFacility()); StoragePos pos = storagePosDao.findOtherPreBindMinQty(outItem.getPn(), outItem.getFacility());
...@@ -466,13 +466,13 @@ public class QisdaApiController extends BaseController { ...@@ -466,13 +466,13 @@ public class QisdaApiController extends BaseController {
break; break;
} }
outItem = resultOutItem; outItem = resultOutItem;
if(outItem.getRealLockQty() > outItem.getQty()){ if(outItem.getRealLockQty() + outItem.getSendQty() > outItem.getQty()){
//已经满足需求了,直接跳出 //已经满足需求了,直接跳出
break; break;
} }
} }
} }
log.info("So=["+outItem.getSo()+"]hSerial=["+outItem.gethSerial()+"]+refno=["+outItem.getRefno()+"]的slot"+outItem.getSlotlocation()+"]pn=["+outItem.getPn()+"]真实绑定结束,当前数量:"+ outItem.getRealLockQty() +"/" + outItem.getQty()); log.info("So=["+outItem.getSo()+"]hSerial=["+outItem.gethSerial()+"]+refno=["+outItem.getRefno()+"]的slot"+outItem.getSlotlocation()+"]pn=["+outItem.getPn()+"]真实绑定结束,当前数量:"+outItem.getSendQty()+"+"+ outItem.getRealLockQty() +"/" + outItem.getQty());
} }
} }
...@@ -993,9 +993,10 @@ public class QisdaApiController extends BaseController { ...@@ -993,9 +993,10 @@ public class QisdaApiController extends BaseController {
tasks.add(task); tasks.add(task);
} }
}else{ }else{
int needNum = outItem.getQty() - outItem.getRealLockQty(); //紧急料,未绑定数量=需求单数量-已出库数量-已绑数量
int needNum = outItem.getQty() - outItem.getOutQty() - outItem.getRealLockQty();
if(needNum >= 0){ if(needNum >= 0){
log.info("紧急料,查找未绑定料盘进行出库,当前数量:"+ outItem.getRealLockQty() +"/" + outItem.getQty()); log.info("紧急料,查找未绑定料盘进行出库,未绑数量为"+needNum+"=(需求单"+ outItem.getQty() + ") - (已出" + outItem.getOutQty() + ")-已绑(" + outItem.getRealLockQty()+")");
while(needNum >= 0){ while(needNum >= 0){
StoragePos pos = storagePosDao.findNoBindMinQty(outItem.getPn(), outItem.getFacility()); StoragePos pos = storagePosDao.findNoBindMinQty(outItem.getPn(), outItem.getFacility());
if(pos != null){ if(pos != null){
...@@ -1139,25 +1140,15 @@ public class QisdaApiController extends BaseController { ...@@ -1139,25 +1140,15 @@ public class QisdaApiController extends BaseController {
} }
} }
//清理掉已经完成的需求单的料架
// Set<String> hserialSet = InquiryShelfBean.hSerialShelfMap.keySet();
// for (String hserial : hserialSet) {
// OutInfo out = outInfoDao.findByHSerial(hSerial);
// if(!outInfo.isReelCutAction() && !outInfo.isUrgentAction()){
// log.info("清理需求单["+out.gethSerial()+"]占用的料架");
// InquiryShelfBean.hSerialShelfMap.remove(hserial);
// }
// }
//TODO:可以出的时候把之前的料架信息清空
outInfo.setTaskNum(0); //如果是工单需求单,设置当前正在执行的工单需求单
outInfo.setTaskFinishNum(0); if(outInfo.isFirstReelAction() || outInfo.isTailAction()){
outInfo.setOutReelNum(0); String oldHSerial = outInfoCache.getCurrentOrderHSerial();
log.info("设置当前正在执行的工单料需求为:" + outInfo.gethSerial()+"清理之前["+oldHSerial+"]出库使用的料架");
outInfo = outInfoDao.save(outInfo); InquiryShelfBean.clearShelf(oldHSerial);
outInfoCache.setCurrentOrderHSerial(outInfo.gethSerial());
}
List<DataLog> tasks = new ArrayList<>(); List<DataLog> tasks = new ArrayList<>();
...@@ -1186,8 +1177,12 @@ public class QisdaApiController extends BaseController { ...@@ -1186,8 +1177,12 @@ public class QisdaApiController extends BaseController {
int outReelNum = tasks.size(); int outReelNum = tasks.size();
if(outReelNum > 0){ if(outReelNum > 0){
log.info("需求单"+outInfo.gethSerial()+"已出("+outInfo.getOutReelNum()+")/已发("+outInfo.getTaskFinishNum()+") 本次出库料盘数量:" + outReelNum);
outInfo.setOutReelNum(0);
outInfo.setTaskFinishNum(0);
outInfo.setTaskNum(outReelNum); outInfo.setTaskNum(outReelNum);
outInfo = outInfoDao.save(outInfo); outInfo = outInfoDao.save(outInfo);
//先出小料盘,再出大料盘 //先出小料盘,再出大料盘
for (DataLog task : tasks) { for (DataLog task : tasks) {
if(task.isSmallReel()){ if(task.isSmallReel()){
...@@ -1201,7 +1196,6 @@ public class QisdaApiController extends BaseController { ...@@ -1201,7 +1196,6 @@ public class QisdaApiController extends BaseController {
} }
} }
log.info("需求单"+outInfo.gethSerial()+" 出库料盘数量:" + outReelNum);
if(outInfo.isReelCutAction() || outInfo.isFirstReelAction()){ if(outInfo.isReelCutAction() || outInfo.isFirstReelAction()){
if(outReelNum == 0){ if(outReelNum == 0){
......
...@@ -584,9 +584,9 @@ public class StorageDataController extends BaseController { ...@@ -584,9 +584,9 @@ public class StorageDataController extends BaseController {
}else { }else {
StoragePos pos = null; StoragePos pos = null;
try { try {
log.info("条码["+barcode.getBarcode()+"]入库,清空Facility入库信息"); // log.info("条码["+barcode.getBarcode()+"]入库,清空Facility入库信息");
barcode.setAppendInfo(null); // barcode.setAppendInfo(null);
barcode = barcodeManager.save(barcode); // barcode = barcodeManager.save(barcode);
pos = taskService.findEmptyPosForPutIn(storageList,barcode, rfid); pos = taskService.findEmptyPosForPutIn(storageList,barcode, rfid);
if(pos != null){ if(pos != null){
......
...@@ -559,30 +559,28 @@ public class TaskService implements ITaskService { ...@@ -559,30 +559,28 @@ public class TaskService implements ITaskService {
} }
} }
//按任务数量从小到大排序 //可用的料仓(在线,且可以放入)
// List<Map.Entry<String, Integer>> list = new ArrayList<>(countMap.entrySet()); List<Storage> availbleStorageList = new ArrayList<>();
// Collections.sort(list, new Comparator<Map.Entry<String, Integer>>()
// { for(Storage storage : storageList){
// @Override StatusBean status = getStatus(storage.getCid());
// public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) if(status.timeOut()){
// { continue;
// //按照value值,用compareTo()方法默认是从小到大排序 }
// return o1.getValue().compareTo(o2.getValue()); if(storage.canPutIn(barcode.getPlateSize(),barcode.getHeight())){
// } availbleStorageList.add(storage);
// }); }
}
// for (Storage storage : availbleStorageList) {
for (Storage storage : storageList) {
String storageId = storage.getId(); String storageId = storage.getId();
Integer taskCount = countMap.get(storageId); Integer taskCount = countMap.get(storageId);
if(taskCount >= 2){ if(taskCount >= 2){
continue; continue;
} }
StatusBean status = getStatus(storage.getCid());
if(status.timeOut()){
continue;
}
try{ try{
log.info("尝试从"+storage.getName()+"["+storage.getCid()+"]查找空位,当前料仓任务数:" + taskCount); log.info("尝试从"+storage.getName()+"["+storage.getCid()+"]查找空位,当前料仓任务数:" + taskCount);
return findLineEmptyPosForPutIn(storage,barcode); return findLineEmptyPosForPutIn(storage,barcode);
...@@ -591,6 +589,17 @@ public class TaskService implements ITaskService { ...@@ -591,6 +589,17 @@ public class TaskService implements ITaskService {
} }
} }
//只有一个料仓可以入时,只能继续往里面放
log.info("可用料仓太少,不按任务数分配,重新查找...");
for (Storage storage : availbleStorageList) {
try{
log.info("尝试从"+storage.getName()+"["+storage.getCid()+"]查找空位,当前料仓任务数");
return findLineEmptyPosForPutIn(storage,barcode);
}catch(Exception e){
log.info("从"+storage.getName()+"["+storage.getCid()+"]查找空位失败:" + e.getMessage());
}
}
return null; return null;
} }
...@@ -1027,6 +1036,11 @@ public class TaskService implements ITaskService { ...@@ -1027,6 +1036,11 @@ public class TaskService implements ITaskService {
} }
} }
if(!shelfNameList.contains(storageTask.getAppendInfo().getTempRfid())){ if(!shelfNameList.contains(storageTask.getAppendInfo().getTempRfid())){
if(storageTask.getAppendInfo().isCShelfTask()){
//大料(C料架)只能同时出一个架子,不然到包装料工位时无法切换
log.info("未完成的工单料架为:["+String.join(",",shelfNameList)+ "]大料架任务["+storageTask.getBarcode()+"]暂停出库,以免包装工位无法切换");
return null;
}
//未完成的工单任务料架数量>2,且未包含此任务,任务先不出,等到只有一个料架时再说 //未完成的工单任务料架数量>2,且未包含此任务,任务先不出,等到只有一个料架时再说
if(shelfNameList.size() >= 2){ if(shelfNameList.size() >= 2){
log.info("未完成的工单任务料架为:["+String.join(",",shelfNameList)+ "]任务"+storageTask.getBarcode()+"暂停出库"); log.info("未完成的工单任务料架为:["+String.join(",",shelfNameList)+ "]任务"+storageTask.getBarcode()+"暂停出库");
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!