فهرست منبع

APS平台新模型

fangpy 1 سال پیش
والد
کامیت
d81926e860

+ 12 - 0
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/domain/Step.java

@@ -0,0 +1,12 @@
+package com.rongwei.rwapsserver.aps.domain;
+
+import org.optaplanner.core.api.domain.entity.PlanningEntity;
+import org.optaplanner.core.api.domain.variable.InverseRelationShadowVariable;
+
+@PlanningEntity
+public class Step extends ApsAbstractPersistable{
+
+    @InverseRelationShadowVariable(sourceVariableName = "previousStep")
+    protected ProductionProcesses nextTask;
+
+}

+ 281 - 0
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/listener/TaskStartTimeListener.java

@@ -0,0 +1,281 @@
+package com.rongwei.rwapsserver.aps.listener;
+
+import com.rongwei.rwapsserver.aps.domain.ApsSolution;
+import com.rongwei.rwapsserver.aps.domain.EquipmentRunTime;
+import com.rongwei.rwapsserver.aps.domain.ProductionProcesses;
+import org.optaplanner.core.api.domain.variable.VariableListener;
+import org.optaplanner.core.api.score.director.ScoreDirector;
+import java.time.LocalDateTime;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 设备赋值后任务起止时间自动计算
+ */
+public class TaskStartTimeListener implements VariableListener<ApsSolution, ProductionProcesses> {
+
+    @Override
+    public void beforeEntityAdded(ScoreDirector<ApsSolution> scoreDirector, ProductionProcesses process) {
+
+    }
+
+    @Override
+    public void afterEntityAdded(ScoreDirector<ApsSolution> scoreDirector, ProductionProcesses process) {
+        updateResponseTime(scoreDirector, process);
+    }
+
+    @Override
+    public void beforeVariableChanged(ScoreDirector<ApsSolution> scoreDirector, ProductionProcesses process) {
+
+    }
+
+    @Override
+    public void afterVariableChanged(ScoreDirector<ApsSolution> scoreDirector, ProductionProcesses process) {
+        updateResponseTime(scoreDirector, process);
+    }
+
+    @Override
+    public void beforeEntityRemoved(ScoreDirector<ApsSolution> scoreDirector, ProductionProcesses process) {
+
+    }
+
+    @Override
+    public void afterEntityRemoved(ScoreDirector<ApsSolution> scoreDirector, ProductionProcesses process) {
+
+    }
+
+    protected void updateResponseTime(ScoreDirector<ApsSolution> scoreDirector, ProductionProcesses process) {
+        if(process.getEquipment() != null){
+//            System.out.println(process.getEquipment().getId()+"-"+process.getEquipment().getEquipmentType());
+            /*scoreDirector.beforeVariableChanged(process, "startTime");
+            // 时间设定
+            LocalDateTime toUpdateStartTime = startTimeSet(process);
+            process.setStartTime(toUpdateStartTime);
+            scoreDirector.afterVariableChanged(process, "startTime");*/
+
+            setNextAllStartTime(scoreDirector,process);
+        }
+
+        /*PreviousCallOrAgent previous = call.getPreviousCallOrAgent();
+        Call shadowCall = call;
+        Duration previousDurationTillPickUp = (previous == null ? null : previous.getDurationTillPickUp());
+        Duration estimatedWaiting = calculateWaitingTimeEstimate(shadowCall, previousDurationTillPickUp);
+        while (shadowCall != null) {
+            scoreDirector.beforeVariableChanged(shadowCall, "estimatedWaiting");
+            shadowCall.setEstimatedWaiting(estimatedWaiting);
+            scoreDirector.afterVariableChanged(shadowCall, "estimatedWaiting");
+            previousDurationTillPickUp = shadowCall.getDurationTillPickUp();
+            shadowCall = shadowCall.getNextCall();
+            estimatedWaiting = calculateWaitingTimeEstimate(shadowCall, previousDurationTillPickUp);
+        }*/
+    }
+
+    private void setNextAllStartTime(ScoreDirector<ApsSolution> scoreDirector,ProductionProcesses process){
+        LocalDateTime startDateTime = startTimeSet(process);
+        scoreDirector.beforeVariableChanged(process, "startTime");
+        process.setStartTime(startDateTime);
+        scoreDirector.afterVariableChanged(process, "startTime");
+        if(process.getNextProcesses() != null && process.getNextProcesses().size()>0){
+            for (ProductionProcesses nextProcess : process.getNextProcesses()) {
+                setNextAllStartTime(scoreDirector,nextProcess);
+            }
+        }
+    }
+
+    /**
+     * 设置开始时间
+     * @param process
+     */
+    private LocalDateTime startTimeSet(ProductionProcesses process){
+        // 时间设定
+        LocalDateTime toUpdateStartTime = null;
+        if(process.getEquipment() != null){
+            // 最大单批次生产时间
+            Integer maxUnitProduceTime = 0;
+            // 最大流转时间
+            Integer lzMaxTimes = 0;
+            // 前道工序最小首批加工最大等待时间
+            LocalDateTime lastFirstMaxWaitTime = null;
+            if(process.getPreviousProcesses() != null && process.getPreviousProcesses().size()>0){
+                // 瓶颈工序,简化为等待前道工序全部完成才加工后道工序
+                if((process.getBottleneck() != null && process.getBottleneck())
+                        || (process.getPreviousProcesses().get(0).getBottleneck() != null && process.getPreviousProcesses().get(0).getBottleneck())){
+                    LocalDateTime lastMaxStartTime = null;
+                    LocalDateTime lastMinMaxWaitTime = null;
+                    for (ProductionProcesses previousProcess : process.getPreviousProcesses()) {
+                        // 流转时间
+                        Integer lzTimes = 0;
+                        if(previousProcess.getEquipment().getWorkshopid() != null && previousProcess.getEquipment().getWorkshopid().equals(process.getEquipment().getWorkshopid())){
+                            lzTimes = process.getApsOverallConfig().getRoamTime().get("WORKSHOP_IN");
+                        }else{
+                            lzTimes = process.getApsOverallConfig().getRoamTime().get("WORKSHOP_CROSS");
+                        }
+                        if(lzMaxTimes<lzTimes){
+                            lzMaxTimes = lzTimes;
+                        }
+                        // 最小等待时间
+                        Integer minWaitTime = previousProcess.getMinWaitTime() == null ? 0 : previousProcess.getMinWaitTime();
+                        if(lzTimes>minWaitTime){
+                            minWaitTime = lzTimes;
+                        }
+                        if(lastMaxStartTime == null){
+                            lastMaxStartTime = previousProcess.getEndTime().plusMinutes(minWaitTime);
+                        }else {
+                            if(lastMaxStartTime.compareTo(previousProcess.getEndTime().plusMinutes(minWaitTime))<0){
+                                lastMaxStartTime = previousProcess.getEndTime().plusMinutes(minWaitTime);
+                            }
+                        }
+                        // 如有最大等待时间,计算首批次加工等待时间不能超过最大等待时间
+                        if(previousProcess.getMaxWaitTime() != null){
+                            if(lastMinMaxWaitTime == null){
+                                lastMinMaxWaitTime = previousProcess.getEndTime().plusMinutes(previousProcess.getMaxWaitTime());
+                            }else{
+                                if(previousProcess.getEndTime().plusMinutes(previousProcess.getMaxWaitTime()).compareTo(lastMinMaxWaitTime)<0){
+                                    lastMinMaxWaitTime = previousProcess.getEndTime().plusMinutes(previousProcess.getMaxWaitTime());
+                                }
+                            }
+                        }
+                    }
+                    // 开始时间不小于最大的最小等待时间、不大于最小的最大等待时间
+                    toUpdateStartTime = lastMaxStartTime;
+
+                /*if(process.getStartTime().compareTo(lastMaxStartTime)<0){
+                    bln = true;
+                }else if(process.getStartTime().compareTo(lastMinMaxWaitTime)>0){
+                    bln = true;
+                }*/
+                }
+                // 非瓶颈工序,非瓶颈工序,默认前道工序只有一个
+                else{
+                    // 此种情况简化为前道工序只有一个
+                    ProductionProcesses preProcess = process.getPreviousProcesses().get(0);
+                    if(preProcess.getStartTime() != null){
+                        maxUnitProduceTime = preProcess.getUnitProduceTime();
+                        // 前道工序的所有下道工序
+                        List<ProductionProcesses> nextProcesses = preProcess.getNextProcesses();
+                        Map<String,Integer> map = new HashMap<>();
+                        for (ProductionProcesses nextProcess : nextProcesses) {
+                            map.put(nextProcess.getId(),0);
+                            allNextProduceTime(nextProcess,map,nextProcess.getId());
+                            nextProcess.setNextAllProduceTime(map.get(nextProcess.getId()));
+                        }
+                        nextProcesses.sort((o1, o2) -> o1.getNextAllProduceTime().compareTo(o2.getNextAllProduceTime()));
+                        // 前道工序
+                        LocalDateTime startTime = preProcess.getStartTime();
+                        LocalDateTime endTime = preProcess.getStartTime();
+                        for (ProductionProcesses nextProcess : nextProcesses) {
+                            int i = preProcess.getUnitProduceTime() * nextProcess.getProducePcNum();
+                            if(!nextProcess.getId().equals(process.getId())){
+                                startTime = startTime.plusMinutes(i);
+                            }else{
+                                endTime = startTime.plusMinutes(i);
+                            }
+                        }
+
+                        // 流转时间
+                        Integer lzTimes = 0;
+                        if(preProcess.getEquipment().getWorkshopid() != null && preProcess.getEquipment().getWorkshopid().equals(process.getEquipment().getWorkshopid())){
+                            lzTimes = process.getApsOverallConfig().getRoamTime().get("WORKSHOP_IN");
+                        }else{
+                            lzTimes = process.getApsOverallConfig().getRoamTime().get("WORKSHOP_CROSS");
+                        }
+                        // 最小等待时间对比流转时间
+                        if(preProcess.getMinWaitTime() != null && lzTimes<preProcess.getMinWaitTime()){
+                            lzTimes = preProcess.getMinWaitTime();
+                        }
+
+                        /**
+                         * 后道工序批次生产时间大于等于前道工序批次生产时间
+                         * 从第一批次开始往后排程
+                         */
+
+                        if(preProcess.getMaxWaitTime() != null){
+                            lastFirstMaxWaitTime = startTime.plusMinutes(preProcess.getUnitProduceTime()).plusMinutes(preProcess.getMaxWaitTime());
+                        }
+                        LocalDateTime lastStartTime = null;
+                        if(process.getUnitProduceTime()>=maxUnitProduceTime){
+                            lastStartTime = startTime.plusMinutes(preProcess.getUnitProduceTime()).plusMinutes(lzTimes);
+                    /*if(process.getStartTime().compareTo(startTime.plusMinutes(preProcess.getUnitProduceTime()).plusMinutes(lzTimes))<0){
+                        bln = true;
+                    }else{
+                        if(lastFirstMaxWaitTime != null){
+                            if(process.getStartTime().compareTo(lastFirstMaxWaitTime)>0){
+                                bln = true;
+                            }
+                        }
+                    }*/
+                            process.setEndTime(lastStartTime.plusMinutes(process.getProduceTime()));
+                        }
+                        /**
+                         * 后道工序批次生产时间小于前道工序批次生产时间
+                         * 从最后批次开始往前排程
+                         */
+                        else{
+                            // 开始时间:最后一批次结束时间加流转时间,再往前倒排批次数减一乘以单批次生产时间
+                            lastStartTime = endTime.plusMinutes(lzTimes).minusMinutes(process.getUnitProduceTime() * (process.getProducePcNum() - 1));
+                    /*if(process.getStartTime().compareTo(startTime1)<0){
+                        bln = true;
+                    }
+                    // 存在最大等待时间时
+                    if(preProcess.getMaxWaitTime() != null){
+                        // 超过最大等待时间
+                        if(process.getStartTime().compareTo(startTime1.plusMinutes(preProcess.getMaxWaitTime()))>0){
+                            bln = true;
+                        }
+                    }*/
+                            // 结束时间重新赋值
+                            process.setEndTime(endTime.plusMinutes(lzTimes).plusMinutes(process.getUnitProduceTime()));
+                        }
+                        // 对比设备已运行时间段来修正时间
+                        LocalDateTime proStartTime = lastStartTime;
+                        LocalDateTime proEndTime = process.getEndTime();
+                        List<EquipmentRunTime> equipmentRunTimes = process.getEquipment().getEquipmentRunTimes();
+                        if(equipmentRunTimes != null && equipmentRunTimes.size()>0){
+                            for (EquipmentRunTime equipmentRunTime : equipmentRunTimes) {
+                                if((proStartTime.compareTo(equipmentRunTime.getStartRunTime())>=0 && proStartTime.compareTo(equipmentRunTime.getEndRunTime())<=0)
+                                        || (proEndTime.compareTo(equipmentRunTime.getStartRunTime())>=0 && proEndTime.compareTo(equipmentRunTime.getEndRunTime())<=0)
+                                        || (proStartTime.compareTo(equipmentRunTime.getStartRunTime())<=0 && proEndTime.compareTo(equipmentRunTime.getEndRunTime())>=0)){
+                                    proStartTime = equipmentRunTime.getEndRunTime().plusMinutes(1);
+                                    proEndTime = proStartTime.plusMinutes(process.getProduceTime());
+                                }
+                            }
+                        }
+                        toUpdateStartTime = proStartTime;
+                    }
+                }
+            }else{
+                LocalDateTime proStartTime = process.getApsOverallConfig().getStartTime();
+                LocalDateTime proEndTime = proStartTime.plusMinutes(process.getProduceTime());
+                List<EquipmentRunTime> equipmentRunTimes = process.getEquipment().getEquipmentRunTimes();
+                if(equipmentRunTimes != null && equipmentRunTimes.size()>0){
+                    for (EquipmentRunTime equipmentRunTime : equipmentRunTimes) {
+                        if((proStartTime.compareTo(equipmentRunTime.getStartRunTime())>=0 && proStartTime.compareTo(equipmentRunTime.getEndRunTime())<=0)
+                                || (proEndTime.compareTo(equipmentRunTime.getStartRunTime())>=0 && proEndTime.compareTo(equipmentRunTime.getEndRunTime())<=0)
+                                || (proStartTime.compareTo(equipmentRunTime.getStartRunTime())<=0 && proEndTime.compareTo(equipmentRunTime.getEndRunTime())>=0)){
+                            proStartTime = equipmentRunTime.getEndRunTime().plusMinutes(1);
+                            proEndTime = proStartTime.plusMinutes(process.getProduceTime());
+                        }
+                    }
+                }
+                toUpdateStartTime = proStartTime;
+            }
+        }
+        return toUpdateStartTime;
+    }
+
+    /**
+     * 汇总所有下道工序的加工时间
+     * @param nextProcess
+     * @param map
+     */
+    private void allNextProduceTime(ProductionProcesses nextProcess,Map<String,Integer> map,String proId){
+        map.put(proId,map.get(proId)+nextProcess.getProduceTime());
+        if(nextProcess.getNextProcesses() != null && nextProcess.getNextProcesses().size()>0){
+            for (ProductionProcesses process : nextProcess.getNextProcesses()) {
+                allNextProduceTime(process,map,proId);
+            }
+        }
+    }
+
+}