public void Pick(RackGripper gripper = RackGripper.None, bool okToReloadConveyor = true)
        {
            OnInfoOccured(20016, "Find gripper for pick.");
            if (gripper == RackGripper.None)
            {
                gripper = GetAvailableGripper();
            }
            OnInfoOccured(20016, "About to pick phone on conveyor with gripper" + gripper + ".");

            if (LatestPhone != null)
            {
                if (LatestPhone.OnGripper != RackGripper.None)
                {
                    OnInfoOccured(20016, "Already got a phone in " + gripper + ".");
                    //Robot not release control on conveyor in this case.
                    OkToReloadOnConveyor();
                    return;
                }
            }
            else
            {
                throw new Exception("Phone is not ready.");
            }

            if (EcatIo.GetInput(Input.PickHasPhone) == false)
            {
                throw new Exception("No phone in pick position. Quit picking.");
            }

            RobotTakeControlOnConveyor();

            CheckGripperAvailable(gripper);

            Conveyor.ReadyForPicking();

            TargetPosition target = Motion.PickPosition;

            if (gripper == RackGripper.Two)
            {
                target.XPos = target.XPos + Motion.PickOffset.XPos;
            }

            MoveToTargetPosition(gripper, target, false, false);

            CloseGripper(gripper);
            MoveToPointTillEnd(Motion.MotorZ, Motion.PickPosition.ApproachHeight);

            CheckPhoneLost(gripper);

            MoveToPointTillEnd(Motion.MotorY, Motion.HomePosition.YPos);
            LatestPhone.OnGripper = gripper;

            if (okToReloadConveyor)
            {
                OkToReloadOnConveyor();
                RobotReleaseControlOnConveyor();
            }

            OnInfoOccured(20017, "Pick phone succeed.");
        }
        /// <summary>
        ///
        /// </summary>
        /// <see cref="Conveyor.Monitor"/>
        private void ConveyorManager()
        {
            while (true)
            {
                _conveyorWorkingManualResetEvent.WaitOne();

                try
                {
                    ConveyorIsBusy = true;
                    if (LatestPhone == null && Conveyor.PickBufferHasPhone)
                    {
                        if (OkToLetInNewPhone())
                        {
                            //if (ScannerOnline)
                            //{
                            //    if (Scanner.ScanSuccessful == false)
                            //    {
                            //        throw new Exception("Scan fail, please remove phone manually.");
                            //    }
                            //}
                            Conveyor.InposForPicking();

                            //Conveyor is still stop, so no new SN would enter, wrong SN would not happen.
                            AddNewPhone();
                        }
                    }

                    if (LatestPhone == null || Conveyor.PickBufferHasPhone == false || Conveyor.HasPlaceAPhone)
                    {
                        Conveyor.RunBeltPick();
                    }

                    if (LatestPhone != null && Conveyor.PickBufferHasPhone && Conveyor.HasPlaceAPhone == false)
                    {
                        Conveyor.StopBeltPick();
                        Delay(100);
                        Conveyor.ReadyForPicking();

                        _conveyorPickReadyManualResetEvent.Set();
                        _conveyorPickReadyManualResetEvent.WaitOne();
                    }
                }
                catch (Exception e)
                {
                    OnErrorOccured(40007, "Conveyor error:" + e.Message);
                    _conveyorWorkingManualResetEvent.Reset();
                }
                finally
                {
                    ConveyorIsBusy = false;
                }

                Delay(100);
            }
        }