Sfoglia il codice sorgente

Improved TM Transfer and Robot Arm, updated and uploaded SeTMViewModel.cs、VenusSeOperationOverView.cs、HongHuVR.cs、SETMEntity.cs、Generic、SERobot.cs、SEMFPMRetractRoutine.cs、SEMFPMExtendRoutine.cs.

intern02 1 anno fa
parent
commit
d308f9a645

+ 452 - 42
Venus/Venus_MainPages/ViewModels/SeTMViewModel.cs

@@ -1,9 +1,11 @@
 using Aitex.Sorter.Common;
+using MECF.Framework.Common.CommonData;
 using MECF.Framework.Common.DataCenter;
 using MECF.Framework.Common.Equipment;
 using MECF.Framework.Common.OperationCenter;
 using MECF.Framework.Common.Schedulers;
 using OpenSEMI.ClientBase;
+using OpenSEMI.Ctrlib.Controls;
 using Prism.Commands;
 using Prism.Mvvm;
 using System;
@@ -16,42 +18,54 @@ using System.Windows.Threading;
 using Venus_Core;
 using Venus_MainPages.Unity;
 using Venus_Themes.CustomControls;
+using static Venus_Themes.CustomControls.SERobot;
 
 namespace Venus_MainPages.ViewModels
 {
     public enum SeTMModule
     {
-        PMA, PMB, PMC, VCE1, Aligner
+        PMA, PMB, PMC, VCE1, VPA
     }
     public enum SeTMBlade
     {
         Blade1, Blade2
     }
-    internal class SeTMViewModel : BindableBase
+    public class SeTMViewModel : BindableBase
     {
         #region 私有字段
-        private ModuleInfo m_VCE1ModuleInfo;
-        private ModuleInfo m_AlignerModuleInfo;
+        public double m_VPAangle;
+
+        private ModuleInfo m_VCEModuleInfo;
+        private ModuleInfo m_VPAModuleInfo;
         private ModuleInfo m_TMModuleInfo;
 
         //Wafer
         private WaferInfo m_PMAWafer;
         private WaferInfo m_PMBWafer;
         private WaferInfo m_PMCWafer;
+        public WaferInfo m_RobotUpperWafer;
+        public WaferInfo m_RobotLowerWafer;
+        public WaferInfo m_PAWafer;
+
         //Door
         private bool m_PMADoorIsOpen;
         private bool m_PMBDoorIsOpen;
         private bool m_PMCDoorIsOpen;
-        private bool m_VCE1DoorIsOpen;
+        private bool m_VCEDoorIsOpen;
+        private bool m_VCEOutDoorIsOpen;
+
         //Pick、Place、Extend、Retract行下拉框内容
         private SeTMModule m_PickSelectedModule;
         private SeTMModule m_PlaceSelectedModule;
         private SeTMModule m_ExtendSelectedModule;
         private SeTMModule m_RetractSelectedModule;
+        private SeTMModule m_GotoSelectedModule;
         private SeTMBlade m_PickSelectedBlade;
         private SeTMBlade m_PlaceSelectedBlade;
         private SeTMBlade m_ExtendSelectedBlade;
         private SeTMBlade m_RetractSelectedBlade;
+        private SeTMBlade m_GoToSelectedBlade;
+
 
         //Pick、Place、Extend、Retract行下拉框关联
         private ObservableCollection<int> m_PickSoltItemsSource = new ObservableCollection<int>();
@@ -70,14 +84,37 @@ namespace Venus_MainPages.ViewModels
         private bool m_PMAIsInstalled;
         private bool m_PMBIsInstalled;
         private bool m_PMCIsInstalled;
-        private bool m_VCE1IsInstalled;
-        private bool m_AlignerIsInstalled;
-        private bool m_VCEOutDoorIsOpen;
+        private bool m_VCEIsInstalled;
+        private bool m_VPAIsInstalled;
         private Dictionary<string, object> m_RtDataValues = new Dictionary<string, object>();
         private List<string> m_RtDataKeys = new List<string>();
+
+        //Robot动画
+        private SERobotTAction m_SERobotTAction;
+        private SERobotTAction m_Robot1TAction;
+        private SERobotXAction m_Robot1XAction;
+        private SERobotTAction m_Robot2TAction;
+        private SERobotXAction m_Robot2XAction;
+        public RobotMoveInfo m_robotMoveInfo;
+        //Cycle
+        private List<string> m_OriginalCycle = new List<string>();
+        private List<string> m_ToCycle = new List<string>();
+        private bool m_CycleEnable;
+
+        private bool m_PMAIsCycle;
+        private bool m_PMBIsCycle;
+        private bool m_PMCIsCycle;
+
+        private int m_CycleCount;
+
         #endregion
 
         #region 属性
+        public double VPAangle
+        {
+            get { return m_VPAangle; }
+            set { SetProperty(ref m_VPAangle, value); }
+        }
         public WaferInfo PMAWafer
         {
             get { return m_PMAWafer; }
@@ -93,15 +130,25 @@ namespace Venus_MainPages.ViewModels
             get { return m_PMCWafer; }
             set { SetProperty(ref m_PMCWafer, value); }
         }
+        public WaferInfo RobotUpperWafer
+        {
+            get { return m_RobotUpperWafer; }
+            set { SetProperty(ref m_RobotUpperWafer, value); }
+        }
 
-        public bool VCE1DoorIsOpen
+        public WaferInfo RobotLowerWafer
         {
-            get => m_VCE1DoorIsOpen;
-            set
-            {
-                SetProperty(ref m_VCE1DoorIsOpen,value);
-            }
+            get { return m_RobotLowerWafer; }
+            set { SetProperty(ref m_RobotLowerWafer, value); }
+        }
+        public WaferInfo PAWafer
+        {
+            get { return m_PAWafer; }
+            set { SetProperty(ref m_PAWafer, value); }
         }
+        public bool VCEDoorIsOpen { get => m_VCEDoorIsOpen; set => SetProperty(ref m_VCEDoorIsOpen, value); }
+        public bool VCEOutDoorIsOpen { get => m_VCEOutDoorIsOpen; set => SetProperty(ref m_VCEOutDoorIsOpen, value); }
+
 
         public bool PMCDoorIsOpen
         {
@@ -122,20 +169,20 @@ namespace Venus_MainPages.ViewModels
             get { return m_PMBDoorIsOpen; }
             set { SetProperty(ref m_PMBDoorIsOpen, value); }
         }
-        public ModuleInfo VCE1ModuleInfo
+        public ModuleInfo VCEModuleInfo
         {
-            get { return m_VCE1ModuleInfo; }
+            get { return m_VCEModuleInfo; }
             set
             {
-                SetProperty(ref m_VCE1ModuleInfo, value);
+                SetProperty(ref m_VCEModuleInfo, value);
             }
         }
-        public ModuleInfo AlignerModuleInfo
+        public ModuleInfo VPAModuleInfo
         {
-            get { return m_AlignerModuleInfo; }
+            get { return m_VPAModuleInfo; }
             set
             {
-                SetProperty(ref m_AlignerModuleInfo, value);
+                SetProperty(ref m_VPAModuleInfo, value);
             }
         }
         public Dictionary<string, object> RtDataValues
@@ -144,7 +191,6 @@ namespace Venus_MainPages.ViewModels
             set { SetProperty(ref m_RtDataValues, value); }
         }
 
-        public bool VCEOutDoorIsOpen { get => m_VCEOutDoorIsOpen; set => SetProperty(ref m_VCEOutDoorIsOpen, value); }
         public bool PMAIsInstalled
         {
             get { return m_PMAIsInstalled; }
@@ -160,15 +206,15 @@ namespace Venus_MainPages.ViewModels
             get { return m_PMCIsInstalled; }
             set { SetProperty(ref m_PMCIsInstalled, value); }
         }
-        public bool VCE1IsInstalled
+        public bool VCEIsInstalled
         {
-            get { return m_VCE1IsInstalled; }
-            set { SetProperty(ref m_VCE1IsInstalled, value); }
+            get { return m_VCEIsInstalled; }
+            set { SetProperty(ref m_VCEIsInstalled, value); }
         }
-        public bool AlignerIsInstalled
+        public bool VPAIsInstalled
         {
-            get { return m_AlignerIsInstalled; }
-            set { SetProperty(ref m_AlignerIsInstalled, value); }
+            get { return m_VPAIsInstalled; }
+            set { SetProperty(ref m_VPAIsInstalled, value); }
         }
 
         public List<SeTMModule> TMModules
@@ -198,6 +244,11 @@ namespace Venus_MainPages.ViewModels
             get { return m_RetractSelectedModule; }
             set { SetProperty(ref m_RetractSelectedModule, value); }
         }
+        public SeTMModule GotoSelectedModule
+        {
+            get { return m_GotoSelectedModule; }
+            set { SetProperty(ref m_GotoSelectedModule, value); }
+        }
         public ModuleInfo TMModuleInfo
         {
             get { return m_TMModuleInfo; }
@@ -227,6 +278,12 @@ namespace Venus_MainPages.ViewModels
             get { return m_RetractSelectedBlade; }
             set { SetProperty(ref m_RetractSelectedBlade, value); }
         }
+        public SeTMBlade GoToSelectedBlade
+        {
+            get { return m_GoToSelectedBlade; }
+            set { SetProperty(ref m_GoToSelectedBlade, value); }
+        }
+
         public ObservableCollection<int> PickSoltItemsSource
         {
             get { return m_PickSoltItemsSource; }
@@ -267,6 +324,77 @@ namespace Venus_MainPages.ViewModels
             get { return m_RetractSoltSelectedIndex; }
             set { SetProperty(ref m_RetractSoltSelectedIndex, value); }
         }
