Sfoglia il codice sorgente

add robot pick/place parameter upper/down releate

chenzk 2 settimane fa
parent
commit
02069c13bc

+ 3 - 1
Framework/Common/CommonData/RobotAnimationData.cs

@@ -10,14 +10,16 @@ namespace MECF.Framework.Common.CommonData
 {
     public class RobotAnimationData
     {
-        public RobotAnimationData(RobotAction action, Hand hand, ModuleName target)
+        public RobotAnimationData(RobotAction action, Hand hand, ModuleName target,Flip flip)
         {
             Action = action;
             Hand = hand;
             Target = target;
+            Flip = flip;
         }
         public RobotAction Action { get; set; }
         public Hand Hand { get; set; }
         public ModuleName Target { get; set; }
+        public Flip Flip { get; set; }
     }
 }

+ 16 - 2
Framework/Common/CommonData/RobotMoveInfo.cs

@@ -1,4 +1,5 @@
-using System;
+using Aitex.Sorter.Common;
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Runtime.Serialization;
@@ -93,9 +94,22 @@ namespace MECF.Framework.Common.CommonData
             }
         }
 
+        private Flip bladeDirection;
+
+        [DataMember]
+        public Flip BladeDirection
+        {
+            get => bladeDirection;
+            set
+            {
+                bladeDirection = value;
+                InvokePropertyChanged("BladeDirection");
+            }
+        }
+
         public override string ToString()
         {
-            return $"{bladeTarget} - {action}";
+            return $"{bladeTarget} - {action} - {bladeDirection}";
         }
     }
 }

+ 15 - 1
PunkHPX8_MainPages/ViewModels/EfemViewModel.cs

@@ -111,6 +111,7 @@ namespace PunkHPX8_MainPages.ViewModels
         private WaferRobotXAction m_Robot1XAction;
         private WaferRobotTAction m_Robot2TAction;
         private WaferRobotXAction m_Robot2XAction;
+        private WaferRobotFAction m_Robot2FAction;
         //int arm1oldWaferStatus = 100;
         //int arm2oldWaferStatus = 100;
         private EFEM.RobotPosition m_CurrentRobotPosition;
@@ -421,6 +422,11 @@ namespace PunkHPX8_MainPages.ViewModels
             get { return m_Robot2XAction; }
             set { SetProperty(ref m_Robot2XAction, value); }
         }
+        public WaferRobotFAction Robot2FAction
+        {
+            get { return m_Robot2FAction; }
+            set { SetProperty(ref m_Robot2FAction, value); }
+        }
         private string m_RobotTarget;
 
         public string RobotTarget
@@ -1160,7 +1166,7 @@ namespace PunkHPX8_MainPages.ViewModels
                 var values = RobotTarget.Split('.');
                 var arm = values[0];
                 var module = values[1];
