Quellcode durchsuchen

1.revise robot device safeOpen/Close logic
2.add saveOpen/Close simulator

chenzk vor 1 Tag
Ursprung
Commit
e2761d1248

+ 7 - 1
CyberX8_RT/Devices/EFEM/SunWayRobot.cs

@@ -979,7 +979,7 @@ namespace CyberX8_RT.Devices.EFEM
                 IsPauseRDYReceived = false;
                 IsActionRDYReceived = true;
             }
-            else if (msg.Contains("_RDY"))
+            else if (msg.StartsWith("_RDY"))
             {
                 _status = RState.End;
                 switch (_currentMessage.Operation)
@@ -998,6 +998,12 @@ namespace CyberX8_RT.Devices.EFEM
                     case EfemOperation.Place:
                         SetRobotMovingInfo(RobotAction.None, Hand.Both, ModuleName.EfemRobot);
                         break;
+                }
+            }
+            else if (msg.Contains("PAUSE_RDY") || msg.Contains("RESUME_RDY"))
+            {
+                switch (_currentMessage.Operation)
+                {
                     case EfemOperation.Pause:
                         //SetRobotMovingInfo(RobotAction.None, Hand.Both, ModuleName.EfemRobot);
                         IsPauseRDYReceived = true;

+ 90 - 135
CyberX8_Simulator/Devices/SunWayEfemSimulator.cs

@@ -38,11 +38,16 @@ namespace CyberX8_Simulator.Devices
         private bool _isLP3Docked;
         public int WaferSize = 200;
         private int _speed = 20;
-        private string _carrier1ID = "12345678";
-        private string _carrier2ID = "12345678";
-        private string _carrier3ID = "12345678";
+
         private List<int> _lpStationNumber; 
-        private List<int> _dummyStationNumber; 
+        private List<int> _dummyStationNumber;
+
+
+        private readonly Queue<(string ack, TaskCompletionSource<bool> tcs)> _pendingAcks = new Queue<(string, TaskCompletionSource<bool>)>();
+        private readonly object _syncRoot = new object();
+        private bool _isPaused;
+
+
         public string SlotMap
         {
             get { return string.Join("", _slotMap); }
@@ -55,8 +60,6 @@ namespace CyberX8_Simulator.Devices
         public bool _isMaintain { get;  set; }
         public bool _isWaferPresent { get;  set; }
         public bool _isMaintainDoorOpen { get; private set; }
-
-
         public bool _isProtrude1 { get; set; }
         public bool _isProtrude2 { get; set; }
         public bool _isVAC { get; set; }
@@ -87,6 +90,31 @@ namespace CyberX8_Simulator.Devices
             GetStationNumber();
         }
 
+        private void Pause()
+        {
+            lock (_syncRoot)
+            {
+                _isPaused = true;
+            }
+        }
+
+        private void Resume()
+        {
+            lock (_syncRoot)
+            {
+                _isPaused = false;
+
+                // 发送所有积压的消息
+                while (_pendingAcks.Count > 0)
+                {
+                    var (ack, tcs) = _pendingAcks.Dequeue();
+                    OnWriteMessage(ack);
+                    tcs.TrySetResult(true);
+                }
+            }
+        }
+
+
         private bool OnSendEvent()
         {
             if (IsConnected)
@@ -170,12 +198,13 @@ namespace CyberX8_Simulator.Devices
             string msg = $"EVT:SIGSTAT/System/{data:X8}/00000000;";
             OnWriteMessage(msg);
         }
-        private void OnWork(string str)
+        private async void OnWork(string str)
         {
             string ack = "";
             if (str.StartsWith("RQ LOAD")) //查询手指是否带片
             {
                 ack = "LOAD A OFF\n_RDY";
+                OnWriteMessage(ack);
             }
             else if (str.StartsWith("RSR"))  //返回扫片结果
             {
@@ -199,152 +228,78 @@ namespace CyberX8_Simulator.Devices
                     }
                     ack = "MAP" + dummywafer;
                 }
+                OnWriteMessage(ack);
             }
             else if (str.StartsWith("PAUSE"))
             {
+                Pause();
                 ack = "PAUSE_RDY";
+                OnWriteMessage(ack);
             }
             else if(str.StartsWith("RESUME"))
             {
+                Resume();
                 ack = "RESUME_RDY";
+                OnWriteMessage(ack);
                 _ = Task.Run(DelayAnswerResume); // 启动后台任务
+                
 
             }
             else //默认回复
             {
+                ack = "_RDY";
                 if (str.StartsWith("PICK") || str.StartsWith("PLACE") || str.StartsWith("MAP")
-                    || str.StartsWith("ALIGNER ALGN") || str.StartsWith("ALIGNER HOME"))
+                   || str.StartsWith("ALIGNER ALGN") || str.StartsWith("ALIGNER HOME"))
+                {
+                    var tcs = new TaskCompletionSource<bool>();
+
+                    lock (_syncRoot)
+                    {
+                        // 如果已经暂停,直接加入队列
+                        if (_isPaused)
+                        {
+                            _pendingAcks.Enqueue((ack, tcs));
+                            return;
+                        }
+                    }
+
+                    // 启动延迟任务
+                    var delayTask = Task.Delay(3200);
+
+                    // 创建监控任务
+                    var monitorTask = Task.Run(async () =>
+                    {
+                        while (!delayTask.IsCompleted)
+                        {
+                            await Task.Delay(100);
+                            lock (_syncRoot)
+                            {
+                                if (_isPaused)
+                                {
+                                    _pendingAcks.Enqueue((ack, tcs));
+                                    return;
+                                }
+                            }
+                        }
+
+                        // 延迟完成且未被暂停
+                        OnWriteMessage(ack);
+                        tcs.SetResult(true);
+                    });
+
+                    await monitorTask;
+                }
+                else
                 {
-                    Thread.Sleep((ushort)2200);
+                    OnWriteMessage(ack);
                 }
-                ack = "_RDY";
-            }
-            OnWriteMessage(ack);
-            //// match basic
-            //Match m1 = Regex.Match(strACK, SCMD);
-
-            //// get mock delay time
-            //string sBasic = m1.Groups[1].Value;
-
-            //if (string.IsNullOrEmpty(sBasic))
-            //    return;
-
-
-
-            //EfemOperation op = EfemConstant.ToOperation(sBasic);
-            //ushort millionSec = this.SimuOperationTime(op);
-
-            //// delay
-            ////await Task.Delay(millionSec);
-            //Thread.Sleep(millionSec);
-
-            //// build the INF string
-            //string strINF = string.Empty;
-
-            //switch (EfemConstant.ToOperation(strACK))
-            //{
-            //    case EfemOperation.GetWaferInfo:
-            //        strINF = strACK.Replace(ACK, "INF");
-            //        strINF = strINF.TrimEnd(';');
-            //        string map1 = string.Join("", _slotMap);
-            //        strINF += $"/{map1};";
-            //        break;
-            //    case EfemOperation.Home:
-            //        int data1 = 0b011111111010100000;
-            //        string s1 = $"EVT:SIGSTAT/LP1/00000000/00000003;\rEVT:SIGSTAT/LP2/0000000/00000003;\rEVT:SIGSTAT/LP3/000000/00000003;\rEVT:SIGSTAT/System/{data1}/00000;\r";
-
-            //        strINF = s1 + strACK.Replace(ACK, "INF");
-            //        SendSystemData();
-            //        SendLP1Data();
-            //        SendLP2Data();
-            //        SendLP3Data();
-            //        SendAlignData();
-            //        OnWriteMessage(strACK.Replace(ACK, "INF"));
-            //        return;
-            //    case EfemOperation.Map:
-            //        if(strACK.Contains("BF"))
-            //        {
-            //            string map = string.Join("", _slotDummy);
-            //            string strEVT = strACK.Replace(ACK,"EVT");
-            //            strEVT = strEVT.Replace("WAFSH","MAPDT");
-            //            strEVT = strEVT.TrimEnd(';');
-            //            string str = $"{strEVT}/{map};";
-            //            OnWriteMessage(str);
-            //        }
-            //        else if (strACK.Contains("LP"))
-            //        {
-            //            string map = string.Join("", _slotMap);
-            //            string strEVT = strACK.Replace(ACK, "EVT");
-            //            strEVT = strEVT.Replace("WAFSH", "MAPDT");
-            //            strEVT = strEVT.TrimEnd(';');
-            //            string str = $"{strEVT}/{map};";
-            //            OnWriteMessage(str);
-            //        }
-            //        strINF = strACK.Replace(ACK, "INF");
-            //        break;
-            //    case EfemOperation.Load:                  
-            //            strINF = strACK.Replace(ACK, "INF"); 
-            //        break;
-            //    case EfemOperation.StateTrack:
-            //        strINF = "INF:STATE/TRACK/NONE/NONE;";
-            //        break;
-            //    case EfemOperation.CarrierId:
-
-
-            //        break;
-
-            //    case EfemOperation.Size:
-
-            //        break;
-            //    case EfemOperation.Dock:
-            //        Match mDock = Regex.Match(strACK, SFOUP);
-            //        if (mDock.Success)
-            //        {
-            //            UpdateLocked(mDock.Groups[1].Value, true);
-            //        }
-            //        strINF = strACK.Replace(ACK, "INF");
-            //        break;
-            //    case EfemOperation.Undock:
-            //        Match mUnDock = Regex.Match(strACK, SFOUP);
-            //        if (mUnDock.Success)
-            //        {
-            //            UpdateLocked(mUnDock.Groups[1].Value, false);
-            //        }
-            //        strINF = strACK.Replace(ACK, "INF");
-            //        break;
-            //    case EfemOperation.Clamp:
-            //        Match mClamp= Regex.Match(strACK, SFOUP);
-            //        if (mClamp.Success)
-            //        {
-            //            UpdateClamped(mClamp.Groups[1].Value, true);
-            //        }
-            //        strINF = strACK.Replace(ACK, "INF");
-            //        break;
-            //    case EfemOperation.Unclamp:
-            //        Match mUnClamp = Regex.Match(strACK, SFOUP);
-            //        if (mUnClamp.Success)
-            //        {
-            //            UpdateClamped(mUnClamp.Groups[1].Value, false);
-            //        }
-            //        strINF = strACK.Replace(ACK, "INF");
-            //        break;
-            //    case EfemOperation.Speed:
-
-            //        break;
-            //    case EfemOperation.Align:
-            //    case EfemOperation.Pick:
-            //    case EfemOperation.Place:
-            //    case EfemOperation.Orgsh:
-            //    case EfemOperation.Light:
-            //    case EfemOperation.SigStatus:
-            //    default:
-            //        strINF = strACK.Replace(ACK, "INF");
-            //        break;
-            //}
-
-            //OnWriteMessage(strINF);
 
+            }
+           
         }
+
+       
+
         private void DelayAnswerResume()
         {
             Thread.Sleep((ushort)3000);