+        //Robot动作
+        public SERobotTAction SERobotTAction
+        {
+            get { return m_SERobotTAction; }
+            set { SetProperty(ref m_SERobotTAction, value); }
+        }
+        public SERobotTAction Robot1TAction
+        {
+            get { return m_Robot1TAction; }
+            set { SetProperty(ref m_Robot1TAction, value); }
+        }
+        public SERobotXAction Robot1XAction
+        {
+            get { return m_Robot1XAction; }
+            set { SetProperty(ref m_Robot1XAction, value); }
+        }
+        public SERobotTAction Robot2TAction
+        {
+            get { return m_Robot2TAction; }
+            set { SetProperty(ref m_Robot2TAction, value); }
+        }
+        public SERobotXAction Robot2XAction
+        {
+            get { return m_Robot2XAction; }
+            set { SetProperty(ref m_Robot2XAction, value); }
+        }
+        public RobotMoveInfo RobotMoveInfo
+        {
+            get { return m_robotMoveInfo; }
+            set
+            {
+                RobotMoveInfoChanged(m_robotMoveInfo, value);
+                m_robotMoveInfo = value;
+            }
+        }
+        //Cycle
+        public List<string> OriginalCycle
+        {
+            get { return m_OriginalCycle; }
+            set { SetProperty(ref m_OriginalCycle, value); }
+        }
+        public List<string> ToCycle
+        {
+            get { return m_ToCycle; }
+            set { SetProperty(ref m_ToCycle, value); }
+        }
+        public bool CycleEnable
+        {
+            get { return m_CycleEnable; }
+            set { SetProperty(ref m_CycleEnable, value); }
+        }
+        public bool PMAIsCycle
+        {
+            get { return m_PMAIsCycle; }
+            set { SetProperty(ref m_PMAIsCycle, value); }
+        }
+        public bool PMBIsCycle
+        {
+            get { return m_PMBIsCycle; }
+            set { SetProperty(ref m_PMBIsCycle, value); }
+        }
+        public bool PMCIsCycle
+        {
+            get { return m_PMCIsCycle; }
+            set { SetProperty(ref m_PMCIsCycle, value); }
+        }
+        public int CycleCount
+        {
+            get { return m_CycleCount; }
+            set { SetProperty(ref m_CycleCount, value); }
+        }
 
 
         #endregion
@@ -296,7 +424,23 @@ namespace Venus_MainPages.ViewModels
         public DelegateCommand _RobotHomeCommand;
         public DelegateCommand RobotHomeCommand =>
             _RobotHomeCommand ?? (_RobotHomeCommand = new DelegateCommand(OnRobotHome));
+        private DelegateCommand _HomeCommand;
+        public DelegateCommand HomeCommand =>
+            _HomeCommand ?? (_HomeCommand = new DelegateCommand(OnHome));
+        private DelegateCommand _GotoCommand;
+        public DelegateCommand GotoCommand =>
+            _GotoCommand ?? (_GotoCommand = new DelegateCommand(OnGoto));
         #endregion
+        //Cycle
+        private DelegateCommand _StartCycleCommand;
+        public DelegateCommand StartCycleCommand =>
+            _StartCycleCommand ?? (_StartCycleCommand = new DelegateCommand(OnStartCycle));
+
+        private DelegateCommand _StopCycleCommand;
+
+        public DelegateCommand StopCycleCommand =>
+            _StopCycleCommand ?? (_StopCycleCommand = new DelegateCommand(OnStopCycle));
+
 
         #region 构造函数
         public SeTMViewModel()
@@ -305,8 +449,8 @@ namespace Venus_MainPages.ViewModels
             PMAIsInstalled = allModules.Contains("PMA");
             PMBIsInstalled = allModules.Contains("PMB");
             PMCIsInstalled = allModules.Contains("PMC");
