package com.zy.asrs.wcs.core.utils; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zy.asrs.framework.common.SnowflakeIdWorker; import com.zy.asrs.framework.exception.CoolException; import com.zy.asrs.wcs.core.entity.Task; import com.zy.asrs.wcs.core.kernel.AnalyzeService; import com.zy.asrs.wcs.core.model.NavigateNode; import com.zy.asrs.wcs.core.model.enums.LiftCodeType; import com.zy.asrs.wcs.core.model.enums.NavigationMapType; import com.zy.asrs.wcs.core.service.TaskService; import com.zy.asrs.wcs.rcs.cache.SlaveConnection; import com.zy.asrs.wcs.rcs.entity.Device; import com.zy.asrs.wcs.rcs.entity.DeviceType; import com.zy.asrs.wcs.rcs.model.enums.SlaveType; import com.zy.asrs.wcs.rcs.model.protocol.ShuttleProtocol; import com.zy.asrs.wcs.rcs.service.DeviceService; import com.zy.asrs.wcs.rcs.service.DeviceTypeService; import com.zy.asrs.wcs.core.service.MotionService; import com.zy.asrs.wcs.rcs.thread.ShuttleThread; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** * Created by vincent on 2023/10/12 */ @Service public class ShuttleDispatcher { private static final Integer INF = 9999999; private static final Integer WEIGHT = 1000000; @Autowired private TaskService taskService; @Autowired private LiftDispatcher liftDispatcher; @Autowired private SnowflakeIdWorker snowflakeIdWorker; // @Autowired // private CommonService commonService; @Autowired private AnalyzeService analyzeService; @Autowired private MotionService motionService; @Autowired private DeviceService deviceService; @Autowired private DeviceTypeService deviceTypeService; public ShuttleThread queryShuttleWhichConvenient(Task task, Integer liftNo) { String locNo = taskService.judgeInbound(task) ? task.getDestLoc() : task.getOriginLoc(); ShuttleThread resThread = null; Integer finalDistance = ShuttleDispatcher.INF; DeviceType deviceType = deviceTypeService.getOne(new LambdaQueryWrapper() .eq(DeviceType::getHostId, task.getHostId()) .eq(DeviceType::getStatus, 1) .eq(DeviceType::getFlag, String.valueOf(SlaveType.Shuttle))); if (deviceType == null) { throw new CoolException("设备类型不存在"); } List list = deviceService.list(new LambdaQueryWrapper() .eq(Device::getDeviceType, deviceType.getId()) .eq(Device::getHostId, task.getHostId()) .eq(Device::getStatus, 1)); for (Device device : list) { if (taskService.hasBusyOutboundByShuttle(Integer.parseInt(device.getDeviceNo()))) { continue; } //获取四向穿梭车线程 ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, device.getId().intValue()); ShuttleProtocol shuttleProtocol = shuttleThread.getStatus(); if (shuttleProtocol == null || shuttleProtocol.getShuttleNo() == null) { continue; } if (!shuttleThread.isIdle()) { continue; } // //检测是否存在充电任务 // WrkCharge wrkCharge = wrkChargeService.selectWorking(shuttle.getId()); // if (wrkCharge != null) { // continue; // } // 有没有被其他任务调度 int currentLev = Utils.getLev(shuttleProtocol.getCurrentLocNo());//小车当前层高 String currentLocNo = shuttleProtocol.getCurrentLocNo();//小车当前库位号 if (currentLocNo.equals(locNo)) { resThread = shuttleThread; break; } String targetLocNo = LiftCodeType.getStandbyLocNo(liftNo, currentLev);//默认到提升机待机位 // 同楼层直接计算到目标库位 if (currentLev == Utils.getLev(locNo)) { targetLocNo = locNo; } //当前穿梭车线程到当前车子所在楼层的提升机口距离 List currentShuttlePath = NavigateUtils.calc( currentLocNo , targetLocNo , NavigationMapType.NORMAL.id , Utils.getShuttlePoints(Integer.parseInt(shuttleThread.getDevice().getDeviceNo()), currentLev) );//搜索空闲穿梭车,使用正常通道地图 if (currentShuttlePath == null) { continue; } Integer currDistance = NavigateUtils.getOriginPathAllDistance(currentShuttlePath);//计算当前路径行走总距离 // 不同楼层权重 if (currentLev != Utils.getLev(locNo)) { currDistance += WEIGHT; } // // 挂载任务权重 // List tasks = taskService.selectWorkingByShuttle(shuttle.getId()); // if (!Cools.isEmpty(tasks)) { // currDistance += tasks.size() * WEIGHT; // } if (currDistance < finalDistance) { finalDistance = currDistance; resThread = shuttleThread; } } return resThread; } // /** // * 生成穿梭车迁移任务 // */ // public WrkCharge generateShuttleChargeWrkComplete(Integer shuttleNo, String locNo) { // WrkCharge wrkCharge = new WrkCharge(); // wrkCharge.setShuttleNo(shuttleNo); // wrkCharge.setWrkNo(commonService.getChargeWorkNo(4)); // wrkCharge.setUuid(String.valueOf(snowflakeIdWorker.nextId())); // wrkCharge.setWrkSts(WrkMastStsType.NEW_MOVE.sts); // 迁移任务 // wrkCharge.setIoType(WrkIoTypeType.MOVE.sts); // wrkCharge.setIoPri((double) 10); // wrkCharge.setLocNo(locNo); // wrkCharge.setMemo("reset"); // wrkCharge.setAppeTime(new Date()); // // // generate motion list // List motionList = analyzeService.generateShuttleChargeWrkComplete(wrkCharge); // if (Cools.isEmpty(motionList)) { // News.error("保存{}号四向穿梭车迁移任务失败!!!", shuttleNo); // return null; // } // motionService.batchInsert(motionList, wrkCharge.getUuid(), wrkCharge.getWrkNo()); // // wrkCharge.setWrkSts(WrkMastStsType.ANALYZE_MOVE.sts); // // if (!wrkChargeService.insert(wrkCharge)) { // News.error("保存{}号四向穿梭车迁移任务失败!!!", shuttleNo); // return null; // } // // return wrkCharge; // } }