StandardRobot.cs 7.9 KB
using DL.Com.Protocol.Modbus;
using DL.Utils;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace DL.StandardRobot
{
    /// <summary>
    /// 斯坦德机器人类
    /// </summary>
    public class StandardRobot
    {
        public delegate void MissionStateChangedEventHandler(MissionState state);
        /// <summary>
        /// 任务态变化事件
        /// </summary>
        public event MissionStateChangedEventHandler MissionSateChanged;
        /// <summary>
        /// 设备地址
        /// </summary>
        private byte equipAddr = 1;
        private Com.TCP.ModbusTCPMaster _client;   //客户端
        private bool _loop;

        private MissionState missionState = new MissionState();

        private const int SEND_SLEEP = 500;   //每条命令发送的间隔
        private const int PORT = 502;        //端口

        private Thread tSend;         //发送命令处理

        /// <summary>
        /// 斯坦德机器人类
        /// </summary>
        /// <param name="logName"></param>
        public StandardRobot()
        {
            _client = new Com.TCP.ModbusTCPMaster();
            _client.ReceiveData += _client_ReceiveData;
        }
        MissionState preState = new MissionState();
        /// <summary>
        /// 收到的数据解析
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <param name="requestInfo"></param>
        /// <param name="data"></param>
        private void _client_ReceiveData(string ip, int port, Com.TCP.RequestInfo requestInfo, byte[] data)
        {
            try
            {
                if (requestInfo.FunCode == 4)
                {
                    if (data.Length >= 240)
                    {
                        preState.RunMissionId = GetUInt32(new byte[] { data[192], data[193], data[194], data[195] });
                        preState.MissionRunState = (MissionRunState)GetUInt16(data[196], data[197]);
                        preState.MissionResult = (MissionResult)GetUInt16(data[198], data[199]);
                        if (!missionState.Equals(preState))
                        {
                            missionState.RunMissionId = preState.RunMissionId;
                            missionState.MissionRunState = preState.MissionRunState;
                            missionState.MissionResult = preState.MissionResult;
                            LogUtil.Error($"ReceiveData:[{requestInfo}][{JsonHelper.SerializeObject(missionState)}]");
                            MissionSateChanged?.Invoke(missionState);
                        }

                    }
                }
            }
            catch (Exception ex)
            {
                LogUtil.Error($"ReceiveData:[{requestInfo}][{data}]", ex);
            }
        }
        uint GetUInt32(byte[] data)
        {
            return (uint)(((data[0] & 0xff) << 24) | ((data[1] & 0xff) << 16) | ((data[2] & 0xff) << 8) | (data[3] & 0xff));
        }
        int GetInt32(byte[] data)
        {
            return (int)((data[0] << 24) | ((data[1] & 0xff) << 16) | ((data[2] & 0xff) << 8) | (data[3] & 0xff));
        }
        ushort GetUInt16(byte H, byte L)
        {
            return (ushort)(((H & 0xff) << 8) | (L & 0xff));
        }
        /// <summary>
        /// IP地址
        /// </summary>
        public string IP { set; get; } = "192.168.1.100";

        /// <summary>
        /// 输入主动上传
        /// </summary>
        public bool Upload { set; get; } = false;

        /// <summary>
        /// 连接
        /// </summary>
        /// <returns></returns>
        public bool Connect()
        {
            _loop = true;
            bool rtn = Utils.HttpHelper.CheckIP(IP);
            if (!rtn) return false;

            _client.Connect(IP, PORT);
            tSend = new Thread(new ThreadStart(Send)) { Name = "Send" };
            tSend.IsBackground = true;
            tSend.Start();
            _client.AddRequest(GetInputRegister());
            return true;
        }

        /// <summary>
        /// 关闭连接
        /// </summary>
        public void Close()
        {
            _loop = false;

            try
            {
                if (_client != null)
                {
                    _client.Close();
                }
            }
            finally
            {
                _client = null;
            }

        }
        public MissionState GetMissionState()
        {
            return missionState;
        }
        /// <summary>
        /// 创建任务,功能码16
        /// </summary>
        /// <returns></returns>
        public bool AddMission(int id)
        {
            try
            {
                Com.TCP.RequestInfo request = new Com.TCP.RequestInfo();
                request.StartAddr = 40097;//起始地址
                request.FunCode = 16;//功能码
                request.EquipAddr = equipAddr;
                request.CountOrValue = 2;   //个数
                Byte4 byte4 = GetStru2Byte(id);
                request.Values = new int[] {(int)GetUInt16(byte4.ByteH1, byte4.ByteH2), (int)GetUInt16(byte4.ByteL1, byte4.ByteL2) };
                _client.AddRequest(request);
                missionState.MissionId = (uint)id;
                LogUtil.Info($"AddMission missionId:{id}");
                MissionSateChanged?.Invoke(missionState);
                return true;
            }
            catch (Exception ex)
            {
                LogUtil.Error($"AddMission missionId:{id}", ex);
                return false;
            }
        }
        static Byte4 GetStru2Byte(int val)
        {
            return new Byte4
            {
                ByteH1 = (byte)((val >> 24) & 0xff),
                ByteH2 = (byte)((val >> 16) & 0xff),
                ByteL1 = (byte)((val >> 8) & 0xff),
                ByteL2 = (byte)((val & 0xff))
            };
        }
        /// <summary>
        /// 发送命令线程
        /// </summary>
        private void Send()
        {

            while (_loop)
            {
                Com.TCP.RequestInfo request = GetInputRegister();
                _client.AddRequest(request);
                Thread.Sleep(SEND_SLEEP);
            }
        }

        /// <summary>
        /// 读取输入,功能码为04,读输入寄存器
        /// </summary>
        /// <returns></returns>
        private Com.TCP.RequestInfo GetInputRegister()
        {
            Com.TCP.RequestInfo request = new Com.TCP.RequestInfo();
            request.StartAddr = 30001;//起始地址
                                      //功能码
            request.FunCode = 4;
            request.EquipAddr = equipAddr;
            request.CountOrValue = 120;   //个数
            return request;
        }
    }
    public class MissionState
    {
        public uint MissionId { get; set; }
        public uint RunMissionId { get; set; }
        public MissionResult MissionResult { get; set; }
        public MissionRunState MissionRunState { get; set; }

        public override bool Equals(object obj)
        {
            MissionState state = obj as MissionState;
            if (state == null) return false;
            if (this.RunMissionId.Equals(state.RunMissionId)
                && this.MissionResult.Equals(state.MissionResult) && this.MissionRunState.Equals(state.MissionRunState))
                return true;
            return false;
        }
    }
    /// <summary>
    /// Mission执行结果
    /// </summary>
    public enum MissionResult
    {
        无效状态,
        任务执行成功,
        任务取消,
        任务执行出错
    }
    /// <summary>
    /// 任务运行状态
    /// </summary>
    public enum MissionRunState
    {
        无效状态,
        任务在队列中但没有启动 = 2,
        正在执行,
        暂停执行,
        执行结束,
        正在取消
    }
}