SingleArmRobot.xaml.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. using Bolt.Toolkit.Wpf.Data;
  2. using MECF.Framework.Common.CommonData;
  3. using OpenSEMI.ClientBase;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.ComponentModel;
  7. using System.Windows;
  8. using System.Windows.Controls;
  9. using System.Windows.Input;
  10. using System.Windows.Media;
  11. using VirgoUI.Controls.Common;
  12. using RobotPosition = Bolt.Toolkit.Wpf.Data.RobotPosition;
  13. using StationPosition = Bolt.Toolkit.Wpf.Data.StationPosition;
  14. namespace VirgoUI.Client.Controls.Parts
  15. {
  16. /// <summary>
  17. /// SingleArmRobot.xaml 的交互逻辑
  18. /// </summary>
  19. public partial class SingleArmRobot : UserControl, INotifyPropertyChanged
  20. {
  21. protected int moveTime = 300;
  22. private const int AnimationTimeout = 3000;
  23. private string CurrentPosition
  24. {
  25. get; set;
  26. }
  27. private RobotAction CurrentAction
  28. {
  29. get; set;
  30. }
  31. public int MoveTime
  32. {
  33. get => moveTime;
  34. set
  35. {
  36. moveTime = value;
  37. }
  38. }
  39. public int RotateAngle
  40. {
  41. get { return (int)GetValue(RotateAngleProperty); }
  42. set { SetValue(RotateAngleProperty, value); }
  43. }
  44. // Using a DependencyProperty as the backing store for RotateAngel. This enables animation, styling, binding, etc...
  45. public static readonly DependencyProperty RotateAngleProperty =
  46. DependencyProperty.Register("RotateAngel", typeof(int), typeof(SingleArmRobot), new PropertyMetadata(0));
  47. public Dictionary<string, StationPosition> StationPosition
  48. {
  49. get { return (Dictionary<string, StationPosition>)GetValue(StationPositionProperty); }
  50. set { SetValue(StationPositionProperty, value); }
  51. }
  52. // Using a DependencyProperty as the backing store for StationPosition. This enables animation, styling, binding, etc...
  53. public static readonly DependencyProperty StationPositionProperty =
  54. DependencyProperty.Register("StationPosition", typeof(Dictionary<string, StationPosition>), typeof(SingleArmRobot), new PropertyMetadata(null, StationPositionChangedCallback));
  55. public RobotMoveInfo RobotMoveInfo
  56. {
  57. get { return (RobotMoveInfo)GetValue(RobotMoveInfoProperty); }
  58. set { SetValue(RobotMoveInfoProperty, value); }
  59. }
  60. public static readonly DependencyProperty RobotMoveInfoProperty =
  61. DependencyProperty.Register("RobotMoveInfo", typeof(RobotMoveInfo), typeof(SingleArmRobot), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));
  62. public WaferInfo Wafer1
  63. {
  64. get { return (WaferInfo)GetValue(Wafer1Property); }
  65. set { SetValue(Wafer1Property, value); }
  66. }
  67. // Using a DependencyProperty as the backing store for Wafer1. This enables animation, styling, binding, etc...
  68. public static readonly DependencyProperty Wafer1Property =
  69. DependencyProperty.Register("Wafer1", typeof(WaferInfo), typeof(SingleArmRobot), new PropertyMetadata(null));
  70. public WaferInfo Wafer2
  71. {
  72. get { return (WaferInfo)GetValue(Wafer2Property); }
  73. set { SetValue(Wafer2Property, value); }
  74. }
  75. // Using a DependencyProperty as the backing store for Wafer2. This enables animation, styling, binding, etc...
  76. public static readonly DependencyProperty Wafer2Property =
  77. DependencyProperty.Register("Wafer2", typeof(WaferInfo), typeof(SingleArmRobot), new PropertyMetadata(null));
  78. public string Station
  79. {
  80. get { return (string)GetValue(StationProperty); }
  81. set { SetValue(StationProperty, value); }
  82. }
  83. // Using a DependencyProperty as the backing store for Station. This enables animation, styling, binding, etc...
  84. public static readonly DependencyProperty StationProperty =
  85. DependencyProperty.Register("Station", typeof(string), typeof(SingleArmRobot), new PropertyMetadata("Robot"));
  86. public ICommand CreateDeleteWaferCommand
  87. {
  88. get { return (ICommand)GetValue(CreateDeleteWaferCommandProperty); }
  89. set { SetValue(CreateDeleteWaferCommandProperty, value); }
  90. }
  91. // Using a DependencyProperty as the backing store for CreateDeleteWaferCommand. This enables animation, styling, binding, etc...
  92. public static readonly DependencyProperty CreateDeleteWaferCommandProperty =
  93. DependencyProperty.Register("CreateDeleteWaferCommand", typeof(ICommand), typeof(SingleArmRobot), new PropertyMetadata(null));
  94. public ICommand MoveWaferCommand
  95. {
  96. get { return (ICommand)GetValue(MoveWaferCommandProperty); }
  97. set { SetValue(MoveWaferCommandProperty, value); }
  98. }
  99. // Using a DependencyProperty as the backing store for MoveWaferCommand. This enables animation, styling, binding, etc...
  100. public static readonly DependencyProperty MoveWaferCommandProperty =
  101. DependencyProperty.Register("MoveWaferCommand", typeof(ICommand), typeof(SingleArmRobot), new PropertyMetadata(null));
  102. public bool WaferPresent
  103. {
  104. get { return (bool)GetValue(WaferPresentProperty); }
  105. set { SetValue(WaferPresentProperty, value); }
  106. }
  107. // Using a DependencyProperty as the backing store for WaferPresent. This enables animation, styling, binding, etc...
  108. public static readonly DependencyProperty WaferPresentProperty =
  109. DependencyProperty.Register("WaferPresent", typeof(bool), typeof(SingleArmRobot), new PropertyMetadata(false));
  110. private List<MenuItem> menu;
  111. public event PropertyChangedEventHandler PropertyChanged;
  112. public List<MenuItem> Menu
  113. {
  114. get
  115. {
  116. return menu;
  117. }
  118. set
  119. {
  120. menu = value;
  121. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Menu"));
  122. }
  123. }
  124. private ICommand MoveCommand
  125. {
  126. get; set;
  127. }
  128. public Dictionary<string, StationPosition> EfemStationPosition
  129. {
  130. get
  131. {
  132. return new Dictionary<string, StationPosition>()
  133. {
  134. { "System", new StationPosition() {
  135. StartPosition = new RobotPosition() {Root = 160, Arm = 191, Hand = 99 }
  136. ,EndPosition = new RobotPosition() {Root = 160, Arm = 191, Hand = 99 }}
  137. }
  138. ,{ "EfemRobot", new StationPosition() {
  139. StartPosition = new RobotPosition() {Root = 160, Arm = 191, Hand = 99 }
  140. ,EndPosition = new RobotPosition() {Root = 160, Arm = 191, Hand = 99 }}
  141. }
  142. ,{ "LP1", new StationPosition() {
  143. StartPosition = new RobotPosition() {X = 0, Root = 160, Arm = 191, Hand = 99 }
  144. ,EndPosition = new RobotPosition() { Root = 140, Arm = 260, Hand = 50 }}
  145. }
  146. ,{ "Cooling1", new StationPosition() {
  147. StartPosition = new RobotPosition() {X = 63, Root = 160, Arm = 191, Hand = 99 }
  148. ,EndPosition = new RobotPosition() { Root = 140, Arm = 260, Hand = 50 }}
  149. }
  150. ,{ "PMA", new StationPosition() {
  151. StartPosition = new RobotPosition() {X = 180, Root = 160, Arm = 191, Hand = 99 }
  152. ,EndPosition = new RobotPosition() { Root = 90, Arm = 360, Hand = 0 }}
  153. }
  154. };
  155. }
  156. }
  157. public SingleArmRobot()
  158. {
  159. InitializeComponent();
  160. root.DataContext = this;
  161. MoveCommand = new RelayCommand(MoveTo);
  162. canvas1.Rotate(90);
  163. canvas2.Rotate(180);
  164. canvas3.Rotate(180);
  165. CurrentPosition = "System";
  166. StationPosition = EfemStationPosition;
  167. }
  168. static void StationPositionChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
  169. {
  170. //return;
  171. // following is for test purpose
  172. var self = (SingleArmRobot)d;
  173. var positions = (Dictionary<string, StationPosition>)e.NewValue;
  174. var menus = new List<MenuItem>();
  175. foreach (var position in positions)
  176. {
  177. var m = new MenuItem() { Header = position.Key };
  178. m.Items.Add(new MenuItem() { Header = "Pick", Command = self.MoveCommand, CommandParameter = new RobotMoveInfo() { BladeTarget = position.Key, Action = RobotAction.Picking } });
  179. m.Items.Add(new MenuItem() { Header = "Place", Command = self.MoveCommand, CommandParameter = new RobotMoveInfo() { BladeTarget = position.Key, Action = RobotAction.Placing } });
  180. m.Items.Add(new MenuItem() { Header = "Move", Command = self.MoveCommand, CommandParameter = new RobotMoveInfo() { BladeTarget = position.Key, Action = RobotAction.Moving } });
  181. menus.Add(m);
  182. }
  183. self.Menu = menus;
  184. self.MoveTo(new RobotMoveInfo() { BladeTarget = "System", Action = RobotAction.None });
  185. }
  186. protected override void OnRender(DrawingContext drawingContext)
  187. {
  188. base.OnRender(drawingContext);
  189. if (DesignerProperties.GetIsInDesignMode(this))
  190. {
  191. return;
  192. }
  193. if (RobotMoveInfo != null)
  194. {
  195. var needMove = CurrentPosition != RobotMoveInfo.BladeTarget || CurrentAction != RobotMoveInfo.Action;
  196. if (needMove)
  197. {
  198. LogMsg(string.Format("Target: {0} - {1}", CurrentPosition, RobotMoveInfo.BladeTarget));
  199. Invoke(() => MoveRobot(RobotMoveInfo));
  200. CurrentAction = RobotMoveInfo.Action;
  201. CurrentPosition = RobotMoveInfo.BladeTarget;
  202. }
  203. }
  204. }
  205. private void MoveRobot(RobotMoveInfo moveInfo, Action onComplete = null)
  206. {
  207. canvas1.Stop();
  208. canvas2.Stop();
  209. canvas3.Stop();
  210. var target = moveInfo.BladeTarget;
  211. if (string.IsNullOrEmpty(target))
  212. return;
  213. MoveToStart(CurrentPosition
  214. , () => RotateTo(target
  215. , () =>
  216. {
  217. if (moveInfo.Action != RobotAction.Moving)
  218. {
  219. MoveToEnd(target, () => MoveToEnd(target, () => UpdateWafer(moveInfo)));
  220. }
  221. }));
  222. }
  223. private void RotateTo(string station, Action onComplete = null)
  224. {
  225. var position = StationPosition[station];
  226. root.Rotate(position.StartPosition.X, true, MoveTime, 0, 0, onComplete);
  227. }
  228. private void MoveToStart(string station, Action onComplete = null)
  229. {
  230. var position = StationPosition[station];
  231. canvas1.Rotate(position.StartPosition.Root, true, MoveTime, 0, 0, onComplete);
  232. canvas2.Rotate(position.StartPosition.Arm, true, MoveTime);
  233. canvas3.Rotate(position.StartPosition.Hand, true, MoveTime);
  234. CurrentPosition = station;
  235. }
  236. private void MoveToEnd(string station, Action onComplete = null)
  237. {
  238. canvas1.Stop();
  239. canvas2.Stop();
  240. canvas3.Stop();
  241. var position = StationPosition[station];
  242. canvas1.Rotate(position.EndPosition.Root, true, MoveTime, 0, 0, onComplete);
  243. canvas2.Rotate(position.EndPosition.Arm, true, MoveTime);
  244. canvas3.Rotate(position.EndPosition.Hand, true, MoveTime);
  245. CurrentPosition = station;
  246. }
  247. private void UpdateWafer(RobotMoveInfo moveInfo, Action onComplete = null)
  248. {
  249. switch (moveInfo.Action)
  250. {
  251. case RobotAction.None:
  252. break;
  253. case RobotAction.Picking:
  254. WaferPresent = true;
  255. break;
  256. case RobotAction.Placing:
  257. WaferPresent = false;
  258. break;
  259. default:
  260. break;
  261. }
  262. }
  263. private void Invoke(Action action)
  264. {
  265. Dispatcher.Invoke(action);
  266. }
  267. private void LogMsg(string msg)
  268. {
  269. var source = "Robot";
  270. Console.WriteLine("{0} {1}", source, msg);
  271. }
  272. private void MoveTo(object target)
  273. {
  274. MoveRobot((RobotMoveInfo)target);
  275. }
  276. }
  277. }