KTK_Store.cs 12.8 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;

        protected int NeedCheckSafetyLight = 0;
        /// <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);
            }
        } 
         
        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;
            try
            {
                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;
                }
            }catch(Exception ex)
            {
                LogUtil.error("BusyMoveProcess出错:"+ex.ToString());
            }
            isInPro = false;
        } 
        protected void SaveAlarmInfo(StoreAlarmType alarmType, string alarmDetial, string alarmMsg,string alarmMsgEn, string alarmMsgJp, 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,alarmMsgEn, alarmMsgJp, 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, StoreMoveType storeMoveType);
        /// <summary>
        /// 重置(夹料装置状态不变)
        /// </summary>
        public abstract void Reset();
        
        /// <summary>
        /// 停止所有运动
        /// </summary>
        public abstract void StopMove( bool IsCloseAxis);
 
        /// <summary>
        /// 重置处理
        /// </summary>
        protected abstract void ResetProcess();
        /// <summary>
        /// 原点返回处理
        /// </summary>
        protected abstract void ReturnHomeProcess();

        /// <summary>
        /// 松下伺服轴原点返回运动,等待收到反馈后才会返回
        /// </summary> 
        protected void ACAxisHomeMove(ConfigMoveAxis moveAxis)
        {
            moveAxis.TargetPosition = 0;
            LogUtil.info(LOGGER, moveAxis.DisplayStr + "speed[" + moveAxis.TargetSpeed + "]开始原点返回");
            StoreMove.WaitList.Add(WaitResultInfo.WaitAxis(moveAxis, true));
            AddAxisMoveTime(moveAxis);
            var HomeAddSpeed = moveAxis.HomeAddSpeed > 0 ? moveAxis.HomeAddSpeed : moveAxis.HomeHighSpeed * 8;
            var HomeLowSpeed = moveAxis.HomeLowSpeed > 0 ? moveAxis.HomeLowSpeed : moveAxis.HomeHighSpeed / 10;

            ACServerManager.HomeMove(moveAxis.DeviceName, (short)moveAxis.GetAxisValue(), moveAxis.HomeHighSpeed, HomeLowSpeed, HomeAddSpeed); 
        }

        /// <summary>
        /// 松下伺服电机运动
        /// </summary> 
        protected void ACAxisMove(ConfigMoveAxis moveAxis, int targetPosition, int targetSpeed)
        {
            StoreMove.WaitList.Add(WaitResultInfo.WaitAxis(moveAxis, targetPosition, targetSpeed));
            moveAxis.TargetPosition = targetPosition;
            AddAxisMoveTime(moveAxis);
            var addSpeed = moveAxis.AddSpeed > 0 ? moveAxis.AddSpeed:targetSpeed * 4;
            var delSpeed = moveAxis.DelSpeed > 0 ? moveAxis.DelSpeed:targetSpeed * 4;
            
            ACServerManager.AbsMove(moveAxis.DeviceName, moveAxis.GetAxisValue(), targetPosition,targetSpeed, addSpeed, delSpeed); 
        }

        /// <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 (StoreMove.MoveStep.Equals(StoreMoveStep.SO_10_DeviceToDoor) ||
                    StoreMove.MoveStep.Equals(StoreMoveStep.SI_05_DeviceToDoor))
                {
                    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 (StoreMove.CanWhileCount > 0)
                {
                    LogUtil.error(LOGGER, moveAxis.DisplayStr + "目标位置[" + targetPosition + "]当前位置[" + outCount +
                     "],误差过大,重新开始运动,剩余[" + StoreMove.CanWhileCount + "]次");

                    var addSpeed = moveAxis.AddSpeed > 0 ? moveAxis.AddSpeed : targetSpeed * 4;
                    var delSpeed = moveAxis.DelSpeed > 0 ? moveAxis.DelSpeed : targetSpeed * 4;
                    ACServerManager.AbsMove(moveAxis.DeviceName, moveAxis.GetAxisValue(), targetPosition, targetSpeed, addSpeed, delSpeed);
                    StoreMove.CanWhileCount--;
                }
                else
                {
                    //msg = StoreName + " storeMoveStep=" + StoreMove.MoveStep + moveAxis.DisplayStr + "目标位置[" + targetPosition + "]当前位置[" + outCount
                    //    + "],误差过大,需要报警"; 
                    SetWarnMsgAndLog(ResourceControl.AxisMoveAlarm, StoreMove.MoveStep + "", moveAxis.GetNameStr(), targetPosition + "", outCount + "");
                    msg = WarnObj.WarnMsg;
                    LogUtil.error(LOGGER, 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 (StoreMove.CanWhileCount > 0)
                {
                    LogUtil.error(LOGGER, moveAxis.DisplayStr + "收到原点完成信号,当前位置[" + outCount + "],重新回原点,剩余[" + StoreMove.CanWhileCount + "]次");
                    //LogUtil.error(LOGGER, StoreName +  moveAxis.DisplayStr +  "重新回原点");

                    var HomeAddSpeed = moveAxis.HomeAddSpeed > 0 ? moveAxis.HomeAddSpeed : moveAxis.HomeHighSpeed * 6;
                    var HomeLowSpeed = moveAxis.HomeLowSpeed > 0 ? moveAxis.HomeLowSpeed : moveAxis.HomeHighSpeed / 10;
                    ACServerManager.HomeMove(moveAxis.DeviceName, moveAxis.GetAxisValue(), moveAxis.HomeHighSpeed, HomeLowSpeed, HomeAddSpeed);
                    StoreMove.CanWhileCount--;
                }
                else
                {
                    //msg = StoreName + " storeMoveStep=" + StoreMove.MoveStep + moveAxis.DisplayStr + "收到原点完成信号,当前位置[" + outCount + "],误差过大,需要报警";

                    SetWarnMsgAndLog(ResourceControl.AxisHomeMoveAlarm, StoreMove.MoveStep + "", moveAxis.GetNameStr(), outCount + "");
                    msg = WarnObj.WarnMsg;
                    LogUtil.error(LOGGER, msg);
                } 
            }
            return false;
        }
        protected bool AxisCountClear(ConfigMoveAxis moveAxis)
        {
            return true;
        }


    }
}