-            VCE1IsInstalled = allModules.Contains("VCE1");
-            AlignerIsInstalled = allModules.Contains("VPA");
+            VCEIsInstalled = allModules.Contains("VCE1");
+            VPAIsInstalled = allModules.Contains("VPA");
             if (PMAIsInstalled == true)
             {
                 TMModules.Add(SeTMModule.PMA);
@@ -318,14 +462,20 @@ namespace Venus_MainPages.ViewModels
             if (PMCIsInstalled == true)
             {
                 TMModules.Add(SeTMModule.PMC);
+                m_VPAangle = 270;
             }
-            if (VCE1IsInstalled == true)
+            else
+            {
+                m_VPAangle = 180;
+            }
+
+            if (VCEIsInstalled == true)
             {
                 TMModules.Add(SeTMModule.VCE1);
             }
-            if (AlignerIsInstalled == true)
+            if (VPAIsInstalled == true)
             {
-                TMModules.Add(SeTMModule.Aligner);
+                TMModules.Add(SeTMModule.VPA);
             }
 
             PickSoltItemsSource.Add(1);
@@ -337,7 +487,7 @@ namespace Venus_MainPages.ViewModels
             addDataKeys();
             RtDataValues = QueryDataClient.Instance.Service.PollData(m_RtDataKeys);
 
-            VCE1DoorIsOpen = !CommonFunction.GetValue<bool>(RtDataValues, "SETM.VCESlitDoorClosed");
+            VCEDoorIsOpen = !CommonFunction.GetValue<bool>(RtDataValues, "SETM.VCESlitDoorClosed");
             PMADoorIsOpen = !CommonFunction.GetValue<bool>(RtDataValues, "SETM.PMASlitDoorClosed");
             PMBDoorIsOpen = !CommonFunction.GetValue<bool>(RtDataValues, "SETM.PMBSlitDoorClosed");
             PMCDoorIsOpen = !CommonFunction.GetValue<bool>(RtDataValues, "SETM.PMCSlitDoorClosed");
@@ -441,8 +591,6 @@ namespace Venus_MainPages.ViewModels
             var selectedHand = (Hand)Enum.Parse(typeof(Hand), PickSelectedBlade.ToString(), true);
             MoveItem moveItem = new MoveItem(moduleName, PickSoltItemsSource[PickSoltSelectedIndex] - 1, ModuleName.TMRobot, 0, selectedHand);
             moveItems.Enqueue(moveItem);
-            //var moduleName = (ModuleName)Enum.Parse(typeof(ModuleName), PickSelectedModule.ToString(), true);
-            //var selectedHand = (Hand)Enum.Parse(typeof(Hand), PickSelectedBlade.ToString(), true);
             if ((int)PickSelectedModule < TMModules.Count - 2)
             {
                 InvokeClient.Instance.Service.DoOperation($"SETM.PMPick", moveItems);
@@ -458,12 +606,13 @@ namespace Venus_MainPages.ViewModels
             Queue<MoveItem> moveItems = new Queue<MoveItem>();
             var moduleName = (ModuleName)Enum.Parse(typeof(ModuleName), PlaceSelectedModule.ToString(), true);
             var selectedHand = (Hand)Enum.Parse(typeof(Hand), PlaceSelectedBlade.ToString(), true);
-            MoveItem moveItem = new MoveItem( ModuleName.TMRobot, 0, moduleName, PlaceSoltItemsSource[PickSoltSelectedIndex] - 1, selectedHand);
+            MoveItem moveItem = new MoveItem(ModuleName.TMRobot, 0, moduleName, PlaceSoltItemsSource[PickSoltSelectedIndex] - 1, selectedHand);
             moveItems.Enqueue(moveItem);
-            if ((int)PickSelectedModule < TMModules.Count - 2)
+            if ((int)PlaceSelectedModule < TMModules.Count - 2)
             {
                 InvokeClient.Instance.Service.DoOperation($"SETM.PMPlace", moveItems);
             }
+            //VCE、VPA
             else
             {
                 InvokeClient.Instance.Service.DoOperation($"SETM.Place", moveItems);
@@ -487,7 +636,52 @@ namespace Venus_MainPages.ViewModels
         //令选择的模块下发Home指令
         private void OnRobotHome()
         {
-            InvokeClient.Instance.Service.DoOperation($"SETM.RobotHome");
+            InvokeClient.Instance.Service.DoOperation($"SETM.Home", "TMRobot");
+            InvokeClient.Instance.Service.DoOperation($"SETM.Retract");
+
+        }
+        private void OnHome()
+        {
+            InvokeClient.Instance.Service.DoOperation($"SETM.Home");
+        }
+        private void OnGoto()
+        {
+            var moduleName = (ModuleName)Enum.Parse(typeof(ModuleName), GotoSelectedModule.ToString(), true);
+            var selectedHand = (Hand)Enum.Parse(typeof(Hand), GoToSelectedBlade.ToString(), true);
+            InvokeClient.Instance.Service.DoOperation($"SETM.Goto", moduleName, 0, selectedHand);
+        }
+        //Cycle
+        private void OnStartCycle()
+        {
+            if (CycleEnable == false)
+            {
+                return;
+            }
+            List<string> stations = new List<string>();
+            stations.Add("VCE1");
+            stations.Add("VPA");
+            if (PMAIsCycle == true)
+            {
+                stations.Add("PMA");
+            }
+            if (PMBIsCycle == true)
+            {
+                stations.Add("PMB");
+            }
+            if (PMCIsCycle == true)
+            {
+                stations.Add("PMC");
+            }
+            stations.Add("VCE1");
+            InvokeClient.Instance.Service.DoOperation("System.SETMCycle", stations.ToArray(), CycleCount);
+
+        }
+
+        private void OnStopCycle()
+        {
+
+            InvokeClient.Instance.Service.DoOperation("System.SEAbort");
+
         }
         #endregion
 
@@ -495,9 +689,9 @@ namespace Venus_MainPages.ViewModels
         private void Timer_Tick(object sender, EventArgs e)
         {
             TMModuleInfo = ModuleManager.ModuleInfos["TMRobot"];
-            if (VCE1IsInstalled)
-            { 
-            
+            if (VCEIsInstalled)
+            {
+
             }
 
             if (PMAIsInstalled == true)
@@ -517,12 +711,228 @@ namespace Venus_MainPages.ViewModels
             }
 
             RtDataValues = QueryDataClient.Instance.Service.PollData(m_RtDataKeys);
-            VCE1DoorIsOpen = !CommonFunction.GetValue<bool>(RtDataValues, "SETM.VCESlitDoorClosed");
+            VCEDoorIsOpen = !CommonFunction.GetValue<bool>(RtDataValues, "SETM.VCESlitDoorClosed");
             PMADoorIsOpen = !CommonFunction.GetValue<bool>(RtDataValues, "SETM.PMASlitDoorClosed");
             PMBDoorIsOpen = !CommonFunction.GetValue<bool>(RtDataValues, "SETM.PMBSlitDoorClosed");
             PMCDoorIsOpen = !CommonFunction.GetValue<bool>(RtDataValues, "SETM.PMCSlitDoorClosed");
             VCEOutDoorIsOpen = !CommonFunction.GetValue<bool>(RtDataValues, "VCE1.VCEOutDoorClosed");
+            RobotMoveInfo = (RobotMoveInfo)QueryDataClient.Instance.Service.GetData("SETM.RobotMoveAction");
+            RobotUpperWafer = TMModuleInfo.WaferManager.Wafers[0];
+            RobotLowerWafer = TMModuleInfo.WaferManager.Wafers[1];
+            PAWafer = ModuleManager.ModuleInfos["VPA"].WaferManager.Wafers[0];
+
+        }
+        private async void RobotMoveInfoChanged(RobotMoveInfo oldValue, RobotMoveInfo newValue)
+        {
+            string RobotTarget;
+            if (oldValue == null || newValue == null)
+            {
+                return;
+            }
+
+            #region Rotating
+            if ((oldValue.Action == RobotAction.None || oldValue.ArmTarget != newValue.ArmTarget) && (newValue.Action == RobotAction.Rotating))
+            {
+                var TMRobotMoveActionBladeTarget = newValue.BladeTarget;
+                if (TMRobotMoveActionBladeTarget != null)
+                {
+                    RobotTarget = TMRobotMoveActionBladeTarget.ToString();
+                }
+                else
+                {
+                    return;
+                }
+                var values = RobotTarget.Split('.');
+                var arm = values[0];
+                var module = values[1];
+                if (arm == "ArmA")
+                {
+                    var SERobotTAction = (SERobotTAction)Enum.Parse(typeof(SERobotTAction), module, true);
+                    if (SERobotTAction != Robot1TAction)
+                    {
+                        Robot1TAction = SERobotTAction;
+                    }
+                }
+                else if (arm == "ArmB")
+                {
+                    var SERobotTAction = (SERobotTAction)Enum.Parse(typeof(SERobotTAction), module, true);
+                    if (SERobotTAction != Robot2TAction)
+                    {
+                        Robot2TAction = SERobotTAction;
+                    }
+                }
+            }
+            #endregion
+
+            #region VPA、VCE1 Pick、Place
+            else if ((oldValue.Action == RobotAction.None || oldValue.ArmTarget != newValue.ArmTarget) && (newValue.Action == RobotAction.Placing || newValue.Action == RobotAction.Picking))
+            {
+                var TMRobotMoveActionBladeTarget = newValue.BladeTarget;
+                if (TMRobotMoveActionBladeTarget != null)
+                {
+                    RobotTarget = TMRobotMoveActionBladeTarget.ToString();
+                }
+                else
+                {
+                    return;
+                }
+                var values = RobotTarget.Split('.');
+                var arm = values[0];
+                var module = values[1];
+                //if (module == "VPA")
+                //{
+                //    module = PMCIsInstalled ? "VPA" : "VPARight";
+                //}
+                if (arm == "ArmA")
+                {
+                    var SERobotTAction = (SERobotTAction)Enum.Parse(typeof(SERobotTAction), module, true);
+                    if (SERobotTAction != Robot1TAction)
+                    {
+                        Robot1TAction = SERobotTAction;
+                    }
+                    await Task.Delay(600);
+
+                    if (module == "VCE1")
+                    {
+                        Robot1XAction = SERobotXAction.ToVCE;
+                    }
+                    else
+                    {
+                        Robot1XAction = SERobotXAction.Extend;
+                    }
+                    while ((newValue.Action == RobotAction.Placing && ModuleManager.ModuleInfos["TMRobot"].WaferManager.Wafers[0].WaferStatus != 0) || (newValue.Action == RobotAction.Picking && ModuleManager.ModuleInfos["TMRobot"].WaferManager.Wafers[0].WaferStatus == 0))
+                    {
+                        await Task.Delay(100);
+                    }
+                    Robot1XAction = SERobotXAction.Retract;
+                }
+                else if (arm == "ArmB")
+                {
+                    var SERobotTAction = (SERobotTAction)Enum.Parse(typeof(SERobotTAction), module, true);
+                    if (SERobotTAction != Robot2TAction)
+                    {
+                        Robot2TAction = SERobotTAction;
+                    }
+                    else
+                    {
+                        //await Task.Delay(100);
+                    }
+                    await Task.Delay(600);
+                    if (module == "VCE1")
+                    {
+                        Robot2XAction = SERobotXAction.ToVCE2;
+                    }
+                    else
+                    {
+                        Robot2XAction = SERobotXAction.Extend2;
+                    }
+                    while ((newValue.Action == RobotAction.Placing && ModuleManager.ModuleInfos["TMRobot"].WaferManager.Wafers[1].WaferStatus != 0) || (newValue.Action == RobotAction.Picking && ModuleManager.ModuleInfos["TMRobot"].WaferManager.Wafers[1].WaferStatus == 0))
+                    {
+                        await Task.Delay(100);
+                    }
+                    Robot2XAction = SERobotXAction.Retract2;
+                }
+
+            }
+            #endregion
+
+            #region PM pick、PM place
+            else if ((oldValue.Action == RobotAction.None || oldValue.ArmTarget != newValue.ArmTarget) && newValue.Action == RobotAction.Extending)
+            {
+                var TMRobotMoveActionBladeTarget = newValue.BladeTarget;
+                if (TMRobotMoveActionBladeTarget != null)
+                {
+                    RobotTarget = TMRobotMoveActionBladeTarget.ToString();
+                }
+                else
+                {
+                    return;
+                }
+                var values = RobotTarget.Split('.');
+                var arm = values[0];
+                var module = values[1];
+                if (arm == "ArmA")
+                {
+                    var SERobotTAction = (SERobotTAction)Enum.Parse(typeof(SERobotTAction), module, true);
+                    if (SERobotTAction != Robot1TAction)
+                    {
+                        Robot1TAction = SERobotTAction;
+                    }
+                    else
+                    {
+                        // await Task.Delay(100);
+                    }
+                    await Task.Delay(600);
+
+                    Robot1XAction = SERobotXAction.Extend;
+                }
+                else if (arm == "ArmB")
+                {
+                    var SERobotTAction = (SERobotTAction)Enum.Parse(typeof(SERobotTAction), module, true);
+                    if (SERobotTAction != Robot2TAction)
+                    {
+                        Robot2TAction = SERobotTAction;
+                    }
+                    else
+                    {
+                        // await Task.Delay(100);
+                    }
+                    await Task.Delay(600);
+
+                    Robot2XAction = SERobotXAction.Extend2;
+                }
+            }
+
+            else if ((oldValue.Action == RobotAction.None || oldValue.ArmTarget != newValue.ArmTarget) && newValue.Action == RobotAction.Retracting)
+            {
+                var TMRobotMoveActionBladeTarget = newValue.BladeTarget;
+                if (TMRobotMoveActionBladeTarget != null)
+                {
+                    RobotTarget = TMRobotMoveActionBladeTarget.ToString();
+                }
+                else
+                {
+                    return;
+                }
+                var values = RobotTarget.Split('.');
+                var arm = values[0];
+                if (arm == "ArmA")
+                {
+                    Robot1XAction = SERobotXAction.Retract;
+                }
+                else if (arm == "ArmB")
+                {
+                    Robot2XAction = SERobotXAction.Retract2;
+                }
+            }
+            #endregion
+            #region Home
+            else if (oldValue.Action == RobotAction.None && newValue.Action == RobotAction.Homing)
+            {
+                if (Robot1XAction == SERobotXAction.Extend)
+                {
+                    Robot1XAction = SERobotXAction.Retract;
+                }
+                if (Robot2XAction == SERobotXAction.Extend2)
+                {
+                    Robot2XAction = SERobotXAction.Retract2;
+                }
+                await Task.Delay(2000);
+                if (Robot1TAction != SERobotTAction.T_Origin)
+                {
+                    Robot1TAction = SERobotTAction.T_Origin;
+                }
+                if (Robot2TAction != SERobotTAction.T_Origin)
+                {
+                    Robot2TAction = SERobotTAction.T_Origin;
+                }
+            }
+
+            #endregion
+
         }
+
+
         #endregion
     }
 

+ 8 - 8
Venus/Venus_MainPages/ViewModels/VenusSeOperationOverViewModel.cs

@@ -20,6 +20,7 @@ using MECF.Framework.Common.Schedulers;
 using Venus_MainPages.Views;
 using System.Windows;
 using static Venus_Themes.CustomControls.SERobot;
+using System.Security.RightsManagement;
 
 namespace Venus_MainPages.ViewModels
 {
@@ -757,7 +758,6 @@ namespace Venus_MainPages.ViewModels
             else if ((oldValue.Action == RobotAction.None || oldValue.ArmTarget != newValue.ArmTarget) && (newValue.Action == RobotAction.Placing || newValue.Action == RobotAction.Picking))
             {
                 var TMRobotMoveActionBladeTarget = newValue.BladeTarget;
-                var TMRobotMoveActionBladeCurrent = oldValue.BladeTarget;
                 if (TMRobotMoveActionBladeTarget != null)
                 {
                     RobotTarget = TMRobotMoveActionBladeTarget.ToString();
@@ -810,17 +810,17 @@ namespace Venus_MainPages.ViewModels
                     await Task.Delay(600);
                     if (module == "VCE1")
                     {
-                        Robot2XAction = SERobotXAction.ToVCE;
+                        Robot2XAction = SERobotXAction.ToVCE2;
                     }
                     else
                     {
-                        Robot2XAction = SERobotXAction.Extend;
+                        Robot2XAction = SERobotXAction.Extend2;
                     }
                     while ((newValue.Action == RobotAction.Placing && ModuleManager.ModuleInfos["TMRobot"].WaferManager.Wafers[1].WaferStatus != 0) || (newValue.Action == RobotAction.Picking && ModuleManager.ModuleInfos["TMRobot"].WaferManager.Wafers[1].WaferStatus == 0))
                     {
                         await Task.Delay(100);
                     }
-                    Robot2XAction = SERobotXAction.Retract;
+                    Robot2XAction = SERobotXAction.Retract2;
                 }
 
             }
@@ -869,7 +869,7 @@ namespace Venus_MainPages.ViewModels
                     }
                     await Task.Delay(600);
 
-                    Robot2XAction = SERobotXAction.Extend;
+                    Robot2XAction = SERobotXAction.Extend2;
                 }
             }
 
