SingleArmRobot.xaml.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  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 Virgo_DUI.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=19, Root = 160, Arm = 191, Hand = 99 }
  127. ,EndPosition = new RobotPosition() { Root = 96, Arm = 347, Hand = 11 }}
  128. }
  129. ,{ "LP2", new StationPosition() {
  130. StartPosition = new RobotPosition() {X=-20, Root = 160, Arm = 191, Hand = 99 }
  131. ,EndPosition = new RobotPosition() { Root = 96, Arm = 347, Hand = 11 }}
  132. }
  133. ,{ "Aligner1", new StationPosition() {
  134. StartPosition = new RobotPosition() {X=73, Root = 160, Arm = 191, Hand = 99 }
  135. ,EndPosition = new RobotPosition() { Root = 96, Arm = 347, Hand = 11 }}
  136. }
  137. ,{ "Aligner2", new StationPosition() {
  138. StartPosition = new RobotPosition() {X=100, Root = 160, Arm = 191, Hand = 99 }
  139. ,EndPosition = new RobotPosition() { Root = 96, Arm = 347, Hand = 11 }}
  140. }
  141. ,{ "PMA", new StationPosition() {
  142. StartPosition = new RobotPosition() {X=152, Root = 160, Arm = 191, Hand = 99 }
  143. ,EndPosition = new RobotPosition() { Root = 96, Arm = 347, Hand = 11 }}
  144. }
  145. ,{ "PMB", new StationPosition() {
  146. StartPosition = new RobotPosition() {X=201, Root = 160, Arm = 191, Hand = 99 }
  147. ,EndPosition = new RobotPosition() { Root = 96, Arm = 347, Hand = 11 }}
  148. }
  149. };
  150. }
  151. }
  152. public SingleArmRobot()
  153. {
  154. InitializeComponent();
  155. //root.DataContext = this;
  156. //MoveCommand = new RelayCommand(MoveTo);
  157. canvas1.Rotate(90);
  158. canvas2.Rotate(180);
  159. canvas3.Rotate(180);
  160. CurrentPosition = "System";
  161. StationPosition = EfemStationPosition;
  162. }
  163. static void StationPositionChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
  164. {
  165. return;
  166. //following is for test purpose
  167. //var self = (SingleArmRobot)d;
  168. //var positions = (Dictionary<string, StationPosition>)e.NewValue;
  169. //var menus = new List<MenuItem>();
  170. //foreach (var position in positions)
  171. //{
  172. // var m = new MenuItem() { Header = position.Key };
  173. // m.Items.Add(new MenuItem() { Header = "Pick", Command = self.MoveCommand, CommandParameter = new RobotMoveInfo() { BladeTarget = position.Key, Action = Bolt.Toolkit.Wpf.Data.Enum.RobotAction.Picking } });
  174. // m.Items.Add(new MenuItem() { Header = "Place", Command = self.MoveCommand, CommandParameter = new RobotMoveInfo() { BladeTarget = position.Key, Action = Bolt.Toolkit.Wpf.Data.Enum.RobotAction.Placing } });
  175. // m.Items.Add(new MenuItem() { Header = "Move", Command = self.MoveCommand, CommandParameter = new RobotMoveInfo() { BladeTarget = position.Key, Action = Bolt.Toolkit.Wpf.Data.Enum.RobotAction.None } });
  176. // menus.Add(m);
  177. //}
  178. //self.Menu = menus;
  179. //self.MoveTo(new RobotMoveInfo() { BladeTarget = "System", Action = Bolt.Toolkit.Wpf.Data.Enum.RobotAction.None });
  180. }
  181. protected override void OnRender(DrawingContext drawingContext)
  182. {
  183. base.OnRender(drawingContext);
  184. if (DesignerProperties.GetIsInDesignMode(this))
  185. {
  186. return;
  187. }
  188. if (RobotMoveInfo != null)
  189. {
  190. var needMove = CurrentPosition != RobotMoveInfo.BladeTarget;
  191. if (needMove)
  192. {
  193. LogMsg(string.Format("Target: {0} - {1}", CurrentPosition, RobotMoveInfo.BladeTarget));
  194. Invoke(() => MoveRobot(RobotMoveInfo));
  195. }
  196. }
  197. }
  198. private void MoveRobot(RobotMoveInfo moveInfo, Action onComplete = null)
  199. {
  200. canvas1.Stop();
  201. canvas2.Stop();
  202. canvas3.Stop();
  203. var target = moveInfo.BladeTarget;
  204. if (string.IsNullOrEmpty(target))
  205. return;
  206. MoveToStart(CurrentPosition
  207. , () => MoveToStart(CurrentPosition
  208. , () => RotateTo(target
  209. , () => MoveToEnd(target
  210. , () => UpdateWafer(moveInfo, onComplete)))));
  211. }
  212. private void RotateTo(string station, Action onComplete = null)
  213. {
  214. var position = StationPosition[station];
  215. root.Rotate(position.StartPosition.X, true, MoveTime, 0, 0, onComplete);
  216. }
  217. private void MoveToStart(string station, Action onComplete = null)
  218. {
  219. var position = StationPosition[station];
  220. canvas1.Rotate(position.StartPosition.Root, true, MoveTime, 0, 0, onComplete);
  221. canvas2.Rotate(position.StartPosition.Arm, true, MoveTime);
  222. canvas3.Rotate(position.StartPosition.Hand, true, MoveTime);
  223. CurrentPosition = station;
  224. }
  225. private void MoveToEnd(string station, Action onComplete = null)
  226. {
  227. var position = StationPosition[station];
  228. canvas1.Rotate(position.EndPosition.Root, true, MoveTime, 0, 0, onComplete);
  229. canvas2.Rotate(position.EndPosition.Arm, true, MoveTime);
  230. canvas3.Rotate(position.EndPosition.Hand, true, MoveTime);
  231. CurrentPosition = station;
  232. }
  233. private void UpdateWafer(RobotMoveInfo moveInfo, Action onComplete = null)
  234. {
  235. switch (moveInfo.Action)
  236. {
  237. case Bolt.Toolkit.Wpf.Data.Enum.RobotAction.None:
  238. break;
  239. case Bolt.Toolkit.Wpf.Data.Enum.RobotAction.Picking:
  240. WaferPresent = true;
  241. break;
  242. case Bolt.Toolkit.Wpf.Data.Enum.RobotAction.Placing:
  243. WaferPresent = false;
  244. break;
  245. default:
  246. break;
  247. }
  248. }
  249. private void Invoke(Action action)
  250. {
  251. Dispatcher.Invoke(action);
  252. }
  253. private void LogMsg(string msg)
  254. {
  255. var source = "Robot";
  256. Console.WriteLine("{0} {1}", source, msg);
  257. }
  258. private void MoveTo(object target)
  259. {
  260. MoveRobot((RobotMoveInfo)target);
  261. }
  262. }
  263. }