自动化立体仓库 - WCS系统
*
lsh
2024-10-19 050abb296f847e787432197c161f746c128e5956
*
8个文件已修改
376 ■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/OpenController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/WrkMast.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java 175 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/utils/SortTheExecutionOfTheCarUtil.java 110 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/MainProcess.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/RgvStatusType.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/RgvTaskModeType.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/RgvThread.java 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/OpenController.java
@@ -20,7 +20,7 @@
@Slf4j
@RestController
@RequestMapping("open/rcs")
public class OpenController extends BaseController {
public class  OpenController extends BaseController {
    private static final boolean auth = true;
    public static final ArrayList<String> APP_KEY_LIST = new ArrayList<String>() {{
src/main/java/com/zy/asrs/entity/WrkMast.java
@@ -30,7 +30,7 @@
    @ApiModelProperty(value= "工作号")
    @TableId(value = "wrk_no", type = IdType.INPUT)
    @TableField("wrk_no")
    private Integer wrkNo;
    private Long wrkNo;
    @ApiModelProperty(value= "")
    @TableField("inv_wh")
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -3,13 +3,11 @@
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Cools;
import com.zy.asrs.entity.BasCircularShuttle;
import com.zy.asrs.entity.BasDevpPosition;
import com.zy.asrs.entity.BasRgv;
import com.zy.asrs.entity.BasSte;
import com.zy.asrs.entity.*;
import com.zy.asrs.service.BasCircularShuttleService;
import com.zy.asrs.service.BasDevpPositionService;
import com.zy.asrs.service.BasDevpService;
import com.zy.asrs.service.WrkMastService;
import com.zy.asrs.utils.SortTheExecutionOfTheCarUtil;
import com.zy.asrs.utils.Utils;
import com.zy.core.DevpThread;
@@ -21,6 +19,7 @@
import com.zy.core.model.RgvSlave;
import com.zy.core.model.SteSlave;
import com.zy.core.model.Task;
import com.zy.core.model.command.RgvCommand;
import com.zy.core.model.command.SteCommand;
import com.zy.core.model.protocol.RgvProtocol;
import com.zy.core.model.protocol.StaProtocol;
@@ -35,10 +34,7 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.*;
/**
 * 立体仓库WCS系统主流程业务
@@ -59,6 +55,8 @@
    private BasDevpPositionService basDevpPositionService;
    @Autowired
    private BasCircularShuttleService basCircularShuttleService;
    @Autowired
    private WrkMastService wrkMastService;
    /**
     * 站点任务检测  下发小车取放任务
     */
@@ -70,7 +68,9 @@
            for (BasCircularShuttle basCircularShuttle : basCircularShuttleList){
                RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, basCircularShuttle.getRgvNo());
                RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
                if (rgvProtocol.modeType != RgvModeType.AUTO || (rgvProtocol.getStatusType() != RgvStatusType.IDLE && rgvProtocol.getStatusType() != RgvStatusType.SOS1001) ){
                if (rgvProtocol == null) {
                    sign = true;
                } else if (rgvProtocol.modeType != RgvModeType.AUTO || (rgvProtocol.getStatusType() != RgvStatusType.IDLE && rgvProtocol.getStatusType() != RgvStatusType.ROAM) ){
                    sign = true;
                } else {
                    rgvNo = basCircularShuttle.getRgvNo();
@@ -108,39 +108,148 @@
     * 站点任务检测  下发小车取放任务
     */
    public synchronized void DevpTaskNoRun() {
        for (DevpSlave devp : slaveProperties.getDevp()) {
            // 遍历空板入库口
            for (DevpSlave.Sta sta : devp.getInSta()) {
                // 获取空板入库站信息
                SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
                StaProtocol staProtocol = devpThread.getStation().get(sta.getStaNo());
                if (staProtocol == null) {
                    continue;
        try{
            BasCircularShuttle basCircularShuttle = basCircularShuttleService.selectOne(new EntityWrapper<BasCircularShuttle>().eq("rgv_id", 1));
            RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, basCircularShuttle.getRgvNo());
            RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
            if (rgvProtocol == null) {
                return;
            }
            List<BasDevpPosition> basDevpPositions = basDevpPositionService.selectList(new EntityWrapper<BasDevpPosition>().orderBy("plc_position",false));
            Integer devNo = SortTheExecutionOfTheCarUtil.LatelyAndLessThan(basDevpPositions, rgvProtocol.getRgvPos());
            BasDevpPosition[] basDevpPositionsList = SortTheExecutionOfTheCarUtil.devpNoSort(basDevpPositions, devNo);
            BasDevpPosition[] basDevpPositionsListUN = SortTheExecutionOfTheCarUtil.devpNoSortUN(basDevpPositionsList);
            List<List<WrkMast>> wrkMastLists = getWrkMastLists(basDevpPositionsListUN);
            //下发任务
            taskDown(wrkMastLists);
        } catch (Exception e){
            log.error("自动下发小车取放任务失败,异常:"+e);
        }
    }
    //获取小车取放任务列表失败
    public synchronized List<List<WrkMast>> getWrkMastLists(BasDevpPosition[] basDevpPositionsListUN) {
        List<List<WrkMast>> wrkMastLists = new ArrayList<>();
        try{
            List<WrkMast> wrkMastlistA = new ArrayList<>();
            List<WrkMast> wrkMastlistB = new ArrayList<>();
            for (BasDevpPosition basDevpPosition : basDevpPositionsListUN){
                WrkMast wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("sta_no", basDevpPosition.getDevNo()).eq("wrk_sts",1L));
                if (!Cools.isEmpty(wrkMast)){
                    if (SortTheExecutionOfTheCarUtil.devpNoSortbj(basDevpPositionsListUN,wrkMast.getSourceStaNo(),wrkMast.getStaNo())){
                        wrkMastlistA.add(wrkMast);
                    } else {
                        wrkMastlistB.add(wrkMast);
                    }
                }
            }
            wrkMastLists.add(wrkMastlistA);
            wrkMastLists.add(wrkMastlistB);
            return wrkMastLists;
        } catch (Exception e){
            log.error("获取小车取放任务列表失败,异常:"+e);
            return wrkMastLists;
        }
    }
    public synchronized void taskDown(List<List<WrkMast>> wrkMastLists) {
        long rgvId = 0;
        runRgv:
        for (List<WrkMast> wrkMastList : wrkMastLists){
            for (WrkMast wrkMast: wrkMastList){
                rgvId++;
                BasCircularShuttle basCircularShuttle = basCircularShuttleService.selectOne(new EntityWrapper<BasCircularShuttle>().eq("rgv_id", 1L));
                RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, basCircularShuttle.getRgvNo());
                RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
                if (rgvProtocol != null
                        && rgvProtocol.modeType == RgvModeType.AUTO
                        && (rgvProtocol.getStatusType() == RgvStatusType.IDLE || rgvProtocol.getStatusType() == RgvStatusType.ROAM)
                        && rgvProtocol.getTaskNo1()==0
                        && rgvProtocol.getAlarm() == 0){
                    RgvCommand rgvCommand = new RgvCommand();
                    rgvCommand.setRgvNo(rgvProtocol.getRgvNo());
                    rgvCommand.setAckFinish1((short) 0);  // 工位1任务完成确认位
                    rgvCommand.setTaskMode1(RgvTaskModeType.FETCH_PUT); // 工位1任务模式:  取放货
                    rgvCommand.setSourceStaNo1(wrkMast.getSourceStaNo().shortValue());   //工位1起点
                    rgvCommand.setDestinationStaNo1(wrkMast.getStaNo().shortValue());   //工位1目标站点
                    rgvCommand.setCommand((short) 1);   //工位1任务确认
                    if (!MessageQueue.offer(SlaveType.Rgv, rgvProtocol.getRgvNo(), new Task(2, rgvCommand))) {
                        //
                        log.error("RGV命令下发失败,RGV号={},任务数据={}", rgvId, JSON.toJSON(rgvCommand));
                        break runRgv;
                    }
                    wrkMast.setWrkSts(2L);
                    try{
                        wrkMastService.updateById(wrkMast);
                        continue ;
                    }catch (Exception e){
                        log.error("更新小车任务失败,任务号:"+wrkMast.getWrkNo());
                    }
                    break runRgv;
                } else {
                    staProtocol = staProtocol.clone();
                    break runRgv;
                }
            }
        }
    }
    public synchronized void loopSteCharge() {
        for (RgvSlave rgv : slaveProperties.getRgv()) {
            RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgv.getId());
            RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
            BasRgv basRgv = basRgvService.selectById(rgv.getId());
            if (Cools.isEmpty(rgvProtocol, basRgv)) { continue; }
            try {
                // 在线 空闲   无作业标记   不在充电
                if (rgvProtocol.getMode() == 0
                        || !rgvProtocol.statusType.equals(RgvStatusType.IDLE)
                        || basRgv.getPakMk().equals("Y")
//                        || steProtocol.getChargeStatus() == 1
                ) {
    //任务完成
    public synchronized void rgvCompleteWrkMastSta() {
        try{
            for (RgvSlave rgvSlave:slaveProperties.getRgv()) {
                RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgvSlave.getId());
                RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
                if (rgvProtocol == null) {
                    continue;
                }
            } catch (Exception e) {
                News.error("fail", e);
                BasRgv basRgv = basRgvService.selectById(rgvSlave.getId());
                if (basRgv == null) {
                    log.error("{}号RGV尚未在数据库进行维护!", rgvSlave.getId());
                    continue;
                }
                // 只有当RGV等待WCS确认、自动
                if (rgvProtocol.getStatusType() == RgvStatusType.WAITING
                        && rgvProtocol.getModeType() == RgvModeType.AUTO
                        && rgvProtocol.getTaskNo1()!=0
                ) {
                    log.info("{}号小车等待wcs确认,状态{},参数{}",rgvProtocol.getRgvNo(),rgvProtocol.getStatusType(),rgvProtocol);
                    WrkMast wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("wrk_no", rgvProtocol.getTaskNo1().longValue()));
                    if (Cools.isEmpty(wrkMast) || !wrkMast.getWrkSts().equals(2L)){
                        log.error("未查到小车执行任务或者执行任务状态不符合!"+wrkMast);
                        continue;
                    }
                    boolean rgvComplete = rgvComplete(rgvProtocol.getRgvNo());
                    if (!rgvComplete){
                        log.error("小车复位失败,小车号{}!",rgvProtocol.getRgvNo());
                        break;
                    }
                    wrkMast.setWrkSts(3L);
                    wrkMastService.updateById(wrkMast);
                }
            }
        } catch (Exception e){
            log.error("小车复位线程报错!"+e);
        }
    }
    /*
     * 小车复位
     * */
    public synchronized boolean rgvComplete(Integer rgvId){
        try{
            //  命令下发区 --------------------------------------------------------------------------
            if (!MessageQueue.offer(SlaveType.Rgv, rgvId, new Task(3, new RgvCommand()))) {
                //step=2,工位1、2写任务;   step=4,工位1写任务;     step=5,工位2写任务
                log.error("RGV命令下发失败,RGV号={}",rgvId);
                return false;
            } else {
                log.info("RGV命令下发成功,RGV号={}",rgvId);
                return true;
            }
        }catch (Exception e){
            log.error("RGV命令下发失败,RGV号={}。异常:"+e,rgvId);
            return false;
        }
    }
}
src/main/java/com/zy/asrs/utils/SortTheExecutionOfTheCarUtil.java
@@ -1,5 +1,6 @@
package com.zy.asrs.utils;
import com.zy.asrs.entity.BasDevpPosition;
import com.zy.core.enums.RouteCollectCountType;
import java.util.Arrays;
@@ -27,27 +28,106 @@
        }
        return ints;
    }
    //排序
    public static int ReorderSteId2(int[][] steList,int steNoStart){
        int[][] ints = new int[steList.length][2];
        int Difference = 0;
        for (int[] steNo : steList){
            if (steNo[0] == steNoStart){
                Difference = steNo[1] - 1;
    //获取最近并在当前位置前边的位置
    public static Integer LatelyAndLessThan(List<BasDevpPosition> devpPosition, long nowPosition){
        Integer result = 0;
        long Difference = 1737000L;
        for (BasDevpPosition positions : devpPosition){
            Long position = positions.getPlcPosition();
            if (position<=nowPosition){
                if ((nowPosition-position) < Difference){
                    Difference = nowPosition-position;
                    result = positions.getDevNo();
                }
            } else {
                if ((nowPosition-(position - 1737000L)) < Difference){
                    Difference = nowPosition-(position - 1737000L);
                    result = positions.getDevNo();
                }
            }
        }
        return result;
    }
    //获取最近并在当前位置前边的位置
    public static Long LatelyAndLessThan(long[] devpPosition,long nowPosition){
        long result = 0L;
        long Difference = 1737000L;
        for (long position : devpPosition){
            if (position<=nowPosition){
                if ((nowPosition-position) < Difference){
                    Difference = nowPosition-position;
                    result = position;
                }
            } else {
                if ((nowPosition-(position - 1737000L)) < Difference){
                    Difference = nowPosition-(position - 1737000L);
                    result = position;
                }
            }
        }
        return result;
    }
    //id初始化
    public static List<BasDevpPosition> devpNoInit(List<BasDevpPosition> devpPosition){
        long i = 0;
        for (BasDevpPosition basDevpPosition : devpPosition){
            i++;
            basDevpPosition.setId(i);
        }
        return devpPosition;
    }
    //站点排序
    public static BasDevpPosition[] devpNoSort(List<BasDevpPosition> devpPosition1,Integer devpNo){
        List<BasDevpPosition> devpPosition = devpNoInit(devpPosition1);
        BasDevpPosition[] basDevpPositions = new BasDevpPosition[devpPosition.size()];
        long Difference = 0L;
        for (BasDevpPosition basDevpPosition : devpPosition){
            if (basDevpPosition.getDevNo().equals(devpNo)){
                Difference = basDevpPosition.getId() - 1L;
                break;
            }
        }
        for (int[] steNo : steList){
            int i = steNo[1];
        for (BasDevpPosition basDevpPosition : devpPosition){
            long i = basDevpPosition.getId();
            if (i > Difference){
                steNo[1] = i - Difference;
                basDevpPosition.setId(i - Difference);
            } else {
                steNo[1] = steList.length + i-Difference;
                basDevpPosition.setId(devpPosition.size() + i - Difference);
            }
            ints[steNo[0]-1] = steNo;
            basDevpPositions[basDevpPosition.getId().intValue()-1] = basDevpPosition;
        }
        return 0;
        return basDevpPositions;
    }
    //逆序排列
    public static BasDevpPosition[] devpNoSortUN(BasDevpPosition[] devpPosition){
        BasDevpPosition[] basDevpPositions = new BasDevpPosition[devpPosition.length];
        for (BasDevpPosition basDevpPosition : devpPosition){
            basDevpPositions[devpPosition.length - basDevpPosition.getId().intValue()] = basDevpPosition;
        }
        return basDevpPositions;
    }
    //逆序排列
    public static boolean devpNoSortbj(BasDevpPosition[] devpPosition,Integer souDevpNo,Integer endDevpNo){
        int sou = 0;
        int end = 0;
        for (int i = 0;i<devpPosition.length;i++){
            if (devpPosition[i].getDevNo().equals(souDevpNo)){
                sou = i;
            }
            if (devpPosition[i].getDevNo().equals(endDevpNo)){
                end = i;
            }
        }
        return sou>end;
    }
    public static void main(String[] args) {
        int[][] ints = new int[][]{{1,1},{3,3},{2,2},{4,4},{5,5},{6,6},{7,7},{8,8},{9,9},{10,10}};
@@ -55,5 +135,9 @@
        for (int[] ste : reorderSteId){
            System.out.println(Arrays.toString(ste));
        }
        long[] longs = new long[]{1L,1000L,200000L,1100000L,1600000L};
        long l = LatelyAndLessThan(longs, 1100000L);
        System.out.println("l:"+l);
    }
}
src/main/java/com/zy/core/MainProcess.java
@@ -60,9 +60,11 @@
                    // 任务下发
                    mainService.DevpTaskNoRun();
                    // 任务下发
                    mainService.loopSteCharge();
                    // 任务完成
                    mainService.rgvCompleteWrkMastSta();
                    //更新位置信息
                    mainService.updateStePosition();
                } catch (Exception e) {
                    e.printStackTrace();
src/main/java/com/zy/core/enums/RgvStatusType.java
@@ -7,14 +7,14 @@
    PICK_UP_WALK(1, "取货行走","#2196F3"),
    IN_STATION_OPERATION(2, "进站运行中","#2196F3"),
    STATION_ENTRY_COMPLETED(3, "进站完成","#2196F3"),
    PUTTING(4, "有物待出站","#2196F3"),
    WAITING1(5, "出站行走","#E2C027"),
    FETCHWAITING(6, "出站请求","#2196F3"),
    SOS99(7, "出站运行中","#2196F3"),
    SOS100(8, "出站完成","#2196F3"),
    SOS1001(11, "漫游","#2196F3"),
    There_IS_something_waiting_to_leave_the_station(4, "有物待出站","#2196F3"),
    Exit_walking(5, "出站行走","#E2C027"),
    Outbound_request(6, "出站请求","#2196F3"),
    Outbound_operation_in_progress(7, "出站运行中","#2196F3"),
    Outbound_completed(8, "出站完成","#2196F3"),
    ROAM(11, "漫游","#2196F3"),
    WAITING(100, "任务执行完成等待确认","#2196F3"),
    SOSSUPER(999, "未知","#2196F3")
    SOS(999, "未知","#2196F3")
    ;
    public Integer id;
@@ -28,7 +28,7 @@
    public static RgvStatusType get(Short id) {
        if (null == id) {
            return SOSSUPER;
            return SOS;
        }
        for (RgvStatusType type : RgvStatusType.values()) {
            if (type.id.equals(id.intValue())) {
@@ -40,13 +40,13 @@
    public static RgvStatusType get(RgvStatusType type) {
        if (null == type) {
            return SOSSUPER;
            return SOS;
        }
        for (RgvStatusType rgvStatusType : RgvStatusType.values()) {
            if (rgvStatusType == type) {
                return rgvStatusType;
            }
        }
        return SOSSUPER;
        return SOS;
    }
}
src/main/java/com/zy/core/enums/RgvTaskModeType.java
@@ -3,9 +3,9 @@
public enum RgvTaskModeType {
    NONE(0),    // 无
    FETCH(1),    // 取货 (空板)单取
    FETCH(3),    // 取货 (空板)单取
    PUT(2),    // 放货 (空板)单放
    FETCH_PUT(3),    // 取放货
    FETCH_PUT(1),    // 取放货
    X_MOVE(4),    // 站位移转
    FETCH_5(5),    // (空板)满取
    PUT_6(6),    // (空板)满放
src/main/java/com/zy/core/thread/RgvThread.java
@@ -72,6 +72,20 @@
                    case 2:
                        write((RgvCommand) task.getData());
                        break;
                    // 复位
                    case 3:
                        RgvCommand command = (RgvCommand) task.getData();
                        if (null == command) {
                            command = new RgvCommand();
                        }
                        command.setRgvNo(slave.getId()); // RGV编号
                        command.setTaskNo1((short) 0); // 工作号
                        command.setAckFinish1((short) 1);  // 任务完成确认位
                        command.setTaskMode1(RgvTaskModeType.NONE); // 任务模式
                        command.setSourceStaNo1((short)0);     // 源站
                        command.setDestinationStaNo1((short)0);     // 目标站
                        write(command);
                        break;
                    default:
                        break;
                }
@@ -148,17 +162,16 @@
                rgvProtocol.setRgvPos(slave.getId().longValue()*100000);
                OutputQueue.RGV.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId()));
                // 工位1复位信号
                if (rgvProtocol.getStatusType1().equals(RgvStatusType.WAITING)
                        || rgvProtocol.getStatusType1().equals(RgvStatusType.FETCHWAITING)) {
                    if (resetFlag1) {
                        RgvCommand rgvCommand = new RgvCommand();
                        rgvCommand.setAckFinish1((short)1);
                        if (write(rgvCommand)) {
                            resetFlag1 = false;
                        }
                    }
                }
//                // 工位1复位信号
//                if (rgvProtocol.getStatusType1().equals(RgvStatusType.WAITING)) {
//                    if (resetFlag1) {
//                        RgvCommand rgvCommand = new RgvCommand();
//                        rgvCommand.setAckFinish1((short)1);
//                        if (write(rgvCommand)) {
//                            resetFlag1 = false;
//                        }
//                    }
//                }
                try {
                    // 根据实时信息更新数据库
@@ -196,23 +209,25 @@
            return false;
        }
//        siemensNet.Write("DB100.20", command.getCommand());
        siemensNet.Write("DB24.10.0", false);
        siemensNet.Write("DB24.10.1", false);
        command.setRgvNo(slave.getId());
        short[] array = new short[5];
        array[0] = command.getAckFinish1();
        array[1] = command.getTaskNo1();
        short[] array = new short[4];
        array[0] = command.getSourceStaNo1();
        array[1] = command.getDestinationStaNo1();
        array[2] = command.getTaskMode1();//任务模式
        array[3] = command.getSourceStaNo1();
        array[4] = command.getDestinationStaNo1();
        array[3] = command.getTaskNo1();
//        siemensNet.Write("DB100.20", 0);
        OperateResult result = siemensNet.Write("DB100.0", array);
        OperateResult result = siemensNet.Write("DB24.2", array);
        if (command.getAckFinish1() == 0) {
            short commandFinish = 1;  //工位1任务写入
        if (command.getAckFinish1().equals((short)0)) {
            boolean commandFinish = true;  //工位1任务写入
            Thread.sleep(100L);
            result = siemensNet.Write("DB100.20", commandFinish);
            result = siemensNet.Write("DB24.10.0", commandFinish);
        } else {
            siemensNet.Write("DB24.10.1", true);
        }
        try {