fyxc
2025-05-22 09fcc4ec56a1ce6c0fcb308348d8dd5e2c08d336
src/main/java/com/zy/core/thread/ShuttleThread.java
@@ -1,275 +1,80 @@
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 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.core.News;
import com.zy.common.ExecuteSupport;
import com.zy.common.model.NavigateNode;
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.enums.ShuttleProtocolStatusType;
import com.zy.core.enums.ShuttleTaskNoType;
import com.zy.core.model.CommandResponse;
import com.zy.core.model.command.ShuttleCommand;
import com.zy.core.model.command.SteCommand;
import com.zy.core.model.param.ShuttleMoveLocParam;
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.List;
/**
 * 四向穿梭车线程
 */
@Data
@Slf4j
public class ShuttleThread implements  Runnable, ThreadHandler {
public interface ShuttleThread extends ThreadHandler {
    private ModbusTcpNet modbusTcpNet;
    private ShuttleSlave slave;
    private ShuttleProtocol shuttleProtocol;
    private SiemensS7Net siemensS7Net;
    ShuttleProtocol getStatus(boolean clone);//获取四向穿梭车状态
    public ShuttleThread(ShuttleSlave slave) {
        this.slave = slave;
    }
    ShuttleProtocol getStatus();//获取四向穿梭车状态-默认clone
    @Override
    public void run() {
        this.connect();
        while (true) {
            try {
                int step = 1;
                Task task = MessageQueue.poll(SlaveType.Shuttle, slave.getId());
                if (task != null) {
                    step = task.getStep();
                }
                switch (step) {
                    // 读数据
                    case 1:
                        readStatus();
                        break;
                    // 写入数据
                    case 2:
                        write((ShuttleCommand) task.getData());
                        break;
                    default:
                        break;
                }
                Thread.sleep(500);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    CommandResponse movePath(List<NavigateNode> nodes, Integer taskNo);//路径下发
    @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;
    }
    CommandResponse move(ShuttleCommand command);//移动
    @Override
    public void close() {
    CommandResponse lift(ShuttleCommand command);//顶升
    }
    CommandResponse charge(ShuttleCommand command);//充电开关
    private void readStatus() {
        try {
            OperateResultExOne<byte[]> result = modbusTcpNet.Read("0", (short) 17);
            if (result.IsSuccess) {
                if (null == shuttleProtocol) {
                    shuttleProtocol = new ShuttleProtocol();
                    shuttleProtocol.setShuttleNo(slave.getId().shortValue());
                }
    CommandResponse reset(ShuttleCommand command);//复位开关
                //----------设置四向穿梭车状态-----------
                //获取数据
                byte[] content = result.Content;
    CommandResponse updateLocation(ShuttleCommand command);//更新坐标
                //--------控制字--------
                //控制指令字
                shuttleProtocol.setCommandWord(modbusTcpNet.getByteTransform().TransUInt16(content, 0));
                //启始二维编号
                shuttleProtocol.setStartCodeNum(modbusTcpNet.getByteTransform().TransUInt16(content, 2));
                //中间二维编号
                shuttleProtocol.setMiddleCodeNum(modbusTcpNet.getByteTransform().TransUInt16(content, 4));
                //目标二维编号
                shuttleProtocol.setDistCodeNum(modbusTcpNet.getByteTransform().TransUInt16(content, 6));
                //起点到目标点的距离长度
                shuttleProtocol.setStartToDistDistance(modbusTcpNet.getByteTransform().TransInt32(content, 8));
                //中间点到目标点的距离长度
                shuttleProtocol.setMiddleToDistDistance(modbusTcpNet.getByteTransform().TransInt32(content, 12));
                //小车运行方向
                shuttleProtocol.setRunDirection(modbusTcpNet.getByteTransform().TransUInt16(content, 16));
                //托盘顶升
                shuttleProtocol.setPalletLift(modbusTcpNet.getByteTransform().TransUInt16(content,18));
                //小车强制移动距离
                shuttleProtocol.setForceMoveDistance(modbusTcpNet.getByteTransform().TransInt32(content, 20));
                //充电开关
                shuttleProtocol.setChargeSwitch(modbusTcpNet.getByteTransform().TransUInt16(content,24));
                //小车IO控制
                shuttleProtocol.setIOControl(modbusTcpNet.getByteTransform().TransUInt16(content,26));
                //小车运行速度
                shuttleProtocol.setRunSpeed(modbusTcpNet.getByteTransform().TransUInt16(content,28));
                //小车雷达备用
                shuttleProtocol.setRadarTmp(modbusTcpNet.getByteTransform().TransUInt16(content,30));
                //指令结束位
                shuttleProtocol.setCommandEnd(modbusTcpNet.getByteTransform().TransUInt16(content,32));
    boolean isIdle();
    boolean isIdle(ExecuteSupport support);//是否空闲
                //---------状态字---------
//                shuttleProtocol.setBusyStatus(modbusTcpNet.getByteTransform().TransUInt16(content,32));
    boolean isDeviceIdle();//设备是否空闲
                ///设置四向穿梭车状态-end
                OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId()));
                //读取四向穿梭车设备信息,提供查询
                //.....
    boolean isDeviceIdle(ExecuteSupport support);//设备是否空闲
    boolean isRequireCharge();//是否满足充电状态
                // 根据实时信息更新数据库
                //.....
    boolean isCharging();//是否充电中
    boolean isChargingCompleted();//是否充电完成
            }else {
                OutputQueue.SHUTTLE.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.SHUTTLE.offer(MessageFormat.format("【{0}】四向穿梭车plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            initShuttle();
        }
    }
    boolean isFault();//是否故障
    private boolean write(ShuttleCommand command){
        if (null == command) {
            News.error("四向穿梭车写入命令为空");
            return false;
        }
    List<NavigateNode> getMoveAdvancePath();//获取穿梭车任务路径
        //判断小车是否在充电
        SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1);
        if (devpThread.charge1){
    int generateDeviceTaskNo(int taskNo, ShuttleTaskNoType type);//生成硬件设备工作号
        }
    boolean setProtocolStatus(ShuttleProtocolStatusType status);//设置工作状态
        command.setShuttleNo(slave.getId());
        OperateResult result = null;
        // 开始任务
        //...
    boolean setTaskNo(Integer taskNo);//设置工作号
    boolean setSyncTaskNo(Integer taskNo);//设置工作号
        try {
            // 日志记录
            if (!command.getComplete() && command.getTaskMode() != 0) {
                //日志记录保存到数据库中
                //.....
            }
        } catch (Exception ignore) {}
    boolean setPakMk(boolean pakMk);//设置标记
        if (result != null && result.IsSuccess) {
            // 维护数据库排列层
//            if (!steProtocol.getWaiting()) {
//                if (!Cools.isEmpty(command.getRow(), command.getBay(), command.getLev())) {
//                    this.modifyPos(command.getRow().intValue(), command.getBay().intValue(), command.getLev().intValue());
//                }
//            }
    boolean enableMoveLoc(ShuttleMoveLocParam param, boolean enable);
            News.info("四向穿梭车命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON(command));
            OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command)));
            return true;
        } else {
            OutputQueue.SHUTTLE.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;
        }
    }
    boolean requestWaiting();
    /**
     * 初始化四向穿梭车
     */
    private void initShuttle() {
        if (null == shuttleProtocol) {
            shuttleProtocol = new ShuttleProtocol();
        }
        shuttleProtocol.setShuttleNo(slave.getId().shortValue());
        shuttleProtocol.setBusyStatus(ShuttleStatusType.BUSY);
        shuttleProtocol.setCurrentCode("0");
    }
    boolean enableDemo(boolean enable);//演示模式
    /******************************************************************************************/
    /**************************************** 测试专用 *****************************************/
    /*****************************************************************************************/
    public static void main(String[] args) throws InterruptedException {
        ShuttleSlave slave = new ShuttleSlave();
        slave.setId(1);
        slave.setIp("192.168.4.24");
        slave.setPort(502);
        ShuttleThread thread = new ShuttleThread(slave);
        thread.connect();
        thread.readStatus();
        System.out.println(JSON.toJSONString(thread.shuttleProtocol));
    boolean offerSystemMsg(String format, Object... arguments);
        // 任务作业
//        SteCommand command = new SteCommand();
//        command.setSteNo(1); // 堆垛机编号
//        Random random = new Random();
//        int taskNo = random.nextInt(9090);
//        command.setTaskNo(taskNo); // 工作号
//        command.setTaskMode(SteTaskModeType.MOVE_LEFT); // 任务模式
//        thread.write(command);
    //***************获取命令*****************
        // 任务完成
//        SteCommand command = new SteCommand();
//        command.setSteNo(1); // 堆垛机编号
//        command.setComplete(Boolean.TRUE); // 任务模式
//        thread.write(command);
    ShuttleCommand getMoveCommand(Integer taskNo, String startCodeNum, String distCodeNum, Integer allDistance, Integer runDirection, Integer runSpeed, List<NavigateNode> nodes);//获取移动命令
        // 控制模式
//        SteCommand command = new SteCommand();
//        command.setControlMode((short) 1);
//        thread.write(command);
    ShuttleCommand getLiftCommand(Integer taskNo, Boolean lift);//顶升命令 true=>顶升 false=>下降
        // 复位信号
//        SteCommand command = new SteCommand();
//        command.setReset(Boolean.TRUE);
//        thread.write(command);
    ShuttleCommand getChargeCommand(Integer taskNo, Boolean charge);//充电开关命令 true=>开 false=>关
        // 删除指令
//        SteCommand command = new SteCommand();
//        command.setDelete(Boolean.TRUE);
//        thread.write(command);
    ShuttleCommand getUpdateLocationCommand(Integer taskNo, String locNo);//获取更新坐标命令
        // 穿梭车运行禁止
//        SteCommand command = new SteCommand();
//        command.setRun((short)0);
//        thread.write(command);
    }
}