KTK_Store.cs 10.5 KB
using DeviceLib;
using log4net; 
using OnlineStore.Common;
using OnlineStore.LoadCSVLibrary;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
 

namespace OnlineStore.DeviceLibrary
{
    /// <summary>
    /// 康泰克单台自动料仓
    /// </summary>
    public abstract class KTK_Store : KTK_DeviceBase
    {
       
        public KTK_Store()
        {
        }
        /// <summary>
        /// 开始运行的时间
        /// </summary>
        public DateTime StartTime { get; set; }
       
        public DateTime statusTime = DateTime.Now;

        public string lastPosId = "";
        public StoreStatus lastPosIdStatus = StoreStatus.StoreOnline;

        public  List<ConfigMoveAxis> moveAxisList = new List<ConfigMoveAxis>();

        protected Dictionary<string, AxisAlarmInfo> AxisAlarmCodeMap = new Dictionary<string, AxisAlarmInfo>();
        /// <summary>
        /// 最后一次气压检测变为0的时间
        /// </summary>
        protected DateTime lastAirCloseTime = DateTime.Now;
        /// <summary>
        /// 是否在急停中
        /// </summary>
        public bool isInSuddenDown = false;
        /// <summary>
        /// 是否没有检测到气压
        /// </summary>
        public bool isNoAirCheck = false;

        protected int NeedCheckSafetyLight = 0;
        /// <summary>
        /// 是否再报警中
        /// </summary>
        public StoreAlarmType alarmType = StoreAlarmType.None;

        protected AlarmInfo alarmInfo = new AlarmInfo();

        /// <summary>
        /// 记录上一次的部分IO状态,主要是急停,气压检测信号,复位信号,用来判断是否io发生改变
        /// </summary>
        public Dictionary<string, IO_VALUE> DILastValueMap = new Dictionary<string, IO_VALUE>();

        public object lastDiListLock = "";
        public void addLastDI(string type, IO_VALUE value)
        {
      
            try
            {
                lock (lastDiListLock)
                {
                    if (DILastValueMap.ContainsKey(type))
                    {
                        DILastValueMap.Remove(type);
                    }
                    DILastValueMap.Add(type, value);
                }
            }
            catch (Exception ex)
            {
                LogUtil.error(ex.ToString());
            }
        }
     
         
        /// <summary>
        /// 获取料仓运行的时间
        /// </summary>
        /// <returns></returns>
        public TimeSpan GetStoreRunTime()
        {
            if (StartTime != null)
            {
                return DateTime.Now - StartTime;
            }
            else
            {
                return new TimeSpan(0);
            }
        } 
          
         
        /// <summary>
        /// 运动处理
        /// </summary> 
        protected bool isInPro = false;
        protected virtual void BusyMoveProcess()
        {
            //if (isInPro)
            //{
            //    return;
            //}
            isInPro = true;
            try
            {
                switch (MoveInfo.MoveType)
                {
                    case MoveType.InStore:
                        InStoreProcess();
                        isInPro = false;
                        break;
                    case MoveType.OutStore:
                        OutStoreProcess();
                        isInPro = false;
                        break;

                    case MoveType.StoreReset:
                        ResetProcess();
                        isInPro = false;
                        break;

             
                    default: break;
                }
            }
            catch (Exception ex)
            {
                LogUtil.error("BusyMoveProcess出错:" + ex.ToString());
            }
            isInPro = false;
        } 
        protected void SaveAlarmInfo(StoreAlarmType alarmType, string alarmDetial, string alarmMsg, MoveType storeMoveType)
        {
            alarmMsg = alarmMsg.Replace(Name, "");
            int inoutStatus = 0;
            if (storeMoveType.Equals(MoveType.InStore))
            {
                inoutStatus = 1;
            }
            else if (storeMoveType.Equals(MoveType.InStore))
            {
                inoutStatus = 2;
            }
            int aType = 0;
            switch (alarmType)
            {
                case StoreAlarmType.AxisMoveError:
                    aType = 2;
                    break;
                case StoreAlarmType.AxisAlarm:
                    aType = 2;
                    break;
                case StoreAlarmType.SuddenStop:
                    aType = 1;
                    alarmDetial = "1";
                    break;
                case StoreAlarmType.NoAirCheck:
                    aType = 1;
                    alarmDetial = "2";
                    break;
                case StoreAlarmType.IoSingleTimeOut:
                    aType = 3;
                    break;
                case StoreAlarmType.StellAlarm:
                    aType = 2;
                    alarmDetial = "5";
                    break;
                default: break;
            }
            alarmInfo = new AlarmInfo(StoreID, aType, alarmDetial, alarmMsg, inoutStatus);
        }

        /// <summary>
        /// 开始运行
        /// </summary>
        public abstract bool StartRun();  
        /// <summary>
        /// 停止运行
        /// </summary>
        public abstract void StopRun();
        /// <summary>
        /// 报警
        /// </summary>
        /// <param name="alarmType"></param>
        public abstract void Alarm(StoreAlarmType alarmType, string alarmDetial, string alarmMsg, MoveType storeMoveType);
        /// <summary>
        /// 重置(夹料装置状态不变)
        /// </summary>
        public abstract void Reset(bool isClear=true);
        
