MainMachine.cs 15.1 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;
using System.Windows.Forms;

namespace DeviceLibrary
{
    public partial class MainMachine : IRobot
    {
        public string Name { get; set; } = "移载";
        private bool _canRunning=true;
        public bool canRunning
        {
            get { return _canRunning; }
            set
            {
                if (_canRunning != value) {
                    Msg.setlogones();
                }
                _canRunning = value;
            }
        }
        public bool isBusy { get; set; } = false;
        public bool isAlarm { get; set; } = false;
        public RunStatus runStatus { get; set; } = RunStatus.Stop;
        public Robot_Config Config { get; set; }
        public bool UserPause { get; set; } = false;


        MoveInfo ResetMoveInfo;
        /// <summary>
        /// 右侧移动信息
        /// </summary>
        public MoveInfo RightMoveInfo;
        public MoveInfo LeftMoveInfo;
        MoveInfo LabelMoveInfo;
        MoveInfo MiddleMoveInfo;

        public delegate void ProcessMsg(List<Msg> msg);
        public event ProcessMsg ProcessMsgEvent;

        public delegate void ProcessMoveinfo(List<MoveInfo> moveinfoList);
        public event ProcessMoveinfo ProcessMoveinfoEvent;

        AxisBean Take_Middle_Axis;
        AxisBean Take_UpDown_Axis;
        AxisBean Left_Batch_Axis;
        AxisBean Right_Batch_Axis;
        AxisBean Label_X_Axis;
        AxisBean Label_Y_Axis;
        AxisBean Label_Z_Axis;
        AxisBean Label_R_Axis;
        ElectricGripper electricClamp;
        /// <summary>
        /// 开始运行的时间
        /// </summary>
        public DateTime StartTime { get; set; }

        /// <summary>
        /// 是否在急停中
        /// </summary>
        public bool isInSuddenDown = false;