-
+   
                 if (arm == "ArmA")
                 {
                     var robot1Robot1TAction= (WaferRobotTAction)Enum.Parse(typeof(WaferRobotTAction), module, true);
@@ -1192,6 +1198,14 @@ namespace PunkHPX8_MainPages.ViewModels
                 }
                 else  //使用上手臂
                 {
+                    if (oldValue.BladeTarget!=null && oldValue.BladeTarget.Split('.')[2] != newValue.BladeTarget.Split('.')[2] && newValue.BladeTarget.Split('.')[2]=="Down")
+                    {
+                        Robot2FAction = WaferRobotFAction.UpperToDown;
+                    }
+                    else if(oldValue.BladeTarget == null || (oldValue.BladeTarget.Split('.')[2] != newValue.BladeTarget.Split('.')[2] && newValue.BladeTarget.Split('.')[2] == "Upper"))
+                    {
+                        Robot2FAction = WaferRobotFAction.DownToUpper;
+                    }
                     var robot1Robot1TAction = (WaferRobotTAction)Enum.Parse(typeof(WaferRobotTAction), module, true);
                     //Robot整体平移动画
                     await ChangePosition(robot1Robot1TAction, newValue.Action);

+ 1 - 0
PunkHPX8_MainPages/Views/EfemView.xaml

@@ -96,6 +96,7 @@
                                 LP2Loaded="{Binding RtDataValues[LP2.IsLoaded]}" 
                                 RobotATAction="{Binding Robot1TAction}" 
                                 RobotAXAction="{Binding Robot1XAction}"
+                                RobotBFAction="{Binding Robot2FAction}"
                                 RobotAWaferInfo="{Binding BladeAWafer}" 
                                 RobotBWaferInfo="{Binding BladeBWafer}" 
                                 CurrentRobotPosition="{Binding CurrentRobotPosition}"

+ 1 - 1
PunkHPX8_RT/Devices/EFEM/EfemBase.cs

@@ -137,7 +137,7 @@ namespace PunkHPX8_RT.Devices.EFEM
         public abstract bool Clamp(ModuleName mod, bool isUnloadClamp);
         public abstract bool Unclamp(ModuleName mod);
         public abstract bool SetThickness(ModuleName mod, string thickness);
-        public abstract void SetRobotMovingInfo(RobotAction action, Hand hand, ModuleName target);
+        public abstract void SetRobotMovingInfo(RobotAction action, Hand hand, ModuleName target,Flip flip);
 
         public abstract bool GetWaferSize(ModuleName mod);
         public abstract bool SetWaferSize(ModuleName mod,int WaferSize);

+ 1 - 0
PunkHPX8_RT/Devices/EFEM/EfemMessage.cs

@@ -33,6 +33,7 @@ namespace PunkHPX8_RT.Devices.YASKAWA
         public IList<string> Parameters { get; set; }
         public string RawString         { get; set; }
         public string Factor            { get; set; }       // NAK, CAN
+        public Flip Flip            { get; set; } 
 
         public override string ToString()
         {

+ 11 - 11
PunkHPX8_RT/Devices/EFEM/JetEfem.cs

@@ -184,7 +184,7 @@ namespace PunkHPX8_RT.Devices.EFEM
 
             _status = RState.Running;
             string data = _currentMsg.ToString();
-            SetRobotMovingInfo(RobotAction.Homing, Hand.Both, ModuleName.EFEM);
+            SetRobotMovingInfo(RobotAction.Homing, Hand.Both, ModuleName.EFEM, Flip.Upper);
 
             return _socket.Write(data);
         }
@@ -317,7 +317,7 @@ namespace PunkHPX8_RT.Devices.EFEM
                 }
             };
 
-            SetRobotMovingInfo(RobotAction.Extending, hand, chamber);
+            SetRobotMovingInfo(RobotAction.Extending, hand, chamber,Flip.Upper);
             _status = RState.Running;
             return _socket.Write(_currentMsg.ToString());
         }
@@ -339,7 +339,7 @@ namespace PunkHPX8_RT.Devices.EFEM
             };
 
             _status = RState.Running;
-            SetRobotMovingInfo(RobotAction.Retracting, hand, chamber);
+            SetRobotMovingInfo(RobotAction.Retracting, hand, chamber, Flip.Upper);
             return _socket.Write(_currentMsg.ToString());
         }
         public override bool PlaceExtend(ModuleName chamber, int slot, Hand hand)
@@ -360,7 +360,7 @@ namespace PunkHPX8_RT.Devices.EFEM
             };
 
             _status = RState.Running;
-            SetRobotMovingInfo(RobotAction.Extending, hand, chamber);
+            SetRobotMovingInfo(RobotAction.Extending, hand, chamber, Flip.Upper);
             return _socket.Write(_currentMsg.ToString());
         }
 
@@ -382,7 +382,7 @@ namespace PunkHPX8_RT.Devices.EFEM
             };
 
             _status = RState.Running;
-            SetRobotMovingInfo(RobotAction.Retracting, hand, chamber);
+            SetRobotMovingInfo(RobotAction.Retracting, hand, chamber, Flip.Upper);
             return _socket.Write(_currentMsg.ToString());
         }
 
@@ -405,7 +405,7 @@ namespace PunkHPX8_RT.Devices.EFEM
             };
 
             _status = RState.Running;
-            SetRobotMovingInfo(RobotAction.Picking, hand, station);
+            SetRobotMovingInfo(RobotAction.Picking, hand, station, Flip.Upper);
             return _socket.Write(_currentMsg.ToString());
         }
 
@@ -428,7 +428,7 @@ namespace PunkHPX8_RT.Devices.EFEM
             };
 
             _status = RState.Running;
-            SetRobotMovingInfo(RobotAction.Placing, hand, station);
+            SetRobotMovingInfo(RobotAction.Placing, hand, station, Flip.Upper);
             return _socket.Write(_currentMsg.ToString());
         }
 