        /// <summary>
        /// 停止所有运动
        /// </summary>
        public abstract void StopMove( bool IsCloseAxis);
 
        /// <summary>
        /// 重置处理
        /// </summary>
        protected abstract void ResetProcess();
        
        /// <summary>
        /// 松下伺服轴原点返回运动,等待收到反馈后才会返回
        /// </summary> 
        protected void ACAxisHomeMove(ConfigMoveAxis moveAxis)
        {
            moveAxis.TargetPosition = 0;
            LogUtil.info(  moveAxis.DisplayStr + "speed[" + moveAxis.TargetSpeed + "]开始原点返回");
            MoveInfo.WaitList.Add(WaitResultInfo.WaitAxis(moveAxis, true));
       
            ACServerManager.HomeMove(moveAxis.DeviceName, (short)moveAxis.GetAxisValue(), moveAxis.HomeHighSpeed); 
        }

        /// <summary>
        /// 松下伺服电机运动
        /// </summary> 
        protected void ACAxisMove(ConfigMoveAxis moveAxis, int targetPosition, int targetSpeed)
        {
            MoveInfo.WaitList.Add(WaitResultInfo.WaitAxis(moveAxis, targetPosition, targetSpeed));
            moveAxis.TargetPosition = targetPosition; 
            ACServerManager.AbsMove(moveAxis.DeviceName, moveAxis.GetAxisValue(), targetPosition,targetSpeed); 
        }

        /// <summary>
        /// 判断AC伺服电机轴是否运动完成
        /// </summary> 
        protected bool ACAxisMoveIsEnd(ConfigMoveAxis moveAxis, int targetPosition, int targetSpeed, out string msg)
        {
            msg = "";
            string deviceName = moveAxis.DeviceName;
            short axisNo = moveAxis.GetAxisValue();

            //如果是进出轴,并且光栅被遮挡,直接返回false 
            if (NeedCheckSafetyLight.Equals(2))
            {
                if (MoveInfo.IsStep(StoreMoveStep.SO_13_InoutToP2) ||
                    MoveInfo.IsStep(StoreMoveStep.SI_05_InoutToP2))
                {
                    return false;
                }
            }

            bool isOk = ACServerManager.GetBusyStatus(deviceName, axisNo).Equals(0);
            int outCount = ACServerManager.GetActualtPosition(deviceName, axisNo);
            int errorCount = Math.Abs(outCount - targetPosition);
            if (isOk)
            { 
                if (errorCount <= moveAxis.CanErrorCountMax)
                {
                    return true;
                }
                //判断是否需要重新运动
                if (MoveInfo.CanWhileCount > 0)
                {
                    LogUtil.error(  moveAxis.DisplayStr + "目标位置[" + targetPosition + "]当前位置[" + outCount +
                     "],误差过大,重新开始运动,剩余[" + MoveInfo.CanWhileCount + "]次"); 
                    ACServerManager.AbsMove(moveAxis.DeviceName, moveAxis.GetAxisValue(), targetPosition, targetSpeed);
                    MoveInfo.CanWhileCount--;
                }
                else
                {
                    msg = Name + " storeMoveStep=" + MoveInfo.MoveStep + moveAxis.DisplayStr + "目标位置[" + targetPosition + "]当前位置[" + outCount
                        + "],误差过大,需要报警";
                    LogUtil.error(  msg);
                }
            }
            return false;
        }
        protected bool ACHomeMoveIsEnd(ConfigMoveAxis moveAxis, out string msg)
        {
            msg = "";
            if (ACServerManager.IsHomeMoveEnd(moveAxis.DeviceName, moveAxis.GetAxisValue()))
            {
                //原点完成并且位置=0
                int outCount = ACServerManager.GetActualtPosition(moveAxis.DeviceName, moveAxis.GetAxisValue());
                int errorCount = Math.Abs(outCount);
                if (errorCount <= moveAxis.CanErrorCountMax)
                {
                    return true;
                }
                //判断是否需要重新运动
                if (MoveInfo.CanWhileCount > 0)
                {
                    LogUtil.error(  moveAxis.DisplayStr + "收到原点完成信号,当前位置[" + outCount + "],重新回原点,剩余[" + MoveInfo.CanWhileCount + "]次");
                    //LogUtil.error(LOGGER, StoreName +  moveAxis.DisplayStr +  "重新回原点");
                    ACServerManager.HomeMove(moveAxis.DeviceName, moveAxis.GetAxisValue(), moveAxis.HomeHighSpeed);
                    MoveInfo.CanWhileCount--;
                }
                else
                {
                    msg = Name + " storeMoveStep=" + MoveInfo.MoveStep + moveAxis.DisplayStr + "收到原点完成信号,当前位置[" + outCount + "],误差过大,需要报警";
                    LogUtil.error(  msg);
                } 
            }
            return false;
        }
      

    }
}