        public MainMachine(Robot_Config _config) {
            Config = _config;
            
            
            RightMoveInfo = new MoveInfo("右侧取料");
            RightMoveInfo.SetStateDelegate(RightState);
            
            MiddleMoveInfo = new MoveInfo("移栽");
            MiddleMoveInfo.SetStateDelegate(MiddleState);
            LeftMoveInfo = new MoveInfo("左侧放料");
            LeftMoveInfo.SetStateDelegate(LeftState);
            LabelMoveInfo = new MoveInfo("贴标");
            LabelMoveInfo.SetStateDelegate(LabelState);
            ResetMoveInfo = new MoveInfo("重置");

            #region 初始化led
            AlarmLed = new Led(Config.DOList[IO_Type.Alarm_HddLed].GetIOAddr());
            StandbyLed = new Led(Config.DOList[IO_Type.RunSign_HddLed].GetIOAddr());
            RunningLed = new Led(Config.DOList[IO_Type.AutoRun_HddLed].GetIOAddr());
            RightLed = new Led(Config.DOList[IO_Type.RightState_Led].GetIOAddr());
            LeftLed = new Led(Config.DOList[IO_Type.LeftState_Led].GetIOAddr());
            #endregion
            #region 初始化伺服轴
            Take_Middle_Axis = new AxisBean(Config.Take_Middle_Axis, Name);
            Take_UpDown_Axis = new AxisBean(Config.Take_UpDown_Axis, Name);
            Left_Batch_Axis = new AxisBean(Config.Left_Batch_Axis, Name);
            Right_Batch_Axis = new AxisBean(Config.Right_Batch_Axis, Name);
            Label_X_Axis = new AxisBean(Config.Label_X_Axis, Name);
            Label_Y_Axis = new AxisBean(Config.Label_Y_Axis, Name);
            Label_Z_Axis = new AxisBean(Config.Label_Z_Axis, Name);
            Label_R_Axis = new AxisBean(Config.Label_R_Axis, Name);
            #endregion
            electricClamp = RobotManage.electricGripper;

            AlarmBuzzer.SetOnOffAction(() =>{ IOMove(IO_Type.Alarm_Buzzer, IO_VALUE.HIGH); }, () => { IOMove(IO_Type.Alarm_Buzzer, IO_VALUE.LOW); });

            InitPrint();
            LedProcessInit();
        }
        /// <summary>
        /// 整机启动变量,设置为false后将退出线程,只在停止时调用
        /// </summary>
        bool mstart=true;
        public void Run() {
            mstart = true;
            while (mstart) {
                try
                {
                    canRunning = DeviceCheck();
                    if (canRunning)
                    {
                        BtnProcess();
                        canRunning = SafeCheck();
                    }
                    Thread.Sleep(200);
                    if (!canRunning || !mstart)
                        continue;
                    if (runStatus == RunStatus.Running)
                    {
                        IOMonitor();
                        RightProcess();
                        MiddleProcess();
                        LeftProcess();
                        LabelProcess();
                    }
                    else if (runStatus == RunStatus.HomeReset)
                    {
                        HomeReset();
                    }
                }
                catch (Exception ex)
                {
                    Msg.add(ex.ToString(), MsgLevel.warning);
                }
                finally {
                    ProcessMsgEvent?.Invoke(Msg.get());
                    //ProcessMoveinfoEvent?.Invoke(MoveInfo.List);
                    Msg.clear();
                }
            }
            LogUtil.info("主线程已退出.");
        }
        public void Stop() {
            mstart = false;
            Thread.Sleep(300);
            Alarm(AlarmType.None);
            StopMove(true);
            IOMove(IO_Type.RightMoto_Run, IO_VALUE.LOW);
            IOMove(IO_Type.LeftMoto_Run, IO_VALUE.LOW);
            IOMove(IO_Type.LabelCylinder_Work, IO_VALUE.LOW);
        }
        public void BeginHomeReset(bool firstRun=false) {
            if (!firstRun)
            {
                StopMove();
                Thread.Sleep(500);
            }
            OpenAllServo();
            Alarm(AlarmType.None);
            runStatus = RunStatus.HomeReset;
            ResetMoveInfo.NewMove(MoveStep.H01_HomeReset);
            ResetMoveInfo.log("开始回原");
            ResetMoveInfo.WaitList.Add(WaitResultInfo.WaitTime(1000));
        }
        void HomeReset()
        {
            if (CheckWait(ResetMoveInfo))
                return;

            switch (ResetMoveInfo.MoveStep)
            {
                case MoveStep.H01_HomeReset:
                    ResetMoveInfo.NextMoveStep(MoveStep.H02_HomeReset);
                    //MoveInfo.WaitList.Add(WaitResultInfo.WaitTime(1000));
                    ResetMoveInfo.log("正在回原");
                    
                    Label_Z_Axis.HomeMove(ResetMoveInfo);
                    Left_Batch_Axis.HomeMove(ResetMoveInfo);
                    Right_Batch_Axis.HomeMove(ResetMoveInfo);
                    electricClamp.HomeReset();
                    break;
                case MoveStep.H02_HomeReset:
                    ResetMoveInfo.NextMoveStep(MoveStep.H03_HomeReset);
                    Label_R_Axis.HomeMove(ResetMoveInfo);
                    ResetMoveInfo.WaitList.Add(WaitResultInfo.WaitTime(500));
                    break;
                case MoveStep.H03_HomeReset:
                    ResetMoveInfo.NextMoveStep(MoveStep.H04_HomeReset);
                    ResetMoveInfo.log("正在回原");
                    Label_X_Axis.HomeMove(ResetMoveInfo);
                    Label_Y_Axis.HomeMove(ResetMoveInfo);
                    Label_Z_Axis.AbsMove(ResetMoveInfo, Config.Label_Z_P1, Config.Label_Z_P1_speed);                    
                    break;
                case MoveStep.H04_HomeReset:
                    ResetMoveInfo.NextMoveStep(MoveStep.H05_HomeReset);
                    ResetMoveInfo.log("正在回原");
                    Label_R_Axis.AbsMove(ResetMoveInfo, Config.Label_R_P1, Config.Label_R_P1_speed);
                    Take_UpDown_Axis.HomeMove(ResetMoveInfo);
                    ResetMoveInfo.WaitList.Add(WaitResultInfo.WaitTime(1000));
                    break;
                case MoveStep.H05_HomeReset:
                    ResetMoveInfo.NextMoveStep(MoveStep.H06_HomeReset);
                    Take_Middle_Axis.HomeMove(ResetMoveInfo);
                    Label_X_Axis.AbsMove(ResetMoveInfo, Config.Label_X_P1, Config.Label_X_P1_speed);
                    Label_Y_Axis.AbsMove(ResetMoveInfo, Config.Label_Y_P1, Config.Label_Y_P1_speed);
                    ResetMoveInfo.WaitList.Add(WaitResultInfo.WaitTime(500));
                    break;
                case MoveStep.H06_HomeReset:
                    ResetMoveInfo.NextMoveStep(MoveStep.H07_HomeReset);
                    ResetMoveInfo.log("正在回原");                    
                    Take_UpDown_Axis.AbsMove(ResetMoveInfo, Config.Take_UpDown_P1, Config.Take_UpDown_P1_speed);
                    Right_Batch_Axis.AbsMove(ResetMoveInfo, Config.Right_Batch_P1, Config.Right_Batch_P1_speed);
                    Left_Batch_Axis.AbsMove(ResetMoveInfo, Config.Left_Batch_P1, Config.Left_Batch_P1_speed);
                    ResetMoveInfo.WaitList.Add(WaitResultInfo.WaitTime(1000));
                    break;
                case MoveStep.H07_HomeReset:
                    ResetMoveInfo.NextMoveStep(MoveStep.HEND_HomeReset);
                    Take_Middle_Axis.AbsMove(ResetMoveInfo, Config.Take_Middle_P1, Config.Take_Middle_P1_speed);
                    ResetMoveInfo.log("正在回原 阻挡气缸判断");
                    if (IOManager.IOValue(IO_Type.LeftEnd_Check) == IO_VALUE.LOW)
                    {
                        CylinderMove(ResetMoveInfo, IO_Type.LeftStopUP, IO_Type.LeftStopDown);
                    }
                    if (IOManager.IOValue(IO_Type.RightEnd_Check) == IO_VALUE.LOW)
                    {
                        CylinderMove(ResetMoveInfo, IO_Type.RightStopUP, IO_Type.RightStopDown);
                    }
                    break;
                case MoveStep.HEND_HomeReset:
                    ResetMoveInfo.log("回原完成");
                    ResetMoveInfo.EndMove();

                    RightShelfNoTray = false;
                    LeftShelfNoTray = false;

                    MiddleMoveInfo.NewMove(MoveStep.M_Standby);
                    LabelMoveInfo.NewMove(MoveStep.Lbl01);
                    runStatus = RunStatus.Running;
                    break;
            }
        }
        public bool IgnoreSafecheck=false;
        public bool IgnoreGratingSignal = false;