@@ -892,7 +892,7 @@ namespace Venus_MainPages.ViewModels
                 }
                 else if (arm == "ArmB")
                 {
-                    Robot2XAction = SERobotXAction.Retract;
+                    Robot2XAction = SERobotXAction.Retract2;
                 }
             }
             #endregion
@@ -903,9 +903,9 @@ namespace Venus_MainPages.ViewModels
                 {
                     Robot1XAction = SERobotXAction.Retract;
                 }
-                if (Robot2XAction == SERobotXAction.Extend)
+                if (Robot2XAction == SERobotXAction.Extend2)
                 {
-                    Robot2XAction = SERobotXAction.Retract;
+                    Robot2XAction = SERobotXAction.Retract2;
                 }
                 await Task.Delay(2000);
                 if (Robot1TAction != SERobotTAction.T_Origin)

File diff suppressed because it is too large
+ 131 - 21
Venus/Venus_MainPages/Views/SeTMView.xaml


+ 2 - 2
Venus/Venus_MainPages/Views/VenusSeOperationOverView.xaml

@@ -269,8 +269,8 @@
                             <RotateTransform Angle="90"></RotateTransform>
                         </Rectangle.RenderTransform>
                     </Rectangle>
-                    <customControls:SERobot Panel.ZIndex="999" OriginT="T_Origin" Canvas.Left="522" Canvas.Top="420"   Width="200" Height="300"   x:Name="robot1"  RobotTAction="{Binding Robot1TAction}" RobotXAction="{Binding Robot1XAction}" RobotWafer="{Binding RobotUpperWafer}"  RobotSpeed="15"/>
-                    <customControls:SERobot Panel.ZIndex="999" OriginT="T_Origin" Canvas.Left="522" Canvas.Top="420"   Width="200" Height="300"   x:Name="robot2"  RobotTAction="{Binding Robot2TAction}" RobotXAction="{Binding Robot2XAction}" RobotWafer="{Binding RobotLowerWafer}"  RobotSpeed="15"/>
+                    <customControls:SERobot Panel.ZIndex="999"  OriginX="X_Origin" OriginT="T_Origin" Canvas.Left="522" Canvas.Top="420"   Width="200" Height="300"   x:Name="robot1"  RobotTAction="{Binding Robot1TAction}" RobotXAction="{Binding Robot1XAction}" RobotWafer="{Binding RobotUpperWafer}"  RobotSpeed="15"/>
+                    <customControls:SERobot Panel.ZIndex="999" OriginX="X_Origin2" OriginT="T_Origin" Canvas.Left="522" Canvas.Top="420"   Width="200" Height="300"   x:Name="robot2"  RobotTAction="{Binding Robot2TAction}" RobotXAction="{Binding Robot2XAction}" RobotWafer="{Binding RobotLowerWafer}"  RobotSpeed="15"/>
                     
                     <userControls:VenusSETM Canvas.Top="450" Canvas.Left="500" PAWafer="{Binding PAWafer}" 
                                             VCEIsInstalled="{Binding VCEIsInstalled }" 

+ 7 - 1
Venus/Venus_RT/Devices/TM/HongHuVR.cs

@@ -9,6 +9,7 @@ using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robot;
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
+using System.Diagnostics.Tracing;
 using System.Linq;
 using System.Runtime.InteropServices;
 using System.Text;
@@ -219,9 +220,13 @@ namespace Venus_RT.Devices.VCE
 
         public bool Goto(ModuleName station, int slot, Hand hand)
         {
+            if (!CheckRobotStatus())
+                return false;
+
             _currentStep = VRStep.Goto;
             _status = RState.Running;
-            return _SendCommand($"GOTO N {_StationNumbers[station]} ARM {Hand2Arm(hand)}");
+            SetRobotMovingInfo(RobotAction.Rotating, hand, station);
+            return _SendCommand($"Goto {_StationNumbers[station]} ARM {Hand2Arm(hand)}");
         }
 
         public bool MoveTo(ModuleName stnFrom, ModuleName stnTo, Hand hand)
@@ -308,6 +313,7 @@ namespace Venus_RT.Devices.VCE
                             _currentStep = VRStep.Idle;
                             _status = RState.End;
                             _IsHomed = true;
+                            SetRobotMovingInfo(RobotAction.Homing, Hand.Both, ModuleName.SETM);
                         }
                         else
                             ReportWrongMsg(RevMsg);

+ 165 - 0
Venus/Venus_RT/Modules/TM/VenusEntity/SEMFPMExtendRoutine.cs

