SingleArmRobot.xaml.cs 11 KB

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