ShelfInfo.java 12.4 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
package com.myproject.bean.qisda;

import com.myproject.util.StorageConstants;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 料架
 * Created by sunke on 2019/12/15.
 */
public class ShelfInfo {

    protected final Logger log = LogManager.getLogger(ShelfInfo.class);

    public ShelfInfo(String shelfType, int locCount) {
        this.shelfType = shelfType;
        this.maxLocCount = locCount;
    }

    public static ShelfInfo newAShelf(){
        return new ShelfInfo(StorageConstants.SHEFL_TYPE.A, 8);
    }

    public static ShelfInfo newBShelf(){
        return new ShelfInfo(StorageConstants.SHEFL_TYPE.B,1000000);
    }

    public static ShelfInfo newCShelf(){
        return new ShelfInfo(StorageConstants.SHEFL_TYPE.C,12);
    }

    public static ShelfInfo newDShelf(){
        return new ShelfInfo(StorageConstants.SHEFL_TYPE.D,92);
    }

    /**
     * 需求单号
     */
    private String hSerial;

    /**
     * 料架出库顺序编号
     */
    private int rfidIndex;

    /**
     * 实际编号
     */
    private String realRfid;

    /**
     * 料架类型
     */
    private String shelfType;

    /**
     * 料架的架位数
     */
    private int maxLocCount = 0;

    /**
     * 料架的目标点位
     */
//    private String targetPoint = "";

    /**
     * 架位放置情况, key小于0表示已经放过,key>0为空的库位
     */
    private Map<Integer, ShelfLoc> locMap = new ConcurrentHashMap<>();

    public Map<Integer, ShelfLoc> getLocMap() {
        return locMap;
    }

    public int getEmptyLocCount(){
        int emptyLocCount = 0;
        for (ShelfLoc loc : locMap.values()) {
            if(loc.isEmpty()){
                emptyLocCount = emptyLocCount + 1;
            }
        }
        return  emptyLocCount;
    }

    /**
     * 库位数
     */
    public int getUsedLocCount(){
        return locMap.size();
    }

    public void setLocMap(Map<Integer, ShelfLoc> locMap) {
        this.locMap = locMap;
    }

    public String getRealRfid() {
        if(realRfid == null){
            return "";
        }
        return realRfid;
    }

    public void setRealRfid(String realRfid) {
        this.realRfid = realRfid;
    }

    public int getRfidIndex() {
        return rfidIndex;
    }

    public void setRfidIndex(int rfidIndex) {
        this.rfidIndex = rfidIndex;
    }

    /**
     * 添加架位时,验证是否架位已达最大数量
     */
    public boolean reachMaxLoc(){
        return locMap.size() >= maxLocCount;
    }

    /**
     * 料架是否放满
     */
    public boolean isFull(){
        for (ShelfLoc loc : locMap.values()) {
            if(loc.isEmpty()){
                return false;
            }
        }
        return true;
    }

    /**
     * 不为空,且也未满,即放过料,但未满
     */
    public boolean isNotEmptyNotFull(){
        boolean hasReel = false;
        boolean hasEmpty = false;
        for (ShelfLoc loc : locMap.values()) {
            if(loc.isEmpty()){
                //有空位
                hasEmpty = true;
            }else{
                //有料
                hasReel = true;
            }
        }
        if(hasEmpty && hasReel){
            //有空位也有料
            return true;
        }
        return false;
    }