@@ -0,0 +1,165 @@
+using Aitex.Core.RT.Log;
+using Aitex.Core.RT.Routine;
+using Aitex.Core.RT.SCCore;
+using Aitex.Core.Util;
+using Aitex.Sorter.Common;
+using MECF.Framework.Common.Equipment;
+using MECF.Framework.Common.SubstrateTrackings;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Venus_Core;
+using Venus_RT.Devices;
+using Venus_RT.Devices.PreAligner;
+using Venus_RT.Modules.PMs;
+using Venus_RT.Modules.VCE;
+
+namespace Venus_RT.Modules.TM.VenusEntity
+{
+    public class SEMFPMExtendRoutine : ModuleRoutineBase, IRoutine
+    {
+        //Extend的步骤
+        private enum ExtendStep
+        {
+            ArmExtend,
+            End,
+        }
+
+        private readonly HongHuTM _TM;
+        private readonly ITransferRobot _robot;
+        private IPreAlign _vpa;
+        private bool _queryAwc;
+        private ModuleName _targetModule;
+        private PMEntity _pmModule;
+        private VceEntity _vceModule;
+        private bool _VCEFlag = false; //是否考虑VCE slot对齐准备
+        private int _targetSlot;
+        private Hand _hand;
+        private int _extendingTimeout = 120 * 1000;
+
+        public SEMFPMExtendRoutine(HongHuTM honghutm, ITransferRobot robot, IPreAlign vpa) : base(ModuleName.TM)
+        {
+            _TM = honghutm;
+            _robot = robot;
+            Name = "Extend to PM VCE VPA";
+            _vpa = vpa;
+            _queryAwc = false;
+        }
+        //开始执行
+        public RState Start(params object[] objs)
+        {
+            //检查robot home
+            if (!_robot.IsHomed)
+            {
+                LOG.Write(eEvent.ERR_TM, Module, $"TM Robot is not homed, please home it first");
+                return RState.Failed;
+            }
+            _targetModule = (ModuleName)objs[0];
+            _targetSlot = (int)objs[1];
+            _hand = (Hand)objs[2];
+            //检查targetModule是否合法
+            if (ModuleHelper.IsPm(_targetModule) && ModuleHelper.IsInstalled(_targetModule))
+            {
+                _pmModule = Singleton<RouteManager>.Instance.GetPM(_targetModule);
+                //检查开关门状态
+                if (_pmModule.IsSlitDoorClose)
+                {
+                    LOG.Write(eEvent.ERR_TM, Module, $"{_targetModule} slit door closed, can not extend robot arm");
+                    return RState.Failed;
+                }
+            }
+            else if (ModuleHelper.IsVCE(_targetModule) && ModuleHelper.IsInstalled(_targetModule))
+            {
+                _VCEFlag = true;
+                _vceModule = Singleton<RouteManager>.Instance.GetVCE(_targetModule);
+                if (_vceModule.IsError)
+                {
+                    LOG.Write(eEvent.ERR_TM, Module, $"Invalid target module : {_targetModule} is Error! Please solve Error first!");
+                    return RState.Failed;
+                }
+                if (_targetSlot < 0)
+                {
+                    LOG.Write(eEvent.ERR_TM, Module, $"VCE target slot cannot be {_targetSlot}. Please check it first.");
+                    return RState.Failed;
+                }
+                //检查槽位置
+                if (_targetSlot != _vceModule.CurrentSlot)
+                {
+                    LOG.Write(eEvent.ERR_TM, Module, $"VCE current slot is {_vceModule.CurrentSlot} ,cannot be {_targetSlot}. Please check it first.");
+                    return RState.Failed;
+                }
+                //检查开关门状态
+                if (_TM.VCESlitDoorClosed)
+                {
+                    LOG.Write(eEvent.ERR_TM, Module, $"{_targetModule} slit door closed, can not extend robot arm");
+                    return RState.Failed;
+                }
+            }
+            else if (ModuleHelper.IsVPA(_targetModule) && ModuleHelper.IsInstalled(_targetModule))
+            {
+                //LOG.Write(eEvent.ERR_TM, Module, $"{_targetModule}");
+            }
+            else
+            {
+                LOG.Write(eEvent.ERR_TM, Module, $"Invalid target module : {_targetModule} for extending action");
+                return RState.Failed;
+            }
+            //检查Robot和targetModule的wafer状态
+            if (WaferManager.Instance.CheckHasWafer(_targetModule, _targetSlot))
+            {
+                if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, (int)_hand))
+                {
+                    LOG.Write(eEvent.ERR_TM, Module, $"Both {_targetModule} and robot arm {_hand} have wafers");
+                    return RState.Failed;
+                }
+                if (_pmModule.LiftPinIsDown && ModuleHelper.IsPm(_targetModule) && ModuleHelper.IsInstalled(_targetModule))
+                {
+                    LOG.Write(eEvent.ERR_TM, Module, $"{_targetModule} has a wafer and Lift Pin is down, can not extend robot arm");
+                    return RState.Failed;
+                }
+            }
+            Reset();
+            _extendingTimeout = SC.GetValue<int>("TM.ExtendTimeout") * 1000;
+            return Runner.Start(Module, $"Extend to {_targetModule}");
+
+        }
+
+        //状态监控
+        public RState Monitor()
+        {
+            Runner.Run(ExtendStep.ArmExtend, ArmExtend, WaitRobotExtendDone)
+                  .End(ExtendStep.End, NullFun, _delay_50ms);
+
+
+            return Runner.Status;
+        }
+        private bool ArmExtend()
+        {
+            return _robot.PickExtend(_targetModule, _targetSlot, _hand);
+        }
+
+        private bool WaitRobotExtendDone()
+        {
+            if (_robot.Status == RState.Running)
+            {
+                return false;
+            }
+            else if (_robot.Status == RState.End)
+            {
+                return true;
+            }
+            else
+            {
+                Runner.Stop($"TM Robot Arm Extend failed, {_robot.Status}");
+                return true;
+            }
+        }
+        public void Abort()
+        {
+            _robot.Halt();
+        }
+
+    }
+}

+ 166 - 0
Venus/Venus_RT/Modules/TM/VenusEntity/SEMFPMRetractRoutine.cs

@@ -0,0 +1,166 @@
+using Aitex.Core.RT.Log;
+using Aitex.Core.RT.Routine;
+using Aitex.Core.RT.SCCore;
+using Aitex.Core.Util;
+using Aitex.Sorter.Common;
+using MECF.Framework.Common.Equipment;
+using MECF.Framework.Common.SubstrateTrackings;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Venus_Core;
+using Venus_RT.Devices;
+using Venus_RT.Devices.PreAligner;
+using Venus_RT.Modules.PMs;
+using Venus_RT.Modules.VCE;
+
+namespace Venus_RT.Modules.TM.VenusEntity
+{
+    public class SEMFPMRetractRoutine : ModuleRoutineBase, IRoutine
+    {
+
+        //进入Retract的步骤
+        private enum RetractStep
+        {
+            ArmRetract,
+            End,
+        }
+
+        private readonly HongHuTM _TM;
+        private readonly ITransferRobot _robot;
+        private bool _queryAwc;
+        private IPreAlign _vpa;
+        private ModuleName _targetModule;
+        private PMEntity _pmModule;
+        private VceEntity _vceModule;
+        private int _targetSlot;
+        private Hand _hand;
+        private int _retractingTimeout = 120 * 1000;
+
+        public SEMFPMRetractRoutine(HongHuTM honghutm, ITransferRobot robot, IPreAlign vpa) : base(ModuleName.TMRobot)
+        {
+            _TM = honghutm;
+            _robot = robot;
+            Name = "Retract to PM VCE VPA";
+            _vpa = vpa;
+            _queryAwc = false;
+        }
+        //开始执行
+        public RState Start(params object[] objs)
+        {
+            //检查robot home
+            if (!_robot.IsHomed)
+            {
+                LOG.Write(eEvent.ERR_TM, Module, $"TM Robot is not homed, please home it first");
+                return RState.Failed;
+            }
+            _targetModule = (ModuleName)objs[0];
+            _targetSlot = (int)objs[1];
+            _hand = (Hand)objs[2];
+            //检查targetModule是否合法
+            if (ModuleHelper.IsPm(_targetModule) && ModuleHelper.IsInstalled(_targetModule))
+            {
+                _pmModule = Singleton<RouteManager>.Instance.GetPM(_targetModule);
+                //检查开关门状态
+                if (_pmModule.IsSlitDoorClose)
+                {
+                    LOG.Write(eEvent.ERR_TM, Module, $"{_targetModule} slit door closed, can not retract robot arm");
+                    return RState.Failed;
+                }
+
+            }
+            else if (ModuleHelper.IsVCE(_targetModule) && ModuleHelper.IsInstalled(_targetModule))
+            {
+                _vceModule = Singleton<RouteManager>.Instance.GetVCE(_targetModule);
+                if (_vceModule.IsError)
+                {
+                    LOG.Write(eEvent.ERR_TM, Module, $"Invalid target module : {_targetModule} is Error! Please solve Error first!");
+                    return RState.Failed;
+                }
+                if (_targetSlot < 0)
+                {
+                    LOG.Write(eEvent.ERR_TM, Module, $"VCE target slot cannot be {_targetSlot}. Please check it first.");
+                    return RState.Failed;
+                }
+                //检查槽位置
+                if (_targetSlot != _vceModule.CurrentSlot)
+                {
+                    LOG.Write(eEvent.ERR_TM, Module, $"VCE current slot is {_vceModule.CurrentSlot} ,cannot be {_targetSlot}. Please check it first.");
+                    return RState.Failed;
+                }
+                //检查开关门状态
+                if (_TM.VCESlitDoorClosed)
+                {
+                    LOG.Write(eEvent.ERR_TM, Module, $"{_targetModule} slit door closed, can not retract robot arm");
+                    return RState.Failed;
+                }
+            }
+            else if (ModuleHelper.IsVPA(_targetModule) && ModuleHelper.IsInstalled(_targetModule))
+            {
+                //LOG.Write(eEvent.ERR_TM, Module, $"{_targetModule}");
+            }
+            else
+            {
+                LOG.Write(eEvent.ERR_TM, Module, $"Invalid target module : {_targetModule} for retracting action");
+                return RState.Failed;
+            }
+            //检查Robot和targetModule的wafer状态
+            if (WaferManager.Instance.CheckHasWafer(_targetModule, _targetSlot))
+            {
+                if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, (int)_hand))
+                {
+                    LOG.Write(eEvent.ERR_TM, Module, $"Both {_targetModule} and robot arm {_hand} have wafers");
+                    return RState.Failed;
+                }
+                if (_pmModule.LiftPinIsDown && ModuleHelper.IsPm(_targetModule) && ModuleHelper.IsInstalled(_targetModule))
+                {
+                    LOG.Write(eEvent.ERR_TM, Module, $"{_targetModule} has a wafer and Lift Pin is down, can not retract robot arm");
+                    return RState.Failed;
+                }
+            }
+
+            Reset();
+            _retractingTimeout = SC.GetValue<int>("TM.RetractTimeout") * 1000;
+
+            return Runner.Start(Module, $"Retract to {_targetModule}");
+
+        }
+
+        //状态监控
+        public RState Monitor()
+        {
+            Runner.Run(RetractStep.ArmRetract, ArmRetract, WaitRobotRetractDone)
+                .End(RetractStep.End, NullFun, _delay_50ms);
+
+            return Runner.Status;
+        }
+        private bool ArmRetract()
+        {
+            return _robot.PickRetract(_targetModule, _targetSlot, _hand);
+        }
+
+        private bool WaitRobotRetractDone()
+        {
+            if (_robot.Status == RState.Running)
+            {
+                return false;
+            }
+            else if (_robot.Status == RState.End)
+            {
+                return true;
+            }
+            else
+            {
+                Runner.Stop($"TM Robot Arm Retract failed, {_robot.Status}");
+                return true;
+            }
+        }
+        public void Abort()
+        {
+            _robot.Halt();
+        }
+
+    }
+}

+ 63 - 2
Venus/Venus_RT/Modules/TM/VenusEntity/SETMEntity.cs