@@ -791,9 +791,9 @@ namespace PunkHPX8_RT.Devices.EFEM
             return _socket.Write(_currentMsg.ToString());
         }
 
-        public override void SetRobotMovingInfo(RobotAction action, Hand hand, ModuleName target)
+        public override void SetRobotMovingInfo(RobotAction action, Hand hand, ModuleName target,Flip flip)
         {
-            blockingCollection.Add(new RobotAnimationData(action, hand, target));
+            blockingCollection.Add(new RobotAnimationData(action, hand, target, flip));
         }
 
         private void OnReceiveMessage(string RevMsg)
@@ -827,7 +827,7 @@ namespace PunkHPX8_RT.Devices.EFEM
                         _revMsg = rec_msg;
 
                         OnCommandUpdated(rec_msg);
-                        SetRobotMovingInfo(RobotAction.None, Hand.Both, ModuleName.EfemRobot);
+                        SetRobotMovingInfo(RobotAction.None, Hand.Both, ModuleName.EfemRobot, Flip.Upper);
 
                         break;
 
@@ -841,7 +841,7 @@ namespace PunkHPX8_RT.Devices.EFEM
                         });
                         if (rec_msg.Operation == EfemOperation.Home)
                         {
-                            SetRobotMovingInfo(RobotAction.Homing, Hand.Both, ModuleName.EFEM);
+                            SetRobotMovingInfo(RobotAction.Homing, Hand.Both, ModuleName.EFEM, Flip.Upper);
                         }
                         break;
 

+ 8 - 8
PunkHPX8_RT/Devices/EFEM/SunWayEfem.cs

@@ -200,7 +200,7 @@ namespace PunkHPX8_RT.Devices.EFEM
 
             _status = RState.Running;
             string data = _currentMsg.ToString();
-            SetRobotMovingInfo(RobotAction.Homing, Hand.Both, ModuleName.EFEM);
+            SetRobotMovingInfo(RobotAction.Homing, Hand.Both, ModuleName.EFEM, Flip.Upper);
             return _socket.Write(data);
         }
 
@@ -231,7 +231,7 @@ namespace PunkHPX8_RT.Devices.EFEM
                 Head = EfemMessage.MsgHead.MOV,
                 Parameters = new List<string> { SunWayMessageHandler.Instance.ModuleString[mod] }
             };
-            if(mod == ModuleName.EfemRobot) SetRobotMovingInfo(RobotAction.Homing, Hand.Blade1, ModuleName.EfemRobot);
+            if(mod == ModuleName.EfemRobot) SetRobotMovingInfo(RobotAction.Homing, Hand.Blade1, ModuleName.EfemRobot, Flip.Upper);
             _status = RState.Running;            
             return _socket.Write(_currentMsg.ToString());
         }
@@ -428,7 +428,7 @@ namespace PunkHPX8_RT.Devices.EFEM
             };
 
             _status = RState.Running;
-            SetRobotMovingInfo(RobotAction.Picking, hand, station);
+            SetRobotMovingInfo(RobotAction.Picking, hand, station, Flip.Upper);
             return _socket.Write(_currentMsg.ToString());
         }
 
@@ -469,7 +469,7 @@ namespace PunkHPX8_RT.Devices.EFEM
             };
 
             _status = RState.Running;
-            SetRobotMovingInfo(RobotAction.Placing, hand, station);
+            SetRobotMovingInfo(RobotAction.Placing, hand, station, Flip.Upper);
             return _socket.Write(_currentMsg.ToString());
         }
 
@@ -1028,9 +1028,9 @@ namespace PunkHPX8_RT.Devices.EFEM
             LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"System cannot support {EfemConstant.OperationString[EfemOperation.SetThickness]}");
             return false;
         }
-        public override void SetRobotMovingInfo(RobotAction action, Hand hand, ModuleName target)
+        public override void SetRobotMovingInfo(RobotAction action, Hand hand, ModuleName target,Flip flip)
         {
-            blockingCollection.Add(new RobotAnimationData(action, hand, target));
+            blockingCollection.Add(new RobotAnimationData(action, hand, target, flip));
         }
 
         private void OnReceiveMessage(string RevMsg)
@@ -1087,7 +1087,7 @@ namespace PunkHPX8_RT.Devices.EFEM
                         _revMsg = rec_msg;
 
                         OnCommandUpdated(rec_msg);
