New file |
| | |
| | | package com.zy.asrs.wcs.core.domain.dto; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.util.Date; |
| | | |
| | | @Data |
| | | public class RedisMapDto { |
| | | |
| | | private String data; |
| | | |
| | | private Date createTime; |
| | | |
| | | private Date updateTime; |
| | | |
| | | private Integer lev; |
| | | |
| | | |
| | | } |
| | |
| | | import com.zy.asrs.framework.exception.CoolException; |
| | | import com.zy.asrs.wcs.core.action.LiftAction; |
| | | import com.zy.asrs.wcs.core.action.ShuttleAction; |
| | | import com.zy.asrs.wcs.core.entity.BasShuttle; |
| | | import com.zy.asrs.wcs.core.entity.Loc; |
| | | import com.zy.asrs.wcs.core.model.NavigateNode; |
| | | import com.zy.asrs.wcs.core.model.command.ShuttleAssignCommand; |
| | |
| | | assignCommand.setTaskNo(motion.getWrkNo()); |
| | | assignCommand.setSourceLocNo(motion.getOrigin()); |
| | | assignCommand.setLocNo(motion.getTarget()); |
| | | assignCommand.setDeviceId(Integer.parseInt(motion.getDevice())); |
| | | |
| | | List<ShuttleCommand> shuttleCommands = new ArrayList<>(); |
| | | ShuttleTaskModeType shuttleTaskModeType = null; |
| | |
| | | |
| | | public synchronized List<ShuttleCommand> shuttleAssignCommand(String startLocNo, String endLocNo, Integer mapType, ShuttleAssignCommand assignCommand, ShuttleThread shuttleThread) { |
| | | //获取小车移动速度 |
| | | Integer runSpeed = Optional.ofNullable(basShuttleService.getById(assignCommand.getShuttleNo()).getRunSpeed()).orElse(1000); |
| | | Integer runSpeed = Optional.ofNullable(basShuttleService.getOne(new LambdaQueryWrapper<BasShuttle>().eq(BasShuttle::getDeviceId, assignCommand.getDeviceId())).getRunSpeed()).orElse(1000); |
| | | Long hostId = shuttleThread.getDevice().getHostId(); |
| | | List<NavigateNode> nodeList = NavigateUtils.calc(startLocNo, endLocNo, mapType, Utils.getShuttlePoints(Integer.parseInt(shuttleThread.getDevice().getDeviceNo()), Utils.getLev(startLocNo))); |
| | | if (nodeList == null) { |
| | |
| | | //开始路径 |
| | | NavigateNode startPath = nodes.get(0); |
| | | |
| | | //中间路径 |
| | | NavigateNode middlePath = null; |
| | | //通过xy坐标小车二维码 |
| | | String middleCodeNum = null; |
| | | Integer middleToDistDistance = null;//计算中间点到目标点行走距离 |
| | | if (nodes.size() > 10) {//中段码传倒数第三个 |
| | | //中间路径 |
| | | middlePath = nodes.get(nodes.size() - 3); |
| | | //通过xy坐标小车二维码 |
| | | middleCodeNum = NavigatePositionConvert.xyToPosition(middlePath.getX(), middlePath.getY(), middlePath.getZ(), hostId); |
| | | middleToDistDistance = NavigateUtils.getMiddleToDistDistance(nodes, middlePath);//计算中间点到目标点行走距离 |
| | | } else if (nodes.size() > 5) {//中段码传倒数第二个 |
| | | //中间路径 |
| | | middlePath = nodes.get(nodes.size() - 2); |
| | | //通过xy坐标小车二维码 |
| | | middleCodeNum = NavigatePositionConvert.xyToPosition(middlePath.getX(), middlePath.getY(), middlePath.getZ(), hostId); |
| | | middleToDistDistance = NavigateUtils.getMiddleToDistDistance(nodes, middlePath);//计算中间点到目标点行走距离 |
| | | } |
| | | |
| | | //目标路径 |
| | | NavigateNode endPath = nodes.get(nodes.size() - 1); |
| | | Integer allDistance = NavigateUtils.getCurrentPathAllDistance(nodes);//计算当前路径行走总距离 |
| | |
| | | //通过xy坐标小车二维码 |
| | | String distCodeNum = NavigatePositionConvert.xyToPosition(endPath.getX(), endPath.getY(), endPath.getZ(), hostId); |
| | | //获取移动命令 |
| | | ShuttleCommand command = shuttleThread.getMoveCommand(assignCommand.getTaskNo().intValue(), startCodeNum, distCodeNum, allDistance, ShuttleRunDirection.get(startPath.getDirection()).id.intValue(), runSpeed); |
| | | ShuttleCommand command = shuttleThread.getMoveCommand(assignCommand.getTaskNo(), startCodeNum, distCodeNum, allDistance, ShuttleRunDirection.get(startPath.getDirection()).id.intValue(), runSpeed); |
| | | command.setNodes(nodes);//将行走节点添加到每一步命令中 |
| | | commands.add(command); |
| | | } |
| | |
| | | private Integer shuttleNo = 0; |
| | | |
| | | /** |
| | | * 设备ID |
| | | */ |
| | | private Integer deviceId; |
| | | |
| | | /** |
| | | * 任务号 |
| | | */ |
| | | private Integer taskNo = 0; |
| | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.zy.asrs.framework.common.Cools; |
| | | import com.zy.asrs.framework.common.SnowflakeIdWorker; |
| | | import com.zy.asrs.wcs.core.domain.dto.RedisMapDto; |
| | | import com.zy.asrs.wcs.core.entity.*; |
| | | import com.zy.asrs.wcs.core.kernel.AnalyzeService; |
| | | import com.zy.asrs.wcs.core.model.MapNode; |
| | |
| | | |
| | | Integer lev = entry.getKey(); |
| | | Date now = new Date(); |
| | | HashMap<String, Object> map = new HashMap<>(); |
| | | map.put("data", JSON.toJSONString(lists)); |
| | | map.put("create_time", now); |
| | | map.put("update_time", now); |
| | | map.put("lev", lev); |
| | | RedisMapDto map = new RedisMapDto(); |
| | | map.setData(JSON.toJSONString(lists)); |
| | | map.setCreateTime(now); |
| | | map.setUpdateTime(now); |
| | | map.setLev(lev); |
| | | |
| | | //将地图数据存入redis |
| | | redisUtil.set(DeviceRedisConstant.MAP + lev, JSON.toJSONString(map)); |
| | |
| | | import com.zy.asrs.common.wms.entity.LocMast; |
| | | import com.zy.asrs.common.wms.service.LocMastService; |
| | | import com.zy.asrs.framework.common.SpringUtils; |
| | | import com.zy.asrs.wcs.core.entity.Loc; |
| | | import com.zy.asrs.wcs.core.model.MapNode; |
| | | import com.zy.asrs.wcs.core.model.NavigateNode; |
| | | import com.zy.asrs.wcs.core.model.enums.NavigationMapType; |
| | | import com.zy.asrs.wcs.core.service.LocService; |
| | | import com.zy.asrs.wcs.rcs.constant.DeviceRedisConstant; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.io.*; |
| | |
| | | */ |
| | | @Component |
| | | public class NavigateMapData { |
| | | |
| | | @Autowired |
| | | private LocService locService; |
| | | |
| | | private Integer lev;//地图楼层 |
| | | |
| | |
| | | |
| | | //获取JSON格式数据 |
| | | public List<List<MapNode>> getJsonData(Integer mapType, List<int[]> whitePoints, List<int[]> shuttlePoints) { |
| | | try { |
| | | String mapFilename = "map_" + lev + ".json"; |
| | | |
| | | String fileName = this.getClass().getClassLoader().getResource(mapFilename).getPath();//获取文件路径 |
| | | File file = new File(fileName); |
| | | StringBuffer stringBuffer = new StringBuffer(); |
| | | if (file.isFile() && file.exists()) { |
| | | InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "GBK"); |
| | | BufferedReader br = new BufferedReader(isr); |
| | | String lineTxt = null; |
| | | while ((lineTxt = br.readLine()) != null) { |
| | | stringBuffer.append(lineTxt); |
| | | } |
| | | br.close(); |
| | | |
| | | //解析json地图数据 |
| | | ArrayList arrayList = JSON.parseObject(stringBuffer.toString(), ArrayList.class); |
| | | List<List<MapNode>> lists = filterMap(mapType, arrayList, lev, whitePoints, shuttlePoints);//过滤地图数据 |
| | | |
| | | return lists; |
| | | } else { |
| | | System.out.println("文件不存在!"); |
| | | } |
| | | } catch (IOException ioException) { |
| | | ioException.printStackTrace(); |
| | | RedisUtil redisUtil = SpringUtils.getBean(RedisUtil.class); |
| | | Object o = redisUtil.get(DeviceRedisConstant.MAP + lev); |
| | | if (o == null) { |
| | | return null; |
| | | } |
| | | return null; |
| | | |
| | | BasMap basMap = JSON.parseObject(o.toString(), BasMap.class); |
| | | ArrayList arrayList = JSON.parseObject(basMap.getData(), ArrayList.class); |
| | | List<List<MapNode>> lists = filterMap(mapType, arrayList, lev, whitePoints, shuttlePoints);//过滤地图数据 |
| | | return lists; |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | |
| | | //过滤数据 |
| | | LocMastService locMastService = SpringUtils.getBean(LocMastService.class); |
| | | //获取当前楼层库位数据 |
| | | List<LocMast> locMasts = locMastService.list(new LambdaQueryWrapper<LocMast>() |
| | | .eq(LocMast::getLev1, lev)); |
| | | for (LocMast locMast : locMasts) { |
| | | Integer row = locMast.getRow1(); |
| | | Integer bay = locMast.getBay1(); |
| | | List<Loc> locs = locService.list(new LambdaQueryWrapper<Loc>() |
| | | .eq(Loc::getLev, lev)); |
| | | for (Loc loc : locs) { |
| | | Integer row = loc.getRow(); |
| | | Integer bay = loc.getBay(); |
| | | |
| | | boolean whiteFlag = false;//默认不存在白名单 |
| | | if (whitePoints != null) { |
| | |
| | | } else if (mapType == NavigationMapType.DFX.id) { |
| | | //车辆有货 |
| | | //读取对应库位数据,将DFX库位状态的节点置为-1(障碍物) |
| | | if (locMast.getLocSts().equals("F") |
| | | || locMast.getLocSts().equals("D") |
| | | || locMast.getLocSts().equals("X") |
| | | || locMast.getLocSts().equals("R") |
| | | || locMast.getLocSts().equals("P") |
| | | if (loc.getLocSts$().equals("F") |
| | | || loc.getLocSts$().equals("D") |
| | | || loc.getLocSts$().equals("X") |
| | | ) { |
| | | mapNode.setValue(-1);//禁用节点 |
| | | } |
| | | } else if (mapType == NavigationMapType.NORMAL.id) { |
| | | //过滤库位状态X |
| | | if (locMast.getLocSts().equals("X")) { |
| | | if (loc.getLocSts$().equals("X")) { |
| | | mapNode.setValue(-1);//禁用节点 |
| | | } |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | NavigateMapData mapData = new NavigateMapData(nodes.get(0).getZ()); |
| | | List<List<MapNode>> realMap = mapData.getJsonData(-1, null, null);//获取完整地图(包括入库出库) |
| | | this.setLev(nodes.get(0).getZ()); |
| | | List<List<MapNode>> realMap = this.getJsonData(-1, null, null);//获取完整地图(包括入库出库) |
| | | for (NavigateNode node : nodes) { |
| | | if (node.getZ() != lev) { |
| | | continue; |
| | |
| | | package com.zy.asrs.wcs.core.utils; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.zy.asrs.common.wms.entity.BasMap; |
| | | import com.zy.asrs.framework.common.SpringUtils; |
| | | import com.zy.asrs.wcs.core.domain.dto.RedisMapDto; |
| | | import com.zy.asrs.wcs.core.model.MapNode; |
| | | import com.zy.asrs.wcs.core.model.NavigateNode; |
| | | import com.zy.asrs.wcs.core.model.enums.NavigationMapType; |
| | | import com.zy.asrs.wcs.rcs.constant.DeviceRedisConstant; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.ArrayList; |
| | |
| | | |
| | | @Component |
| | | public class NavigateMapUtils { |
| | | |
| | | @Autowired |
| | | private NavigateMapData navigateMapData; |
| | | |
| | | /** |
| | | * 写入路径节点数据到redis地图中 |
| | |
| | | return true; |
| | | } |
| | | |
| | | NavigateMapData navigateMapData = new NavigateMapData(lev); |
| | | |
| | | navigateMapData.setLev(lev); |
| | | Object o = redisUtil.get(DeviceRedisConstant.MAP + lev); |
| | | if (o == null) { |
| | | return false; |
| | |
| | | //获取小车节点 |
| | | List<int[]> shuttlePoints = Utils.getShuttlePoints(shuttleNo, lev); |
| | | |
| | | BasMap basMap = JSON.parseObject(o.toString(), BasMap.class); |
| | | ArrayList arrayList = JSON.parseObject(basMap.getData(), ArrayList.class); |
| | | RedisMapDto redisMap = JSON.parseObject(o.toString(), RedisMapDto.class); |
| | | ArrayList arrayList = JSON.parseObject(redisMap.getData(), ArrayList.class); |
| | | //带小车地图 |
| | | List<List<MapNode>> listsHasShuttle = navigateMapData.filterMap(NavigationMapType.NONE.id, arrayList, lev, null, shuttlePoints);//获取带小车地图数据 |
| | | List<List<MapNode>> lists = navigateMapData.filterMap(NavigationMapType.NONE.id, arrayList, lev, null, null);//获取全部地图数据 |
| | |
| | | } |
| | | |
| | | //尝试锁定/解锁路径 |
| | | NavigateMapData mapData = new NavigateMapData(nodes.get(0).getZ()); |
| | | List<List<MapNode>> realMap = mapData.getJsonData(-1, null, null);//获取完整地图(包括入库出库) |
| | | navigateMapData.setLev(nodes.get(0).getZ()); |
| | | List<List<MapNode>> realMap = navigateMapData.getJsonData(-1, null, null);//获取完整地图(包括入库出库) |
| | | for (NavigateNode node : nodes) { |
| | | if (node.getZ() != lev) { |
| | | continue; |
| | |
| | | listX.set(node.getY(), mapNode); |
| | | lists.set(node.getX(), listX); |
| | | } |
| | | basMap.setData(JSON.toJSONString(lists)); |
| | | basMap.setUpdateTime(new Date()); |
| | | redisMap.setData(JSON.toJSONString(lists)); |
| | | redisMap.setUpdateTime(new Date()); |
| | | //将数据库地图数据存入redis |
| | | redisUtil.set(DeviceRedisConstant.MAP + lev, JSON.toJSONString(basMap)); |
| | | redisUtil.set(DeviceRedisConstant.MAP + lev, JSON.toJSONString(redisMap)); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | |
| | | public class NavigatePositionConvert { |
| | | |
| | | public static String xyToPosition(int x, int y, int z, Long hostId) { |
| | | StringBuffer sb = new StringBuffer(); |
| | | if (x < 10) { |
| | | sb.append("0"); |
| | | } |
| | | sb.append(x); |
| | | |
| | | if (y < 10) { |
| | | sb.append("00"); |
| | | } else if (y < 100) { |
| | | sb.append("0"); |
| | | } |
| | | sb.append(y); |
| | | |
| | | if (z < 10) { |
| | | sb.append("0"); |
| | | } |
| | | sb.append(z); |
| | | String position = sb.toString();//库位号 |
| | | String locNo = Utils.getLocNo(x, y, z); |
| | | |
| | | //库位号转小车二维码 |
| | | LocService locMastService = SpringUtils.getBean(LocService.class); |
| | | Loc locMast = locMastService.getOne(new LambdaQueryWrapper<Loc>() |
| | | .eq(Loc::getLocNo, position) |
| | | .eq(Loc::getLocNo, locNo) |
| | | .eq(Loc::getHostId, hostId)); |
| | | if (locMast == null) { |
| | | // //当前库位号查不到,可能是站点库位号 |
| | | // BasDevpService basDevpService = SpringUtils.getBean(BasDevpService.class); |
| | | // BasDevp basDevp = basDevpService.queryByLocNo(position); |
| | | // if (basDevp == null) { |
| | | // return null; |
| | | // } |
| | | // return Short.parseShort(basDevp.getQrCodeValue()); |
| | | return null; |
| | | } |
| | | return locMast.getCode(); |
| | |
| | | |
| | | //坐标编号转xy轴 |
| | | public static int[] positionToXY(String position) { |
| | | int col = Integer.parseInt(position.substring(0, 2)); |
| | | int row = Integer.parseInt(position.substring(2, 5)); |
| | | int col = Utils.getRow(position); |
| | | int row = Utils.getBay(position); |
| | | int[] newPosition = coverPosition(col,row); |
| | | //返回x和y |
| | | // return new int[]{row, col}; |
| | |
| | | package com.zy.asrs.wcs.core.utils; |
| | | |
| | | import com.zy.asrs.framework.common.SpringUtils; |
| | | import com.zy.asrs.wcs.core.model.NavigateNode; |
| | | |
| | | import java.util.ArrayList; |
| | |
| | | |
| | | public NavigateSolution() { |
| | | //载入地图 |
| | | NavigateMapData mapData = new NavigateMapData(); |
| | | NavigateMapData mapData = SpringUtils.getBean(NavigateMapData.class); |
| | | mapData.setLev(1); |
| | | int[][] data = mapData.getData(); |
| | | this.map = data; |
| | | } |
| | | |
| | | public NavigateSolution(Integer mapType, Integer lev, List<int[]> whitePoints, List<int[]> shuttlePoints) { |
| | | //载入地图指定层高地图 |
| | | NavigateMapData mapData = new NavigateMapData(lev); |
| | | NavigateMapData mapData = SpringUtils.getBean(NavigateMapData.class); |
| | | mapData.setLev(lev); |
| | | int[][] data = mapData.getDataFromRedis(mapType, whitePoints, shuttlePoints); |
| | | if (data == null) { |
| | | data = mapData.getData(mapType, whitePoints, shuttlePoints); |
| | |
| | | package com.zy.asrs.wcs.core.utils; |
| | | |
| | | import com.zy.asrs.framework.common.SpringUtils; |
| | | import com.zy.asrs.wcs.core.model.MapNode; |
| | | import com.zy.asrs.wcs.core.model.NavigateNode; |
| | | import com.zy.asrs.wcs.core.model.enums.NavigationMapType; |
| | |
| | | |
| | | //获取从x点到下一点的行走距离 |
| | | public static Integer getXToNextDistance(NavigateNode xNode) { |
| | | NavigateMapData mapData = new NavigateMapData(); |
| | | NavigateMapData mapData = SpringUtils.getBean(NavigateMapData.class); |
| | | mapData.setLev(xNode.getZ()); |
| | | List<List<MapNode>> lists = mapData.getJsonData(NavigationMapType.NONE.id, null, null); |
| | | if (lists != null) { |
| | | MapNode mapNode = lists.get(xNode.getX()).get(xNode.getY()); |
| | |
| | | import java.text.MessageFormat; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.*; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | @Slf4j |
| | | @SuppressWarnings("all") |
| | |
| | | .setPath("/RDS/runRoute") |
| | | .setHeaders(headers) |
| | | .setJson(JSON.toJSONString(param)) |
| | | .setTimeout(60, TimeUnit.SECONDS) |
| | | .build() |
| | | .doPost(); |
| | | JSONObject jsonObject = JSON.parseObject(response); |
| | |
| | | .setPath("/RDS/runOrder") |
| | | .setHeaders(headers) |
| | | .setJson(command.getBody()) |
| | | .setTimeout(60, TimeUnit.SECONDS) |
| | | .build() |
| | | .doPost(); |
| | | JSONObject jsonObject = JSON.parseObject(response); |
| | |
| | | .setPath("/RDS/actionOrder") |
| | | .setHeaders(headers) |
| | | .setJson(command.getBody()) |
| | | .setTimeout(60, TimeUnit.SECONDS) |
| | | .build() |
| | | .doPost(); |
| | | JSONObject jsonObject = JSON.parseObject(response); |
| | |
| | | .setPath("/RDS/actionOrder") |
| | | .setHeaders(headers) |
| | | .setJson(command.getBody()) |
| | | .setTimeout(60, TimeUnit.SECONDS) |
| | | .build() |
| | | .doPost(); |
| | | JSONObject jsonObject = JSON.parseObject(response); |