MainMachine.cs 12.4 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>
        MoveInfo RightMoveInfo;
        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;
            

            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(50);
                    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.Message, MsgLevel.warning);
                }
                finally {
                    ProcessMsgEvent?.Invoke(Msg.get());
                    ProcessMoveinfoEvent?.Invoke(MoveInfo.List);
                    Msg.clear();
                }
            }
            LogUtil.info("主线程已退出.");
        }
        public void Stop() {
            mstart = false;
            StopMove(true);
        }
        public void BeginHomeReset(bool firstRun=false) {
            if (!firstRun)
            {
                StopMove();
                Thread.Sleep(500);
            }
            OpenAllServo();
            alarmType = 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("正在回原");
                    Take_Middle_Axis.HomeMove(ResetMoveInfo);
                    Take_UpDown_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);
                    ResetMoveInfo.log("正在回原");
                    Label_Z_Axis.HomeMove(ResetMoveInfo);
                    Take_Middle_Axis.AbsMove(ResetMoveInfo, Config.Take_Middle_P1, Config.Take_Middle_P1_speed);
                    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);
                    break;
                case MoveStep.H03_HomeReset:
                    ResetMoveInfo.NextMoveStep(MoveStep.H04_HomeReset);
                    ResetMoveInfo.log("正在回原");
                    Label_Z_Axis.HomeMove(ResetMoveInfo);
                    Label_X_Axis.HomeMove(ResetMoveInfo);
                    Label_Y_Axis.HomeMove(ResetMoveInfo);
                    Label_R_Axis.HomeMove(ResetMoveInfo);
                    break;
                case MoveStep.H04_HomeReset:
                    ResetMoveInfo.NextMoveStep(MoveStep.H05_HomeReset);
                    ResetMoveInfo.log("正在回原");
                    Label_Z_Axis.AbsMove(ResetMoveInfo, Config.Label_Z_P1, Config.Label_Z_P1_speed);
                    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);
                    Label_R_Axis.AbsMove(ResetMoveInfo, Config.Label_R_P1, Config.Label_R_P1_speed);
                    break;
                case MoveStep.H05_HomeReset:
                    ResetMoveInfo.NextMoveStep(MoveStep.HEND_HomeReset);
                    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();
                    MiddleMoveInfo.NewMove(MoveStep.M_Standby);
                    LabelMoveInfo.NewMove(MoveStep.Lbl01);
                    runStatus = RunStatus.Running;
                    break;
            }
        }
        public bool IgnoreSafecheck=false;
        public bool IgnoreGratingSignal = false;
        bool SafeCheck() {
            bool ok = true;
            if (UserPause)
            {
                Msg.add("用户暂停", MsgLevel.warning);
                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;

                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))
            {
                Msg.add("左后门没有关闭", MsgLevel.warning);
                if (!IgnoreSafecheck)
                    ok = false;
            }
            if (IOValue(IO_Type.RightBackDoor_Check).Equals(IO_VALUE.LOW))
            {
                Msg.add("右后门没有关闭", MsgLevel.warning);
                if (!IgnoreSafecheck)
                    ok = false;
            }
            return ok;
        }
        /// <summary>
        /// 最后一次气压检测变为0的时间
        /// </summary>
        DateTime lastAirCloseTime = DateTime.MinValue;
        

        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) {
                Msg.add("系统需要重置", MsgLevel.info);
                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)
            {
                foreach (ConfigMoveAxis configMoveAxis in Config.moveAxisList)
                {
                    if (AxisManager.GetAlarmStatus("", configMoveAxis.GetAxisValue()) == 1)
                    {
                        Msg.add($"{configMoveAxis.DeviceName}:运动报警", MsgLevel.warning);
                        ok = false;
                    }
                }
            }
            return ok;
        }



    }
}