-                        SetRobotMovingInfo(RobotAction.None, Hand.Both, ModuleName.EfemRobot);
+                        SetRobotMovingInfo(RobotAction.None, Hand.Both, ModuleName.EfemRobot, Flip.Upper);
 
                         break;
 
@@ -1101,7 +1101,7 @@ namespace PunkHPX8_RT.Devices.EFEM
                         });
                         if (rec_msg.Operation == EfemOperation.Home)
                         {
-                            SetRobotMovingInfo(RobotAction.Homing, Hand.Both, ModuleName.EFEM);
+                            SetRobotMovingInfo(RobotAction.Homing, Hand.Both, ModuleName.EFEM, Flip.Upper);
                         }
                         if (rec_msg.Operation == EfemOperation.Error)
                         {

+ 22 - 12
PunkHPX8_RT/Devices/EFEM/SunWayRobot.cs

@@ -157,7 +157,8 @@ namespace PunkHPX8_RT.Devices.EFEM
                 {
                     _robotMoveInfo.Action = data.Action;
                     _robotMoveInfo.ArmTarget = data.Hand == Hand.Blade1 ? RobotArm.ArmA : (data.Hand == Hand.Both ? RobotArm.Both : RobotArm.ArmB);
-                    _robotMoveInfo.BladeTarget = $"{_robotMoveInfo.ArmTarget}.{data.Target}";
+                    _robotMoveInfo.BladeDirection = data.Flip;
+                    _robotMoveInfo.BladeTarget = $"{_robotMoveInfo.ArmTarget}.{data.Target}.{data.Flip}";
                     System.Threading.Thread.Sleep(600);
                 }
             });
@@ -297,7 +298,7 @@ namespace PunkHPX8_RT.Devices.EFEM
                 LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"Socket is not Conntected");
                 return false;
             }
-            if(mod == ModuleName.EfemRobot) SetRobotMovingInfo(RobotAction.Homing, Hand.Blade1, ModuleName.EfemRobot);
+            if(mod == ModuleName.EfemRobot) SetRobotMovingInfo(RobotAction.Homing, Hand.Blade1, ModuleName.EfemRobot,Flip.Upper);
             _status = RState.Running;
             string cmd = "Home ALL\r";
             if (mod == ModuleName.Aligner1)
@@ -362,7 +363,7 @@ namespace PunkHPX8_RT.Devices.EFEM
                 Operation = EfemOperation.Abort,
                 Module = ModuleName.EfemRobot
             };
-            SetRobotMovingInfo(RobotAction.None, Hand.Both, ModuleName.EFEM);
+            SetRobotMovingInfo(RobotAction.None, Hand.Both, ModuleName.EFEM,Flip.Upper);
             string cmd = "HALT\r";
             return WriteCommand(cmd);
         }
@@ -477,10 +478,11 @@ namespace PunkHPX8_RT.Devices.EFEM
             }
             _currentMessage = new EfemMessage()
             {
-                Operation=EfemOperation.Pick
+                Operation=EfemOperation.Pick,
+                Flip = flip
             };
             _status = RState.Running;
-            SetRobotMovingInfo(RobotAction.Picking, hand, station);
+            SetRobotMovingInfo(RobotAction.Picking, hand, station, flip);
             return WriteCommand(cmd);
         }
 
@@ -521,7 +523,8 @@ namespace PunkHPX8_RT.Devices.EFEM
             string strModuleWaferSize = $"{station}_{waferSize}_{hand}_{flip}";
             _currentMessage = new EfemMessage()
             {
-                Operation = EfemOperation.Place
+                Operation = EfemOperation.Place,
+                Flip = flip
             };
             _status = RState.Running;
             int stationNumber = _moduleStationNumberDictionary[strModuleWaferSize];
@@ -535,7 +538,7 @@ namespace PunkHPX8_RT.Devices.EFEM
             {
                 cmd = $"PLACE {stationNumber} PHOME\r";
             }
-            SetRobotMovingInfo(RobotAction.Placing, hand, station);
+            SetRobotMovingInfo(RobotAction.Placing, hand, station, flip);
             return WriteCommand(cmd);
         }
 
@@ -1003,9 +1006,9 @@ namespace PunkHPX8_RT.Devices.EFEM
             LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"System cannot support {EfemConstant.OperationString[EfemOperation.SetThickness]}");
             return false;
         }
