JetFlipper.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. using Aitex.Core.RT.IOCore;
  2. using Aitex.Core.RT.Log;
  3. using Aitex.Core.Util;
  4. using System;
  5. using System.Xml;
  6. namespace EFEM.RT.Devices.Flipper
  7. {
  8. public class JetFlipper : FlipperBase
  9. {
  10. private DIAccessor _diIsOrigin;//是否在原点即0°-- IsOrigin==true && IsHorizontal==true为0°
  11. private DIAccessor _diIsHorizontal;//是否在水平 -- IsOrigin==false && IsHorizontal==true为180°
  12. private DIAccessor _diIsTurnOK;//是否在旋转中
  13. private DIAccessor _diIsClampOK;//是否在Clamp中
  14. private DIAccessor _diTurnOverMotorAlarm;//无法旋转警告
  15. private DIAccessor _diEnableToRobot;//是否Robot可伸向
  16. private DIAccessor _diIsClampOpen;//是否打开Clamp(UnGrip)
  17. private DIAccessor _diIsClampClose;//是否关闭Clamp(Grip)
  18. private DIAccessor _diClampMotorAlarm;//无法夹紧警告
  19. private DOAccessor _doTurnOverRunMode;//旋转模式 -- TurnHome_START_STOP==true && TurnOverRunMode=false旋转到0°
  20. private DOAccessor _doTurnHome_START_STOP;//开始/停止动作,取决于Run Mode -- TurnHome_START_STOP==true && TurnOverRunMode=true 旋转到180°
  21. private DOAccessor _doTurnOverPositionA;//转到预设角度A
  22. private DOAccessor _doTurnOverPositionB;//转到预设角度B
  23. private DOAccessor _doTurnOverPositionC;//转到预设角度C
  24. private DOAccessor _doClampRunMode;//Clamp模式 -- ClampHome_START_STOP==true && ClampRunMode=false为Clamp关闭
  25. private DOAccessor _doClampHome_START_STOP;//Clamp开始/停止动作 -- ClampHome_START_STOP==true && ClampRunMode=true为Clamp打开
  26. private DOAccessor _doClampPositionA;//到预设位置A
  27. private DOAccessor _doClampPositionB;//到预设位置B
  28. private DOAccessor _doClampPositionC;//到预设位置C
  29. private DOAccessor _doClearClampAlarm;//清除Clamp警告
  30. private DOAccessor _doClearTurnOverAlarm;//清除TurnOver警告
  31. private DOAccessor _doTurnOverJOGP;//TurnOver JogP
  32. private DOAccessor _doTurnOverJOGN;//TurnOver JogN
  33. private DOAccessor _doTurnOverJOG0;//TurnOver 设置原点位
  34. private DOAccessor _doClampJOGP;//Clamp JogP
  35. private DOAccessor _doClampJOGN;//Clamp JogN
  36. private DOAccessor _doClampJOG0;//Clamp 设置原点位(前提ClampClosed)
  37. private bool _NotFlipped => _diIsOrigin.Value && _diIsHorizontal.Value;
  38. private string _module;
  39. private FlipperState _state;
  40. private DeviceTimer _timer;
  41. private bool _targetClampON;
  42. private string jogNP;
  43. public override bool IsBusy => !_diIsTurnOK.Value || !_diIsClampOK.Value;//旋转且夹紧完成
  44. public override bool IsError => !_diClampMotorAlarm.Value || !_diTurnOverMotorAlarm.Value;
  45. public override bool IsReadyForRobot => _diEnableToRobot.Value;//是否Robot可以向Flipper取放
  46. public override bool IsClampOpen => _diIsClampOpen.Value;//是否打开
  47. public override bool IsClampClose => _diIsClampClose.Value;//是否打开
  48. public bool IsFlipperOrigin => _diIsOrigin.Value && _diIsHorizontal.Value;//是否在原点(0°)
  49. public bool IsFlipperHorizontal => _diIsHorizontal.Value && !_diIsOrigin.Value;//是否在反面(180°)
  50. public bool IsFlipperOverOrigin => _diIsOrigin.Value;//是否反转(UI)
  51. public override FlipperState State => _state;
  52. public R_TRIG _trigError = new R_TRIG();
  53. //flipper的业务主要分为3件事
  54. //clamp
  55. //TurnOver
  56. //Home/Initialize
  57. public JetFlipper(string module, XmlElement node, string ioModule = "")
  58. {
  59. base.Module = (string.IsNullOrEmpty(node.GetAttribute("module")) ? module : node.GetAttribute("module"));
  60. base.Name = node.GetAttribute("id");
  61. base.Display = node.GetAttribute("display");
  62. base.DeviceID = node.GetAttribute("schematicId");
  63. //Name = module.ToString();
  64. _module = module;
  65. _state = FlipperState.Init;
  66. _diIsOrigin = ParseDiNode("diFlipperTurnOverOriginSensor", node, ioModule);
  67. _diIsHorizontal = ParseDiNode("diFlipperTurnOverHorizontalSensor", node, ioModule);
  68. _diIsTurnOK = ParseDiNode("diFlipperTurnOverMotorPosCompleted", node, ioModule);
  69. _diTurnOverMotorAlarm = ParseDiNode("diFlipperTurnOverMotorAlarm", node, ioModule);
  70. _diEnableToRobot = ParseDiNode("diFlipperEnableToRobot", node, ioModule);
  71. _diIsClampClose = ParseDiNode("diFlipperClampClosedSensor", node, ioModule);
  72. _diIsClampOpen = ParseDiNode("diFlipperClampOpenedSensor", node, ioModule);
  73. _diIsClampOK = ParseDiNode("diFlipperClampMotorPosCompleted", node, ioModule);
  74. _diClampMotorAlarm = ParseDiNode("diFlipperClampMotorAlarm", node, ioModule);
  75. _doTurnOverRunMode = ParseDoNode("doFlipperTurnOverMotorModeSW", node, ioModule);
  76. _doClampRunMode = ParseDoNode("doFlipperClampMotorModeSW", node, ioModule);
  77. _doTurnHome_START_STOP = ParseDoNode("doFlipperTurnOverStartStop", node, ioModule);
  78. _doClampHome_START_STOP = ParseDoNode("doFlipperClampSTARTSTOP", node, ioModule);
  79. _doTurnOverPositionA = ParseDoNode("doFlipperTurnOverSEL0", node, ioModule);
  80. _doTurnOverPositionB = ParseDoNode("doFlipperTurnOverSEL1", node, ioModule);
  81. _doTurnOverPositionC = ParseDoNode("doFlipperTurnOverSEL2", node, ioModule);
  82. _doClampPositionA = ParseDoNode("doFlipperClampSEL0", node, ioModule);
  83. _doClampPositionB = ParseDoNode("doFlipperClampSEL1", node, ioModule);
  84. _doClampPositionC = ParseDoNode("doFlipperClampSEL2", node, ioModule);
  85. _doClearClampAlarm = ParseDoNode("doFlipperClampPGMRES", node, ioModule);
  86. _doClearTurnOverAlarm = ParseDoNode("doFlipperTurnOverPgmres", node, ioModule);
  87. _doTurnOverJOGP = ParseDoNode("doFlipperTurnOverSEL0", node, ioModule);
  88. _doTurnOverJOGN = ParseDoNode("doFlipperTurnOverSEL1", node, ioModule);
  89. _doTurnOverJOG0 = ParseDoNode("doFlipperTurnOverSEL2", node, ioModule);
  90. _doClampJOGP = ParseDoNode("doFlipperClampSEL0", node, ioModule);
  91. _doClampJOGN = ParseDoNode("doFlipperClampSEL1", node, ioModule);
  92. _doClampJOG0 = ParseDoNode("doFlipperClampSEL2", node, ioModule);
  93. _timer = new DeviceTimer();
  94. }
  95. public override bool Home()
  96. {
  97. //在夹子关闭的状态下方可执行 否则在旋转过程中可能会导致wafer滑落
  98. //IO中已有interlock 是否拦两层?
  99. //整Home动作不能直接一个命令 应该分为两组 首先是闭合确认 然后是旋转home
  100. //LogObject.Error(_module.ToString(), $"flipper HOME:status = {_state}.");
  101. if (_state == FlipperState.Init || _state == FlipperState.Idle || _state == FlipperState.Error || _state == FlipperState.Gripping)
  102. {
  103. string reason = "";
  104. LOG.Info($"{_module.ToString()}: Home start");
  105. _state = FlipperState.Homing;
  106. return true;
  107. //超时时间60s
  108. //_timer.Start(60000);
  109. }
  110. else
  111. {
  112. _trigError.CLK = true;
  113. _state = FlipperState.Error;
  114. LOG.Error($"{_module.ToString()}: Home failed. Status:{_state}.");
  115. return false;
  116. }
  117. }
  118. public override void Monitor()
  119. {
  120. try
  121. {
  122. //超时就直接错误
  123. //if (_timer.IsTimeout())
  124. // _state = FlipperState.Error;
  125. switch (State)
  126. {
  127. case FlipperState.Gripping:
  128. if (IsClampClose)
  129. {
  130. _doClampRunMode.SetValue(false, out _);
  131. _doClampHome_START_STOP.SetValue(false, out _);
  132. _state = FlipperState.Idle;
  133. LOG.Info($"{_module.ToString()}: Grip is completed");
  134. }
  135. else
  136. {
  137. //_doClampHome_START_STOP.SetValue(true, out _);
  138. _doClampRunMode.SetValue(false, out _);
  139. _doClampHome_START_STOP.SetValue(true, out _);
  140. }
  141. break;
  142. case FlipperState.UnGripping:
  143. if (IsClampOpen)
  144. {
  145. _doClampRunMode.SetValue(false, out _);
  146. _doClampHome_START_STOP.SetValue(false, out _);
  147. _state = FlipperState.Idle;
  148. LOG.Info($"{_module.ToString()}: UnGrip is completed");
  149. }
  150. else
  151. {
  152. _doClampRunMode.SetValue(true, out _);
  153. _doClampHome_START_STOP.SetValue(true, out _);
  154. //_doClampPositionA.SetValue(true, out _);
  155. }
  156. break;
  157. case FlipperState.TurnOverJog:
  158. if (jogNP == "P")
  159. {
  160. _doTurnOverJOGP.SetValue(true, out _);
  161. }
  162. else { _doTurnOverJOGN.SetValue(true, out _); }
  163. break;
  164. case FlipperState.TurnOverJogStop:
  165. if (jogNP == "P")
  166. {
  167. _doTurnOverJOGP.SetValue(false, out _);
  168. }
  169. else
  170. {
  171. _doTurnOverJOGN.SetValue(false, out _);
  172. }
  173. _state = FlipperState.Idle;
  174. break;
  175. case FlipperState.Turning:
  176. //_diIsHorizontal = true and _diIsOrigin = true: 0°
  177. //_diIsHorizontal = true and _diIsOrigin = false: 180°
  178. if (_diIsHorizontal.Value && !_diIsOrigin.Value)//180°
  179. {
  180. _doTurnOverRunMode.SetValue(false, out _);
  181. _doTurnHome_START_STOP.SetValue(false, out _);
  182. _state = FlipperState.Idle;
  183. }
  184. else
  185. {
  186. _doTurnOverRunMode.SetValue(true, out _);
  187. _doTurnHome_START_STOP.SetValue(true, out _);
  188. }
  189. break;
  190. case FlipperState.Homing:
  191. if (_diIsHorizontal.Value && _diIsOrigin.Value)//0°为Home位置
  192. {
  193. _doTurnOverRunMode.SetValue(false, out _);
  194. _doTurnHome_START_STOP.SetValue(false, out _);
  195. _state = FlipperState.Idle;
  196. }
  197. else
  198. {
  199. _doTurnOverRunMode.SetValue(false, out _);
  200. _doTurnHome_START_STOP.SetValue(true, out _);
  201. }
  202. break;
  203. case FlipperState.Idle:
  204. _doClampRunMode.SetValue(false, out _);
  205. _doClampHome_START_STOP?.SetValue(false, out _);
  206. _doTurnOverRunMode.SetValue(false, out _);
  207. _doTurnHome_START_STOP.SetValue(false, out _);
  208. break;
  209. default:
  210. break;
  211. }
  212. //如果是错误
  213. _trigError.CLK = State == FlipperState.Error;
  214. //DO_SafetytoFLP触发(待添加)
  215. if (_diIsHorizontal.Value && _diIsClampOpen.Value && _diEnableToRobot.Value)
  216. {
  217. //+ Safety to FLP sw interlock逻辑
  218. }
  219. }
  220. catch (Exception ex)
  221. {
  222. LOG.Error($"{_module.ToString()}: {ex}");
  223. }
  224. }
  225. public override bool TurnOver()
  226. {
  227. if (_state == FlipperState.Idle && IsClampClose)
  228. {
  229. if (_NotFlipped)
  230. _state = FlipperState.Turning;
  231. else
  232. _state = FlipperState.Homing;
  233. LOG.Info($"{_module.ToString()}: Turn over start");
  234. return true;
  235. //超时时间60s
  236. //_timer.Start(60000);
  237. }
  238. else
  239. {
  240. if (_state != FlipperState.Idle)
  241. {
  242. LOG.Error($"{_module.ToString()}: Turn over failed. Status:{_state}");
  243. }
  244. if (!IsClampClose)
  245. {
  246. LOG.Error($"{_module.ToString()}: Turn over failed. Clamp is not closed");
  247. }
  248. _trigError.CLK = true;
  249. _state = FlipperState.Error;
  250. return false;
  251. }
  252. }
  253. public override bool Clamp(bool ClampOn)
  254. {
  255. _targetClampON = ClampOn;
  256. if (_state == FlipperState.Idle || _state == FlipperState.Init)
  257. {
  258. //关闭
  259. if (ClampOn)
  260. {
  261. LOG.Info($"{_module.ToString()}: Clamp start");
  262. _state = FlipperState.Gripping;
  263. }
  264. //打开
  265. else
  266. {
  267. LOG.Info($"{_module.ToString()}: UnClamp start");
  268. _state = FlipperState.UnGripping;
  269. }
  270. return true;
  271. }
  272. else
  273. {
  274. LOG.Error($"{_module.ToString()}: Clamp failed. Status:{_state}");
  275. return false;
  276. }
  277. }
  278. public bool TrunOverJog(string NorP)
  279. {
  280. LOG.Info($"{_module.ToString()}: TurnOverJog-{NorP} start");
  281. jogNP = NorP;
  282. if (jogNP == "P")
  283. {
  284. _state = FlipperState.TurnOverJog;
  285. }
  286. else
  287. {
  288. _state = FlipperState.TurnOverJog;
  289. }
  290. return true;
  291. }
  292. public bool TrunOverJogStop(string NorP)
  293. {
  294. LOG.Info($"{_module.ToString()}: TurnOverJog-{NorP} stop");
  295. jogNP = NorP;
  296. if (jogNP == "P")
  297. {
  298. _state = FlipperState.TurnOverJogStop;
  299. }
  300. else
  301. {
  302. _state = FlipperState.TurnOverJogStop;
  303. }
  304. return true;
  305. }
  306. public override void Reset()
  307. {
  308. //错误条件下方可执行
  309. if (State == FlipperState.Error)
  310. {
  311. string error_reason;
  312. if (_doClearClampAlarm.SetValue(false, out error_reason) &&
  313. _doClearTurnOverAlarm.SetValue(false, out error_reason))
  314. {
  315. _trigError.RST = true;//清除错误
  316. _state = FlipperState.Idle;//可以直接出状态
  317. }
  318. else
  319. {
  320. LOG.Error($"{_module.ToString()}: Clear error failed. Reason:{error_reason}");
  321. }
  322. }
  323. _state = FlipperState.Idle;
  324. }
  325. public override void ShowAction()
  326. {
  327. LOG.Info($"{_module.ToString()}: TurnOver complete:{_diIsTurnOK.Value}, Clamp complete:{_diIsClampOK.Value}");
  328. }
  329. public bool IsEnableTransferWafer(out string reason)
  330. {
  331. reason = "";
  332. return true;
  333. }
  334. }
  335. }