        bool lastSafeCheckStatus = true;
        bool SafeCheck() {
            bool ok = true;
            if (UserPause)
            {
                Msg.add("用户暂停", MsgLevel.warning);
                DeviceSuddenStop();
                ok = false;
            }
            if (IOValue(IO_Type.GratingSignal_Check).Equals(IO_VALUE.LOW))
            {
                if (!IgnoreSafecheck && !IgnoreGratingSignal
                    && IOValue(IO_Type.RightCar_Check).Equals(IO_VALUE.LOW)
                    && IOValue(IO_Type.LeftCar_Check).Equals(IO_VALUE.LOW))
                {
                    ok = false;
                    DeviceSuddenStop();
                }
                
                Msg.add("安全光栅被遮挡"+(ok?"[已忽略]":""), MsgLevel.warning);
            }
            if (IOValue(IO_Type.HasNgBox).Equals(IO_VALUE.LOW))
            {
                Msg.add("没有检测到NG料箱", MsgLevel.warning);
                ok = false;
            }
            if (IOValue(IO_Type.HasPrinter).Equals(IO_VALUE.LOW))
            {
                Msg.add("没有检测打印机", MsgLevel.warning);
                ok = false;
            }
            if (IOValue(IO_Type.LeftBackDoor_Check).Equals(IO_VALUE.LOW))
            {
                if (!IgnoreSafecheck)
                {
                    ok = false;
                    DeviceSuddenStop();
                }
                Msg.add("左后门没有关闭" + (ok ? "[已忽略]" : ""), MsgLevel.warning);
            }
            if (IOValue(IO_Type.RightBackDoor_Check).Equals(IO_VALUE.LOW))
            {

                if (!IgnoreSafecheck)
                {
                    ok = false;
                    DeviceSuddenStop();
                }
                Msg.add("右后门没有关闭" + (ok ? "[已忽略]" : ""), MsgLevel.warning);
            }
            lastSafeCheckStatus = ok;
            return ok;
        }

