EpsonRobotDevice.cs 11.3 KB
using log4net;
using URSoldering.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using URSoldering.LoadCSVLibrary;

namespace URSoldering.DeviceLibrary
{
    public class EpsonDevice
    {
        private static readonly ILog LOGGER = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        private static TcpClient moveTcp = new TcpClient();

        private static string EpsonIp = "";
        private static int MovePointPort = 2000;
        public static double Robot_LIM_Z = (double)ConfigAppSettings.GetNumValue(Setting_Init.Soldering_LIM_Z);

        private static string MoveOK = "point ok";
        private static string FreeOK = "free ok";
        private static string LockOK = "lock ok";

        internal static void Init(object epson_IP)
        {
            throw new NotImplementedException();
        }

        //最后一次从机械臂读取到的坐标位置
        public static PointValue LastPoint = new PointValue(0, 0, 0, 0, 0);
        //最后一次软件控制移动到的位置
        public static PointValue LastSendPoint = new PointValue(0, 0, 0, 0, 0);

        public delegate void OpEnd(string result);
        private static event OpEnd OnMoveEnd;

        public delegate void GetPoint(double x, double y, double z, double u, int hand);
        private static event GetPoint WhenGetPoint;

        private static object LockObj = new object();

        /// <summary>
        /// 是否锁住轴
        /// </summary>
        public static bool IsLock = true;
        /// <summary>
        /// 是否运行中
        /// </summary>
        public static bool IsRun = false;

        public static void Init(string ip)
        {
            EpsonIp = ip;
        }

        /// <summary>
        /// 是否有错误,(检查Ready和Alarm信号)
        /// </summary>
        /// <returns></returns>
        public static bool HasError()
        {
            bool isReady = IO_VALUE.HIGH.Equals(RobotBean.KNDIOValue(IO_Type.EpsonRunning));
            if (!isReady)
            {
                return true;
            }
            bool hasError = IO_VALUE.HIGH.Equals(RobotBean.KNDIOValue(IO_Type.EpsonAlarm));
            return hasError;
        }

        public static string Start()
        {
            Stop();

            LogUtil.info("开始连接Epson");

            RobotBean.KNDIOMove(IO_Type.EpsonReset, IO_VALUE.HIGH);
            Thread.Sleep(200);
            RobotBean.KNDIOMove(IO_Type.EpsonReset, IO_VALUE.LOW);
            Thread.Sleep(500);
            //判断是否有报警
            if (IO_VALUE.HIGH.Equals(RobotBean.KNDIOValue(IO_Type.EpsonAlarm)))
            {
                LogUtil.info("Epson有报警,进行复位");
                //复位
                RobotBean.KNDIOMove(IO_Type.EpsonReset, IO_VALUE.HIGH);
                Thread.Sleep(200);
                RobotBean.KNDIOMove(IO_Type.EpsonReset, IO_VALUE.HIGH);
                Thread.Sleep(2000);
            }

            if (IO_VALUE.HIGH.Equals(RobotBean.KNDIOValue(IO_Type.EpsonAlarm)))
            {
                LogUtil.error("Epson报警无法复位");
                return "Epson报警无法复位";
            } 
            //启动程序
            RobotBean.KNDIOMove(IO_Type.EpsonStart, IO_VALUE.HIGH);
            Thread.Sleep(200);
            RobotBean.KNDIOMove(IO_Type.EpsonStart, IO_VALUE.LOW);
            try
            {
                //Running信号
                RobotBean.WaitIo("Epson准备信号", IO_Type.EpsonRunning, IO_VALUE.HIGH, 3000);
            }
            catch (TimeoutException te)
            {
                LogUtil.error("Epson连接失败:" + te.Message);
                return te.Message;
            } 
            Thread.Sleep(200);
            moveTcp = new TcpClient();
            bool result = moveTcp.connect(EpsonIp, MovePointPort, new TcpClient.HandleMessage(OnMoveRevice));
            if (!result)
            {
                LogUtil.error(LOGGER, "Epson 连接【" + EpsonIp + "】【" + MovePointPort + "】失败");
                IsRun = false;
                return "连接【" + EpsonIp + "】【" + MovePointPort + "】失败";
            }
            else
            {
                IsRun = true;
                LogUtil.info(LOGGER, "连接【" + EpsonIp + "】【" + MovePointPort + "】成功");
                return "";
            } 
        } 
        public static bool LockAxis()
        {
            try
            {
                IsLock = true;
                moveTcp.sendLine(GetSendStr("lock"));
                bool freeResult = WaitUtil.Wait(2000, delegate ()
                {
                    return IsLock.Equals(false);
                });
                IsLock = !freeResult;
                return freeResult;
            }
            catch (Exception ex)
            {
                LogUtil.error(LOGGER, "出错啦" + ex.ToString());
            }
            return true;
        }
        public static bool FreeAxis()
        {
            try
            {
                IsLock = false;
                moveTcp.sendLine(GetSendStr("free"));
                bool lockResult = WaitUtil.Wait(2000, delegate ()
                {
                    return IsLock.Equals(true);
                });
                IsLock = lockResult;
                return lockResult;
            }
            catch (Exception ex)
            {
                LogUtil.error(LOGGER, "出错啦" + ex.ToString());
            }
            return false;
        }