@@ -82,7 +82,7 @@ namespace Venus_RT.Modules.TM.VenusEntity
             Align,
             CreateJob,
             StartJob,
-
+			Goto,
         }
 
         #region 公开变量
@@ -155,7 +155,8 @@ namespace Venus_RT.Modules.TM.VenusEntity
         private readonly SEMFSwapRoutine _swaproutine;
         private readonly SEMFPMSwapRoutine _pmswaproutine;
 
-
+        private readonly SEMFPMRetractRoutine _pmRetractRoutine;
+        private readonly SEMFPMExtendRoutine _pmExtendRoutine;
 
         //private readonly
         private readonly Stopwatch _robotWatch = new Stopwatch();
@@ -180,6 +181,8 @@ namespace Venus_RT.Modules.TM.VenusEntity
             _placepmRoutine = new SEMFPMPlaceRoutine(_tm, _robot);
             _swaproutine = new SEMFSwapRoutine(_tm, _robot);
             _pmswaproutine = new SEMFPMSwapRoutine(_tm, _robot);
+            _pmExtendRoutine = new SEMFPMExtendRoutine(_tm, _robot, _vpa);
+            _pmRetractRoutine = new SEMFPMRetractRoutine(_tm, _robot, _vpa);
 
             InitFsmMap();
         }
@@ -193,9 +196,13 @@ namespace Venus_RT.Modules.TM.VenusEntity
             DATA.Subscribe("SETM.RobotMoveAction.BladeTarget", () => _robot.TMRobotMoveInfo.BladeTarget, SubscriptionAttribute.FLAG.IgnoreSaveDB);
             DATA.Subscribe("SETM.RobotMoveAction.RobotAction", () => _robot.TMRobotMoveInfo.Action.ToString(), SubscriptionAttribute.FLAG.IgnoreSaveDB);
 
+            OP.Subscribe("SETM.Goto", (cmd, args) => RobotGoto(args));
             OP.Subscribe("SETM.Home", (cmd, args) => { PostMsg(MSG.Home); return true; });
             OP.Subscribe("SETM.Pick", (cmd, args) => { PostMsg(MSG.Pick, args); return true; });
             OP.Subscribe("SETM.Place", (cmd, args) => { PostMsg(MSG.Place, args); return true; });
+            OP.Subscribe("SETM.Extend", (cmd, args) => { PostMsg(MSG.Extend, args); return true; });
+            OP.Subscribe("SETM.Retract", (cmd, args) => { PostMsg(MSG.Retract, args); return true; });
+            
             OP.Subscribe("SETM.PMPick", (cmd, args) => { PostMsg(MSG.PMPick, args); return true; });
             OP.Subscribe("SETM.PMPlace", (cmd, args) => { PostMsg(MSG.PMPlace, args); return true; });
             OP.Subscribe("SETM.PumpDown", (cmd, args) => { PostMsg(MSG.Pump); return true; });
@@ -261,10 +268,64 @@ namespace Venus_RT.Modules.TM.VenusEntity
             Transition(STATE.PMSwaping,         FSM_MSG.TIMER,      fnPMSwapTimeout,    STATE.Idle);
             Transition(STATE.PMSwaping,         MSG.Abort,          fnAbortPMSwap,      STATE.Idle);
 
+            //Extend
+            Transition(STATE.Idle,              MSG.Extend,         FnStartExtend,      STATE.Extending);
+            Transition(STATE.Extending,         FSM_MSG.TIMER,      FnExtend,           STATE.Idle);
+            Transition(STATE.Extending,         MSG.Abort,          FnAbortExtend,      STATE.Idle);
+
+            //Retract
+            Transition(STATE.Idle,              MSG.Retract,        FnStartRetract,     STATE.Retracting);
+            Transition(STATE.Retracting,        FSM_MSG.TIMER,      FnRetract,          STATE.Idle);
+            Transition(STATE.Retracting,        MSG.Abort,          FnAbortRetract,     STATE.Idle);
+
 
             Running = true;
 
         }
+        private bool RobotGoto(object[] param)
+        {
+            return _robot.Goto((ModuleName)param[0], (int)param[1], (Hand)param[2]);
+        }
+        private bool FnStartExtend(object[] param)
+        {
+            return _pmExtendRoutine.Start(param) == RState.Running;
+        }
+        private bool FnExtend(object[] param)
+        {
+            RState ret = _pmExtendRoutine.Monitor();
+            if (ret == RState.Failed || ret == RState.Timeout)
+            {
+                PostMsg(MSG.Error);
+                return false;
+            }
+
+            return ret == RState.End;
+        }
+        private bool FnAbortExtend(object[] param)
+        {
+            _pmExtendRoutine.Abort();
+            return true;
+        }
+        private bool FnStartRetract(object[] param)
+        {
+            return _pmRetractRoutine.Start(param) == RState.Running;
+        }
+        private bool FnRetract(object[] param)
+        {
+            RState ret = _pmRetractRoutine.Monitor();
+            if (ret == RState.Failed || ret == RState.Timeout)
+            {
+                PostMsg(MSG.Error);
+                return false;
+            }
+
+            return ret == RState.End;
+        }
+        private bool FnAbortRetract(object[] param)
+        {
+            _pmRetractRoutine.Abort();
+            return true;
+        }
         private bool fnAbortPMSwap(object[] param)
         {
             _pmswaproutine.Abort();

+ 51 - 3
Venus/Venus_Themes/CustomControls/SERobot.cs

@@ -7,6 +7,7 @@ using System.Threading.Tasks;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Media.Animation;
+using Venus_Themes.UserControls;
 
 namespace Venus_Themes.CustomControls
 {
@@ -19,7 +20,13 @@ namespace Venus_Themes.CustomControls
             ToVCE,
             FromVCE,
             FromVCEToVPA,
-            Retract
+            Retract,
+            X_Origin2,
+            Extend2,
+            ToVCE2,
+            FromVCE2,
+            FromVCEToVPA2,
+            Retract2
         }
 
         public enum SERobotTAction
@@ -30,6 +37,7 @@ namespace Venus_Themes.CustomControls
             PMC,
             VCE1,
             VPA,
+            VPARight,
             RightLocation,
             LeftLocation
 
@@ -39,6 +47,13 @@ namespace Venus_Themes.CustomControls
             DefaultStyleKeyProperty.OverrideMetadata(typeof(SERobot), new FrameworkPropertyMetadata(typeof(SERobot)));
         }
         //注册Wafer、ExtendTime、RobotWafer、RobotXAction属性
+        public static readonly DependencyProperty PMCIsInstalledProperty = DependencyProperty.Register(
+    "PMCIsInstalled", typeof(bool), typeof(SERobot));
+        public bool PMCIsInstalled
+        {
+            get { return (bool)this.GetValue(PMCIsInstalledProperty); }
+            set { SetValue(PMCIsInstalledProperty, value); }
+        }
         public static readonly DependencyProperty WaferProperty = DependencyProperty.Register("Wafer", typeof(int), typeof(SERobot));
         public int Wafer { get => (int)GetValue(WaferProperty); set => SetValue(WaferProperty, value); }
 
@@ -103,6 +118,33 @@ namespace Venus_Themes.CustomControls
                         VisualStateManager.GoToState(control, newAct.ToString(), true);
                     }
                     break;
+                case SERobotXAction.X_Origin2:
+                    VisualStateManager.GoToState(control, newAct.ToString(), true);
+                    break;
+                case SERobotXAction.Extend2:
+                    if (newAct != oldAct)
+                    {
+                        VisualStateManager.GoToState(control, newAct.ToString(), true);
+                    }
+                    break;
+                case SERobotXAction.Retract2:
+                    if (newAct != oldAct)
+                    {
+                        VisualStateManager.GoToState(control, newAct.ToString(), true);
+                    }
+                    break;
+                case SERobotXAction.ToVCE2:
+                    if (newAct != oldAct)
+                    {
+                        VisualStateManager.GoToState(control, newAct.ToString(), true);
+                    }
+                    break;
+                case SERobotXAction.FromVCEToVPA2:
+                    if (newAct != oldAct)
+                    {
+                        VisualStateManager.GoToState(control, newAct.ToString(), true);
+                    }
+                    break;
                 default:
                     break;
             }
@@ -136,6 +178,7 @@ namespace Venus_Themes.CustomControls
 
 
         }
+        public string OriginX { get; set; }
         public string OriginT { get; set; }
 
         private static void RobotTActionPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
@@ -143,6 +186,10 @@ namespace Venus_Themes.CustomControls
             var control = d as SERobot;
             var oldAct = (SERobotTAction)e.OldValue;
             var newAct = (SERobotTAction)e.NewValue;
+            while (newAct.ToString() == "VPA"&&!control.PMCIsInstalled)
+            {
+                newAct = SERobotTAction.VPARight;
+            }
             if (oldAct != newAct)
             {
                 VisualStateManager.GoToState(control, newAct.ToString(), true);//前后动作不一致,改变控件状态
@@ -152,8 +199,9 @@ namespace Venus_Themes.CustomControls
         public override void OnApplyTemplate()
         {
             base.OnApplyTemplate();
-
-            VisualStateManager.GoToState(this, SERobotXAction.X_Origin.ToString(), true);
+            VisualStateManager.GoToState(this, OriginX, true);
+            //VisualStateManager.GoToState(this, SERobotXAction.X_Origin.ToString(), true);
+            
             VisualStateManager.GoToState(this, OriginT, true);
         }
     }

+ 272 - 4
Venus/Venus_Themes/Themes/Generic.xaml

