Exemple #1
0
        void DoWork(RUN_MODE mode = RUN_MODE.ONCE)
        {
            if (InvokeRequired)
            {
                Invoke(new DoWorkDelegate(DoWork), mode);
            }
            else
            {
                string reason = (mode == RUN_MODE.MONITOR) ? "Display change detected" : "Applied settings";

                var res = Program.Run();
                if (res == ApplyResult.Success_WriteOK)
                {
                    FlashIcon(Constants.OK_ICON);
                    if (!Program.SilentMode)
                    {
                        ShowBalloon($"{reason}\n\nPowerPoint will output on display \"{Config.LoadConfig().GetShortName()}\"");
                    }
                }
                else if (res == ApplyResult.Fail_NotDetected)
                {
                    FlashIcon(Constants.NO_ICON);
                    if (!Program.SilentMode)
                    {
                        ShowBalloon($"Failed to apply settings\n\nDid not detect display \"{Config.LoadConfig().GetShortName()}\"");
                    }
                }
                else if (res == ApplyResult.Success_NoWriteNeeded)
                {
                    // no need for balloon, but flash the tray icon for assurance
                    FlashIcon(Constants.OK_ICON);
                }
            }
        }
    //训练神经网络
    private bool TrainNetwork()
    {
        mode = RUN_MODE.TRAINING;
        if (!(net.Train(data)))
        {
            return(false);
        }

        mode = RUN_MODE.ACTIVE;
        return(true);
    }
 //学习新的手势
 private void StartLearn()
 {
     if (mode == RUN_MODE.LEARNING)
     {
         //保存新的手势并重新训练网络
         print(vectors.Count);
         data.AddPattern(vectors, strName);
         numValidPatterns++;
         net = new NeuralNet(Useful.NUM_VECTORS * 2, numValidPatterns);
         RenewNetwork();
         mode = RUN_MODE.ACTIVE;
     }
 }
Exemple #4
0
        // Constructor
        public EventWatcher(RUN_MODE mode)
        {
            InitializeComponent();

            runMode = mode;

            Action <int> a = (arg) =>
            {
                DoWork(RUN_MODE.MONITOR);
            };

            debouncedWrapper = a.Debounce();
        }
    void Update()
    {
        txtError.text = "误差率:" + ((float)net.errorSum).ToString();
        if (Input.GetKeyDown(KeyCode.S))
        {
            mode   = RUN_MODE.SAVING;
            isShow = true;
        }
        if (Input.GetKeyDown(KeyCode.L))
        {
            mode = RUN_MODE.LEARNING;
        }
        if (Input.GetKeyDown(KeyCode.T))
        {
            //Thread oThread = new Thread(new ThreadStart(StartTrainNetWork));
            //oThread.Start();
            StartTrainNetWork();
        }

        if (Input.GetMouseButton(0))
        {
            Record();
        }
        else
        {
            mouseMode = MouseState.LEAVE;
        }

        if (Input.GetMouseButtonDown(0))
        {
            ClearRecord();
        }
        if (Input.GetMouseButtonUp(0))
        {
            if (mode == RUN_MODE.LEARNING)
            {
                if (Smooth())
                {
                    ShowSmoothPoint();
                    CreateVectors();
                }
                isShow = true;
            }
            else
            {
                StartMatch();
            }
        }
    }