    /**
     * 将料盘放入库位
     * @param loc
     * @param barcode
     */
    public boolean putInLoc(String rfid, int loc, String barcode){
        if(this.realRfid != null && !this.realRfid.isEmpty()){
            //已绑定过真实料架,必须一致才能放入
            if(!this.realRfid.equals(rfid)){
                return false;
            }
        }

        if(!rfid.contains(shelfType)){
            //未绑定过料架的,需要判断类型是否一致
            return false;
        }


        int lockLocation = -1;
        for (ShelfLoc shelfLoc : locMap.values()) {
            if(shelfLoc.isLock() && shelfLoc.getBarcode().equals(barcode)){
                log.info("找到条码["+barcode+"]锁定的架位["+shelfLoc.getLoc()+"]");
                lockLocation = shelfLoc.getLoc();
            }
        }

        if(lockLocation == -1){
            log.error("["+tempRfid()+"]未找到["+barcode+"]锁定的位置信息");
            return false;
        }

        if(lockLocation != loc){
            log.error(barcode + "放置位置["+loc+"]与锁定位置["+lockLocation+"]不一致");
            return false;
        }
        this.setRealRfid(rfid);
        ShelfLoc shelfLoc = locMap.get(loc);
        if(shelfLoc == null){
            log.error("未找到["+loc+"]的位置信息,当前料架位置信息:"+ locMap);
            return false;
        }
        if(shelfLoc.isEmpty()){
            boolean putInResult = shelfLoc.putIn(barcode);
            locMap.put(loc, shelfLoc);

            return putInResult;
        }else{
            log.error("料盘["+barcode+"]放入位置"+rfid+"["+loc+"]失败,此位置料盘已放入");
            return false;
        }
    }

    public boolean putInLimitLoc(String rfid, int rfidLoc, String barcode){
        if(rfid.contains(shelfType)){//不是同一种料架的忽略
            ShelfLoc shelfLoc = locMap.get(rfidLoc);
            if(shelfLoc.isInThisLoc(barcode)){
                if(shelfLoc.isEmpty()){
                    shelfLoc.putIn(barcode);
                    locMap.put(rfidLoc, shelfLoc);
                    this.setRealRfid(rfid);
                    return true;
                }else {
                    log.error("料盘["+barcode+"]放入"+rfid+"["+rfidLoc+"]失败,此位置料盘已放入");
                }
            }

        }
        return false;
    }

    /**
     * 根据条码获取库位信息
     */
    public int getBarcodeLoc(String barcode, String theShelfType){
        if(theShelfType.contains(shelfType)) {//不是同一种料架的忽略
            //先看看此条码是否已经锁定过
            for (ShelfLoc shelfLoc : locMap.values()) {
                if (shelfLoc.isLock() && shelfLoc.getBarcode().equals(barcode)) {
                    return shelfLoc.getLoc();
                }
            }
        }
        return -1;
    }

    /**
     * 为包装料锁定架位
     * @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)) {
            //不是同一种料架的忽略
            //先看看此条码是否已经锁定过
            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;
                        }
                    }
                }
                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){
                            return shelfLoc;
                        }
                    }
                }
                return shelfLoc;

            }else {
                //包装料
                for(int i=1; i<= usedCount; i++){
                    ShelfLoc shelfLoc = lockLocation(i,barcode,reelType);
                    if(shelfLoc != null){
                        return shelfLoc;
                    }
                }
            }

        //}
        return null;
    }

    /**
     * 锁定库位,如果成功返回库位,如果失败返回null
     */
    private ShelfLoc lockLocation(int loc,String barcode, int reelType){
        ShelfLoc shelfLoc = locMap.get(loc);
        if(shelfLoc != null && shelfLoc.isEmpty() && !shelfLoc.isLock()){
            log.info("为[" + barcode + "]锁定架位"+tempRfid() + "["+loc+"]");
            //未放过料,且未锁定
            shelfLoc.setBarcode(barcode);
            shelfLoc.setReelType(reelType);
            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){
        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);
                }
                shelfLoc.setLoc(i);
                shelfLoc.setBarcode(barcode);
                shelfLoc.setReelType(reelType);
                locMap.put(i, shelfLoc);
                return i;
            }
        }
        return -1;
    }

    public int getMaxLocCount() {
        return maxLocCount;
    }

    public void setMaxLocCount(int maxLocCount) {
        this.maxLocCount = maxLocCount;
    }

    public String gethSerial() {
        if(hSerial == null){
            return "";
        }
        return hSerial;
    }

    public void sethSerial(String hSerial) {
        this.hSerial = hSerial;
    }

    public String getShelfType() {
        return shelfType;
    }

    public boolean isCShelf(){
        return StorageConstants.SHEFL_TYPE.isCShelf(getShelfType());
    }

    public boolean isDShelf(){
        return StorageConstants.SHEFL_TYPE.isDShelf(getShelfType());
    }

    public void setShelfType(String shelfType) {
        this.shelfType = shelfType;
    }

    public String tempRfid(){
        return gethSerial() + "-" + rfidIndex + shelfType;
    }
}