@@ -3,6 +3,7 @@
                     xmlns:converters="clr-namespace:Venus_Themes.Converters"
                     xmlns:customControls="clr-namespace:Venus_Themes.CustomControls"
                     xmlns:userControls="clr-namespace:Venus_Themes.UserControls"
+                    x:Name="Generic"
                     >
 
     <converters:BoolToDirection x:Key="boolToDirection"/>
@@ -658,13 +659,266 @@
                                     </Storyboard>
                                 </VisualState>
                             </VisualStateGroup>
-
+                            <!--ArmB动画-->
+                            <VisualStateGroup Name="RobotXActions2">
+                                <VisualStateGroup.Transitions>
+                                    <VisualTransition To="Extend2">
+                                        <Storyboard FillBehavior="HoldEnd" Timeline.SpeedRatio="13">
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT1RotateAct" Storyboard.TargetProperty="Angle">
+                                                <LinearDoubleKeyFrame Value="120" KeyTime="0:0:0"/>
+                                                <LinearDoubleKeyFrame Value="90" KeyTime="0:0:6"/>
+                                            </DoubleAnimationUsingKeyFrames>
+                                            <!--中臂-->
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT2ArmRotateAct" Storyboard.TargetProperty="Angle">
+                                                <LinearDoubleKeyFrame Value="115" KeyTime="0:0:0"/>
+                                                <LinearDoubleKeyFrame Value="210" KeyTime="0:0:6"/>
+                                            </DoubleAnimationUsingKeyFrames>
+                                            <!--前臂-->
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT3ArmTranslateAct" Storyboard.TargetProperty="X">
+                                                <LinearDoubleKeyFrame Value="225" KeyTime="0:0:0"/>
+                                                <LinearDoubleKeyFrame Value="110" KeyTime="0:0:6"/>
+                                            </DoubleAnimationUsingKeyFrames>
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT3ArmTranslateAct" Storyboard.TargetProperty="Y">
+                                                <LinearDoubleKeyFrame Value="0" KeyTime="0:0:6"/>
+                                                <LinearDoubleKeyFrame Value="5" KeyTime="0:0:5"/>
+                                                <LinearDoubleKeyFrame Value="10" KeyTime="0:0:4"/>
+                                                <LinearDoubleKeyFrame Value="11" KeyTime="0:0:3"/>
+                                                <LinearDoubleKeyFrame Value="10" KeyTime="0:0:2"/>
+                                                <LinearDoubleKeyFrame Value="5" KeyTime="0:0:1"/>
+                                                <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0"/>
+                                            </DoubleAnimationUsingKeyFrames>
+                                        </Storyboard>
+                                    </VisualTransition>
+                                    <VisualTransition To="Retract2">
+                                        <Storyboard FillBehavior="HoldEnd" SpeedRatio="14">
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT1RotateAct" Storyboard.TargetProperty="Angle">
+                                                <LinearDoubleKeyFrame Value="90" KeyTime="0:0:0"/>
+                                                <LinearDoubleKeyFrame Value="115" KeyTime="0:0:6"/>
+                                            </DoubleAnimationUsingKeyFrames>
+                                            <!--中臂-->
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT2ArmRotateAct" Storyboard.TargetProperty="Angle">
+                                                <LinearDoubleKeyFrame Value="210" KeyTime="0:0:0"/>
+                                                <LinearDoubleKeyFrame Value="120" KeyTime="0:0:6"/>
+                                            </DoubleAnimationUsingKeyFrames>
+                                            <!--前臂-->
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT3ArmTranslateAct" Storyboard.TargetProperty="X">
+                                                <LinearDoubleKeyFrame Value="110" KeyTime="0:0:0"/>
+                                                <LinearDoubleKeyFrame Value="225" KeyTime="0:0:6"/>
+                                            </DoubleAnimationUsingKeyFrames>
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT3ArmTranslateAct" Storyboard.TargetProperty="Y">
+                                                <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0"/>
+                                                <LinearDoubleKeyFrame Value="5" KeyTime="0:0:1"/>
+                                                <LinearDoubleKeyFrame Value="10" KeyTime="0:0:2"/>
+                                                <LinearDoubleKeyFrame Value="11" KeyTime="0:0:3"/>
+                                                <LinearDoubleKeyFrame Value="10" KeyTime="0:0:4"/>
+                                                <LinearDoubleKeyFrame Value="5" KeyTime="0:0:5"/>
+                                                <LinearDoubleKeyFrame Value="0" KeyTime="0:0:6"/>
+                                            </DoubleAnimationUsingKeyFrames>
+                                        </Storyboard>
+                                    </VisualTransition>
+                                    <VisualTransition To="ToVCE2">
+                                        <Storyboard FillBehavior="HoldEnd" SpeedRatio="14">
+                                            <!--后臂+底座-->
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT1RotateAct" Storyboard.TargetProperty="Angle">
+                                                <LinearDoubleKeyFrame Value="115" KeyTime="0:0:0"/>
+                                                <LinearDoubleKeyFrame Value="0" KeyTime="0:0:6"/>
+                                            </DoubleAnimationUsingKeyFrames>
+                                            <!--中臂-->
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT2ArmRotateAct" Storyboard.TargetProperty="Angle">
+                                                <LinearDoubleKeyFrame Value="120" KeyTime="0:0:0"/>
+                                                <LinearDoubleKeyFrame Value="360" KeyTime="0:0:6"/>
+                                            </DoubleAnimationUsingKeyFrames>
+                                            <!--前臂-->
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT3ArmTranslateAct" Storyboard.TargetProperty="X">
+                                                <LinearDoubleKeyFrame Value="225" KeyTime="0:0:0"/>
+                                                <LinearDoubleKeyFrame Value="178" KeyTime="0:0:1"/>
+                                                <LinearDoubleKeyFrame Value="127" KeyTime="0:0:2"/>
+                                                <LinearDoubleKeyFrame Value="80" KeyTime="0:0:3"/>
+                                                <LinearDoubleKeyFrame Value="40" KeyTime="0:0:4"/>
+                                                <LinearDoubleKeyFrame Value="10" KeyTime="0:0:5"/>
+                                                <LinearDoubleKeyFrame Value="0" KeyTime="0:0:6"/>
+                                            </DoubleAnimationUsingKeyFrames>
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT3ArmTranslateAct" Storyboard.TargetProperty="Y">
+                                                <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0"/>
+                                                <LinearDoubleKeyFrame Value="7" KeyTime="0:0:1"/>
+                                                <LinearDoubleKeyFrame Value="10" KeyTime="0:0:2"/>
+                                                <LinearDoubleKeyFrame Value="10" KeyTime="0:0:3"/>
+                                                <LinearDoubleKeyFrame Value="8" KeyTime="0:0:4"/>
+                                                <LinearDoubleKeyFrame Value="5" KeyTime="0:0:5"/>
+                                                <LinearDoubleKeyFrame Value="0" KeyTime="0:0:6"/>
+                                            </DoubleAnimationUsingKeyFrames>
+                                        </Storyboard>
+                                    </VisualTransition>
+                                    <VisualTransition To="FromVCE2">
+                                        <Storyboard FillBehavior="HoldEnd" SpeedRatio="14">
+                                            <!--后臂+底座-->
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT1RotateAct" Storyboard.TargetProperty="Angle">
+                                                <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0"/>
+                                                <LinearDoubleKeyFrame Value="115" KeyTime="0:0:6"/>
+                                            </DoubleAnimationUsingKeyFrames>
+                                            <!--中臂-->
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT2ArmRotateAct" Storyboard.TargetProperty="Angle">
+                                                <LinearDoubleKeyFrame Value="360" KeyTime="0:0:0"/>
+                                                <LinearDoubleKeyFrame Value="120" KeyTime="0:0:6"/>
+                                            </DoubleAnimationUsingKeyFrames>
+                                            <!--前臂-->
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT3ArmTranslateAct" Storyboard.TargetProperty="X">
+                                                <LinearDoubleKeyFrame Value="225" KeyTime="0:0:6"/>
+                                                <LinearDoubleKeyFrame Value="178" KeyTime="0:0:5"/>
+                                                <LinearDoubleKeyFrame Value="127" KeyTime="0:0:4"/>
+                                                <LinearDoubleKeyFrame Value="80" KeyTime="0:0:3"/>
+                                                <LinearDoubleKeyFrame Value="40" KeyTime="0:0:2"/>
+                                                <LinearDoubleKeyFrame Value="10" KeyTime="0:0:1"/>
+                                                <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0"/>
+                                            </DoubleAnimationUsingKeyFrames>
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT3ArmTranslateAct" Storyboard.TargetProperty="Y">
+                                                <LinearDoubleKeyFrame Value="0" KeyTime="0:0:6"/>
+                                                <LinearDoubleKeyFrame Value="7" KeyTime="0:0:5"/>
+                                                <LinearDoubleKeyFrame Value="10" KeyTime="0:0:4"/>
+                                                <LinearDoubleKeyFrame Value="10" KeyTime="0:0:3"/>
+                                                <LinearDoubleKeyFrame Value="8" KeyTime="0:0:2"/>
+                                                <LinearDoubleKeyFrame Value="5" KeyTime="0:0:1"/>
+                                                <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0"/>
+                                            </DoubleAnimationUsingKeyFrames>
+                                        </Storyboard>
+                                    </VisualTransition>
+                                    <VisualTransition To="FromVCEToVPA2">
+                                        <Storyboard FillBehavior="HoldEnd" SpeedRatio="14">
+                                            <!--后臂+底座-->
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT1RotateAct" Storyboard.TargetProperty="Angle">
+                                                <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0"/>
+                                                <LinearDoubleKeyFrame Value="90" KeyTime="0:0:6"/>
+                                            </DoubleAnimationUsingKeyFrames>
+                                            <!--中臂-->
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT2ArmRotateAct" Storyboard.TargetProperty="Angle">
+                                                <LinearDoubleKeyFrame Value="360" KeyTime="0:0:0"/>
+                                                <LinearDoubleKeyFrame Value="210" KeyTime="0:0:6"/>
+                                            </DoubleAnimationUsingKeyFrames>
+                                            <!--前臂-->
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT3ArmTranslateAct" Storyboard.TargetProperty="X">
+                                                <LinearDoubleKeyFrame Value="110" KeyTime="0:0:6"/>
+                                                <LinearDoubleKeyFrame Value="82" KeyTime="0:0:5"/>
+                                                <LinearDoubleKeyFrame Value="55" KeyTime="0:0:4"/>
+                                                <LinearDoubleKeyFrame Value="32" KeyTime="0:0:3"/>
+                                                <LinearDoubleKeyFrame Value="15" KeyTime="0:0:2"/>
+                                                <LinearDoubleKeyFrame Value="5" KeyTime="0:0:1"/>
+                                                <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0"/>
+                                            </DoubleAnimationUsingKeyFrames>
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT3ArmTranslateAct" Storyboard.TargetProperty="Y">
+                                                <LinearDoubleKeyFrame Value="0" KeyTime="0:0:6"/>
+                                                <LinearDoubleKeyFrame Value="5" KeyTime="0:0:5"/>
+                                                <LinearDoubleKeyFrame Value="8" KeyTime="0:0:4"/>
+                                                <LinearDoubleKeyFrame Value="8" KeyTime="0:0:3"/>
+                                                <LinearDoubleKeyFrame Value="6" KeyTime="0:0:2"/>
+                                                <LinearDoubleKeyFrame Value="4" KeyTime="0:0:1"/>
+                                                <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0"/>
+                                            </DoubleAnimationUsingKeyFrames>
+                                        </Storyboard>
+                                    </VisualTransition>
+                                </VisualStateGroup.Transitions>
+                                <VisualState Name="X_Origin2">
+                                    <Storyboard FillBehavior="HoldEnd">
+                                        <!--后臂+底座-->
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT1RotateAct" Storyboard.TargetProperty="Angle">
+                                            <LinearDoubleKeyFrame Value="115" KeyTime="0:0:0"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                        <!--中臂-->
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT2ArmRotateAct" Storyboard.TargetProperty="Angle">
+                                            <LinearDoubleKeyFrame Value="120" KeyTime="0:0:0"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                        <!--前臂-->
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT3ArmTranslateAct" Storyboard.TargetProperty="X">
+                                            <LinearDoubleKeyFrame Value="225" KeyTime="0:0:0"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState Name="ToVCE2">
+                                    <Storyboard FillBehavior="HoldEnd">
+                                        <!--后臂+底座-->
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT1RotateAct" Storyboard.TargetProperty="Angle">
+                                            <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                        <!--中臂-->
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT2ArmRotateAct" Storyboard.TargetProperty="Angle">
+                                            <LinearDoubleKeyFrame Value="360" KeyTime="0:0:0"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                        <!--前臂-->
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT3ArmTranslateAct" Storyboard.TargetProperty="X">
+                                            <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState Name="FromVCE2">
+                                    <Storyboard FillBehavior="HoldEnd">
+                                        <!--后臂+底座-->
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT1RotateAct" Storyboard.TargetProperty="Angle">
+                                            <LinearDoubleKeyFrame Value="115" KeyTime="0:0:0"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                        <!--中臂-->
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT2ArmRotateAct" Storyboard.TargetProperty="Angle">
+                                            <LinearDoubleKeyFrame Value="120" KeyTime="0:0:0"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                        <!--前臂-->
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT3ArmTranslateAct" Storyboard.TargetProperty="X">
+                                            <LinearDoubleKeyFrame Value="225" KeyTime="0:0:0"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState Name="FromVCEToVPA2">
+                                    <Storyboard FillBehavior="HoldEnd">
+                                        <!--后臂+底座-->
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT1RotateAct" Storyboard.TargetProperty="Angle">
+                                            <LinearDoubleKeyFrame Value="90" KeyTime="0:0:0"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                        <!--中臂-->
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT2ArmRotateAct" Storyboard.TargetProperty="Angle">
+                                            <LinearDoubleKeyFrame Value="210" KeyTime="0:0:0"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                        <!--前臂-->
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT3ArmTranslateAct" Storyboard.TargetProperty="X">
+                                            <LinearDoubleKeyFrame Value="110" KeyTime="0:0:0"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState Name="Extend2">
+                                    <Storyboard FillBehavior="HoldEnd">
+                                        <!--后臂+底座-->
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT1RotateAct" Storyboard.TargetProperty="Angle">
+                                            <LinearDoubleKeyFrame Value="90" KeyTime="0:0:0"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                        <!--中臂-->
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT2ArmRotateAct" Storyboard.TargetProperty="Angle">
+                                            <LinearDoubleKeyFrame Value="210" KeyTime="0:0:0"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                        <!--前臂-->
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT3ArmTranslateAct" Storyboard.TargetProperty="X">
+                                            <LinearDoubleKeyFrame Value="110" KeyTime="0:0:0"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState Name="Retract2">
+                                    <Storyboard FillBehavior="HoldEnd">
+                                        <!--后臂+底座-->
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT1RotateAct" Storyboard.TargetProperty="Angle">
+                                            <LinearDoubleKeyFrame Value="115" KeyTime="0:0:0"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                        <!--中臂-->
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT2ArmRotateAct" Storyboard.TargetProperty="Angle">
+                                            <LinearDoubleKeyFrame Value="120" KeyTime="0:0:0"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                        <!--前臂-->
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="armXT3ArmTranslateAct" Storyboard.TargetProperty="X">
+                                            <LinearDoubleKeyFrame Value="225" KeyTime="0:0:0"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                            </VisualStateGroup>
                             <VisualStateGroup Name="RobotTActions">
                                 <VisualStateGroup.Transitions>
                                     <VisualTransition To="T_Origin">
                                         <Storyboard FillBehavior="HoldEnd">
                                             <DoubleAnimationUsingKeyFrames Storyboard.TargetName="robotRotateAct" Storyboard.TargetProperty="Angle">
