EquipBase.cs 14.3 KB
using OnlineStore.Common;
using OnlineStore.LoadCSVLibrary;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace OnlineStore.DeviceLibrary
{
    public abstract class EquipBase : KTK_Store
    {
        private bool IsIntSlvBlock = false;
        public bool IsDebug = false;

        public AxisAlarmInfo AxisAlarm = new AxisAlarmInfo();
        public bool UseAxis = false;
        #region 上下气缸伺服运动
        protected string portName;
        protected short slvAddr;
        public bool RunAxis(bool isCheck,ConfigMoveAxis axis)
        {
            if (!UseAxis)
            {
                return true;
            }
            IOMove(IO_Type.BatchAxis_ServoOn, IO_VALUE.HIGH);
            Thread.Sleep(1000);
            //打开所有轴 
            ACServerManager.OpenPort(portName);
            Thread.Sleep(50);
            //初始化
            if (!IsIntSlvBlock)
            {
                ACServerManager.InitSlvAddr(portName, slvAddr, axis.TargetSpeed, axis.AddSpeed, axis.DelSpeed);
                Thread.Sleep(100);
            }
            ACServerManager.AlarmClear(portName, slvAddr);
            Thread.Sleep(50);
            ACServerManager.ServoOn(portName, slvAddr);

            Thread.Sleep(1000);
            //打开所有轴
            if (isCheck)
            {
                if (!OpenAxis(axis))
                {
                    return false;
                }
            }
            IsIntSlvBlock = true;
            IOMove(IO_Type.BatchAxis_BreakOn, IO_VALUE.HIGH);
            return true;
        }

        protected void IOMove(object batchAxis_ServoOn, IO_VALUE hIGH)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 打开所有轴
        /// </summary>
        /// <returns></returns>
        protected bool OpenAxis(ConfigMoveAxis axis)
        {
            //判断轴是否正常

            if (ACServerManager.ServerOnStatus(portName, slvAddr))
            {
                LogUtil.info(Name + "成功打开轴:" + axis.Explain);
            }
            else
            {
                //清理报警,再重新打开一次
                LogUtil.info(Name + "第一次打开轴" + axis.Explain + "失败,先清理一下报警,再重新打开一次");
                ACServerManager.AlarmClear(portName, slvAddr);
                System.Threading.Thread.Sleep(1200);
                ACServerManager.ServoOn(portName, slvAddr);
                System.Threading.Thread.Sleep(100);
                if (ACServerManager.ServerOnStatus(portName, slvAddr))
                {
                    LogUtil.info(Name + "清理报警后重新打卡轴成功:" + axis.Explain);
                }
                else
                {
                    ACServerManager.ServoOff(portName, slvAddr);
                    WarnMsg = Name + "打开轴" + axis.Explain + "失败 ";
                    LogUtil.info(Name + WarnMsg);
                    Alarm(LineAlarmType.AxisAlarm, 5.ToString(), WarnMsg, MoveInfo.MoveType);
                    return false;
                }
            }

            return true;
        }


        public void CloseAxis()
        {
            LogUtil.info(Name + "关闭刹车,关闭伺服");
            IOMove(IO_Type.BatchAxis_BreakOn, IO_VALUE.LOW);

            ACServerManager.ServoOff(portName, slvAddr);
            //关闭串口,等下次重新打开
            ACServerManager.ColsePort(portName);

            Thread.Sleep(100);
            IOMove(IO_Type.BatchAxis_ServoOn, IO_VALUE.LOW);
        }


        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();

            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( 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;
        }

        #endregion

        #region CheckWait处理

        /// <summary>
        /// 上一个盘号
        /// </summary>
        public int preTrayNum = 0;
        /// <summary>
        /// 当前正在通过的托盘号
        /// </summary>
        protected int currMoveTrayNum = 0;
        protected DateTime preRWTime = DateTime.Now;
        protected void CheckWait(LineMoveInfo moveInfo)
        {
            List<WaitResultInfo> list = moveInfo.WaitList;
            if (list.Count <= 0)
            {
                moveInfo.EndStepWait();
                return;
            }

            //当等待超过一分钟时,需要打印提示 
            TimeSpan span = DateTime.Now - moveInfo.LastSetpTime;
            string NotOkMsg = "";
            bool isOk = true;
            if (moveInfo.OneWaitCanEndStep)
            {
                isOk = false;
            }
            foreach (WaitResultInfo wait in list)
            {
                if (wait.IsEnd)
                {
                    continue;
                }
                NotOkMsg = wait.ToStr();
                if (wait.WaitType.Equals(1))
                {
                    string msg = "";
                    if (wait.IsHomeMove)
                    {
                        wait.IsEnd = ACHomeMoveIsEnd(wait.AxisInfo, out msg);
                    }
                    else
                    {
                        wait.IsEnd = ACAxisMoveIsEnd(wait.AxisInfo, wait.TargetPosition, wait.TargetSpeed, out msg);
                    }
                    if (!msg.Equals(""))
                    {
                        isOk = false;
                        WarnMsg = msg;
                        Alarm(LineAlarmType.AxisMoveError, 5.ToString(), WarnMsg, moveInfo.MoveType);
                        break;
                    }
                }
                else if (wait.WaitType.Equals(2))
                {
                    NotOkMsg = " (" + baseConfig.GetDisplayName(wait.IoType) + "=" + wait.IoValue + ") ";
                    wait.IsEnd = IOValue(wait.IoType).Equals(wait.IoValue);

                    if (!wait.IsEnd)
                    {
                        //屏蔽料盘检测信号
                        if (wait.IoType.Equals(IO_Type.TrayCheck) && wait.IoValue.Equals(IO_VALUE.HIGH) && LineManager.Config.IsUse_Tray_Check.Equals(0))
                        {
                            LogUtil.debug(moveInfo.Name + "未检测到:IsUse_Tray_Check= " + wait.IoValue + ",直接跳过检测继续下一步");
                        }
                        //夹紧按钮若果超过一秒钟还未收到,默认成功
                        else if (wait.IoType.Equals(IO_Type.ClampCylinder_Slack) && wait.IoValue.Equals(IO_VALUE.HIGH) && span.TotalMilliseconds > 4000)
                        {
                            LogInfo("未检测到:ClampCylinder_Slack=HIGH,超过4秒钟,默认下一步骤");
                            wait.IsEnd = true;
                        }
                        else
                        {
                            TimeSpan rwSpan = DateTime.Now - preRWTime;
                            //一分钟还未检测到
                            if (span.TotalMilliseconds > LineManager.Config.IOSingle_TimerOut)
                            {
                                ConfigIO io = baseConfig.getWaitIO(wait.IoType);
                                WarnMsg = Name + "等待" + NotOkMsg + " 超时";
                                Alarm(LineAlarmType.IoSingleTimeOut, io.ElectricalDefinition, WarnMsg, MoveInfo.MoveType);
                                LogUtil.error(MoveInfo.Name + WarnMsg, 13);
                            }
                            else if (rwSpan.TotalSeconds > 3 && span.TotalSeconds > 3)
                            {
                                preRWTime = DateTime.Now;
                                string msg = moveInfo.Name + "  " + NotOkMsg + "已等待 " + Math.Abs(span.TotalSeconds) + "秒,重写DO:";
                                bool isLog = false;
                                foreach (WaitResultInfo ww in list)
                                {
                                    if (ww != null && ww.WaitType.Equals(2) && baseConfig.DOList.ContainsKey(ww.IoType))
                                    {
                                        isLog = true;
                                        IOMove(ww.IoType, ww.IoValue);
                                        msg += ww.ToStr() + ",";
                                    }
                                }
                                if (isLog)
                                {
                                    LogUtil.error(msg);
                                }
                            }
                            isOk = false;
                            break;
                        }
                    }
                }
                else if (wait.WaitType.Equals(3))
                {
                    wait.IsEnd = (span.TotalMilliseconds >= wait.TimeMSeconds);
                }
                else if (wait.WaitType.Equals(8))
                {
                    string posId = moveInfo.MoveParam.PosId;
                    int id = moveInfo.MoveParam.GetStoreId();
                    wait.IsEnd = LineServer.RightInPosId(id, posId);
                }
                else if (wait.WaitType.Equals(9))
                {
                    int storeId = moveInfo.MoveParam.GetStoreId();
                    wait.IsEnd = LineServer.BoxCanReviceTray(storeId);
                }
                else if (wait.WaitType.Equals(10))
                {
                    wait.IsEnd = LineManager.Line.SideWay34HasTray().Equals(false);
                }
                if (wait.IsEnd && moveInfo.OneWaitCanEndStep)
                {
                    isOk = true;
                    break;
                }
                else if (!moveInfo.OneWaitCanEndStep)
                {
                    isOk = false;
                    break;
                }
            }
            if (isOk)
            {
                moveInfo.EndStepWait();
            }
            else if (span.TotalSeconds > moveInfo.TimeOutSeconds)
            {
                WarnMsg = moveInfo.Name + "[" + moveInfo.MoveType + "][" + moveInfo.MoveStep + "]等待[" + NotOkMsg
                    + "]超时[" + Math.Round(span.TotalSeconds, 1) + "]秒";
                LogUtil.error(WarnMsg, 18);
                Alarm(LineAlarmType.IoSingleTimeOut, "", WarnMsg, moveInfo.MoveType);
            }

        }

        #endregion

        public override void Alarm(LineAlarmType alarmType, string alarmDetial, string alarmMsg, LineMoveType storeMoveType)
        {
            if (this.alarmType.Equals(alarmType))
            {
                return;
            }
            this.alarmType = alarmType;
        }

      
    }
}