        void DeviceSuddenStop() {
            if (lastSafeCheckStatus)
            {
                //lastSafeCheckStatus = false;
                //AxisBean.StopMultiAxis(new List<AxisBean>() { Take_Middle_Axis, Take_UpDown_Axis, Label_X_Axis,Label_Y_Axis, Label_Z_Axis, Label_R_Axis });
                AxisBean.StopMultiAxis(AxisBean.List);
                MoveInfo.List.ForEach((m) => { m.CanWhileCount = 5; });

                if (runStatus == RunStatus.HomeReset)
                {
                    ResetMoveInfo.NewMove(MoveStep.H01_HomeReset);
                }
            }
        }

        /// <summary>
        /// 最后一次气压检测变为0的时间
        /// </summary>
        DateTime lastAirCloseTime = DateTime.MinValue;

        internal DateTime checkAlarmTime = DateTime.Now;
        public bool DeviceCheck() {
            bool ok = true;
            if (IOValue(IO_Type.SuddenStop_BTN).Equals(IO_VALUE.LOW))
            {
                Alarm(AlarmType.SuddenStop);
                Msg.add("急停中", MsgLevel.warning);
                ok = false;
            }            
            else if (alarmType == AlarmType.SuddenStop) {
                //if (IOValue(IO_Type.Right_BTN).Equals(IO_VALUE.HIGH) || IOValue(IO_Type.Left_BTN).Equals(IO_VALUE.HIGH))
                //{
                //    Alarm(AlarmType.None);
                //}
                //else
                {
                    Msg.add("系统需要重置", MsgLevel.warning);
                    ok = false;
                }
            }
            if (IOValue(IO_Type.Airpressure_Check).Equals(IO_VALUE.LOW))
            {
                if (lastAirCloseTime == DateTime.MinValue)
                    lastAirCloseTime = DateTime.Now;

                TimeSpan span = DateTime.Now - lastAirCloseTime;
                if (span.TotalSeconds > RobotManage.Config.AirCheckSeconds)
                {
                    ok = false;
                    Msg.add("气压不足", MsgLevel.warning);
                }
            }
            else {
                lastAirCloseTime = DateTime.MinValue;
            }
            if (alarmType!=AlarmType.SuddenStop)
            {
                TimeSpan span = DateTime.Now - checkAlarmTime;
                //在回原点,复位,出入库时,检测报警间隔减小
                if ((!runStatus.Equals(RunStatus.Stop) && span.TotalSeconds > 3) || span.TotalSeconds > 1)
                {
                    foreach (ConfigMoveAxis configMoveAxis in Config.moveAxisList)
                    {
                        if (AxisManager.GetAlarmStatus(configMoveAxis.DeviceName, configMoveAxis.GetAxisValue()) == 1)
                        {
                            Msg.add($"{configMoveAxis.Explain}:运动报警", MsgLevel.warning);
                            ok = false;
                        }
                    }
                }
            }
            return ok;
        }



    }
}