-                                                <LinearDoubleKeyFrame Value="0" KeyTime="0:0:1"/>
+                                                <LinearDoubleKeyFrame Value="-90" KeyTime="0:0:1"/>
                                             </DoubleAnimationUsingKeyFrames>
                                         </Storyboard>
                                     </VisualTransition>
@@ -697,6 +951,13 @@
                                             </DoubleAnimationUsingKeyFrames>
                                         </Storyboard>
                                     </VisualTransition>
+                                    <VisualTransition To="VPARight">
+                                        <Storyboard FillBehavior="HoldEnd">
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="robotRotateAct" Storyboard.TargetProperty="Angle">
+                                                <LinearDoubleKeyFrame Value="180" KeyTime="0:0:0.5"/>
+                                            </DoubleAnimationUsingKeyFrames>
+                                        </Storyboard>
+                                    </VisualTransition>
                                     <VisualTransition To="VCE1">
                                         <Storyboard FillBehavior="HoldEnd">
                                             <DoubleAnimationUsingKeyFrames Storyboard.TargetName="robotRotateAct" Storyboard.TargetProperty="Angle">
@@ -709,7 +970,7 @@
                                 <VisualState Name="T_Origin">
                                     <Storyboard FillBehavior="HoldEnd">
                                         <DoubleAnimationUsingKeyFrames Storyboard.TargetName="robotRotateAct" Storyboard.TargetProperty="Angle">
-                                            <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0"/>
+                                            <LinearDoubleKeyFrame Value="-90" KeyTime="0:0:0"/>
                                         </DoubleAnimationUsingKeyFrames>
                                     </Storyboard>
                                 </VisualState>
@@ -741,6 +1002,13 @@
                                         </DoubleAnimationUsingKeyFrames>
                                     </Storyboard>
                                 </VisualState>
+                                <VisualState Name="VPARight">
+                                    <Storyboard FillBehavior="HoldEnd">
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="robotRotateAct" Storyboard.TargetProperty="Angle">
+                                            <LinearDoubleKeyFrame Value="180" KeyTime="0:0:0.0"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
                                 <VisualState Name="VCE1">
                                     <Storyboard FillBehavior="HoldEnd">
                                         <DoubleAnimationUsingKeyFrames Storyboard.TargetName="robotRotateAct" Storyboard.TargetProperty="Angle">
@@ -806,7 +1074,7 @@
                                     <Viewbox  Canvas.Left="56" Canvas.Top="-60" Width="45" Height="160">
                                         <userControls:SERobot1 IsEnabled="False"/>
                                     </Viewbox>
-                                    <Viewbox Canvas.Left="-40" Canvas.Top="-23" Width="85" Height="85">
+                                    <Viewbox Canvas.Left="-30" Canvas.Top="-15" Width="70" Height="70">
                                         <!--<Border BorderBrush="Black" BorderThickness="2">-->
                                         <userControls:WaferCtrl WaferData="{Binding RobotWafer,RelativeSource={RelativeSource TemplatedParent}}" IsEnabled="False"/>
                                         <!--</Border>-->