zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/ShuttleDispatcher.java
@@ -6,32 +6,25 @@ import com.zy.asrs.framework.common.Cools; import com.zy.asrs.framework.common.SnowflakeIdWorker; import com.zy.asrs.framework.exception.CoolException; import com.zy.asrs.wcs.core.entity.BasShuttle; import com.zy.asrs.wcs.core.entity.Motion; import com.zy.asrs.wcs.core.entity.Task; import com.zy.asrs.wcs.core.entity.TaskCtg; import com.zy.asrs.wcs.core.entity.*; import com.zy.asrs.wcs.core.kernel.AnalyzeService; import com.zy.asrs.wcs.core.model.NavigateNode; import com.zy.asrs.wcs.core.model.enums.DeviceCtgType; import com.zy.asrs.wcs.core.model.enums.LiftCodeType; import com.zy.asrs.wcs.core.model.enums.NavigationMapType; import com.zy.asrs.wcs.core.model.enums.TaskStsType; import com.zy.asrs.wcs.core.service.BasShuttleService; import com.zy.asrs.wcs.core.service.TaskCtgService; import com.zy.asrs.wcs.core.service.TaskService; import com.zy.asrs.wcs.core.service.*; import com.zy.asrs.wcs.rcs.News; import com.zy.asrs.wcs.rcs.cache.SlaveConnection; import com.zy.asrs.wcs.rcs.entity.Device; 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.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.Date; import java.util.List; import java.util.*; /** * Created by vincent on 2023/10/12 @@ -58,6 +51,8 @@ private BasShuttleService basShuttleService; @Autowired private TaskCtgService taskCtgService; @Autowired private ShuttleStandbyService shuttleStandbyService; public ShuttleThread queryShuttleWhichConvenient(Task task, Integer liftNo) { String locNo = taskService.judgeInbound(task) ? task.getDestLoc() : task.getOriginLoc(); @@ -138,6 +133,97 @@ return resThread; } public synchronized ShuttleThread searchIdleShuttle(Task task) { String locNo = taskService.judgeInbound(task) ? task.getDestLoc() : task.getOriginLoc(); ShuttleThread resThread = null; Integer finalDistance = ShuttleDispatcher.INF; List<Device> list = deviceService.list(new LambdaQueryWrapper<Device>() .eq(Device::getDeviceType, DeviceCtgType.SHUTTLE.val()) .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; } //检测是否存在充电任务 Task taskCharge = taskService.selectChargeWorking(Integer.valueOf(device.getDeviceNo())); if (taskCharge != null) { continue; } // 有没有被其他任务调度 int currentLev = Utils.getLev(shuttleProtocol.getCurrentLocNo());//小车当前层高 String currentLocNo = shuttleProtocol.getCurrentLocNo();//小车当前库位号 if (currentLocNo.equals(locNo)) { resThread = shuttleThread; break; } String targetLocNo = null;//默认到提升机待机位 // 同楼层直接计算到目标库位 if (currentLev == Utils.getLev(locNo)) { targetLocNo = locNo; }else { Device recentTransferLift = Utils.getRecentTransferLift(locNo, Integer.parseInt(device.getDeviceNo())); if (recentTransferLift == null) { continue; } //获取小车楼层提升机待机位 ShuttleStandby shuttleStandby = shuttleStandbyService.getOne(new LambdaQueryWrapper<ShuttleStandby>() .eq(ShuttleStandby::getDeviceId, recentTransferLift.getId()) .eq(ShuttleStandby::getDeviceLev, currentLev) .eq(ShuttleStandby::getStatus, 1)); targetLocNo = shuttleStandby.getDeviceLoc(); } //当前穿梭车线程到当前车子所在楼层的提升机口距离 List<NavigateNode> 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<Task> tasks = taskService.selectWorkingByShuttle(Integer.valueOf(device.getDeviceNo())); if (!Cools.isEmpty(tasks)) { currDistance += tasks.size() * WEIGHT; } if (currDistance < finalDistance) { finalDistance = currDistance; resThread = shuttleThread; } } return resThread; } //生成迁移任务 public synchronized Task generateMoveTask(Device device, String locNo) { // 已有迁移任务 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/FlowExecute.java
@@ -3,10 +3,16 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zy.asrs.framework.common.Cools; import com.zy.asrs.wcs.asrs.entity.param.FlowLogicCodeParam; import com.zy.asrs.wcs.core.entity.Task; import com.zy.asrs.wcs.core.service.TaskService; import com.zy.asrs.wcs.core.utils.RedisUtil; import com.zy.asrs.wcs.core.utils.ShuttleDispatcher; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.Md5Crypt; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.List; @@ -15,44 +21,63 @@ @Component public class FlowExecute { @Autowired private RedisUtil redisUtil; @Autowired private TaskService taskService; @Autowired private ShuttleDispatcher shuttleDispatcher; //执行流程图 public boolean execute(List<JSONObject> list) { String currentId = list.get(0).getString("id"); String listId = DigestUtils.md5Hex(JSON.toJSONString(list)); JSONObject devpType = list.get(0).getJSONObject("data").getJSONObject("devpType"); String staNo = devpType.getString("staNo"); //搜索工作档 List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>() .eq(Task::getOriginSite, staNo) .eq(Task::getStatus, 1)); while (currentId != null) { //获取流程图 JSONObject flow = findFLow(list, currentId); if (flow == null) { break; for (Task task : tasks) { String redisKey = DigestUtils.md5Hex(JSON.toJSONString(list)); while (currentId != null) { //获取流程图 JSONObject flow = findFLow(list, currentId); if (flow == null) { break; } //执行 boolean result = executeFlow(task, flow, redisKey); //执行后续流程 if (Cools.isEmpty(flow.get("nextTrue")) && Cools.isEmpty(flow.get("nextFalse"))) { break;//无后续流程 } //更新id currentId = result ? flow.getString("nextTrue") : flow.getString("nextFalse"); } //执行 boolean result = executeFlow(flow, listId); //执行后续流程 if (Cools.isEmpty(flow.get("nextTrue")) && Cools.isEmpty(flow.get("nextFalse"))) { break;//无后续流程 } //更新id currentId = result ? flow.getString("nextTrue") : flow.getString("nextFalse"); System.out.println("执行完成"); redisUtil.del(redisKey);//释放缓存 } System.out.println("执行完成"); return true; } private boolean executeFlow(JSONObject flow, String listId) { private boolean executeFlow(Task task, JSONObject flow, String redisKey) { System.out.println(flow.getString("id") + "被执行"); String type = flow.getString("type"); JSONObject data = flow.getJSONObject("data"); String type = data.getString("type"); boolean result = false; if (type.equals("devp")) { result = executeDevpFlow(task, data, redisKey); } else if (type.equals("shuttle")) { result = executeShuttleFlow(task, data, redisKey); } return true; return result; } private JSONObject findFLow(List<JSONObject> list, String id) { @@ -64,6 +89,48 @@ return null; } private boolean executeDevpFlow(Task task, JSONObject data, String redisKey) { JSONObject devpType = data.getJSONObject("devpType"); String staNo = devpType.getString("staNo"); //搜索工作 return true; } private boolean executeShuttleFlow(Task task, JSONObject data, String redisKey) { JSONObject shuttleType = data.getJSONObject("shuttleType"); JSONArray shuttleOper = shuttleType.getJSONArray("shuttleOper"); for (Object object : shuttleOper) { String oper = String.valueOf(object); if (oper.equals("searchIdleShuttle")) { //搜索空闲车 ShuttleThread shuttleThread = shuttleDispatcher.searchIdleShuttle(task); if (shuttleThread == null) { return false; } //存入缓存 redisSet(redisKey, "shuttleDevice", shuttleThread.getDevice()); return true; } } return true; } private boolean redisSet(String redisKey, String key, Object data) { if (redisUtil.hasKey(redisKey)) { Object obj = redisUtil.get(redisKey); JSONObject object = JSON.parseObject(String.valueOf(obj)); object.put(key, data); redisUtil.set(redisKey, JSON.toJSONString(object)); } else { JSONObject object = new JSONObject(); object.put(key, data); redisUtil.set(redisKey, JSON.toJSONString(object)); } return true; } // private boolean executeFlow(List<Map<String, Object>> list) { // for (Map<String, Object> map : list) { // JSONObject data = (JSONObject) map.get("data");