Exemple #6
0
        //开始手势识别
        private bool StartMatch()
        {
            if (Smooth())
            {
                ShowSmoothPoint();
                CreateVectors();

                //识别
                if (Mode == RUN_MODE.ACTIVE)
                {
                    if (!TestForMatch())
                    {
                        MessageBox.Show("An internal error accured when matching!", "GestureStudy", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return(false);
                    }
                    else
                    {
                        ShowResult();
                    }
                }
                //学习
                else if (Mode == RUN_MODE.LEARNING)
                {
                    //保存新的手势并重新训练网络
                    if (MessageBox.Show("Do you want to save this gesture?", "GestureStudy", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        string name = Microsoft.VisualBasic.Interaction.InputBox("Name for this gesture?", "GestureStudy", "", this.Left + 100, this.Top + 100);
                        data.AddPattern(Vectors, name);
                        NumValidPatterns++;

                        net              = new NeuralNet(Useful.NUM_VECTORS * 2, NumValidPatterns, Useful.NUM_HIDDEN_NEURONS, Useful.LEARNING_RATE);
                        net.SendMessage += new NeuralNet.DelegateOfSendMessage(ShowMessage);

                        txtState.BackColor = Color.FromKnownColor(KnownColor.Control);
                        RenewNetwork();

                        Mode = RUN_MODE.ACTIVE;
                    }
                }
            }
            else
            {
                MessageBox.Show("Too few points captured, please draw line slowly!", "GestureStudy", MessageBoxButtons.OK, MessageBoxIcon.Information);
                Clear();
                ClearDraw();
            }

            return(true);
        }
Exemple #7
0
 //初始化数据
 private void InitData()
 {
     Mode             = RUN_MODE.UNREADY;
     NumValidPatterns = Useful.NUM_PATTERNS;
     NumSmoothPoints  = Useful.NUM_VECTORS + 1;
     HighestOutput    = 0.0;
     BestMatch        = -1;
     Match            = -1;
     RawPath          = new List <Point>();
     SmoothPath       = new List <Point>();
     Vectors          = new List <double>();
     data             = new GestureData(NumValidPatterns, Useful.NUM_VECTORS);
     net              = new NeuralNet(Useful.NUM_VECTORS * 2, NumValidPatterns, Useful.NUM_HIDDEN_NEURONS, Useful.LEARNING_RATE);
     net.SendMessage += new NeuralNet.DelegateOfSendMessage(ShowMessage);
 }
Exemple #8
0
        public void Run()
        {
            if (!isAcceptRun())
            {
                return;
            }
            if (nSeqNo != nPreSeqNo)
            {
                resetCmd();
            }
            nPreSeqNo = nSeqNo;

            CaseVTM seqCase = (CaseVTM)nSeqNo;

            alwaysCheck();

            RUN_MODE RunMode = RecipeMgr.Inst.TempRcp.eRunMode; //현재 레시피

            if (RunMode == RUN_MODE.ONLY_LAMI)
            {
                //현재 진행 모드가 라미 모드일 경우 진행하지 않기 위함
                return;
            }


            switch (seqCase)
            {
            case CaseVTM.Initialze:
                break;

            case CaseVTM.Check_Interlock:
                break;

            case CaseVTM.Check_Status:

                //웨이퍼 로딩 상태 확인
                ReqStatus = CheckStatusReqeust();
                if (ReqStatus == ReqStatus_VTM.LOADLOCK_LOAD)
                {
                    //Pickup Loadlock
                    Working_Arm = ARM.UPPER;
                    nextSeq(CaseVTM.Check_LL_Pickup);
                }
                else if (ReqStatus == ReqStatus_VTM.LOAD_PMC)
                {
                    //Load PMC Seq
                    Working_Arm = ARM.UPPER;
                    nextSeq(CaseVTM.Start_VTM_Load_PMC);
                }
                else if (ReqStatus == ReqStatus_VTM.UNLOAD_PMC)
                {
                    //Unload Seq
                    Working_Arm = ARM.LOWER;
                    nextSeq(CaseVTM.Start_VTM_Unload_PMC);
                }
                else if (ReqStatus == ReqStatus_VTM.UNLOAD_BONDED)
                {
                    Working_Arm = ARM.LOWER;

                    nextSeq(CaseVTM.Check_LL_Place);
                }
                else
                {
                    //요청이 없을 경우 대기하자
                }
                return;

            /////////////////////////////////
            //VTM Pickup LL -> Load PMC
            /////////////////////////////////

            case CaseVTM.Check_WaferStatus:
                break;


            case CaseVTM.Check_LL_Pickup:
                //Loadlock이 동작 중인지 확인
                if (GlobalVariable.interlock.bLLMoving)
                {
                    return;
                }
                GlobalVariable.interlock.bLLMoving = true;
                break;

            case CaseVTM.Move_LL_Move_Pickup:
                //Pickup LL
                //GlobalSeq.autoRun.procLoadlock.Move(MotionPos.Pos3);
                GlobalSeq.autoRun.procLoadlock.MoveExit((int)MotionPos.Pos3);

                strLog = string.Format("Loadlock VTM Pickup Move Start -> {0}, {1}", Working_Stage.ToString(), Working_Arm.ToString());
                AddMessage(strLog);
                break;

            case CaseVTM.Compl_LL_Move_Pickup:
                if (GlobalSeq.autoRun.procLoadlock.CheckMoveDone((int)MotionPos.Pos3) == false)
                {
                    return;
                }


                strLog = string.Format("Loadlock VTM Pickup Move End -> {0}, {1}", Working_Stage.ToString(), Working_Arm.ToString());
                AddMessage(strLog);
                break;


            case CaseVTM.Start_VTM_Pickup_LL:

                break;

            case CaseVTM.Set_Pumping_Pickup_LL:

                GlobalSeq.autoRun.prcVTM.Pmc.GetStatus(CTC_STATUS.CTCRunMode, ref status);
                if (status == (short)CTC_RunMode.ModeAtm)
                {
                    break;
                }

                //Loadlock Pumping 상태로 만든다.
                fRet = GlobalSeq.autoRun.procLoadlock.Loadlock_Pumping();
                if (fRet == fn.success)
                {
                    break;
                }
                else if (fRet == fn.busy)
                {
                    return;
                }
                else
                {
                    //Error
                    return;
                }

            case CaseVTM.Door_Open_Pickup_LL:

                //VTM Door Open
                GlobalVariable.io.VTM_Door_Open();
                break;

            case CaseVTM.Check_Open_Pickup_LL:

                //VTM Door Open Check
                if (GlobalVariable.io.Check_VTM_Door_Open() == false)
                {
                    //타임아웃 체크
                    return;
                }
                break;


            case CaseVTM.Move_VTM_Pickup_LL:

                Working_Stage = VtmStage.LL;
                Working_Arm   = ARM.UPPER;

                //VTM Pickup/Place 시 부분동작으로 변경 함

                if (GlobalSeq.autoRun.procLoadlock.SetBlock() == false)
                {
                    return;
                }
                MoveRobot(Working_Stage, Working_Arm, true);     //Arm Fold 이동
                //MoveRobot(Working_Stage, Working_Arm, false); //Arm Fold 이동

                strLog = string.Format("VTM Robot Pickup Move Start -> {0}, {1}", Working_Stage.ToString(), Working_Arm.ToString());
                AddMessage(strLog);
                break;

            case CaseVTM.Move_VTM_Pickup_LL_Check:
                if (CheckComplete() != fn.success)
                {
                    return;
                }
                break;

            case CaseVTM.Move_VTM_Pickup_LL_Stretch:
                //if (CheckComplete() != fn.success) return;
                MoveRobot_Stretch(Working_Stage, Working_Arm, UPDOWN_POS.DOWN);
                break;

            case CaseVTM.Move_VTM_Pickup_LL_Stretch_Check:
                if (CheckComplete() != fn.success)
                {
                    return;
                }
                break;

            case CaseVTM.Move_VTM_Pickup_LL_HandUp:
                MoveRobot_HandUp(Working_Stage, Working_Arm);
                break;

            case CaseVTM.Move_VTM_Pickup_LL_HandUp_Check:
                if (CheckComplete() != fn.success)
                {
                    return;
                }
                break;

            case CaseVTM.Move_VTM_Pickup_LL_Fold:
                MoveRobot_Fold(Working_Stage, Working_Arm, UPDOWN_POS.UP);
                break;

            case CaseVTM.Move_VTM_Pickup_LL_Fold_Check:
                if (CheckComplete() != fn.success)
                {
                    return;
                }
                GlobalSeq.autoRun.procLoadlock.UnBlock();
                break;

            case CaseVTM.Compl_VTM_Pickup_LL:

                strLog = string.Format("VTM Robot Pickup Move End -> {0}, {1}", Working_Stage.ToString(), Working_Arm.ToString());
                AddMessage(strLog);
                break;

            case CaseVTM.Door_Close_Pickup_LL:

                //VTM Door Close
                GlobalVariable.io.VTM_Door_Close();

                break;

            case CaseVTM.Check_Close_Pickup_LL:

                //VTM Door Close Check
                if (GlobalVariable.io.Check_VTM_Door_Close() == false)
                {
                    //타임아웃 체크
                    return;
                }
                break;

            case CaseVTM.End_VTM_Pickup_LL:
                GlobalVariable.seqShared.LoadingLoadLockToVtm(WaferType.CARRIER, (HAND)Working_Arm);
                //GlobalVariable.seqShared.LoadingLoadLockToVtm(WaferType.DEVICE, (HAND)Working_Arm);

                GlobalVariable.interlock.bLLMoving   = false;
                GlobalVariable.interlock.bLLUsed_VTM = false;     //Loadlock 사용 해제 Flag

                //Loadlock 픽업 후 리턴
                nextSeq(CaseVTM.Check_Interlock);
                break;

            /////////////////////////////////
            //VTM Load PMC
            /////////////////////////////////
            case CaseVTM.Start_VTM_Load_PMC:

                strLog = string.Format("VTM PMC Load Move Start -> {0}, {1}", Working_Stage.ToString(), Working_Arm.ToString());
                AddMessage(strLog);

                break;

            case CaseVTM.Set_Pumping_Load_PMC:

                GlobalSeq.autoRun.prcVTM.Pmc.GetStatus(CTC_STATUS.CTCRunMode, ref status);
                if (status == (short)CTC_RunMode.ModeAtm)
                {
                    break;
                }

                //PMC에 Vacuum 상태를 확인한다.
                fRet = GlobalSeq.autoRun.procLoadlock.VTM_Pumping();
                if (fRet == fn.success)
                {
                    break;
                }
                else if (fRet == fn.busy)
                {
                    return;
                }
                else
                {
                    //Error
                    return;
                }

            ////Convectron Sensor On Check
            //if (GlobalVariable.io.ReadInput(GlobalVariable.io.I_VacuumTm_ConvectronRy_1) == true
            //    && GlobalVariable.io.ReadInput(GlobalVariable.io.I_VacuumTm_ConvectronRy_2) == true)
            //{
            //    //조건이 맞으면 다음 케이스로 넘긴다
            //    break;
            //}
            //else
            //{
            //    //Error
            //    return;
            //}

            case CaseVTM.Door_Open_Load_PMC:

                //PMC Door Open
                GlobalVariable.io.BD_Door_Open();
                break;

            case CaseVTM.Check_Open_Load_PMC:

                //PMC Door Open Check
                if (GlobalVariable.io.Check_BD_Door_Open() == false)
                {
                    //타임아웃 체크
                    return;
                }
                break;

            case CaseVTM.Move_VTM_Load_PMC:
                if (Load_PMC(Working_Arm) != fn.success)
                {
                    return;
                }
                break;

            case CaseVTM.Compl_VTM_Load_PMC:
                break;

            case CaseVTM.Door_Close_Load_PMC:

                //PMC Door Close
                GlobalVariable.io.BD_Door_Close();

                break;

            case CaseVTM.Check_Close_Load_PMC:

                //PMC Door Close Check
                if (GlobalVariable.io.Check_BD_Door_Close() == false)
                {
                    //타임아웃 체크
                    return;
                }
                break;

            case CaseVTM.End_VTM_Load_PMC:
                GlobalVariable.seqShared.LoadingVtmToBonder((HAND)Working_Arm);

                strLog = string.Format("VTM PMC Load Move End -> {0}, {1}", Working_Stage.ToString(), Working_Arm.ToString());
                AddMessage(strLog);
                break;

            case CaseVTM.Set_Recipe:

                break;

            case CaseVTM.Start_Process:

                //Set Process Start
                GlobalVariable.interlock.bBondingProcess = true;

                strLog = string.Format("Pmc Process On -> {0}, {1}", Working_Stage.ToString(), Working_Arm.ToString());
                AddMessage(strLog);

                nextSeq(CaseVTM.Check_Interlock);
                return;


            /////////////////////////////////
            //VTM Unload PMC
            /////////////////////////////////
            case CaseVTM.Start_VTM_Unload_PMC:

                strLog = string.Format("VTM PMC Unload Move Start -> {0}, {1}", Working_Stage.ToString(), Working_Arm.ToString());
                AddMessage(strLog);
                break;

            case CaseVTM.Set_Pumping_Unload_PMC:

                GlobalSeq.autoRun.prcVTM.Pmc.GetStatus(CTC_STATUS.CTCRunMode, ref status);
                if (status == (short)CTC_RunMode.ModeAtm)
                {
                    break;
                }

                //PMC에 Vacuum 상태를 확인한다.
                fRet = GlobalSeq.autoRun.procLoadlock.VTM_Pumping();
                if (fRet == fn.success)
                {
                    break;
                }
                else if (fRet == fn.busy)
                {
                    return;
                }
                else
                {
                    //Error
                    return;
                }

            case CaseVTM.Door_Open_Unload_PMC:

                //PMC Door Open
                GlobalVariable.io.BD_Door_Open();

                break;

            case CaseVTM.Check_Open_Unload_PMC:

                //PMC Door Open Check
                if (GlobalVariable.io.Check_BD_Door_Open() == false)
                {
                    //타임아웃 체크
                    return;
                }
                break;

            case CaseVTM.Move_VTM_Unload_PMC:
                Working_Arm = ARM.LOWER;     //언로드 시 Lower Hand
                if (Unload_PMC(Working_Arm) != fn.success)
                {
                    return;
                }

                strLog = string.Format("VTM PMC Unload Move End -> {0}, {1}", Working_Stage.ToString(), Working_Arm.ToString());
                AddMessage(strLog);
                break;

            case CaseVTM.Compl_VTM_Unload_PMC:
                break;

            case CaseVTM.Door_Close_Unload_PMC:

                //Door Close
                GlobalVariable.io.BD_Door_Close();
                break;

            case CaseVTM.Check_Close_Unload_PMC:

                //Door Close Check
                if (GlobalVariable.io.Check_BD_Door_Close() == false)
                {
                    //타임아웃 체크
                    return;
                }
                break;

            case CaseVTM.End_VTM_Unload_PMC:

                //데이터 이동
                GlobalVariable.seqShared.LoadingBonderToVtm((HAND)Working_Arm);

                nextSeq(CaseVTM.Check_Interlock);
                return;

            case CaseVTM.Check_LL_Place:
                //Loadlock이 동작 중인지 확인
                if (GlobalVariable.interlock.bLLMoving)
                {
                    return;
                }
                GlobalVariable.interlock.bLLMoving   = true;
                GlobalVariable.interlock.bLLUsed_VTM = true;     //Loadlock 사용 Flag

                break;

            case CaseVTM.Move_LL_Move_Place:
                //BD Place -> Unload
                //GlobalSeq.autoRun.procLoadlock.Move(MotionPos.Pos1);
                GlobalSeq.autoRun.procLoadlock.MoveExit((int)MotionPos.Pos1);

                strLog = string.Format("Loadlock VTM Place Move Start -> {0}, {1}", Working_Stage.ToString(), Working_Arm.ToString());
                AddMessage(strLog);
                break;

            case CaseVTM.Compl_LL_Move_Place:
                // if (GlobalSeq.autoRun.procLoadlock.CheckComplete() != fn.success) return;
                if (GlobalSeq.autoRun.procLoadlock.CheckMoveDone((int)MotionPos.Pos1) == false)
                {
                    return;
                }

                strLog = string.Format("Loadlock VTM Place Move End -> {0}, {1}", Working_Stage.ToString(), Working_Arm.ToString());
                AddMessage(strLog);
                break;

            case CaseVTM.Start_VTM_Place_LL:
                if (Working_Arm != ARM.LOWER)
                {
                    //Hand Fail
                    return;
                }
                break;

            case CaseVTM.Set_Pumping_Place_LL:

                GlobalSeq.autoRun.prcVTM.Pmc.GetStatus(CTC_STATUS.CTCRunMode, ref status);
                if (status == (short)CTC_RunMode.ModeAtm)
                {
                    break;
                }

                //Loadlock Pumping 상태로 만든다.
                fRet = GlobalSeq.autoRun.procLoadlock.Loadlock_Pumping();
                if (fRet == fn.success)
                {
                    break;
                }
                else if (fRet == fn.busy)
                {
                    return;
                }
                else
                {
                    //Error
                    return;
                }

            case CaseVTM.Door_Open_Place_LL:

                //VTM Door Open
                GlobalVariable.io.VTM_Door_Open();

                break;

            case CaseVTM.Check_Open_Place_LL:

                //VTM Door Open Check
                if (GlobalVariable.io.Check_VTM_Door_Open() == false)
                {
                    //타임아웃 체크
                    return;
                }
                break;

            case CaseVTM.Move_VTM_Place_LL:
                Working_Stage = VtmStage.Bonded;
                if (GlobalSeq.autoRun.procLoadlock.SetBlock() == false)
                {
                    return;
                }
                //MoveRobot(Working_Stage, Working_Arm, false);

                MoveRobot(Working_Stage, Working_Arm, true);     //Hand Fold 이동

                strLog = string.Format("VTM Robot Place Move Start -> {0}, {1}", Working_Stage.ToString(), Working_Arm.ToString());
                AddMessage(strLog);
                break;

            case CaseVTM.Move_VTM_Place_LL_Check:
                if (CheckComplete() != fn.success)
                {
                    return;
                }
                break;

            case CaseVTM.Move_VTM_Place_LL_Stretch:
                MoveRobot_Stretch(Working_Stage, Working_Arm, UPDOWN_POS.UP);
                break;

            case CaseVTM.Move_VTM_Place_LL_Stretch_Check:
                if (CheckComplete() != fn.success)
                {
                    return;
                }
                break;

            case CaseVTM.Move_VTM_Place_LL_HandDown:
                MoveRobot_HandDown(Working_Stage, Working_Arm);
                break;

            case CaseVTM.Move_VTM_Place_LL_HandDown_Check:
                if (CheckComplete() != fn.success)
                {
                    return;
                }
                break;

            case CaseVTM.Move_VTM_Place_LL_Fold:
                MoveRobot_Fold(Working_Stage, Working_Arm, UPDOWN_POS.DOWN);
                break;

            case CaseVTM.Move_VTM_Place_LL_Fold_Check:
                if (CheckComplete() != fn.success)
                {
                    return;
                }
                GlobalSeq.autoRun.procLoadlock.UnBlock();
                break;

            case CaseVTM.Compl_VTM_Place_LL:
                strLog = string.Format("VTM Robot Place Move End -> {0}, {1}", Working_Stage.ToString(), Working_Arm.ToString());
                AddMessage(strLog);
                break;

            case CaseVTM.Door_Close_Place_LL:

                //VTM Door Close
                GlobalVariable.io.VTM_Door_Close();
                break;

            case CaseVTM.Check_Close_Place_LL:

                //VTM Door Close Check
                if (GlobalVariable.io.Check_VTM_Door_Close() == false)
                {
                    //타임아웃 체크
                    return;
                }
                break;


            case CaseVTM.End_VTM_Place_LL:
                //데이터 이동
                GlobalVariable.seqShared.LoadingVtmToLoadlock(WaferType.BONDED, (HAND)Working_Arm);
                GlobalVariable.interlock.bLLMoving = false;

                //본딩 완료 된 웨이퍼 LL에 언로딩 하고
                //LL에 투입된 웨이퍼 있는지 확인
                //있으면 Pickup 하자, Exchange

                if (GlobalVariable.seqShared.IsInLoadLock((int)WaferType.DEVICE) == true &&
                    GlobalVariable.seqShared.IsInLoadLock((int)WaferType.CARRIER) == true &&
                    GlobalVariable.seqShared.IsInVTM(HAND.UPPER) == false)
                {
                    //Pickup Loadlock
                    Working_Arm = ARM.UPPER;
                    nextSeq(CaseVTM.Check_LL_Pickup);
                    return;
                }
                else
                {
                    //Loadlock 사용 해제
                    GlobalVariable.interlock.bLLUsed_VTM = false;
                    nextSeq(CaseVTM.Check_Interlock);
                    return;
                }
                return;
            }
            nSeqNo++;
        }
Exemple #9
0
 private void btnLearn_Click(object sender, EventArgs e)
 {
     Mode               = RUN_MODE.LEARNING;
     txtState.Text      = "Learning";
     txtState.BackColor = Color.Yellow;
 }
Exemple #10
0
        public void Run()
        {
            if (!isAcceptRun())
            {
                return;
            }
            if (nSeqNo != nPreSeqNo)
            {
                resetCmd();
            }
            nPreSeqNo = nSeqNo;

            CaseFM seqCase = (CaseFM)nSeqNo;

            //test
            int nRetV = 0;


            alwaysCheck();

            switch (seqCase)
            {
            case CaseFM.Initialze:
                break;

            case CaseFM.Check_Interlock:

                //임시 테스트, 웨이퍼 2장만 진행하기 위함
                //if (nWaferCount >= 2) return;
                //strLog = seqCase.ToString();
                //AddMessage(strLog);
                break;

            case CaseFM.Start_LPM_Load:

                if (bLPM_Load[(int)EFEM.LPMA] && bLPM_Load[(int)EFEM.LPMC])
                {
                    //이미 LPM 로드 상태면 진행하지 않는다
                    nextSeq((int)CaseFM.Check_Status);
                    return;
                }
                break;

            case CaseFM.Move_LPM_Load:

                if (bLPM_Load[(int)EFEM.LPMA] == false)
                {
                    //로드 전 Flag 초기화
                    LpmRoot.InitMappingFlag(EFEM.LPMA);
                    LoadLPM(EFEM.LPMA);
                }
                if (bLPM_Load[(int)EFEM.LPMC] == false)
                {
                    LpmRoot.InitMappingFlag(EFEM.LPMC);
                    LoadLPM(EFEM.LPMC);
                }

                Thread.Sleep(500);     //Load Delay
                break;

            case CaseFM.Compl_LPM_Load:
                if (CheckLoad_LPM(EFEM.LPMA) != fn.success)
                {
                    return;
                }
                break;

            case CaseFM.End_LPM_Load:
                if (CheckLoad_LPM(EFEM.LPMC) != fn.success)
                {
                    return;
                }
                break;

            case CaseFM.LPM_Mapping_Data:

                //로드 시 Scan한 Map Data 연결
                break;

            case CaseFM.Check_Status_Load_A:

                //Status를 체크 할 경우 LPM Alarm이 발생함,
                //테스트 시 제거 후 진행 함
                //LpmRoot.GetStatus(EFEM.LPMA);
                break;

            case CaseFM.Compl_Status_Load_A:
                //if (CheckLoad_LPM(EFEM.LPMA) != fn.success) return;
                break;

            case CaseFM.End_Status_Load_A:

#if _REAL_MC
                //LPM Load 후 Mapping Flag가 변경되면 완료
                if (LpmRoot.GetMappingComplete(EFEM.LPMA) == false)
                {
                    return;
                }
                if (LpmRoot.GetMappingComplete(EFEM.LPMC) == false)
                {
                    return;
                }
#endif

                bLPM_Load[(int)EFEM.LPMA] = true;
                bLPM_Load[(int)EFEM.LPMC] = true;
                break;

            case CaseFM.Check_Status:

                RUN_MODE RunMode = RecipeMgr.Inst.TempRcp.eRunMode;     //현재 레시피
                if (RunMode == RUN_MODE.FULL || RunMode == RUN_MODE.ONLY_BOND)
                {
                    //FULL Mode
                    if (nWaferCount % 2 == 0)
                    {
                        Working_LPM = EFEM.LPMA;
                        efemType    = EFEM_TYPE.A_CARRIER;
                    }
                    else
                    {
                        Working_LPM = EFEM.LPMC;
                        efemType    = EFEM_TYPE.C_DEVICE;
                    }
                }
                else if (RunMode == RUN_MODE.ONLY_LAMI)
                {
                    //Only Lami 일경우 Carrier 고정 사용
                    Working_LPM = EFEM.LPMA;
                    efemType    = EFEM_TYPE.A_CARRIER;
                }
                else
                {
                    return;
                }

                //Next Wafer Slot 유/무 확인
                GlobalVariable.WaferInfo.nWaferLoadSlot[(int)Working_LPM] = LpmRoot.GetNextWaferSlot(Working_LPM, LPMStatus.Load, COUNT.MAX_PORT_SLOT);
                if (GlobalVariable.WaferInfo.nWaferLoadSlot[(int)Working_LPM] < 0)
                {
                    //Wafer Empty
                    //더이상 투입할 웨이퍼가 없을경우 언로딩 시퀀스로 보낸다
                    nextSeq((int)CaseFM.Check_Unload_Wafer);
                    return;
                }
                break;

            case CaseFM.Start_FM_Pickup_LPM:
                //FM 로봇 상태 확인
                //FM 로봇 웨이퍼 상태 확인

                //웨이퍼 택타임 측정 시작 시간
                if (Working_LPM == EFEM.LPMA)
                {
                    GlobalVariable.seqShared.carrierArray1[GlobalVariable.WaferInfo.nWaferLoadSlot[(int)Working_LPM]].strTotalSt = DateTime.Now.ToString("hh:mm:ss.fff");
                }
                else if (Working_LPM == EFEM.LPMB)
                {
                    GlobalVariable.seqShared.carrierArray2[GlobalVariable.WaferInfo.nWaferLoadSlot[(int)Working_LPM]].strTotalSt = DateTime.Now.ToString("hh:mm:ss.fff");
                }
                else if (Working_LPM == EFEM.LPMC)
                {
                    GlobalVariable.seqShared.deviceArray1[GlobalVariable.WaferInfo.nWaferLoadSlot[(int)Working_LPM]].strTotalSt = DateTime.Now.ToString("hh:mm:ss.fff");
                }
                else if (Working_LPM == EFEM.LPMD)
                {
                    GlobalVariable.seqShared.deviceArray2[GlobalVariable.WaferInfo.nWaferLoadSlot[(int)Working_LPM]].strTotalSt = DateTime.Now.ToString("hh:mm:ss.fff");
                }

                break;

            case CaseFM.Move_FM_Pickup_LPM:

                fmStatus      = FMStatus.LPM_LOAD;
                Working_Stage = (FMStage)Working_LPM + 1;                                      //현재 LPM을 작업 할 Stage로 변경
                nWorking_Slot = GlobalVariable.WaferInfo.nWaferLoadSlot[(int)Working_LPM] + 1; //현재 작업할 Wafer Slot
                Working_Arm   = ARM.UPPER;
                MoveFmRobot(Working_Stage, nWorking_Slot, Working_Arm, fmStatus);

                strLog = string.Format("FmRobot Pickup Move Start -> {0}, {1}, {2}", Working_Stage.ToString(), nWorking_Slot, Working_Arm.ToString());
                AddMessage(strLog);
                break;

            case CaseFM.Compl_FM_Pickup_LPM:
                if (CheckCompl_FM() != fn.success)
                {
                    return;
                }

                //nRetV = CheckCompl_FM();
                //f(nRetV == err )

                strLog = string.Format("FmRobot Pickup Move End -> {0}, {1}, {2}", Working_Stage.ToString(), nWorking_Slot, Working_Arm.ToString());
                AddMessage(strLog);
                break;

            case CaseFM.End_FM_Pickup_LPM:
                GlobalSeq.autoRun.prcFM.LpmRoot.SetWaferInfo(Working_LPM, nWorking_Slot - 1, false);   //웨이퍼 맵핑 데이터 갱신
                GlobalVariable.seqShared.LoadingEfemToFm(efemType, nWorking_Slot - 1, (HAND)Working_Arm);

                nWaferCount++;
                break;

            case CaseFM.Waiting_AL:

                if (GlobalVariable.seqShared.IsInAligner() ||
                    GlobalVariable.interlock.bAlignMoving == true)
                {
                    //Alinger에 Wafer가 아직 있으면 대기 하도록 하자
                    return;
                }
                break;

            case CaseFM.Start_FM_Place_AL:
                break;

            case CaseFM.Move_FM_Place_AL:
                fmStatus      = FMStatus.BUFFER_LOAD;
                Working_Stage = FMStage.AL;
                nWorking_Slot = 1;
                Working_Arm   = ARM.UPPER;
                MoveFmRobot(Working_Stage, nWorking_Slot, Working_Arm, fmStatus);

                strLog = string.Format("FmRobot Place Move Start -> {0}, {1}, {2}", Working_Stage.ToString(), nWorking_Slot, Working_Arm.ToString());
                AddMessage(strLog);
                break;

            case CaseFM.Compl_FM_Place_AL:
                if (CheckCompl_FM() != fn.success)
                {
                    return;
                }

                strLog = string.Format("FmRobot Place Move End -> {0}, {1}, {2}", Working_Stage.ToString(), nWorking_Slot, Working_Arm.ToString());
                AddMessage(strLog);
                break;

            case CaseFM.End_FM_Place_AL:
                GlobalVariable.seqShared.LoadingFmToAligner((HAND)Working_Arm);
                GlobalVariable.interlock.bAlignMoving = true;     //얼라인 동작
                break;

            case CaseFM.Check_Unload_Wafer:
                //CP에 언로드 할 웨이퍼가 있는지 확인
                if (GlobalVariable.seqShared.IsInCP(0) == false)
                {
                    nextSeq((int)CaseFM.Initialze);
                    return;
                }
                break;

//////////////////////////////////////
//Wafer Unload
/////////////////////////////////////
            case CaseFM.Start_FM_Pickup_CP:
                //CP 웨이퍼 감지 센서 확인 필요!
                break;

            case CaseFM.Move_FM_Pickup_CP:
                fmStatus      = FMStatus.BUFFER_UNLOAD;
                Working_Stage = FMStage.CP1;
                nWorking_Slot = 1;
                Working_Arm   = ARM.LOWER;   //CP에서 언로딩 시에는 LOW ARM 사용하자
                MoveFmRobot(Working_Stage, nWorking_Slot, Working_Arm, fmStatus);

                strLog = string.Format("FmRobot Pickup Move Start -> {0}, {1}, {2}", Working_Stage.ToString(), nWorking_Slot, Working_Arm.ToString());
                AddMessage(strLog);
                break;

            case CaseFM.Compl_FM_Pickup_CP:
                if (CheckCompl_FM() != fn.success)
                {
                    return;
                }

                strLog = string.Format("FmRobot Pickup Move End -> {0}, {1}, {2}", Working_Stage.ToString(), nWorking_Slot, Working_Arm.ToString());
                AddMessage(strLog);
                break;

            case CaseFM.End_FM_Pickup_cp:
                GlobalVariable.seqShared.LoadingCpToFm(0, (HAND)Working_Arm);
                break;

            case CaseFM.Start_FM_Place_LPM:

                //완료 웨이퍼 언로딩 시 LPM A부터 채워넣자
                Working_LPM = EFEM.LPMA;

                //LPM 상태를 확인하자
                if (CheckLoad_LPM(Working_LPM) != fn.success)
                {
                    //로드 상태가 아니면 에러
                    return;
                }

                //Unload Slot Check
                //Next Wafer Slot 유/무 확인
                GlobalVariable.WaferInfo.nWaferUnloadSlot[(int)Working_LPM] = LpmRoot.GetNextWaferSlot(Working_LPM, LPMStatus.Unload, COUNT.MAX_PORT_SLOT);
                if (GlobalVariable.WaferInfo.nWaferUnloadSlot[(int)Working_LPM] < 0)
                {
                    //Wafer Empty
                    return;
                }

                break;

            case CaseFM.Move_FM_Place_LPM:
                fmStatus      = FMStatus.LPM_UNLOAD;
                Working_Stage = (FMStage)Working_LPM + 1;
                nWorking_Slot = GlobalVariable.WaferInfo.nWaferUnloadSlot[(int)Working_LPM] + 1; //현재 작업할 Wafer Slot
                Working_Arm   = ARM.LOWER;                                                       //CP에서 언로딩 시에는 LOW ARM 사용하자
                MoveFmRobot(Working_Stage, nWorking_Slot, Working_Arm, fmStatus);

                strLog = string.Format("FmRobot Place Move Start -> {0}, {1}, {2}", Working_Stage.ToString(), nWorking_Slot, Working_Arm.ToString());
                AddMessage(strLog);
                break;

            case CaseFM.Compl_FM_Place_LPM:
                if (CheckCompl_FM() != fn.success)
                {
                    return;
                }

                strLog = string.Format("FmRobot Place Move End -> {0}, {1}, {2}", Working_Stage.ToString(), nWorking_Slot, Working_Arm.ToString());
                AddMessage(strLog);
                break;

            case CaseFM.End_FM_Place_LPM:

                GlobalVariable.seqShared.LoadingFmToEfem(EFEM_TYPE.A_CARRIER, nWorking_Slot - 1, (HAND)Working_Arm);

                //Wafer Unload 후 Data 변경
                GlobalSeq.autoRun.prcFM.LpmRoot.SetUnloadSlot(Working_LPM, nWorking_Slot - 1, true);



                if (Working_LPM == EFEM.LPMA)
                {
                    GlobalVariable.seqShared.carrierArray1[GlobalVariable.WaferInfo.nWaferUnloadSlot[(int)Working_LPM]].strTotalEnd = DateTime.Now.ToString("hh:mm:ss.fff");
                }
                else if (Working_LPM == EFEM.LPMB)
                {
                    GlobalVariable.seqShared.carrierArray2[GlobalVariable.WaferInfo.nWaferUnloadSlot[(int)Working_LPM]].strTotalEnd = DateTime.Now.ToString("hh:mm:ss.fff");
                }
                else if (Working_LPM == EFEM.LPMC)
                {
                    GlobalVariable.seqShared.deviceArray1[GlobalVariable.WaferInfo.nWaferUnloadSlot[(int)Working_LPM]].strTotalEnd = DateTime.Now.ToString("hh:mm:ss.fff");
                }
                else if (Working_LPM == EFEM.LPMD)
                {
                    GlobalVariable.seqShared.deviceArray2[GlobalVariable.WaferInfo.nWaferUnloadSlot[(int)Working_LPM]].strTotalEnd = DateTime.Now.ToString("hh:mm:ss.fff");
                }

                nextSeq((int)CaseFM.Initialze);
                return;


///////////////////////////////////
//LPM Unload
//////////////////////////////////

            case CaseFM.Start_LPM_Unload:
                break;

            case CaseFM.Move_LPM_Unload:
                UnloadLPM(Working_LPM);
                break;

            case CaseFM.Check_Status_Unload:
                LpmRoot.GetStatus(Working_LPM);
                break;

            case CaseFM.Compl_LPM_Unload:
                if (CheckUnload_LPM(Working_LPM) != fn.success)
                {
                    return;
                }
                break;

            case CaseFM.End_LPM_Unload:

                //처음 case로
                nextSeq((int)CaseFM.Initialze);
                return;
            }

            nSeqNo++;
        }