-        public override void SetRobotMovingInfo(RobotAction action, Hand hand, ModuleName target)
+        public override void SetRobotMovingInfo(RobotAction action, Hand hand, ModuleName target,Flip flip)
         {
-            blockingCollection.Add(new RobotAnimationData(action, hand, target));
+            blockingCollection.Add(new RobotAnimationData(action, hand, target,flip));
         }
 
         private void OnReceiveMessage(string msg)
@@ -1020,7 +1023,7 @@ namespace PunkHPX8_RT.Devices.EFEM
                 string error = msg.Replace("_ERR", "").Trim();
                 OnErrorOccurred(error);
                 _currentMessage = null;
-                SetRobotMovingInfo(RobotAction.None, Hand.Both, ModuleName.EFEM);
+                SetRobotMovingInfo(RobotAction.None, Hand.Both, ModuleName.EFEM, Flip.Upper);
                 return;
             }
             else if (msg.StartsWith("ACTION _RDY"))
@@ -1036,7 +1039,7 @@ namespace PunkHPX8_RT.Devices.EFEM
                 switch (_currentMessage.Operation)
                 {
                     case EfemOperation.Home:
-                        SetRobotMovingInfo(RobotAction.Homing, Hand.Both, ModuleName.EFEM);
+                        SetRobotMovingInfo(RobotAction.Homing, Hand.Both, ModuleName.EFEM, Flip.Upper);
                         break;
                     case EfemOperation.Map:
                     case EfemOperation.GotoMap:
@@ -1047,7 +1050,14 @@ namespace PunkHPX8_RT.Devices.EFEM
                         break;
                     case EfemOperation.Pick:
                     case EfemOperation.Place:
-                        SetRobotMovingInfo(RobotAction.None, Hand.Both, ModuleName.EfemRobot);
+                        if(_currentMessage.Flip == Flip.Down)
+                        {
+                            SetRobotMovingInfo(RobotAction.None, Hand.Both, ModuleName.EfemRobot, Flip.Down);
+                        }
+                        else
+                        {
+                            SetRobotMovingInfo(RobotAction.None, Hand.Both, ModuleName.EfemRobot, Flip.Upper);
+                        }
                         break;
                 }
             }

+ 2 - 2
PunkHPX8_Themes/CustomControls/CustomRobot.cs

@@ -48,8 +48,8 @@ namespace PunkHPX8_Themes.CustomControls
 
     public enum WaferRobotFAction
     {
-        Upper,
-        Down
+        UpperToDown,
+        DownToUpper
     }
 
     public enum WaferRobotTAction

+ 36 - 0
PunkHPX8_Themes/CustomControls/PunkRobotControl.cs

@@ -97,6 +97,42 @@ namespace PunkHPX8_Themes.CustomControls
             }
         }
 
