zjj
2024-06-27 f2c8334b9988edd7c8fa5d9c0da506060f85a16a
#移库
1个文件已添加
11个文件已修改
319 ■■■■■ 已修改文件
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/asrs/entity/param/CreateWcsTaskParam.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/MainProcess.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/controller/OpenController.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/AnalyzeService.java 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/mapper/TaskMapper.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/enums/TaskStsType.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/TaskService.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/MainServiceImpl.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/TaskServiceImpl.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/timer/MotionTimer.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/timer/TaskTimer.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/resources/mapper/core/TaskMapper.xml 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/asrs/entity/param/CreateWcsTaskParam.java
New file
@@ -0,0 +1,28 @@
package com.zy.asrs.wcs.asrs.entity.param;
import lombok.Data;
import java.io.Serializable;
@Data
public class CreateWcsTaskParam implements Serializable {
    private static final long serialVersionUID = 1L;
    private String requestPK; //请求编号
    private String dvcNo; //初始设备编号
    private String contNo; //容器条码
    private String trkType; //任务类型
    private String trkSubType; //子任务类型
    private String trkPrty; //任务优先级
    private String frmPos; //起始位置
    private String toPos; //目标位置
    private String isFull; //容器空满状态
    private String contType; //容器类型
    private String operator; //上位系统名
    private String operationTime; //任务下发时间
}
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/MainProcess.java
@@ -53,6 +53,8 @@
                    mainService.analyzeInBoundTask();
                    // 解析小车移动工作档
                    mainService.analyzeMoveTask();
                    // 解析小车载货移动工作档
                    mainService.analyzeLadenMoveTask();
                    // 出库  ===>> 工作档信息写入led显示器
                    mainService.ledExecute();
                    // 其他  ===>> LED显示器复位,显示默认信息
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/controller/OpenController.java
@@ -366,6 +366,57 @@
        return R.ok();
    }
    //生成载货移动任务
    @PostMapping("/createLadenMoveTakeTask")
    public R createLadenMoveTakeTask(@RequestBody CreateManualTakeTaskParam param) {
        //获取手动任务类型
        TaskCtg taskCtg = taskCtgService.getOne(new LambdaQueryWrapper<TaskCtg>()
                .eq(TaskCtg::getFlag, String.valueOf(TaskCtgType.MOVE))
                .eq(TaskCtg::getStatus, 1));
        if (taskCtg == null) {
            return R.error("任务类型异常");
        }
        Task one = taskService.getOne(new LambdaQueryWrapper<Task>()
                .eq(Task::getTaskCtg, taskCtg.getId())
                .eq(Task::getOriginLoc, param.getOriginLoc())
                .eq(Task::getDestLoc, param.getDestLoc()));
        if (one != null) {
            return R.error("任务已存在");
        }
        //优先级
        Integer priority = 10;
        if (param.getPriority() != null) {
            priority = param.getPriority();
        }
        Task task = new Task();
        task.setUuid(String.valueOf(snowflakeIdWorker.nextId()));
        task.setTaskNo(String.valueOf(Utils.getTaskNo("OUT")));
        task.setWmsTaskNo(param.getTaskNo());
        task.setTaskSts(TaskStsType.NEW_LADEN_MOVE.sts);
        task.setTaskCtg(taskCtg.getId());
        task.setPriority(priority);
        task.setOriginSite(null);
        task.setOriginLoc(param.getOriginLoc());//源库位
        task.setDestSite(null);
        task.setDestLoc(param.getDestLoc());//目标库位
        task.setIoTime(new Date());
        task.setStartTime(new Date());
        task.setStatus(1);
        task.setMemo("");
        task.setShuttleNo(null);//等待主线程分配小车
        task.setRecordLoc(param.getRecord() ? "Y" : "N");//记录库存信息
        task.setHostId(1L);//临时控制只允许host为1
        boolean result = taskService.save(task);
        if (!result) {
            return R.error("生成手动取放货任务失败!");
        }
        return R.ok();
    }
    //生成小车移动任务
    @PostMapping("/createMoveTask")
    public R createMoveTask(@RequestBody CreateMoveTaskParam param) {
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/AnalyzeService.java
@@ -1,8 +1,6 @@
package com.zy.asrs.wcs.core.kernel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zy.asrs.framework.common.Cools;
import com.zy.asrs.framework.common.R;
import com.zy.asrs.wcs.core.domain.dto.MotionDto;
import com.zy.asrs.wcs.core.entity.*;
import com.zy.asrs.wcs.core.model.enums.DeviceCtgType;
@@ -1408,6 +1406,91 @@
        }
        return motionList;
    }
    /**
     * 生成小车载货迁移动作
     */
    public List<Motion> generateShuttleLadenMoveMotion(Task task) {
        List<Motion> motionList = new ArrayList<>();
        if (task.getTaskSts() != TaskStsType.NEW_LADEN_MOVE.sts) {
            return motionList;
        }
        //originLoc 源库位
        String originLoc =  task.getOriginLoc();
        // locNo 目标库位
        String locNo = task.getDestLoc();
        Device shuttleDevice = deviceService.getOne(new LambdaQueryWrapper<Device>()
                .eq(Device::getDeviceNo, task.getShuttleNo())
                .eq(Device::getDeviceType, DeviceCtgType.SHUTTLE.val())
                .eq(Device::getHostId, task.getHostId())
                .eq(Device::getStatus, 1));
        if (shuttleDevice == null) {
            return motionList;
        }
        ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleDevice.getId().intValue());
        if (shuttleThread == null) {
            return motionList;
        }
        ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
        if (shuttleProtocol == null || shuttleProtocol.getShuttleNo() == null) {
            return motionList;
        }
        String shuttleLocNo = shuttleProtocol.getCurrentLocNo();
        // 判断穿梭车是否在目标层
        if (Utils.getLev(shuttleLocNo) == Utils.getLev(locNo)) {
            if (!shuttleLocNo.equals(locNo)) {//小车不在目标库位
                // 穿梭车走行至源库位
                motionList.addAll(kernelService.shuttleMove(
                        MotionDto.build((dto -> {
                            dto.setShuttleNo(shuttleDevice.getId().intValue());
                            dto.setLocNo(shuttleLocNo);
                        })),
                        MotionDto.build((dto -> {
                            dto.setShuttleNo(shuttleDevice.getId().intValue());
                            dto.setLocNo(originLoc);
                        })),
                        MotionCtgType.SHUTTLE_MOVE
                ));
                // 穿梭车顶升
                motionList.add(Motion.build(motion -> {
                    motion.setDeviceCtg(DeviceCtgType.SHUTTLE.val());
                    motion.setDevice(String.valueOf(shuttleDevice.getId()));
                    motion.setMotionCtg(MotionCtgType.SHUTTLE_PALLET_LIFT.val());
                }));
                // 穿梭车走行至目标库位
                motionList.addAll(kernelService.shuttleMove(
                        MotionDto.build((dto -> {
                            dto.setShuttleNo(shuttleDevice.getId().intValue());
                            dto.setLocNo(originLoc);
                        })),
                        MotionDto.build((dto -> {
                            dto.setShuttleNo(shuttleDevice.getId().intValue());
                            dto.setLocNo(locNo);
                        })),
                        MotionCtgType.SHUTTLE_MOVE
                ));
                //穿梭车托盘下降
                motionList.add(Motion.build(motion -> {
                    motion.setDeviceCtg(DeviceCtgType.SHUTTLE.val());
                    motion.setDevice(String.valueOf(shuttleDevice.getId()));
                    motion.setMotionCtg(MotionCtgType.SHUTTLE_PALLET_DOWN.val());
                }));
            }
        } else {
            //小车跨层
        }
        return motionList;
    }
    /**
     * 生成小车手动动作
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/mapper/TaskMapper.java
@@ -36,6 +36,12 @@
    List<Task> selectWaitAnalyzeMoveTask();
    List<Task> selectWaitAnalyzeLadenMoveTask();
    List<Task> selectLadenMoveByAnalyzeSts();
    List<Task> selectLadenMoveByExecuteSts();
    List<Task> hasChargeInLoc(String locNo);
    Task selectMoveWorking(Integer shuttleNo);
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/enums/TaskStsType.java
@@ -1,10 +1,6 @@
package com.zy.asrs.wcs.core.model.enums;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zy.asrs.framework.common.SpringUtils;
import com.zy.asrs.framework.exception.CoolException;
import com.zy.asrs.wcs.core.entity.TaskSts;
import com.zy.asrs.wcs.core.service.TaskStsService;
public enum TaskStsType {
@@ -35,6 +31,11 @@
    ANALYZE_MANUAL(402, "手动任务解析"),
    EXECUTE_MANUAL(403, "执行手动任务"),
    COMPLETE_MANUAL(410, "手动任务完成"),
    NEW_LADEN_MOVE(501,"生成移库任务"),
    ANALYZE_LADEN_MOVE(502, "移库任务解析"),
    EXECUTE_LADEN_MOVE(503, "执行移库任务"),
    COMPLETE_LADEN_MOVE(504, "移库任务完成"),
    ;
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/TaskService.java
@@ -34,6 +34,12 @@
    List<Task> selectWaitAnalyzeMoveTask();
    List<Task> selectWaitAnalyzeLadenMoveTask();
    List<Task> selectLadenMoveByAnalyzeSts();
    List<Task> selectLadenMoveByExecuteSts();
    List<Task> hasChargeInLoc(String locNo);
    Task selectMoveWorking(Integer shuttleNo);
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/MainServiceImpl.java
@@ -603,6 +603,42 @@
        }
    }
    // 解析小车载货移动工作档
    public synchronized void analyzeLadenMoveTask() {
        for (Task task : taskService.selectWaitAnalyzeLadenMoveTask()) {
            if (Cools.isEmpty(task.getShuttleNo())) {
                //分配小车
                //搜索空闲车
                ShuttleThread shuttleThread = shuttleDispatcher.searchIdleShuttle(task);
                if (shuttleThread == null) {
                    News.info("{}任务未找到空闲穿梭车", task.getTaskNo());
                    continue;
                }
                task.setShuttleNo(Integer.valueOf(shuttleThread.getDevice().getDeviceNo()));//保存穿梭车号
                task.setUpdateTime(new Date());
                if (!taskService.updateById(task)) {
                    News.info("{}任务更新穿梭车号失败", task.getTaskNo());
                }
                continue;
            }
            // generate motion list
            List<Motion> motionList = analyzeService.generateShuttleLadenMoveMotion(task);
            if (motionList.isEmpty()) {
                continue;
            }
            motionService.batchInsert(motionList, task.getUuid(), Integer.valueOf(task.getTaskNo()), task.getHostId());
            // 更新工作主档
            task.setTaskSts(TaskStsType.ANALYZE_LADEN_MOVE.sts); // 工作状态
            task.setUpdateTime(new Date());
            if (!taskService.updateById(task)) {
                News.error("更新工作档失败!!! [工作号:{}]", task.getTaskNo());
            }
        }
    }
    /**
     * 四向穿梭车电量检测 ===>> 发起充电
     */
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/TaskServiceImpl.java
@@ -112,6 +112,21 @@
    }
    @Override
    public List<Task> selectWaitAnalyzeLadenMoveTask() {
        return this.baseMapper.selectWaitAnalyzeLadenMoveTask();
    }
    @Override
    public List<Task> selectLadenMoveByAnalyzeSts() {
        return this.baseMapper.selectLadenMoveByAnalyzeSts();
    }
    @Override
    public List<Task> selectLadenMoveByExecuteSts() {
        return this.baseMapper.selectLadenMoveByExecuteSts();
    }
    @Override
    public List<Task> hasChargeInLoc(String locNo) {
        return this.baseMapper.hasChargeInLoc(locNo);
    }
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/timer/MotionTimer.java
@@ -173,6 +173,65 @@
    }
    @Scheduled(cron = "0/1 * * * * ? ")
    public synchronized void executeLadenMoveTask() {
        Date now = new Date();
        // ANALYZE_CHARGE
        for (Task taskCharge : taskService.selectLadenMoveByAnalyzeSts()) {
            Motion executingMotion = motionService.selectOfTop1(taskCharge.getUuid(), MotionStsType.EXECUTING.val(), taskCharge.getHostId());
            if (executingMotion != null) {//存在正在执行的motion
                if (executingMotion.getSync() == 1) {//当前执行中的动作是同步动作,等待执行完成后再执行下一个动作
                    continue;
                }
            }
            Motion motion = motionService.selectOfTop1(taskCharge.getUuid(), MotionStsType.INIT.val(), taskCharge.getHostId());
            if (null != motion) {
                boolean result = this.executeMotion(motion);
                if (!result) {
                    continue;
                }
                // 更新Task
                switch (TaskStsType.query(taskCharge.getTaskSts())) {
                    case ANALYZE_LADEN_MOVE:
                        taskCharge.setTaskSts(TaskStsType.EXECUTE_LADEN_MOVE.sts);
                        break;
                }
                taskCharge.setUpdateTime(now);
                if (!taskService.updateById(taskCharge)) {
                    log.error("{}其他工作档更新状态失败!", taskCharge.getTaskNo());
                }
            }
        }
        // EXECUTE_CHARGE
        for (Task taskCharge : taskService.selectLadenMoveByExecuteSts()) {
            if (!motionService.hasRunningMotion(taskCharge.getUuid(), taskCharge.getHostId())) {
                Motion motion = motionService.selectOfTop1(taskCharge.getUuid(), MotionStsType.WAITING.val(), taskCharge.getHostId());
                if (null != motion) {
                    boolean result = this.executeMotion(motion);
                    if (!result) {
                        continue;
                    }
                } else {
                    if (motionService.selectOfTop1(taskCharge.getUuid(), MotionStsType.EXECUTING.val(), taskCharge.getHostId()) != null) {
                        continue;
                    }
                    // 更新Task
                    switch (TaskStsType.query(taskCharge.getTaskSts())) {
                        case EXECUTE_LADEN_MOVE:
                            taskCharge.setTaskSts(TaskStsType.COMPLETE_LADEN_MOVE.sts);
                            break;
                    }
                    taskCharge.setUpdateTime(now);
                    if (!taskService.updateById(taskCharge)) {
                        log.error("{}他工作档更新状态失败!", taskCharge.getTaskNo());
                    }
                }
            }
        }
    }
    @Scheduled(cron = "0/1 * * * * ? ")
    public synchronized void executeManualTask() {
        Date now = new Date();
        // ANALYZE_MANUAL
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/timer/TaskTimer.java
@@ -40,6 +40,7 @@
        taskSts.add(TaskStsType.COMPLETE_CHARGE.sts);
        taskSts.add(TaskStsType.COMPLETE_MOVE.sts);
        taskSts.add(TaskStsType.COMPLETE_MANUAL.sts);
        taskSts.add(TaskStsType.COMPLETE_LADEN_MOVE.sts);
        List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>()
                .eq(Task::getStatus, 1)
zy-asrs-wcs/src/main/resources/mapper/core/TaskMapper.xml
@@ -82,6 +82,25 @@
        order by priority desc,start_time,task_no asc
    </select>
    <select id="selectWaitAnalyzeLadenMoveTask" resultType="com.zy.asrs.wcs.core.entity.Task">
        select * from wcs_task where task_sts = 501
        order by priority desc,start_time,task_no asc
    </select>
    <select id="selectLadenMoveByAnalyzeSts" resultType="com.zy.asrs.wcs.core.entity.Task">
        select * from wcs_task
        where 1=1
          and task_sts in (502)
        order by priority desc,start_time,task_no asc
    </select>
    <select id="selectLadenMoveByExecuteSts" resultType="com.zy.asrs.wcs.core.entity.Task">
        select * from wcs_task
        where 1=1
          and task_sts in (503)
        order by priority desc,start_time,task_no asc
    </select>
    <select id="hasChargeInLoc" resultType="com.zy.asrs.wcs.core.entity.Task">
        select * from wcs_task
        where task_sts in (201,202,203,204)