自动化立体仓库 - WCS系统
Junjie
2023-03-24 09c4b134bf8b8221635a06bd7ee3064c759b7dcf
提升机代码部分
4个文件已添加
6个文件已修改
532 ■■■■■ 已修改文件
src/main/java/com/zy/core/ServerBootstrap.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/cache/OutputQueue.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/SlaveType.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/LiftSlave.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/command/LiftCommand.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/command/ShuttleCommand.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/protocol/LiftProtocol.java 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/properties/SlaveProperties.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/LiftThread.java 237 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/ShuttleThread.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/ServerBootstrap.java
@@ -98,6 +98,13 @@
            new Thread((Runnable) devpThread).start();
            SlaveConnection.put(SlaveType.Devp, devp.getId(), devpThread);
        }
        // 初始化提升机
        News.info("初始化提升机........................................................");
        for (LiftSlave liftSlave : slaveProperties.getLift()) {
            LiftThread liftThread = new LiftThread(liftSlave);
            new Thread(liftThread).start();
            SlaveConnection.put(SlaveType.Lift, liftSlave.getId(), liftThread);
        }
        // 初始化四向穿梭车
        News.info("初始化四向穿梭车......................................................");
        for (ShuttleSlave shuttleSlave : slaveProperties.getShuttle()) {
src/main/java/com/zy/core/cache/OutputQueue.java
@@ -19,5 +19,7 @@
    public static ArrayBlockingQueue<String> STE = new ArrayBlockingQueue<>(32);
    //四向穿梭车输出日志
    public static ArrayBlockingQueue<String> SHUTTLE = new ArrayBlockingQueue<>(32);
    //提升机输出日志
    public static ArrayBlockingQueue<String> LIFT = new ArrayBlockingQueue<>(32);
}
src/main/java/com/zy/core/enums/SlaveType.java
@@ -10,6 +10,7 @@
    Car,
    Ste,
    Shuttle,
    Lift,
    ;
    public static SlaveType findInstance(String s){
src/main/java/com/zy/core/model/LiftSlave.java
New file
@@ -0,0 +1,37 @@
package com.zy.core.model;
import com.zy.core.Slave;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class LiftSlave extends Slave {
    private Integer rack;
    private Integer slot;
    private Boolean demo;
    @Data
    public static class Sta {
        // 输送线plc编号
        private Integer devpPlcId;
        // 穿梭车站点编号
        private Integer staNo;
        // 排
        private Integer row;
        // 列
        private Integer bay;
        // 层
        private Integer lev;
    }
}
src/main/java/com/zy/core/model/command/LiftCommand.java
New file
@@ -0,0 +1,67 @@
package com.zy.core.model.command;
import lombok.Data;
/**
 * 提升机命令报文
 */
@Data
public class LiftCommand {
    /**
     * 提升机号
     */
    private Integer liftNo = 0;
    /**
     * 任务号
     */
    private Integer taskNo = 0;
    /**
     * 作业类型
     */
    private Short taskMode = 0;
    /**
     * 任务确认 false:未确认 true:已确认
     */
    private Boolean complete = Boolean.FALSE;
    /**
     * 开始运行
     */
    private Short run;
    /**
     * 目标位置
     */
    private Short distPosition;
    /**
     * 运行速度
     */
    private Short speed;
    /**
     * 二层高度设定
     */
    private Short height2;
    /**
     * 三层高度设定
     */
    private Short height3;
    /**
     * 四层高度设定
     */
    private Short height4;
    /**
     * 提升机锁定
     */
    private Short liftLock;
}
src/main/java/com/zy/core/model/command/ShuttleCommand.java
@@ -2,6 +2,9 @@
import lombok.Data;
/**
 * 四向穿梭车命令报文
 */
@Data
public class ShuttleCommand {
src/main/java/com/zy/core/model/protocol/LiftProtocol.java
New file
@@ -0,0 +1,164 @@
package com.zy.core.model.protocol;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
/**
 * 提升机
 */
@Slf4j
@Data
public class LiftProtocol {
    /**
     * 提升机号
     */
    private Short liftNo;
    /**
     * 任务号
     */
    private Short taskNo = 0;
    /**
     * 层
     */
    private Short lev;
    /**
     * 提升机锁定
     */
    private Short liftLock;
    /**
     * 位置到达反馈
     */
    private Short positionArrivalFeedback;
    /**
     * 准备就绪
     * 就绪为1,未就绪为0
     */
    private Boolean ready;
    /**
     * 运行中
     * 运行中为1,未运行为0
     */
    private Boolean running;
    /**
     * 联机/单机
     * 联机为1,单机为0
     */
    private Boolean mode;
    /**
     * 输送线前端光电有货
     * 有货为1,无货为0(前端指靠近货架侧)
     */
    private Boolean lineFrontHasStock;
    /**
     * 输送线正转反馈
     * 正转运行为1,否则为0
     */
    private Boolean forwardRotationFeedback;
    /**
     * 输送线反转反馈
     * 反转运行为1,否则为0
     */
    private Boolean reverseFeedback;
    /**
     * 输送线电机过载
     * 过载为0,正常为1
     */
    private Boolean motorOverload;
    /**
     * 输送线末端光电有货
     * 有货为1,无货为0
     */
    private Boolean lineEndHasStock;
    /**
     * 进输送线卡托盘报警
     * 报警为1,未报警为0
     */
    private Boolean inConveyLineCardTrayAlarm;
    /**
     * 出输送线卡托盘报警
     * 报警为1,未报警为0
     */
    private Boolean outConveyLineCardTrayAlarm;
    /**
     * 平台位置偏差报警
     * 报警为1,未报警为0
     */
    private Boolean platPositionDeviationAlarm;
    /**
     * 平台扭矩偏差报警
     * 报警为1,未报警为0
     */
    private Boolean platTorqueDeviationAlarm;
    /**
     * 平台四向车检测
     * 有车为1,无车为0
     */
    private Boolean platShuttleCheck;
    /**
     * 未就绪状态
     * 1.    不在指定层
     * 2.    四轴不同步
     * 3.    平台前限光电被挡到(靠近货架)
     * 4.    平台后限光电被挡到(远离货架)
     * 5.    平台上限位报警
     * 6.    平台下限位报警
     * 7.    电柜急停报警
     * 8.    输送线前限位被挡到(靠近货架)
     * 9.    输送线后限位被挡到(远离货架)
     * 10.    触摸屏紧急停止被按下
     * 11.    四轴动力线断线
     * 12.    单机模式
     * 13.    四轴报警
     * 14.    位置偏差过大
     * 15.    扭矩偏差过大
     * 16.    输送线过载
     * 17.    进提升机卡托盘
     * 18.    出提升机卡托盘
     */
    private Short notReady;
    /**
     * 伺服1错误
     */
    private Short servoError1;
    /**
     * 伺服2错误
     */
    private Short servoError2;
    /**
     * 伺服3错误
     */
    private Short servoError3;
    /**
     * 伺服4错误
     */
    private Short servoError4;
    /**
     * 提升机实际速度反馈
     */
    private Short liftActualSpeed;
}
src/main/java/com/zy/core/properties/SlaveProperties.java
@@ -41,4 +41,6 @@
    private List<ShuttleSlave> shuttle = new ArrayList<>();
    private List<LiftSlave> lift = new ArrayList<>();
}
src/main/java/com/zy/core/thread/LiftThread.java
New file
@@ -0,0 +1,237 @@
package com.zy.core.thread;
import HslCommunication.Core.Transfer.DataFormat;
import HslCommunication.Core.Types.OperateResult;
import HslCommunication.Core.Types.OperateResultExOne;
import HslCommunication.ModBus.ModbusTcpNet;
import com.alibaba.fastjson.JSON;
import com.core.common.DateUtils;
import com.core.exception.CoolException;
import com.zy.core.News;
import com.zy.core.ThreadHandler;
import com.zy.core.cache.MessageQueue;
import com.zy.core.cache.OutputQueue;
import com.zy.core.enums.SlaveType;
import com.zy.core.model.LiftSlave;
import com.zy.core.model.Task;
import com.zy.core.model.command.LiftCommand;
import com.zy.core.model.protocol.LiftProtocol;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.text.MessageFormat;
import java.util.Date;
/**
 * 提升机线程
 */
@Data
@Slf4j
public class LiftThread implements  Runnable, ThreadHandler {
    private ModbusTcpNet modbusTcpNet;
    private LiftSlave slave;
    private LiftProtocol liftProtocol;
    public LiftThread(LiftSlave slave) {
        this.slave = slave;
    }
    @Override
    public void run() {
        this.connect();
        while (true) {
            try {
                int step = 1;
                Task task = MessageQueue.poll(SlaveType.Lift, slave.getId());
                if (task != null) {
                    step = task.getStep();
                }
                switch (step) {
                    // 读数据
                    case 1:
                        readStatus();
                        break;
                    // 写入数据
                    case 2:
                        write((LiftCommand) task.getData());
                        break;
                    default:
                        break;
                }
                Thread.sleep(500);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    @Override
    public boolean connect() {
        boolean result = false;
        //-------------------------提升机连接方法------------------------//
        modbusTcpNet = new ModbusTcpNet(slave.getIp(), slave.getPort(), (byte) 0x01);
        // 当你需要指定格式的数据解析时,就需要设置下面的这个信息
        modbusTcpNet.setDataFormat(DataFormat.ABCD);
        OperateResult connect = modbusTcpNet.ConnectServer();
        if(connect.IsSuccess){
            result = true;
            OutputQueue.CRN.offer(MessageFormat.format( "【{0}】提升机plc连接成功 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            log.info("提升机plc连接成功 ===>> [id:{}] [ip:{}] [port:{}] ", slave.getId(), slave.getIp(), slave.getPort());
        } else {
            OutputQueue.CRN.offer(MessageFormat.format("【{0}】提升机plc连接失败!!! ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            log.error("提升机plc连接失败!!! ===>> [id:{}] [ip:{}] [port:{}] ", slave.getId(), slave.getIp(), slave.getPort());
        }
        modbusTcpNet.ConnectClose();
        //-------------------------提升机连接方法------------------------//
        return result;
    }
    @Override
    public void close() {
        modbusTcpNet.ConnectClose();
    }
    private void readStatus() {
        try {
            OperateResultExOne<byte[]> result = modbusTcpNet.Read("29", (short) 17);
            if (result.IsSuccess) {
                if (null == liftProtocol) {
                    liftProtocol = new LiftProtocol();
                    liftProtocol.setLiftNo(slave.getId().shortValue());
                }
                //----------读取提升机状态-----------
                //获取数据
                byte[] content = result.Content;
                //提升机锁定
                liftProtocol.setLiftLock(modbusTcpNet.getByteTransform().TransInt16(content,0));
                //位置到达反馈
                liftProtocol.setPositionArrivalFeedback(modbusTcpNet.getByteTransform().TransInt16(content,2));
                //准备就绪
                liftProtocol.setReady(modbusTcpNet.getByteTransform().TransBool(content,3));
                //运行中
                liftProtocol.setRunning(modbusTcpNet.getByteTransform().TransBool(content,4));
                //联机/单机
                liftProtocol.setMode(modbusTcpNet.getByteTransform().TransBool(content,5));
                //输送线前端光电有货
                liftProtocol.setLineFrontHasStock(modbusTcpNet.getByteTransform().TransBool(content,6));
                //输送线正转反馈
                liftProtocol.setForwardRotationFeedback(modbusTcpNet.getByteTransform().TransBool(content,7));
                //输送线反转反馈
                liftProtocol.setReverseFeedback(modbusTcpNet.getByteTransform().TransBool(content,8));
                //输送线电机过载
                liftProtocol.setMotorOverload(modbusTcpNet.getByteTransform().TransBool(content,9));
                //输送线末端光电有货
                liftProtocol.setLineEndHasStock(modbusTcpNet.getByteTransform().TransBool(content,10));
                //进输送线卡托盘报警
                liftProtocol.setInConveyLineCardTrayAlarm(modbusTcpNet.getByteTransform().TransBool(content,11));
                //出输送线卡托盘报警
                liftProtocol.setOutConveyLineCardTrayAlarm(modbusTcpNet.getByteTransform().TransBool(content,12));
                //平台位置偏差报警
                liftProtocol.setPlatPositionDeviationAlarm(modbusTcpNet.getByteTransform().TransBool(content,13));
                //平台扭矩偏差报警
                liftProtocol.setPlatTorqueDeviationAlarm(modbusTcpNet.getByteTransform().TransBool(content,14));
                //平台四向车检测
                liftProtocol.setPlatShuttleCheck(modbusTcpNet.getByteTransform().TransBool(content,15));
                //未就绪状态
                liftProtocol.setNotReady(modbusTcpNet.getByteTransform().TransInt16(content,16));
                //伺服1错误
                liftProtocol.setServoError1(modbusTcpNet.getByteTransform().TransInt16(content,17));
                //伺服2错误
                liftProtocol.setServoError2(modbusTcpNet.getByteTransform().TransInt16(content,18));
                //伺服3错误
                liftProtocol.setServoError3(modbusTcpNet.getByteTransform().TransInt16(content,19));
                //伺服4错误
                liftProtocol.setServoError4(modbusTcpNet.getByteTransform().TransInt16(content,20));
                //提升机实际速度反馈
                liftProtocol.setLiftActualSpeed(modbusTcpNet.getByteTransform().TransInt16(content,21));
                ///读取提升机状态-end
                OutputQueue.LIFT.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId()));
                log.info(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId()));
                // 根据实时信息更新数据库
                //.....
            }else {
                OutputQueue.LIFT.offer(MessageFormat.format("【{0}】{1}提升机plc状态信息失败", DateUtils.convert(new Date()), slave.getId()));
                throw new CoolException(MessageFormat.format( "提升机plc状态信息失败 ===>> [id:{0}] [ip:{1}] [port:{2}]", slave.getId(), slave.getIp(), slave.getPort()));
            }
        } catch (Exception e) {
            OutputQueue.LIFT.offer(MessageFormat.format("【{0}】提升机plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            initLift();
        }
    }
    private boolean write(LiftCommand command){
        if (null == command) {
            News.error("提升机写入命令为空");
            return false;
        }
        command.setLiftNo(slave.getId());
        // 开始任务
        short[] array = new short[30];
        //开始运行
        array[0] = command.getRun();
        //目标位置
        array[1] = command.getDistPosition();
        //运行速度
        array[2] = command.getSpeed();
        //二层高度设定
        array[3] = command.getHeight2();
        //三层高度设定
        array[4] = command.getHeight3();
        //四层高度设定
        array[5] = command.getHeight4();
        //提升机锁定
        array[29] = command.getLiftLock();
        OperateResult result = modbusTcpNet.Write("0", array);;
        if (result != null && result.IsSuccess) {
            News.info("提升机命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON(command));
            OutputQueue.LIFT.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command)));
            return true;
        } else {
            OutputQueue.LIFT.offer(MessageFormat.format("【{0}】写入提升机plc数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            News.error("写入提升机plc数据失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
            return false;
        }
    }
    /**
     * 初始化提升机
     */
    private void initLift() {
        if (null == liftProtocol) {
            liftProtocol = new LiftProtocol();
        }
    }
    /******************************************************************************************/
    /**************************************** 测试专用 *****************************************/
    /*****************************************************************************************/
    public static void main(String[] args) throws InterruptedException {
        LiftSlave slave = new LiftSlave();
        slave.setId(1);
        slave.setIp("192.168.4.24");
        slave.setPort(502);
        LiftThread thread = new LiftThread(slave);
        thread.connect();
        thread.readStatus();
        LiftCommand command = new LiftCommand();
        command.setRun((short) 0);
        command.setDistPosition((short) 12);
        command.setSpeed((short) 300);
        command.setHeight2((short) 100);
        command.setHeight3((short) 200);
        command.setHeight4((short) 303);
        command.setLiftLock((short) 1);
        thread.write(command);
    }
}
src/main/java/com/zy/core/thread/ShuttleThread.java
@@ -4,32 +4,24 @@
import HslCommunication.Core.Types.OperateResult;
import HslCommunication.Core.Types.OperateResultExOne;
import HslCommunication.ModBus.ModbusTcpNet;
import HslCommunication.Profinet.Siemens.SiemensPLCS;
import HslCommunication.Profinet.Siemens.SiemensS7Net;
import com.alibaba.fastjson.JSON;
import com.core.common.DateUtils;
import com.core.common.RadixTools;
import com.core.exception.CoolException;
import com.zy.common.utils.CommonUtils;
import com.zy.core.News;
import com.zy.core.ThreadHandler;
import com.zy.core.cache.MessageQueue;
import com.zy.core.cache.OutputQueue;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.ShuttleStatusType;
import com.zy.core.enums.SlaveType;
import com.zy.core.model.ShuttleSlave;
import com.zy.core.model.SteSlave;
import com.zy.core.model.Task;
import com.zy.core.model.command.ShuttleCommand;
import com.zy.core.model.command.SteCommand;
import com.zy.core.model.protocol.ShuttleProtocol;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.text.MessageFormat;
import java.util.Date;
import java.util.Random;
/**
 * 四向穿梭车线程
@@ -41,7 +33,6 @@
    private ModbusTcpNet modbusTcpNet;
    private ShuttleSlave slave;
    private ShuttleProtocol shuttleProtocol;
    private SiemensS7Net siemensS7Net;
    public ShuttleThread(ShuttleSlave slave) {
        this.slave = slave;
@@ -99,7 +90,7 @@
    @Override
    public void close() {
        modbusTcpNet.ConnectClose();
    }
    private void readStatus() {
@@ -175,7 +166,6 @@
        command.setShuttleNo(slave.getId());
        // 开始任务
        //...
        short[] array = new short[17];
        //控制指令字
        array[0] = command.getCommandWord();