+        public static readonly DependencyProperty RobotFActionProperty = DependencyProperty.Register(
+           "RobotFAction",
+           typeof(WaferRobotFAction),
+           typeof(PunkRobotControl),
+           new PropertyMetadata(WaferRobotFAction.DownToUpper, RobotFActionPropertyChangedCallback));
+        public WaferRobotFAction RobotFAction
+        {
+            get => (WaferRobotFAction)GetValue(RobotFActionProperty);
+            set => SetValue(RobotFActionProperty, value);
+        }
+        private static void RobotFActionPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            //KeyTime value = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(9));
+            var control = d as PunkRobotControl;
+            var oldAct = (WaferRobotFAction)e.OldValue;
+            var newAct = (WaferRobotFAction)e.NewValue;
+            switch (newAct)
+            {
+                
+                case WaferRobotFAction.UpperToDown:
+                    if (newAct != oldAct)
+                    {
+                        VisualStateManager.GoToState(control, newAct.ToString(), true);
+                    }
+                    break;
+                case WaferRobotFAction.DownToUpper:
+                    if (newAct != oldAct)
+                    {
+                        VisualStateManager.GoToState(control, newAct.ToString(), true);
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+
         public static readonly DependencyProperty RobotTActionProperty = DependencyProperty.Register(
            "RobotTAction",
            typeof(WaferRobotTAction),

+ 96 - 4
PunkHPX8_Themes/Themes/Generic.xaml

@@ -1041,10 +1041,53 @@
             <Setter.Value>
                 <ControlTemplate TargetType="{x:Type customControls:PunkRobotControl}">
                     <Viewbox x:Name="viewbox" Stretch="Fill">
-
-                      
-                        
                         <VisualStateManager.VisualStateGroups>
+                            <VisualStateGroup Name="RobotFActions">
+                                <VisualStateGroup.Transitions>
+                                    <VisualTransition To="UpperToDown">
+                                        <Storyboard FillBehavior="HoldEnd" SpeedRatio="18">
+                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="armGripper2" Storyboard.TargetProperty="Visibility">
+                                                <DiscreteObjectKeyFrame KeyTime="0:0:4.5" Value="{x:Static Visibility.Hidden}"/>
+                                            </ObjectAnimationUsingKeyFrames>
+                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="armGripper2Down" Storyboard.TargetProperty="Visibility">
+                                                <DiscreteObjectKeyFrame KeyTime="0:0:4.5" Value="{x:Static Visibility.Visible}"/>
+                                            </ObjectAnimationUsingKeyFrames>
+                                        </Storyboard>
+                                    </VisualTransition>
+                                    <VisualTransition To="DownToUpper">
+                                        <Storyboard FillBehavior="HoldEnd" SpeedRatio="18">
+                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="armGripper2" Storyboard.TargetProperty="Visibility">
+                                                <DiscreteObjectKeyFrame KeyTime="0:0:4.5" Value="{x:Static Visibility.Hidden}"/>
+                                            </ObjectAnimationUsingKeyFrames>
+                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="armGripper2Down" Storyboard.TargetProperty="Visibility">
+                                                <DiscreteObjectKeyFrame KeyTime="0:0:4.5" Value="{x:Static Visibility.Visible}"/>
+                                            </ObjectAnimationUsingKeyFrames>
+                                        </Storyboard>
+                                    </VisualTransition>
+                                </VisualStateGroup.Transitions>
+
+                                <VisualState Name="UpperToDown">
+                                    <Storyboard FillBehavior="HoldEnd">
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="armGripper2" Storyboard.TargetProperty="Visibility">
+                                            <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Hidden}"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="armGripper2Down" Storyboard.TargetProperty="Visibility">
+                                            <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState Name="DownToUpper">
+                                    <Storyboard FillBehavior="HoldEnd">
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="armGripper2" Storyboard.TargetProperty="Visibility">
+                                            <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="armGripper2Down" Storyboard.TargetProperty="Visibility">
+                                            <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Hidden}"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                            </VisualStateGroup>
+                            
                             <VisualStateGroup Name="RobotXActions">
                                 <VisualStateGroup.Transitions>
                                     <VisualTransition To="Extend">
@@ -1066,6 +1109,10 @@
                                                 <LinearDoubleKeyFrame Value="90" KeyTime="0:0:0"/>
                                                 <LinearDoubleKeyFrame Value="90" KeyTime="0:0:9"/>
                                             </DoubleAnimationUsingKeyFrames>
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="grip2DownRotateAct" Storyboard.TargetProperty="Angle">
+                                                <LinearDoubleKeyFrame Value="90" KeyTime="0:0:0"/>
+                                                <LinearDoubleKeyFrame Value="90" KeyTime="0:0:9"/>
+                                            </DoubleAnimationUsingKeyFrames>
                                         </Storyboard>
                                     </VisualTransition>
                                     <VisualTransition To="Retract">
@@ -1087,6 +1134,10 @@
                                                 <LinearDoubleKeyFrame Value="90" KeyTime="0:0:0"/>
                                                 <LinearDoubleKeyFrame Value="90" KeyTime="0:0:9"/>
                                             </DoubleAnimationUsingKeyFrames>
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="grip2DownRotateAct" Storyboard.TargetProperty="Angle">
+                                                <LinearDoubleKeyFrame Value="90" KeyTime="0:0:0"/>
+                                                <LinearDoubleKeyFrame Value="90" KeyTime="0:0:9"/>
+                                            </DoubleAnimationUsingKeyFrames>
 
                                         </Storyboard>
                                     </VisualTransition>
@@ -1108,6 +1159,12 @@
                                                 <LinearDoubleKeyFrame Value="-30" KeyTime="0:0:6"/>
                                                 <LinearDoubleKeyFrame Value="-90" KeyTime="0:0:9"/>
                                             </DoubleAnimationUsingKeyFrames>
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="grip2DownRotateAct" Storyboard.TargetProperty="Angle">
+                                                <LinearDoubleKeyFrame Value="90" KeyTime="0:0:0"/>
+                                                <LinearDoubleKeyFrame Value="30" KeyTime="0:0:3"/>
+                                                <LinearDoubleKeyFrame Value="-30" KeyTime="0:0:6"/>
+                                                <LinearDoubleKeyFrame Value="-90" KeyTime="0:0:9"/>
+                                            </DoubleAnimationUsingKeyFrames>
                                         </Storyboard>
                                     </VisualTransition>
                                     <VisualTransition To="Retract2">
@@ -1128,6 +1185,12 @@
                                                 <LinearDoubleKeyFrame Value="-30" KeyTime="0:0:3"/>
                                                 <LinearDoubleKeyFrame Value="-90" KeyTime="0:0:0"/>
                                             </DoubleAnimationUsingKeyFrames>
+                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="grip2DownRotateAct" Storyboard.TargetProperty="Angle">
+                                                <LinearDoubleKeyFrame Value="90" KeyTime="0:0:9"/>
+                                                <LinearDoubleKeyFrame Value="30" KeyTime="0:0:6"/>
+                                                <LinearDoubleKeyFrame Value="-30" KeyTime="0:0:3"/>
+                                                <LinearDoubleKeyFrame Value="-90" KeyTime="0:0:0"/>
+                                            </DoubleAnimationUsingKeyFrames>
                                         </Storyboard>
                                     </VisualTransition>
                                 </VisualStateGroup.Transitions>
@@ -1147,6 +1210,9 @@
                                         <DoubleAnimationUsingKeyFrames Storyboard.TargetName="grip2RotateAct" Storyboard.TargetProperty="Angle">
                                             <LinearDoubleKeyFrame Value="90" KeyTime="0:0:0"/>
                                         </DoubleAnimationUsingKeyFrames>
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="grip2DownRotateAct" Storyboard.TargetProperty="Angle">
+                                            <LinearDoubleKeyFrame Value="90" KeyTime="0:0:0"/>
+                                        </DoubleAnimationUsingKeyFrames>
                                     </Storyboard>
                                 </VisualState>
                                 <VisualState Name="Extend">
@@ -1160,6 +1226,9 @@
                                         <DoubleAnimationUsingKeyFrames Storyboard.TargetName="grip2RotateAct" Storyboard.TargetProperty="Angle">
                                             <LinearDoubleKeyFrame Value="90" KeyTime="0:0:0"/>
                                         </DoubleAnimationUsingKeyFrames>
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="grip2DownRotateAct" Storyboard.TargetProperty="Angle">
+                                            <LinearDoubleKeyFrame Value="90" KeyTime="0:0:0"/>
+                                        </DoubleAnimationUsingKeyFrames>
                                     </Storyboard>
                                 </VisualState>
                                 <VisualState Name="Retract">
@@ -1173,6 +1242,9 @@
                                         <DoubleAnimationUsingKeyFrames Storyboard.TargetName="grip2RotateAct" Storyboard.TargetProperty="Angle">
                                             <LinearDoubleKeyFrame Value="90" KeyTime="0:0:0"/>
                                         </DoubleAnimationUsingKeyFrames>
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="grip2DownRotateAct" Storyboard.TargetProperty="Angle">
+                                            <LinearDoubleKeyFrame Value="90" KeyTime="0:0:0"/>
+                                        </DoubleAnimationUsingKeyFrames>
                                     </Storyboard>
                                 </VisualState>
                                 <VisualState Name="Extend2">
@@ -1186,6 +1258,9 @@
                                         <DoubleAnimationUsingKeyFrames Storyboard.TargetName="grip2RotateAct" Storyboard.TargetProperty="Angle">
                                             <LinearDoubleKeyFrame Value="-90" KeyTime="0:0:0"/>
                                         </DoubleAnimationUsingKeyFrames>
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="grip2DownRotateAct" Storyboard.TargetProperty="Angle">
+                                            <LinearDoubleKeyFrame Value="-90" KeyTime="0:0:0"/>
+                                        </DoubleAnimationUsingKeyFrames>
                                     </Storyboard>
                                 </VisualState>
                                 <VisualState Name="Retract2">
@@ -1199,6 +1274,9 @@
                                         <DoubleAnimationUsingKeyFrames Storyboard.TargetName="grip2RotateAct" Storyboard.TargetProperty="Angle">
                                             <LinearDoubleKeyFrame Value="90" KeyTime="0:0:0"/>
                                         </DoubleAnimationUsingKeyFrames>
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="grip2DownRotateAct" Storyboard.TargetProperty="Angle">
+                                            <LinearDoubleKeyFrame Value="90" KeyTime="0:0:0"/>
+                                        </DoubleAnimationUsingKeyFrames>
                                     </Storyboard>
                                 </VisualState>
 
@@ -1601,13 +1679,27 @@
 
                                         <Canvas x:Name="armGripper2" Height="120" Width="50"  Canvas.Left="-30" Canvas.Top="-100" RenderTransformOrigin="0.5,1">
                                             <Canvas.RenderTransform>
-                                                <RotateTransform x:Name="grip2RotateAct"/>
+                                                <TransformGroup>
+                                                    <RotateTransform x:Name="grip2RotateAct"/>
+                                                </TransformGroup>
                                             </Canvas.RenderTransform>
                                             <Image Width="48" Source="pack://application:,,,/PunkHPX8_Themes;component/Themes/Images/parts/atmrobot/hand1.png"></Image>
                                             <Viewbox Canvas.Left="-20" Canvas.Top="-30" Width="85" Height="85">
                                                 <userControls:WaferCtrl WaferData="{Binding Robot2Wafer,RelativeSource={RelativeSource TemplatedParent}}"/>
                                             </Viewbox>
                                         </Canvas>
+
+                                        <Canvas x:Name="armGripper2Down" Height="120" Width="50"  Canvas.Left="-30" Canvas.Top="-100" RenderTransformOrigin="0.5,1">
+                                            <Canvas.RenderTransform>
+                                                <TransformGroup>
+                                                    <RotateTransform x:Name="grip2DownRotateAct"/>
+                                                </TransformGroup>
+                                            </Canvas.RenderTransform>
+                                            <Image Width="48" Source="pack://application:,,,/PunkHPX8_Themes;component/Themes/Images/parts/atmrobot/hand1.png" Panel.ZIndex="1"></Image>
+                                            <Viewbox Canvas.Left="-20" Canvas.Top="-30" Width="85" Height="85" Panel.ZIndex="0">
+                                                <userControls:WaferCtrl WaferData="{Binding Robot2Wafer,RelativeSource={RelativeSource TemplatedParent}}"/>
+                                            </Viewbox>
+                                        </Canvas>
                                     </Canvas>
                                 </Canvas>
                             </Canvas>

+ 2 - 1
PunkHPX8_Themes/UserControls/CellChamber.xaml

@@ -413,7 +413,8 @@
             <Canvas Width="500" Height="500" Canvas.Left="670" Canvas.Top="560">
                 <customControls:PunkRobotControl  OriginT="T_Origin"  Canvas.Left="-30" Canvas.Top="-180"   Width="540" Height="810"     
                                                   RobotTAction="{Binding ElementName=efem,Path=RobotATAction}"  
-                                                  RobotXAction="{Binding ElementName=efem,Path=RobotAXAction}" 
+                                                  RobotXAction="{Binding ElementName=efem,Path=RobotAXAction}"
+                                                  RobotFAction="{Binding ElementName=efem,Path=RobotBFAction}" 
                                                   RobotWafer="{Binding ElementName=efem,Path=RobotAWaferInfo}"
                                                   Robot2Wafer="{Binding ElementName=efem,Path=RobotBWaferInfo}"/>
             </Canvas>

+ 9 - 0
PunkHPX8_Themes/UserControls/CellChamber.xaml.cs

@@ -218,6 +218,15 @@ namespace PunkHPX8_Themes.UserControls
             set { this.SetValue(RobotAXActionProperty, value); }
         }
 
+        public static readonly DependencyProperty RobotBFActionProperty = DependencyProperty.Register(
+        "RobotBFAction", typeof(WaferRobotFAction), typeof(CellChamber),
+        new FrameworkPropertyMetadata(WaferRobotFAction.DownToUpper, FrameworkPropertyMetadataOptions.AffectsRender));
+        public WaferRobotFAction RobotBFAction
+        {
+            get { return (WaferRobotFAction)this.GetValue(RobotBFActionProperty); }
+            set { this.SetValue(RobotBFActionProperty, value); }
+        }
+
 
         public static readonly DependencyProperty RobotAWaferInfoProperty = DependencyProperty.Register(
     "RobotAWaferInfo", typeof(WaferInfo), typeof(CellChamber));