KTK_Store.cs 11.6 KB
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;
        /// <summary>
        /// 伺服运行时间列表,key=轴,key=开始时间,value=结束时间
        /// </summary>
        public Dictionary<int, Dictionary<DateTime, DateTime>> AxisRunTimeMap = new Dictionary<int, Dictionary<DateTime, DateTime>>();
        public Dictionary<int, DateTime> AxisLastStartTime = new Dictionary<int, DateTime>();
       
        /// <summary>
        /// 最后一次气压检测变为0的时间
        /// </summary>
        public DateTime lastAirCloseTime = DateTime.Now;
        /// <summary>
        /// 是否在急停中
        /// </summary>
        public bool isInSuddenDown = false;
        /// <summary>
        /// 是否没有检测到气压
        /// </summary>
        public bool isNoAirCheck = false;
        /// <summary>
        /// 是否再报警中
        /// </summary>
        public StoreAlarmType alarmType = StoreAlarmType.None;

        public 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)
            {
                LOGGER.Error(ex.ToString());
            }
        }
     
         
        /// <summary>
        /// 获取料仓运行的时间
        /// </summary>
        /// <returns></returns>
        public TimeSpan GetStoreRunTime()
        {
            if (StartTime != null)
            {
                return DateTime.Now - StartTime;
            }
            else
            {
                return new TimeSpan(0);
            }
        }
        /// <summary>
        /// 获取轴已运行时间
        /// </summary>
        /// <returns></returns>
        public TimeSpan GetAxisRunTime(int axisNo)
        {
            TimeSpan span = new TimeSpan(0); 
            try
            {
                if (AxisRunTimeMap.ContainsKey(axisNo))
                {
                    Dictionary<DateTime, DateTime> moveMap = AxisRunTimeMap[axisNo];
                    if (moveMap != null && moveMap.Count > 0)
                    {
                        foreach (DateTime key in moveMap.Keys)
                        {
                            span += moveMap[key] - key;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogUtil.error(LOGGER, ex.ToString());
            }
            return span;
        }
         
        protected void AddAxisMoveTime(ConfigMoveAxis axis)
        {
            int axisNo = axis.GetAxisValue();
            if (AxisLastStartTime.ContainsKey(axisNo))
            {
                AxisLastStartTime.Remove(axisNo);
            }
            AxisLastStartTime.Add(axisNo, DateTime.Now);
        }
         
         
        /// <summary>
        /// 运动处理
        /// </summary> 
        protected bool isInPro = false;
        protected virtual void BusyMoveProcess()
        {
            if (isInPro)
            {
                return;
            }
            isInPro = true;
       

            switch (StoreMove.MoveType)
            {
                case StoreMoveType.InStore:
                    InStoreProcess();
                    isInPro = false;
                    break;
                case StoreMoveType.OutStore:
                    OutStoreProcess();
                    isInPro = false;
                    break;
                case StoreMoveType.ReturnHome:
                    ReturnHomeProcess();
                    isInPro = false;
                    break;
                case StoreMoveType.StoreReset:
                    ResetProcess();
                    isInPro = false;
                    break;
                default: break;
            } 
            isInPro = false;
        } 
        protected void SaveAlarmInfo(StoreAlarmType alarmType, string alarmDetial, string alarmMsg, StoreMoveType storeMoveType)
        {
            alarmMsg = alarmMsg.Replace(StoreName, "");
            int inoutStatus = 0;
            if (storeMoveType.Equals(StoreMoveType.InStore))
            {
                inoutStatus = 1;
            }
            else if (storeMoveType.Equals(StoreMoveType.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, StoreMoveType storeMoveType);
        /// <summary>
        /// 重置(夹料装置状态不变)
        /// </summary>
        public abstract void Reset();
        
        /// <summary>
        /// 停止所有运动
        /// </summary>
        public abstract void StopMove();
 
        /// <summary>
        /// 重置处理
        /// </summary>
        protected abstract void ResetProcess();
        /// <summary>
        /// 原点返回处理
        /// </summary>
        protected abstract void ReturnHomeProcess();

        /// <summary>
        /// 松下伺服轴原点返回运动,等待收到反馈后才会返回
        /// </summary> 
        protected void ACAxisHomeMove(ConfigMoveAxis moveAxis)
        { 
            moveAxis.TargetPosition = 0;
            LogUtil.debug(LOGGER, "DeviceName=" + moveAxis.DeviceName + ",AxisNo=" + moveAxis.GetAxisValue() + ",speed=" + moveAxis.TargetSpeed + "开始原点返回");
            AddAxisMoveTime(moveAxis);
            ACServerManager.HomeMove(moveAxis.DeviceName, (short)moveAxis.GetAxisValue(), moveAxis.TargetSpeed); 
            StoreMove.WaitList.Add(WaitResultInfo.WaitAxis(moveAxis, true));
        }

        /// <summary>
        /// 松下伺服电机运动
        /// </summary> 
        protected void ACAxisMove(ConfigMoveAxis moveAxis, int targetPosition, int targetSpeed, int startSpeed)
        {
            moveAxis.TargetPosition = targetPosition;
            AddAxisMoveTime(moveAxis);
            ACServerManager.AbsMove(moveAxis.DeviceName, moveAxis.GetAxisValue(), targetPosition,targetSpeed); 
            StoreMove.WaitList.Add(WaitResultInfo.WaitAxis(moveAxis, 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();
 
            bool isend =ACServerManager.IsHomeMoveEnd(deviceName, axisNo);
            int outCount = ACServerManager.GetActualtPosition(deviceName, axisNo);
            int errorCount = Math.Abs(outCount - targetPosition);
            if (isend)
            {
                if (errorCount > moveAxis.CanErrorCountMax)
                {
                    //判断是否需要重新运动
                    if (StoreMove.CanWhileCount > 0)
                    {
                        LogUtil.error(LOGGER, StoreName + " storeMoveStep=" + StoreMove.MoveStep + ",  DeviceName=" + deviceName + ",AxisNo=" + axisNo + ",targetPosition=" + targetPosition + ",targetSpeed=" + targetSpeed + ",当前outCount=" + outCount +
                         ",误差值大于最大误差【" + moveAxis.CanErrorCountMax + "】,但是轴已经停止运动,还有【" + StoreMove.CanWhileCount + "】次可以重复运动的次数");
                        LogUtil.error(LOGGER, StoreName + " storeMoveStep=" + StoreMove.MoveStep + ",  DeviceName=" + deviceName + ",AxisNo=" + axisNo + ",targetPosition=" + targetPosition + "开始重新运动");
                        ACServerManager.AbsMove(moveAxis.DeviceName, moveAxis.GetAxisValue(), targetPosition,targetSpeed); 
                        StoreMove.CanWhileCount--;
                    }
                    else
                    {
                        msg = StoreName + " storeMoveStep=" + StoreMove.MoveStep + ",  DeviceName=" + deviceName + ",AxisNo=" + axisNo + ",targetPosition=" + targetPosition + ",targetSpeed=" + targetSpeed + ",当前outCount=" + outCount + ",误差值大于最大误差【" + moveAxis.CanErrorCountMax + "】,但是轴已经停止运动,需要报警";
                        LogUtil.error(LOGGER, msg);
                        return false;
                    }

                }
                else
                {
                   
                    return true;
                }
            }
            else if (errorCount < moveAxis.CanErrorCountMin)
            {
                LogUtil.info(LOGGER, " storeMoveStep=" + StoreMove.MoveStep + ", DeviceName=" + deviceName + ",AxisNo=" + axisNo + ",targetPosition=" + targetPosition + ",当前outCount=" + outCount +
                        ",误差值小于最小误差【" + moveAxis.CanErrorCountMin + "】,默认轴已经停止运动");
         
                return true;
            }

            return false;
        }
        protected bool ACHomeMoveIsEnd(ConfigMoveAxis moveAxis)
        {
            if (ACServerManager.IsHomeMoveEnd(moveAxis.DeviceName, moveAxis.GetAxisValue()) )
            { 
                return true;
            }
            return false;
        }
        protected bool AxisCountClear(ConfigMoveAxis moveAxis)
        {
            return true;
        }


    }
}