zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/MapNode.java
New file @@ -0,0 +1,32 @@ package com.zy.asrs.wcs.core.model; import lombok.Data; /** * 地图数据节点 */ @Data public class MapNode { /** * -1 禁用 * 0 子轨道 * 3 母轨道 * 4 充电桩 * 5 充电桩 * 66 穿梭车坐标 * -999 锁定节点 */ private Integer value; private String data; private Integer top; private Integer bottom; private Integer left; private Integer right; } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/NavigateNode.java
New file @@ -0,0 +1,49 @@ package com.zy.asrs.wcs.core.model; import lombok.Data; /** * A*寻路算法Node节点 */ @Data public class NavigateNode implements Comparable<NavigateNode>{ private int x;//坐标x private int y;//坐标y private int z;//坐标z(高度) private int F;//综合花费的步数 private int G;//已经花费的步数 private int H;//将要花费的步数 private NavigateNode Father;//父节点 private Boolean isInflectionPoint;//是否为拐点 private String direction;//行走方向 private Integer moveDistance;//行走距离 public NavigateNode(int x, int y) { this.x = x; this.y = y; } //通过结点的坐标和目标结点的坐标可以计算出F, G, H三个属性 //需要传入这个节点的上一个节点和最终的结点 public void init_node(NavigateNode father, NavigateNode end) { this.Father = father; if (this.Father != null) { //走过的步数等于父节点走过的步数加一 this.G = father.G + 1; } else { //父节点为空代表它是第一个结点 this.G = 0; } //以下计算方案为算法原始方案,没有去拐点方案。已被Solution计算时自动覆盖。 //计算通过现在的结点的位置和最终结点的位置计算H值(曼哈顿法:坐标分别取差值相加) this.H = Math.abs(this.x - end.x) + Math.abs(this.y - end.y); this.F = this.G + this.H; } @Override public int compareTo(NavigateNode o) { return Integer.compare(this.F, o.F); } } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/enums/NavigationMapType.java
New file @@ -0,0 +1,42 @@ package com.zy.asrs.wcs.core.model.enums; public enum NavigationMapType { NONE(-1, "无过滤"), DFX(1, "过滤库位状态DFX"), // 带货走行 NORMAL(2, "过滤库位状态X"), // 无货走行 ; public Integer id; public String desc; NavigationMapType(Integer id, String desc) { this.id = id; this.desc = desc; } public static NavigationMapType get(Short id) { if (null == id) { return null; } for (NavigationMapType type : NavigationMapType.values()) { if (type.id.equals(id.intValue())) { return type; } } return null; } public static NavigationMapType get(NavigationMapType type) { if (null == type) { return null; } for (NavigationMapType type1 : NavigationMapType.values()) { if (type1 == type) { return type1; } } return null; } } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateMapData.java
New file @@ -0,0 +1,298 @@ package com.zy.asrs.wcs.core.utils; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zy.asrs.common.wms.entity.BasMap; 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.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.stereotype.Component; import java.io.*; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * A*算法地图获取类 */ @Component public class NavigateMapData { private Integer lev;//地图楼层 public NavigateMapData() { this.lev = 1; } public NavigateMapData(Integer lev) { this.lev = lev; } public void setLev(Integer lev) { this.lev = lev; } public int[][] getData() { return getData(NavigationMapType.NONE.id, null, null);//默认读取无过滤的全部地图数据 } public int[][] getData(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);//过滤地图数据 int[][] map = new int[lists.size()][]; int j = 0; for (List<MapNode> list : lists) { int[] tmp = new int[list.size()]; int i = 0; for (MapNode mapNode : list) { //将数据添加进二维数组 tmp[i++] = mapNode.getValue(); } //数据添加进一维数组 map[j++] = tmp; } return map; } else { System.out.println("文件不存在!"); } } catch (IOException ioException) { ioException.printStackTrace(); } return null; } /** * 尝试从redis获取数据 */ public int[][] getDataFromRedis(Integer mapType, List<int[]> whitePoints, List<int[]> shuttlePoints) { RedisUtil redisUtil = SpringUtils.getBean(RedisUtil.class); Object o = redisUtil.get(DeviceRedisConstant.MAP + lev); if (o == null) { return null; } BasMap basMap = JSON.parseObject(o.toString(), BasMap.class); return this.getDataFormString(basMap.getData(), mapType, whitePoints, shuttlePoints); } /** * 从List数据中获取地图 */ public int[][] getDataFormString(String data, Integer mapType, List<int[]> whitePoints, List<int[]> shuttlePoints) { ArrayList arrayList = JSON.parseObject(data, ArrayList.class); List<List<MapNode>> lists = filterMap(mapType, arrayList, lev, whitePoints, shuttlePoints);//过滤地图数据 int[][] map = new int[lists.size()][]; int j = 0; for (List<MapNode> list : lists) { int[] tmp = new int[list.size()]; int i = 0; for (MapNode mapNode : list) { //将数据添加进二维数组 tmp[i++] = mapNode.getValue(); } //数据添加进一维数组 map[j++] = tmp; } return map; } //获取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(); } return null; } /** * 过滤地图数据 * mapType -1=>无过滤,1=》过滤库位状态DFX,2=》过滤库位状态X * * @param whitePoints 白名单节点,不需要被过滤 * @param shuttlePoints 穿梭车节点,需要加载进地图 */ public List<List<MapNode>> filterMap(Integer mapType, List arrayList, Integer lev, List<int[]> whitePoints, List<int[]> shuttlePoints) { List<List<MapNode>> lists = new ArrayList<>(); //重建数据格式 for (int i = 0; i < arrayList.size(); i++) { Object obj = arrayList.get(i); List<MapNode> list = JSON.parseArray(obj.toString(), MapNode.class); for (int j = 0; j < list.size(); j++) { MapNode mapNode = list.get(j); list.set(j, mapNode); } lists.add(list); } //过滤数据 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(); boolean whiteFlag = false;//默认不存在白名单 if (whitePoints != null) { for (int[] whitePoint : whitePoints) { if (whitePoint[0] == row && whitePoint[1] == bay) { //存在白名单 whiteFlag = true; break; } } } if (whiteFlag) { continue;//存在白名单,不执行下列过滤方案 } List<MapNode> list = lists.get(row); MapNode mapNode = list.get(bay); if (mapType == NavigationMapType.NONE.id) { //不过滤任何数据 } 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") ) { mapNode.setValue(-1);//禁用节点 } } else if (mapType == NavigationMapType.NORMAL.id) { //过滤库位状态X if (locMast.getLocSts().equals("X")) { mapNode.setValue(-1);//禁用节点 } } //更新list list.set(bay, mapNode); lists.set(row, list); } //加载车辆坐标到地图中 if (shuttlePoints != null) { for (int[] points : shuttlePoints) { int x = points[0]; int y = points[1]; List<MapNode> list = lists.get(x); MapNode mapNode = list.get(y); mapNode.setValue(66);//设置为车辆代码66 //更新list list.set(y, mapNode); lists.set(x, list); } } return lists; } /** * 锁/解锁 路径节点 * 写入路径节点数据到redis地图中 * lock为true 禁用库位,lock为false恢复库位 */ public synchronized boolean writeNavigateNodeToRedisMap(List<NavigateNode> nodes, boolean lock) { RedisUtil redisUtil = SpringUtils.getBean(RedisUtil.class); Object o = redisUtil.get("realtimeBasMap_" + lev); if (o == null) { return false; } BasMap basMap = JSON.parseObject(o.toString(), BasMap.class); ArrayList arrayList = JSON.parseObject(basMap.getData(), ArrayList.class); List<List<MapNode>> lists = filterMap(NavigationMapType.NONE.id, arrayList, lev, null, null);//获取全部地图数据 // 防止重复锁路径 if (lock) { for (NavigateNode node : nodes) { List<MapNode> listX = lists.get(node.getX()); MapNode mapNode = listX.get(node.getY()); if (mapNode.getValue() == -999) { return false; } } } NavigateMapData mapData = new NavigateMapData(nodes.get(0).getZ()); List<List<MapNode>> realMap = mapData.getJsonData(-1, null, null);//获取完整地图(包括入库出库) for (NavigateNode node : nodes) { if (node.getZ() != lev) { continue; } List<MapNode> listX = lists.get(node.getX()); MapNode mapNode = listX.get(node.getY()); if (lock) { mapNode.setValue(-999);//禁用库位 }else { //获取原始节点数据 List<MapNode> rows = realMap.get(node.getX()); MapNode col = rows.get(node.getY()); mapNode.setValue(col.getValue());//恢复库位 } listX.set(node.getY(), mapNode); lists.set(node.getX(), listX); } basMap.setData(JSON.toJSONString(lists)); basMap.setUpdateTime(new Date()); //将数据库地图数据存入redis redisUtil.set("realtimeBasMap_" + lev, JSON.toJSONString(basMap)); return true; } } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateMapUtils.java
New file @@ -0,0 +1,93 @@ //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.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.stereotype.Component; // //import java.util.ArrayList; //import java.util.Date; //import java.util.List; // //@Component //public class NavigateMapUtils { // // /** // * 写入路径节点数据到redis地图中 // * lock为true 禁用库位,lock为false恢复库位 // */ // public synchronized boolean writeNavigateNodeToRedisMap(Integer lev, Integer shuttleNo, List<NavigateNode> nodes, boolean lock) { // RedisUtil redisUtil = SpringUtils.getBean(RedisUtil.class); // try { // if (nodes.isEmpty()) { // return true; // } // // NavigateMapData navigateMapData = new NavigateMapData(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); // //带小车地图 // 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);//获取全部地图数据 // // //检测路径是否被锁定 // if (lock) { // for (NavigateNode node : nodes) { // List<MapNode> listX = listsHasShuttle.get(node.getX()); // MapNode mapNode = listX.get(node.getY()); // if (mapNode.getValue() == -999) { // return false;//路径被锁定过,禁止再次锁定 // } // if (mapNode.getValue() == 66) { // return false;//路径存在小车,禁止锁定 // } // } // } // // //尝试锁定/解锁路径 // NavigateMapData mapData = new NavigateMapData(nodes.get(0).getZ()); // List<List<MapNode>> realMap = mapData.getJsonData(-1, null, null);//获取完整地图(包括入库出库) // for (NavigateNode node : nodes) { // if (node.getZ() != lev) { // continue; // } // // List<MapNode> listX = lists.get(node.getX()); // MapNode mapNode = listX.get(node.getY()); // if (lock) { // mapNode.setValue(-999);//禁用库位 // } else { // //获取原始节点数据 // List<MapNode> rows = realMap.get(node.getX()); // MapNode col = rows.get(node.getY()); // mapNode.setValue(col.getValue());//恢复库位 // } // // listX.set(node.getY(), mapNode); // lists.set(node.getX(), listX); // } // basMap.setData(JSON.toJSONString(lists)); // basMap.setUpdateTime(new Date()); // //将数据库地图数据存入redis // redisUtil.set(DeviceRedisConstant.MAP + lev, JSON.toJSONString(basMap)); // return true; // } catch (Exception e) { // e.printStackTrace(); // } // return false; // } // //} zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/MotionCtgController.java
New file @@ -0,0 +1,101 @@ package com.zy.asrs.wcs.system.controller; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.zy.asrs.framework.common.Cools; import com.zy.asrs.framework.common.R; import com.zy.asrs.wcs.common.annotation.OperationLog; import com.zy.asrs.wcs.common.domain.BaseParam; import com.zy.asrs.wcs.common.domain.KeyValVo; import com.zy.asrs.wcs.common.domain.PageParam; import com.zy.asrs.wcs.rcs.entity.MotionCtg; import com.zy.asrs.wcs.rcs.service.MotionCtgService; import com.zy.asrs.wcs.utils.ExcelUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; @RestController @RequestMapping("/api") public class MotionCtgController extends BaseController { @Autowired private MotionCtgService motionCtgService; @PreAuthorize("hasAuthority('rcs:motionCtg:list')") @PostMapping("/motionCtg/page") public R page(@RequestBody Map<String, Object> map) { BaseParam baseParam = buildParam(map, BaseParam.class); PageParam<MotionCtg, BaseParam> pageParam = new PageParam<>(baseParam, MotionCtg.class); return R.ok().add(motionCtgService.page(pageParam, pageParam.buildWrapper(true))); } @PreAuthorize("hasAuthority('rcs:motionCtg:list')") @PostMapping("/motionCtg/list") public R list(@RequestBody Map<String, Object> map) { return R.ok().add(motionCtgService.list()); } @PreAuthorize("hasAuthority('rcs:motionCtg:list')") @GetMapping("/motionCtg/{id}") public R get(@PathVariable("id") Long id) { return R.ok().add(motionCtgService.getById(id)); } @PreAuthorize("hasAuthority('rcs:motionCtg:save')") @OperationLog("添加Motion标记") @PostMapping("/motionCtg/save") public R save(@RequestBody MotionCtg motionCtg) { if (!motionCtgService.save(motionCtg)) { return R.error("添加失败"); } return R.ok("添加成功"); } @PreAuthorize("hasAuthority('rcs:motionCtg:update')") @OperationLog("修改Motion标记") @PostMapping("/motionCtg/update") public R update(@RequestBody MotionCtg motionCtg) { if (!motionCtgService.updateById(motionCtg)) { return R.error("修改失败"); } return R.ok("修改成功"); } @PreAuthorize("hasAuthority('rcs:motionCtg:remove')") @OperationLog("删除Motion标记") @PostMapping("/motionCtg/remove/{ids}") public R remove(@PathVariable Long[] ids) { if (!motionCtgService.removeByIds(Arrays.asList(ids))) { return R.error("删除失败"); } return R.ok("删除成功"); } @PreAuthorize("hasAuthority('rcs:motionCtg:list')") @PostMapping("/motionCtg/query") public R query(@RequestParam(required = false) String condition) { List<KeyValVo> vos = new ArrayList<>(); LambdaQueryWrapper<MotionCtg> wrapper = new LambdaQueryWrapper<>(); if (!Cools.isEmpty(condition)) { wrapper.like(MotionCtg::getName, condition); } motionCtgService.page(new Page<>(1, 30), wrapper).getRecords().forEach( item -> vos.add(new KeyValVo(item.getId(), item.getName())) ); return R.ok().add(vos); } @PreAuthorize("hasAuthority('rcs:motionCtg:list')") @PostMapping("/motionCtg/export") public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception { ExcelUtil.build(ExcelUtil.create(motionCtgService.list(), MotionCtg.class), response); } } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/MotionStsController.java
New file @@ -0,0 +1,101 @@ package com.zy.asrs.wcs.system.controller; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.zy.asrs.framework.common.Cools; import com.zy.asrs.framework.common.R; import com.zy.asrs.wcs.common.annotation.OperationLog; import com.zy.asrs.wcs.common.domain.BaseParam; import com.zy.asrs.wcs.common.domain.KeyValVo; import com.zy.asrs.wcs.common.domain.PageParam; import com.zy.asrs.wcs.rcs.entity.MotionSts; import com.zy.asrs.wcs.rcs.service.MotionStsService; import com.zy.asrs.wcs.utils.ExcelUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; @RestController @RequestMapping("/api") public class MotionStsController extends BaseController { @Autowired private MotionStsService motionStsService; @PreAuthorize("hasAuthority('rcs:motionSts:list')") @PostMapping("/motionSts/page") public R page(@RequestBody Map<String, Object> map) { BaseParam baseParam = buildParam(map, BaseParam.class); PageParam<MotionSts, BaseParam> pageParam = new PageParam<>(baseParam, MotionSts.class); return R.ok().add(motionStsService.page(pageParam, pageParam.buildWrapper(true))); } @PreAuthorize("hasAuthority('rcs:motionSts:list')") @PostMapping("/motionSts/list") public R list(@RequestBody Map<String, Object> map) { return R.ok().add(motionStsService.list()); } @PreAuthorize("hasAuthority('rcs:motionSts:list')") @GetMapping("/motionSts/{id}") public R get(@PathVariable("id") Long id) { return R.ok().add(motionStsService.getById(id)); } @PreAuthorize("hasAuthority('rcs:motionSts:save')") @OperationLog("添加Motion状态") @PostMapping("/motionSts/save") public R save(@RequestBody MotionSts motionSts) { if (!motionStsService.save(motionSts)) { return R.error("添加失败"); } return R.ok("添加成功"); } @PreAuthorize("hasAuthority('rcs:motionSts:update')") @OperationLog("修改Motion状态") @PostMapping("/motionSts/update") public R update(@RequestBody MotionSts motionSts) { if (!motionStsService.updateById(motionSts)) { return R.error("修改失败"); } return R.ok("修改成功"); } @PreAuthorize("hasAuthority('rcs:motionSts:remove')") @OperationLog("删除Motion状态") @PostMapping("/motionSts/remove/{ids}") public R remove(@PathVariable Long[] ids) { if (!motionStsService.removeByIds(Arrays.asList(ids))) { return R.error("删除失败"); } return R.ok("删除成功"); } @PreAuthorize("hasAuthority('rcs:motionSts:list')") @PostMapping("/motionSts/query") public R query(@RequestParam(required = false) String condition) { List<KeyValVo> vos = new ArrayList<>(); LambdaQueryWrapper<MotionSts> wrapper = new LambdaQueryWrapper<>(); if (!Cools.isEmpty(condition)) { wrapper.like(MotionSts::getName, condition); } motionStsService.page(new Page<>(1, 30), wrapper).getRecords().forEach( item -> vos.add(new KeyValVo(item.getId(), item.getName())) ); return R.ok().add(vos); } @PreAuthorize("hasAuthority('rcs:motionSts:list')") @PostMapping("/motionSts/export") public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception { ExcelUtil.build(ExcelUtil.create(motionStsService.list(), MotionSts.class), response); } } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/entity/MotionCtg.java
New file @@ -0,0 +1,224 @@ package com.zy.asrs.wcs.rcs.entity; import java.text.SimpleDateFormat; import java.util.Date; import com.zy.asrs.wcs.rcs.service.DeviceTypeService; import com.zy.asrs.wcs.system.entity.Host; import com.zy.asrs.wcs.system.entity.User; import org.springframework.format.annotation.DateTimeFormat; import java.text.SimpleDateFormat; import java.util.Date; import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import com.zy.asrs.framework.common.Cools; import com.zy.asrs.framework.common.SpringUtils; import com.zy.asrs.wcs.system.service.UserService; import com.zy.asrs.wcs.system.service.HostService; import java.io.Serializable; import java.util.Date; @Data @TableName("rcs_motion_ctg") public class MotionCtg implements Serializable { private static final long serialVersionUID = 1L; /** * ID */ @ApiModelProperty(value= "ID") @TableId(value = "id", type = IdType.AUTO) private Long id; /** * 设备类型 */ @ApiModelProperty(value= "设备类型") private Long deviceType; /** * 编号 */ @ApiModelProperty(value= "编号") private String uuid; /** * 名称 */ @ApiModelProperty(value= "名称") private String name; /** * 标识 */ @ApiModelProperty(value= "标识") private String flag; /** * 状态 1: 正常 0: 禁用 */ @ApiModelProperty(value= "状态 1: 正常 0: 禁用 ") private Integer status; /** * 添加人员 */ @ApiModelProperty(value= "添加人员") private Long createBy; /** * 添加时间 */ @ApiModelProperty(value= "添加时间") @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") private Date createTime; /** * 修改人员 */ @ApiModelProperty(value= "修改人员") private Long updateBy; /** * 修改时间 */ @ApiModelProperty(value= "修改时间") @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") private Date updateTime; /** * 备注 */ @ApiModelProperty(value= "备注") private String memo; /** * 是否删除 1: 是 0: 否 */ @ApiModelProperty(value= "是否删除 1: 是 0: 否 ") @TableLogic private Integer deleted; /** * 所属机构 */ @ApiModelProperty(value= "所属机构") private Long hostId; public MotionCtg() {} public MotionCtg(Long deviceType,String uuid,String name,String flag,Integer status,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo,Integer deleted,Long hostId) { this.deviceType = deviceType; this.uuid = uuid; this.name = name; this.flag = flag; this.status = status; this.createBy = createBy; this.createTime = createTime; this.updateBy = updateBy; this.updateTime = updateTime; this.memo = memo; this.deleted = deleted; this.hostId = hostId; } // MotionCtg motionCtg = new MotionCtg( // null, // 设备类型 // null, // 编号 // null, // 名称[非空] // null, // 标识 // null, // 状态 // null, // 添加人员 // null, // 添加时间 // null, // 修改人员 // null, // 修改时间 // null, // 备注 // null, // 是否删除 // null // 所属机构 // ); public String getDeviceType$(){ DeviceTypeService service = SpringUtils.getBean(DeviceTypeService.class); DeviceType deviceType = service.getById(this.deviceType); if (!Cools.isEmpty(deviceType)){ return String.valueOf(deviceType.getId()); } return null; } public String getStatus$(){ if (null == this.status){ return null; } switch (this.status){ case 1: return "正常"; case 0: return "禁用"; default: return String.valueOf(this.status); } } public String getCreateBy$(){ UserService service = SpringUtils.getBean(UserService.class); User user = service.getById(this.createBy); if (!Cools.isEmpty(user)){ return String.valueOf(user.getNickname()); } return null; } public String getCreateTime$(){ if (Cools.isEmpty(this.createTime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime); } public String getUpdateBy$(){ UserService service = SpringUtils.getBean(UserService.class); User user = service.getById(this.updateBy); if (!Cools.isEmpty(user)){ return String.valueOf(user.getNickname()); } return null; } public String getUpdateTime$(){ if (Cools.isEmpty(this.updateTime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime); } public String getDeleted$(){ if (null == this.deleted){ return null; } switch (this.deleted){ case 1: return "是"; case 0: return "否"; default: return String.valueOf(this.deleted); } } public String getHostId$(){ HostService service = SpringUtils.getBean(HostService.class); Host host = service.getById(this.hostId); if (!Cools.isEmpty(host)){ return String.valueOf(host.getName()); } return null; } } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/entity/MotionSts.java
New file @@ -0,0 +1,206 @@ package com.zy.asrs.wcs.rcs.entity; import java.text.SimpleDateFormat; import java.util.Date; import com.zy.asrs.wcs.system.entity.Host; import com.zy.asrs.wcs.system.entity.User; import org.springframework.format.annotation.DateTimeFormat; import java.text.SimpleDateFormat; import java.util.Date; import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import com.zy.asrs.framework.common.Cools; import com.zy.asrs.framework.common.SpringUtils; import com.zy.asrs.wcs.system.service.UserService; import com.zy.asrs.wcs.system.service.HostService; import java.io.Serializable; import java.util.Date; @Data @TableName("rcs_motion_sts") public class MotionSts implements Serializable { private static final long serialVersionUID = 1L; /** * ID */ @ApiModelProperty(value= "ID") @TableId(value = "id", type = IdType.AUTO) private Long id; /** * 编号 */ @ApiModelProperty(value= "编号") private String uuid; /** * 名称 */ @ApiModelProperty(value= "名称") private String name; /** * 标识 */ @ApiModelProperty(value= "标识") private String flag; /** * 状态 1: 正常 0: 禁用 */ @ApiModelProperty(value= "状态 1: 正常 0: 禁用 ") private Integer status; /** * 添加人员 */ @ApiModelProperty(value= "添加人员") private Long createBy; /** * 添加时间 */ @ApiModelProperty(value= "添加时间") @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") private Date createTime; /** * 修改人员 */ @ApiModelProperty(value= "修改人员") private Long updateBy; /** * 修改时间 */ @ApiModelProperty(value= "修改时间") @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") private Date updateTime; /** * 备注 */ @ApiModelProperty(value= "备注") private String memo; /** * 是否删除 1: 是 0: 否 */ @ApiModelProperty(value= "是否删除 1: 是 0: 否 ") @TableLogic private Integer deleted; /** * 所属机构 */ @ApiModelProperty(value= "所属机构") private Long hostId; public MotionSts() {} public MotionSts(String uuid,String name,String flag,Integer status,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo,Integer deleted,Long hostId) { this.uuid = uuid; this.name = name; this.flag = flag; this.status = status; this.createBy = createBy; this.createTime = createTime; this.updateBy = updateBy; this.updateTime = updateTime; this.memo = memo; this.deleted = deleted; this.hostId = hostId; } // MotionSts motionSts = new MotionSts( // null, // 编号 // null, // 名称[非空] // null, // 标识 // null, // 状态 // null, // 添加人员 // null, // 添加时间 // null, // 修改人员 // null, // 修改时间 // null, // 备注 // null, // 是否删除 // null // 所属机构 // ); public String getStatus$(){ if (null == this.status){ return null; } switch (this.status){ case 1: return "正常"; case 0: return "禁用"; default: return String.valueOf(this.status); } } public String getCreateBy$(){ UserService service = SpringUtils.getBean(UserService.class); User user = service.getById(this.createBy); if (!Cools.isEmpty(user)){ return String.valueOf(user.getNickname()); } return null; } public String getCreateTime$(){ if (Cools.isEmpty(this.createTime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime); } public String getUpdateBy$(){ UserService service = SpringUtils.getBean(UserService.class); User user = service.getById(this.updateBy); if (!Cools.isEmpty(user)){ return String.valueOf(user.getNickname()); } return null; } public String getUpdateTime$(){ if (Cools.isEmpty(this.updateTime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime); } public String getDeleted$(){ if (null == this.deleted){ return null; } switch (this.deleted){ case 1: return "是"; case 0: return "否"; default: return String.valueOf(this.deleted); } } public String getHostId$(){ HostService service = SpringUtils.getBean(HostService.class); Host host = service.getById(this.hostId); if (!Cools.isEmpty(host)){ return String.valueOf(host.getName()); } return null; } } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/kernel/command/ShuttleCommandService.java
New file @@ -0,0 +1,511 @@ //package com.zy.asrs.wcs.rcs.kernel.command; // //import com.zy.asrs.common.wms.mapper.WrkMastMapper; //import com.zy.asrs.common.wms.service.LocMastService; //import com.zy.asrs.wcs.core.utils.NavigateMapUtils; //import com.zy.asrs.wcs.core.utils.RedisUtil; //import lombok.extern.slf4j.Slf4j; //import org.springframework.beans.factory.annotation.Autowired; //import org.springframework.stereotype.Service; // //import java.util.ArrayList; //import java.util.Objects; //import java.util.Optional; // ///** // * Created by vincent on 2023/10/23 // */ //@Slf4j //@Service //public class ShuttleCommandService { // // public static final Integer SHUTTLE_ADDITION_COMMAND_SPEED = 500; // // @Autowired // private RedisUtil redisUtil; // @Autowired // private MotionService motionService; // @Autowired // private WrkMastMapper wrkMastMapper; // @Autowired // private BasShuttleService basShuttleService; // @Autowired // private LocMastService locMastService; // @Autowired // private NavigateMapUtils navigateMapUtils; // // // 计算 // public Boolean accept(Motion motion) { // Integer deviceNo = Integer.parseInt(motion.getDevice()); // ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, deviceNo); // ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol(); // if (null == shuttleProtocol) { // return false; // } // if (shuttleProtocol.getBusyStatus().intValue() == ShuttleStatusType.BUSY.id // || !shuttleProtocol.isIdle()) { // return false; // } // if (!shuttleProtocol.getPakMk()) { // return false; // } // if (motionService.selectCount(new EntityWrapper<Motion>() // .eq("device_ctg", DeviceCtgType.SHUTTLE.val()) // .eq("device", motion.getDevice()) // .eq("motion_sts", MotionStsType.EXECUTING.val())) > 0) { // return false; // } // // ShuttleAssignCommand assignCommand = new ShuttleAssignCommand(); // assignCommand.setShuttleNo(deviceNo.shortValue()); // assignCommand.setTaskNo(motion.getWrkNo().shortValue()); // assignCommand.setSourceLocNo(motion.getOrigin()); // assignCommand.setLocNo(motion.getTarget()); // // List<ShuttleCommand> shuttleCommands = new ArrayList<>(); // ShuttleTaskModeType shuttleTaskModeType = null; // // SiemensLiftThread liftThread = null; // LiftProtocol liftProtocol = null; // // //判断小车状态 // if (shuttleProtocol.getBusyStatusType().equals(ShuttleStatusType.IDLE) // && shuttleProtocol.getProtocolStatusType().equals(ShuttleProtocolStatusType.IDLE) // && shuttleProtocol.getTaskNo().intValue() != 0 // ) { // return false; // } // // switch (Objects.requireNonNull(MotionCtgType.get(motion.getMotionCtgEl()))){ // case SHUTTLE_MOVE: // // 如果已经在当前条码则过滤 // if (String.valueOf(shuttleProtocol.getCurrentCode()).equals(locMastService.selectById(motion.getTarget()).getQrCodeValue())) { // return true; // } // shuttleCommands = this.shuttleAssignCommand(motion.getOrigin(), motion.getTarget(), NavigationMapType.NORMAL.id, assignCommand, shuttleThread); // shuttleTaskModeType = ShuttleTaskModeType.SHUTTLE_MOVE_LOC_NO; // break; // case SHUTTLE_MOVE_LIFT_PALLET://穿梭车顶升并移动 // shuttleCommands = this.shuttleAssignCommand(motion.getOrigin(), motion.getTarget(), NavigationMapType.DFX.id, assignCommand, shuttleThread); // shuttleTaskModeType = ShuttleTaskModeType.PAK_IN; // shuttleCommands.add(0, shuttleThread.getPalletCommand((short) 1)); // break; // case SHUTTLE_MOVE_DOWN_PALLET://穿梭车移动并托盘下降 // shuttleCommands = this.shuttleAssignCommand(motion.getOrigin(), motion.getTarget(), NavigationMapType.DFX.id, assignCommand, shuttleThread); // shuttleTaskModeType = ShuttleTaskModeType.PAK_IN; // shuttleCommands.add(shuttleCommands.size(), shuttleThread.getPalletCommand((short) 2)); // break; // case SHUTTLE_MOVE_FROM_LIFT://出提升机 // // 判断提升机状态 // liftThread = (SiemensLiftThread) SlaveConnection.get(SlaveType.Lift, Integer.parseInt(motion.getTemp())); // if (liftThread == null) { // return false; // } // liftProtocol = liftThread.getLiftProtocol(); // // 判断提升机是否自动、空闲、准备就绪、链条没有转动、没有未就绪报错 // if (!liftProtocol.getMode() // || liftProtocol.getRunning() // || !liftProtocol.getReady() // || liftProtocol.getForwardRotationFeedback() // || liftProtocol.getReverseFeedback() // || liftProtocol.getNotReady().intValue() != 0 // ) { // return false; // } // // if (liftProtocol.getLev().intValue() != Utils.getLev(motion.getTarget())) {//判断提升机是否达到目标层 // return false; // } // // //判断提升机是否被锁定 // if (!liftProtocol.getLiftLock()) { // //锁定提升机 // LiftCommand lockCommand = liftThread.getLockCommand(true);//获取提升机锁定命令 // lockCommand.setLiftNo(liftProtocol.getLiftNo()); // lockCommand.setTaskNo(motion.getWrkNo().shortValue());//获取任务号 // liftThread.assignWork(lockCommand); // return false;//等待下一次轮询 // } // // //判断提升机工作号是否和当前任务相同 // if (liftProtocol.getTaskNo().intValue() != motion.getWrkNo()) { // return false; // } // // shuttleCommands = this.shuttleAssignCommand(motion.getOrigin(), motion.getTarget(), NavigationMapType.NORMAL.id, assignCommand, shuttleThread); // shuttleTaskModeType = ShuttleTaskModeType.SHUTTLE_MOVE_LOC_NO; // break; // case SHUTTLE_MOVE_TO_LIFT://进提升机 // // 判断提升机状态 // liftThread = (SiemensLiftThread) SlaveConnection.get(SlaveType.Lift, Integer.parseInt(motion.getTemp())); // if (liftThread == null) { // return false; // } // liftProtocol = liftThread.getLiftProtocol(); // // 判断提升机是否自动、空闲、准备就绪、链条没有转动、没有未就绪报错 // if (!liftProtocol.getMode() // || liftProtocol.getRunning() // || !liftProtocol.getReady() // || liftProtocol.getForwardRotationFeedback() // || liftProtocol.getReverseFeedback() // || liftProtocol.getNotReady().intValue() != 0 // ) { // return false; // } // // if (liftProtocol.getLev().intValue() != Utils.getLev(motion.getTarget())) {//判断提升机是否达到目标层 // return false; // } // // //判断提升机是否被锁定 // if (!liftProtocol.getLiftLock()) { // //锁定提升机 // LiftCommand lockCommand = liftThread.getLockCommand(true);//获取提升机锁定命令 // lockCommand.setLiftNo(liftProtocol.getLiftNo()); // lockCommand.setTaskNo(motion.getWrkNo().shortValue());//获取任务号 // liftThread.assignWork(lockCommand); // return false;//等待下一次轮询 // } // // //判断提升机工作号是否和当前任务相同 // if (liftProtocol.getTaskNo().intValue() != motion.getWrkNo()) { // return false; // } // // shuttleCommands = this.shuttleAssignCommand(motion.getOrigin(), motion.getTarget(), NavigationMapType.NORMAL.id, assignCommand, shuttleThread); // shuttleTaskModeType = ShuttleTaskModeType.SHUTTLE_MOVE_LOC_NO; // break; // case SHUTTLE_MOVE_FROM_CONVEYOR: // shuttleCommands = this.shuttleAssignCommand(motion.getOrigin(), motion.getTarget(), NavigationMapType.NORMAL.id, assignCommand, shuttleThread); // shuttleTaskModeType = ShuttleTaskModeType.SHUTTLE_MOVE_LOC_NO; // break; // case SHUTTLE_MOVE_TO_CONVEYOR: // shuttleCommands = this.shuttleAssignCommand(motion.getOrigin(), motion.getTarget(), NavigationMapType.NORMAL.id, assignCommand, shuttleThread); // shuttleTaskModeType = ShuttleTaskModeType.SHUTTLE_MOVE_LOC_NO; // break; // case SHUTTLE_MOVE_FROM_LIFT_TO_CONVEYOR://穿梭车出提升机去输送线 // // 判断提升机状态 // liftThread = (SiemensLiftThread) SlaveConnection.get(SlaveType.Lift, Integer.parseInt(motion.getTemp())); // if (liftThread == null) { // return false; // } // liftProtocol = liftThread.getLiftProtocol(); // // 判断提升机是否自动、空闲、准备就绪、链条没有转动、没有未就绪报错 // if (!liftProtocol.getMode() // || liftProtocol.getRunning() // || !liftProtocol.getReady() // || liftProtocol.getForwardRotationFeedback() // || liftProtocol.getReverseFeedback() // || liftProtocol.getNotReady().intValue() != 0 // ) { // return false; // } // // if (liftProtocol.getLev().intValue() != Utils.getLev(motion.getTarget())) {//判断提升机是否达到目标层 // return false; // } // // //判断提升机是否被锁定 // if (!liftProtocol.getLiftLock()) { // //锁定提升机 // LiftCommand lockCommand = liftThread.getLockCommand(true);//获取提升机锁定命令 // lockCommand.setLiftNo(liftProtocol.getLiftNo()); // lockCommand.setTaskNo(motion.getWrkNo().shortValue());//获取任务号 // liftThread.assignWork(lockCommand); // return false;//等待下一次轮询 // } // // //判断提升机工作号是否和当前任务相同 // if (liftProtocol.getTaskNo().intValue() != motion.getWrkNo()) { // return false; // } // // shuttleCommands = this.shuttleAssignCommand(motion.getOrigin(), motion.getTarget(), NavigationMapType.NORMAL.id, assignCommand, shuttleThread); // shuttleTaskModeType = ShuttleTaskModeType.SHUTTLE_MOVE_LOC_NO; // break; // case SHUTTLE_TRANSPORT: // shuttleCommands = this.shuttleAssignCommand(motion.getOrigin(), motion.getTarget(), NavigationMapType.DFX.id, assignCommand, shuttleThread); // shuttleTaskModeType = ShuttleTaskModeType.PAK_IN; // // shuttleCommands.add(0, shuttleThread.getPalletCommand((short) 1)); // shuttleCommands.add(shuttleCommands.size(), shuttleThread.getPalletCommand((short) 2)); // break; // case SHUTTLE_TRANSPORT_FROM_LIFT://穿梭车载货出提升机 // // 判断提升机状态 // liftThread = (SiemensLiftThread) SlaveConnection.get(SlaveType.Lift, Integer.parseInt(motion.getTemp())); // if (liftThread == null) { // return false; // } // liftProtocol = liftThread.getLiftProtocol(); // // 判断提升机是否自动、空闲、准备就绪、链条没有转动、没有未就绪报错 // if (!liftProtocol.getMode() // || liftProtocol.getRunning() // || !liftProtocol.getReady() // || liftProtocol.getForwardRotationFeedback() // || liftProtocol.getReverseFeedback() // || liftProtocol.getNotReady().intValue() != 0 // ) { // return false; // } // // if (liftProtocol.getLev().intValue() != Utils.getLev(motion.getTarget())) {//判断提升机是否达到目标层 // return false; // } // // //判断提升机是否被锁定 // if (!liftProtocol.getLiftLock()) { // //锁定提升机 // LiftCommand lockCommand = liftThread.getLockCommand(true);//获取提升机锁定命令 // lockCommand.setLiftNo(liftProtocol.getLiftNo()); // lockCommand.setTaskNo(motion.getWrkNo().shortValue());//获取任务号 // liftThread.assignWork(lockCommand); // return false;//等待下一次轮询 // } // // //判断提升机工作号是否和当前任务相同 // if (liftProtocol.getTaskNo().intValue() != motion.getWrkNo()) { // return false; // } // // shuttleCommands = this.shuttleAssignCommand(motion.getOrigin(), motion.getTarget(), NavigationMapType.DFX.id, assignCommand, shuttleThread); // shuttleTaskModeType = ShuttleTaskModeType.PAK_IN; // shuttleCommands.add(0, shuttleThread.getPalletCommand((short) 1)); //// shuttleCommands.add(shuttleCommands.size(), shuttleThread.getPalletCommand((short) 2)); // break; // case SHUTTLE_TRANSPORT_TO_LIFT://穿梭车载货进提升机 // // 判断提升机状态 // liftThread = (SiemensLiftThread) SlaveConnection.get(SlaveType.Lift, Integer.parseInt(motion.getTemp())); // if (liftThread == null) { // return false; // } // liftProtocol = liftThread.getLiftProtocol(); // // 判断提升机是否自动、空闲、准备就绪、链条没有转动、没有未就绪报错 // if (!liftProtocol.getMode() // || liftProtocol.getRunning() // || !liftProtocol.getReady() // || liftProtocol.getForwardRotationFeedback() // || liftProtocol.getReverseFeedback() // || liftProtocol.getNotReady().intValue() != 0 // ) { // return false; // } // // if (liftProtocol.getLev().intValue() != Utils.getLev(motion.getTarget())) {//判断提升机是否达到目标层 // return false; // } // // //判断提升机是否被锁定 // if (!liftProtocol.getLiftLock()) { // //锁定提升机 // LiftCommand lockCommand = liftThread.getLockCommand(true);//获取提升机锁定命令 // lockCommand.setLiftNo(liftProtocol.getLiftNo()); // lockCommand.setTaskNo(motion.getWrkNo().shortValue());//获取任务号 // liftThread.assignWork(lockCommand); // return false;//等待下一次轮询 // } // // //判断提升机工作号是否和当前任务相同 // if (liftProtocol.getTaskNo().intValue() != motion.getWrkNo()) { // return false; // } // // shuttleCommands = this.shuttleAssignCommand(motion.getOrigin(), motion.getTarget(), NavigationMapType.DFX.id, assignCommand, shuttleThread); // shuttleTaskModeType = ShuttleTaskModeType.PAK_IN; //// shuttleCommands.add(0, shuttleThread.getPalletCommand((short) 1)); // shuttleCommands.add(shuttleCommands.size(), shuttleThread.getPalletCommand((short) 2)); // break; // case SHUTTLE_TRANSPORT_FROM_CONVEYOR: // shuttleCommands = this.shuttleAssignCommand(motion.getOrigin(), motion.getTarget(), NavigationMapType.DFX.id, assignCommand, shuttleThread); // shuttleTaskModeType = ShuttleTaskModeType.PAK_IN; // // shuttleCommands.add(0, shuttleThread.getPalletCommand((short) 1)); // shuttleCommands.add(shuttleCommands.size(), shuttleThread.getPalletCommand((short) 2)); // break; // case SHUTTLE_TRANSPORT_TO_CONVEYOR: // shuttleCommands = this.shuttleAssignCommand(motion.getOrigin(), motion.getTarget(), NavigationMapType.DFX.id, assignCommand, shuttleThread); // shuttleTaskModeType = ShuttleTaskModeType.PAK_IN; // // shuttleCommands.add(0, shuttleThread.getPalletCommand((short) 1)); // shuttleCommands.add(shuttleCommands.size(), shuttleThread.getPalletCommand((short) 2)); // break; // case SHUTTLE_CHARGE_ON: // shuttleTaskModeType = ShuttleTaskModeType.CHARGE; // shuttleCommands.add(shuttleThread.getChargeSwitchCommand((short) 1)); // assignCommand.setCharge(Boolean.TRUE); // break; // default: // throw new CoolException(motion.getMotionCtgEl() + "没有指定任务作业流程!!!"); // } // // if (Cools.isEmpty(shuttleCommands)) { // return false; // } // // assert null != shuttleTaskModeType; // assignCommand.setTaskMode(shuttleTaskModeType.id.shortValue());//入出库模式 // assignCommand.setCommands(shuttleCommands); // // if (motion.getOrigin() != null && motion.getTarget() != null) { // //所使用的路径进行锁定禁用 // boolean lockResult = navigateMapUtils.writeNavigateNodeToRedisMap(Utils.getLev(motion.getTarget()), shuttleProtocol.getShuttleNo().intValue(), assignCommand.getNodes(), true);//所使用的路径进行锁定禁用 // if (!lockResult) { // return false;//锁定失败 // } // shuttleThread.assignWork(assignCommand); // }else { // shuttleThread.assignWork(assignCommand); // } // // return Boolean.TRUE; // } // // public Boolean finish(Motion motion) { // Integer deviceNo = Integer.parseInt(motion.getDevice()); // ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, deviceNo); // ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol(); // if (null == shuttleProtocol) { // return false; // } // // if (shuttleProtocol.getTaskNo() != 0 && shuttleProtocol.getTaskNo().intValue() != motion.getWrkNo()) { // return false; // } // // //充电任务 // if (Objects.requireNonNull(MotionCtgType.get(motion.getMotionCtgEl())).equals(MotionCtgType.SHUTTLE_CHARGE_ON)) { // // 复位穿梭车 // shuttleProtocol.setTaskNo((short) 0); // shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.IDLE); // shuttleProtocol.setPakMk(true); // return true; // } // // if (!shuttleProtocol.getProtocolStatusType().equals(ShuttleProtocolStatusType.WAITING) // && !shuttleProtocol.getProtocolStatusType().equals(ShuttleProtocolStatusType.CHARGING_WAITING) // ) { // return false; // } // // if (shuttleProtocol.getBusyStatusType().equals(ShuttleStatusType.BUSY)) { // return false; // } // // SiemensLiftThread liftThread = null; // LiftProtocol liftProtocol = null; // // switch (Objects.requireNonNull(MotionCtgType.get(motion.getMotionCtgEl()))){ // case SHUTTLE_MOVE: // case SHUTTLE_MOVE_LIFT_PALLET: // case SHUTTLE_MOVE_DOWN_PALLET: // case SHUTTLE_MOVE_TO_CONVEYOR: // case SHUTTLE_MOVE_FROM_CONVEYOR: // if (!shuttleProtocol.getCurrentLocNo().equals(motion.getTarget())) { // return false; // } // break; // case SHUTTLE_MOVE_TO_LIFT: // case SHUTTLE_MOVE_FROM_LIFT: // case SHUTTLE_TRANSPORT_FROM_LIFT: // case SHUTTLE_TRANSPORT_TO_LIFT: // case SHUTTLE_MOVE_FROM_LIFT_TO_CONVEYOR: // liftThread = (SiemensLiftThread) SlaveConnection.get(SlaveType.Lift, Integer.parseInt(motion.getTemp())); // if (liftThread == null) { // return false; // } // liftProtocol = liftThread.getLiftProtocol(); // // if (!shuttleProtocol.getCurrentLocNo().equals(motion.getTarget())) { // return false; // } // // //判断提升机是否被锁定 // if (liftProtocol.getLiftLock()) { // //解锁提升机 // LiftCommand lockCommand = liftThread.getLockCommand(false);//获取提升机解锁命令 // lockCommand.setLiftNo(liftProtocol.getLiftNo()); // lockCommand.setTaskNo(motion.getWrkNo().shortValue());//获取任务号 // liftThread.assignWork(lockCommand); // return false; // } // // //判断提升机工作号是否和当前任务相同 // if (liftProtocol.getTaskNo().intValue() != motion.getWrkNo()) { // return false; // } // // if (liftProtocol.getTaskNo().intValue() != 0) { // //清空提升机号 // liftThread.setTaskNo(0); // } // // break; // default: // break; // } // // // 复位穿梭车 // shuttleProtocol.setTaskNo((short) 0); // shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.IDLE); // shuttleProtocol.setPakMk(true); // // return true; // } // // public synchronized List<ShuttleCommand> shuttleAssignCommand(String startLocNo, String endLocNo, Integer mapType, ShuttleAssignCommand assignCommand, ShuttleThread shuttleThread) { // //获取小车移动速度 // Integer runSpeed = Optional.ofNullable(basShuttleService.selectById(assignCommand.getShuttleNo()).getRunSpeed()).orElse(1000); // // List<NavigateNode> nodeList = NavigateUtils.calc(startLocNo, endLocNo, mapType, Utils.getShuttlePoints(shuttleThread.getSlave().getId(), Utils.getLev(startLocNo))); // if (nodeList == null) { // News.error("{} dash {} can't find navigate path!", startLocNo, endLocNo); // return null; // } // List<NavigateNode> allNode = new ArrayList<>(nodeList); // // List<ShuttleCommand> commands = new ArrayList<>(); // //获取分段路径 // ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(nodeList); // //将每一段路径分成command指令 // for (ArrayList<NavigateNode> nodes : data) { // //开始路径 // NavigateNode startPath = nodes.get(0); // // //中间路径 // NavigateNode middlePath = null; // //通过xy坐标小车二维码 // Short 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()); // 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()); // middleToDistDistance = NavigateUtils.getMiddleToDistDistance(nodes, middlePath);//计算中间点到目标点行走距离 // } // // //目标路径 // NavigateNode endPath = nodes.get(nodes.size() - 1); // Integer allDistance = NavigateUtils.getCurrentPathAllDistance(nodes);//计算当前路径行走总距离 // //通过xy坐标小车二维码 // Short startCodeNum = NavigatePositionConvert.xyToPosition(startPath.getX(), startPath.getY(), startPath.getZ()); // //通过xy坐标小车二维码 // Short distCodeNum = NavigatePositionConvert.xyToPosition(endPath.getX(), endPath.getY(), endPath.getZ()); // //获取移动命令 // ShuttleCommand command = shuttleThread.getMoveCommand(startCodeNum, distCodeNum, allDistance, ShuttleRunDirection.get(startPath.getDirection()).id, middleCodeNum, middleToDistDistance, runSpeed); // command.setNodes(nodes);//将行走节点添加到每一步命令中 // commands.add(command); // } // // assignCommand.setNodes(allNode);//当前任务所占用的节点list // // return commands; // } // // //} zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/mapper/MotionCtgMapper.java
New file @@ -0,0 +1,12 @@ package com.zy.asrs.wcs.rcs.mapper; import com.zy.asrs.wcs.rcs.entity.MotionCtg; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository; @Mapper @Repository public interface MotionCtgMapper extends BaseMapper<MotionCtg> { } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/mapper/MotionStsMapper.java
New file @@ -0,0 +1,12 @@ package com.zy.asrs.wcs.rcs.mapper; import com.zy.asrs.wcs.rcs.entity.MotionSts; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository; @Mapper @Repository public interface MotionStsMapper extends BaseMapper<MotionSts> { } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/service/MotionCtgService.java
New file @@ -0,0 +1,8 @@ package com.zy.asrs.wcs.rcs.service; import com.baomidou.mybatisplus.extension.service.IService; import com.zy.asrs.wcs.rcs.entity.MotionCtg; public interface MotionCtgService extends IService<MotionCtg> { } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/service/MotionStsService.java
New file @@ -0,0 +1,8 @@ package com.zy.asrs.wcs.rcs.service; import com.baomidou.mybatisplus.extension.service.IService; import com.zy.asrs.wcs.rcs.entity.MotionSts; public interface MotionStsService extends IService<MotionSts> { } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/service/impl/MotionCtgServiceImpl.java
New file @@ -0,0 +1,12 @@ package com.zy.asrs.wcs.rcs.service.impl; import com.zy.asrs.wcs.rcs.mapper.MotionCtgMapper; import com.zy.asrs.wcs.rcs.entity.MotionCtg; import com.zy.asrs.wcs.rcs.service.MotionCtgService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; @Service("motionCtgService") public class MotionCtgServiceImpl extends ServiceImpl<MotionCtgMapper, MotionCtg> implements MotionCtgService { } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/service/impl/MotionStsServiceImpl.java
New file @@ -0,0 +1,12 @@ package com.zy.asrs.wcs.rcs.service.impl; import com.zy.asrs.wcs.rcs.mapper.MotionStsMapper; import com.zy.asrs.wcs.rcs.entity.MotionSts; import com.zy.asrs.wcs.rcs.service.MotionStsService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; @Service("motionStsService") public class MotionStsServiceImpl extends ServiceImpl<MotionStsMapper, MotionSts> implements MotionStsService { } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/ShuttleThread.java
@@ -6,4 +6,10 @@ ShuttleProtocol getStatus();//获取四向穿梭车状态 boolean movePath();//路径下发 boolean move();//移动 boolean lift();//顶升 } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/impl/SurayShuttleThread.java
@@ -147,6 +147,20 @@ return this.shuttleProtocol; } @Override public synchronized boolean movePath() { return false; } @Override public synchronized boolean move() { return false; } @Override public synchronized boolean lift() { return false; } //***************设备层通讯-不同厂商设备通讯方案不一致*************** zy-asrs-wcs/src/main/java/motionCtg.sql
New file @@ -0,0 +1,9 @@ -- save motionCtg record -- mysql insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `host_id`, `status`) values ( 'Motion标记管理', '0', '/rcs/motionCtg', '/rcs/motionCtg', '0' , '0', '1' , '1'); insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '查询Motion标记', '', '1', 'rcs:motionCtg:list', '0', '1', '1'); insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '添加Motion标记', '', '1', 'rcs:motionCtg:save', '1', '1', '1'); insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '修改Motion标记', '', '1', 'rcs:motionCtg:update', '2', '1', '1'); insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '删除Motion标记', '', '1', 'rcs:motionCtg:remove', '3', '1', '1'); zy-asrs-wcs/src/main/java/motionSts.sql
New file @@ -0,0 +1,9 @@ -- save motionSts record -- mysql insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `host_id`, `status`) values ( 'Motion状态管理', '0', '/rcs/motionSts', '/rcs/motionSts', '0' , '0', '1' , '1'); insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '查询Motion状态', '', '1', 'rcs:motionSts:list', '0', '1', '1'); insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '添加Motion状态', '', '1', 'rcs:motionSts:save', '1', '1', '1'); insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '修改Motion状态', '', '1', 'rcs:motionSts:update', '2', '1', '1'); insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '删除Motion状态', '', '1', 'rcs:motionSts:remove', '3', '1', '1'); zy-asrs-wcs/src/main/resources/mapper/rcs/MotionCtgMapper.xml
New file @@ -0,0 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.zy.asrs.wcs.rcs.mapper.MotionCtgMapper"> </mapper> zy-asrs-wcs/src/main/resources/mapper/rcs/MotionStsMapper.xml
New file @@ -0,0 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.zy.asrs.wcs.rcs.mapper.MotionStsMapper"> </mapper>