        public static bool GetPosition(GetPoint AfterGet)
        {
            try
            {
                if (IsRun)
                {
                    WhenGetPoint = AfterGet;
                    moveTcp.sendLine(GetSendStr("save"));
                } 
            }
            catch (Exception ex)
            {
                LogUtil.error(LOGGER, "出错啦" + ex.ToString());
            }
            return true;
        }
        public static void MoveTo(double x, double y, double z, double u, bool IsHighSpeed, int hand,double limZ, OpEnd AfterMove)
        {
            EpsonDevice.OnMoveEnd = AfterMove;
            SendMovePoint(x, y, z, u, IsHighSpeed, hand, limZ);
        }
        public static void MoveTo(double x, double y, double z, double u, bool IsHighSpeed, int hand, OpEnd AfterMove)
        {
            EpsonDevice.OnMoveEnd = AfterMove;
            SendMovePoint(x, y, z, u, IsHighSpeed, hand, Robot_LIM_Z);
        }
         
        public static void Stop()
        {
            try
            {
                IsRun = false;
                if (moveTcp.IsConnected())
                {
                    moveTcp.close();
                }
                //关闭程序
                RobotBean.KNDIOMove(IO_Type.EpsonStop, IO_VALUE.HIGH);
                Thread.Sleep(500);
                RobotBean.KNDIOMove(IO_Type.EpsonStop, IO_VALUE.LOW); 
            }
            catch (Exception ex)
            {
                LogUtil.error("Stop Epson出错啦" + ex.ToString());
            }
        }

        /// <summary>
        /// 发送坐标移动
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="z">上下</param>
        /// <param name="u">旋转</param>
        /// <param name="IsHighSpeed"></param>
        /// <param name="hand">1=右手,2=左手</param> 
        private static void SendMovePoint(double x, double y, double z, double u, bool IsHighSpeed, int hand, double limZ)
        {
            lock (LockObj)
            { 
                if (z > 0)
                {
                    OnMoveEnd?.Invoke("坐标错误:Z坐标不能小于0,当前为:" + z);
                }
                if (limZ > EpsonDevice.Robot_LIM_Z)
                {
                    limZ = EpsonDevice.Robot_LIM_Z;
                }
                string speed = "l";
                if (IsHighSpeed)
                {
                    speed = "h";
                }

                string handStr = "0";
                if (hand == 2)
                {
                    handStr = "l";
                }
                else if (hand == 1)
                {
                    handStr = "r";
                }
                string str = "move" + "," + x + "," + y + "," + z + "," + u + "," + speed + "," + handStr + "," + limZ;
                LastSendPoint = new PointValue(x, y, u, z, hand);
                if (IsLock == false)
                {
                    OnMoveEnd?.Invoke("轴没有锁定");
                }
                if (!IsRun)
                {
                    OnMoveEnd?.Invoke("机器人未连接");
                }
                moveTcp.sendLine(str);
            }

        }
        /// <summary>
        /// 记录最后一次收到OK的时间
        /// </summary>
        private static Dictionary<string, DateTime> LastOkMap = new Dictionary<string, DateTime>();
        public static DateTime MoveOKTime()
        {
            if (LastOkMap.ContainsKey(MoveOK))
            {
                return LastOkMap[MoveOK];
            }
            return new DateTime(0);
        }
        private static void AddOkTime(string type)
        {
            if (LastOkMap.ContainsKey(type))
            {
                LastOkMap.Remove(type);
            }
            LastOkMap.Add(type, DateTime.Now);
        }
        private static void OnMoveRevice(string message)
        {
            if (message == null || message.Equals(""))
            {
                return;
            } 
            try
            {
                LogUtil.debug("【" + EpsonIp + "】【" + MovePointPort + "】收到数据:" + message.Replace("\r\n", ""));
                if (message.Contains(MoveOK))
                {
                    AddOkTime(MoveOK);
                       OnMoveEnd?.Invoke("");
                }
                else if (message.Contains(FreeOK))
                {
                    AddOkTime(FreeOK);
                    IsLock = false;
                }
                else if (message.Contains(LockOK))
                {
                    AddOkTime(LockOK);
                    IsLock = true;
                }
                else if (message.StartsWith("ERR"))
                {
                    LogUtil.error("收到Epson机器人错误:" + message);
                }
                else
                {
                    string[] posList = message.Split(',');
                    if (posList.Length == 5)
                    {
                        double x = Convert.ToDouble(posList[0]);
                        double y = Convert.ToDouble(posList[1]);
                        double z = Convert.ToDouble(posList[2]);
                        double u = Convert.ToDouble(posList[3]);
                        int hand = Convert.ToInt32(posList[4]);
                        WhenGetPoint?.Invoke(x, y, z, u, hand);
                        LastPoint = new PointValue(x, y, u, z, hand);
                    }
                }
            }
            catch (Exception ex)
            {
                LogUtil.error(LOGGER, "收到数据【" + message + "】出错啦" + ex.ToString());
            }
        }

        private static string GetSendStr(string str)
        {
            return str + ",0,0,0,0,0,0,0";
        }

    }
}