#
Junjie
2024-03-26 161b7184288c47d8446fdc21786821d489be736a
#
20个文件已添加
2个文件已修改
1769 ■■■■■ 已修改文件
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/MapNode.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/NavigateNode.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/enums/NavigationMapType.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateMapData.java 298 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateMapUtils.java 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/MotionCtgController.java 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/MotionStsController.java 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/entity/MotionCtg.java 224 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/entity/MotionSts.java 206 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/kernel/command/ShuttleCommandService.java 511 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/mapper/MotionCtgMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/mapper/MotionStsMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/service/MotionCtgService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/service/MotionStsService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/service/impl/MotionCtgServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/service/impl/MotionStsServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/ShuttleThread.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/impl/SurayShuttleThread.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/motionCtg.sql 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/motionSts.sql 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/resources/mapper/rcs/MotionCtgMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/resources/mapper/rcs/MotionStsMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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>