AtmRobot3.xaml.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. using Aitex.Core.Common;
  2. using Aitex.Core.UI.MVVM;
  3. using Aitex.Sorter.UI.Controls.Common;
  4. using MECF.Framework.Common.Equipment;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.ComponentModel;
  8. using System.Linq;
  9. using System.Threading;
  10. using System.Windows;
  11. using System.Windows.Controls;
  12. using System.Windows.Input;
  13. using System.Windows.Media;
  14. using System.Windows.Media.Animation;
  15. namespace Aitex.Sorter.UI.Controls
  16. {
  17. /// <summary>
  18. /// AtmRobot3.xaml 的交互逻辑
  19. /// </summary>
  20. public partial class AtmRobot3 : UserControl, INotifyPropertyChanged
  21. {
  22. protected readonly int MoveTime = 300;
  23. private const int AnimationTimeout = 3000; // seconds
  24. public int RotateAngle
  25. {
  26. get { return (int)GetValue(RotateAngleProperty); }
  27. set { SetValue(RotateAngleProperty, value); }
  28. }
  29. // Using a DependencyProperty as the backing store for RotateAngel. This enables animation, styling, binding, etc...
  30. public static readonly DependencyProperty RotateAngleProperty =
  31. DependencyProperty.Register("RotateAngel", typeof(int), typeof(AtmRobot3), new PropertyMetadata(0));
  32. public ModuleName Station
  33. {
  34. get { return (ModuleName)GetValue(StationProperty); }
  35. set { SetValue(StationProperty, value); }
  36. }
  37. // Using a DependencyProperty as the backing store for Station. This enables animation, styling, binding, etc...
  38. public static readonly DependencyProperty StationProperty =
  39. DependencyProperty.Register("Station", typeof(ModuleName), typeof(AtmRobot3), new PropertyMetadata(ModuleName.Robot));
  40. public ICommand Command
  41. {
  42. get { return (ICommand)GetValue(CommandProperty); }
  43. set { SetValue(CommandProperty, value); }
  44. }
  45. // Using a DependencyProperty as the backing store for Command. This enables animation, styling, binding, etc...
  46. public static readonly DependencyProperty CommandProperty =
  47. DependencyProperty.Register("Command", typeof(ICommand), typeof(AtmRobot3), new PropertyMetadata(null));
  48. public string RobotBladeTarget
  49. {
  50. get { return (string)GetValue(RobotBladeTargetProperty); }
  51. set { SetValue(RobotBladeTargetProperty, value); }
  52. }
  53. public static readonly DependencyProperty RobotBladeTargetProperty =
  54. DependencyProperty.Register("RobotBladeTarget", typeof(string), typeof(AtmRobot3), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));
  55. public string RobotBlade2Target
  56. {
  57. get { return (string)GetValue(RobotBlade2TargetProperty); }
  58. set { SetValue(RobotBlade2TargetProperty, value); }
  59. }
  60. public static readonly DependencyProperty RobotBlade2TargetProperty =
  61. DependencyProperty.Register("RobotBlade2Target", typeof(string), typeof(AtmRobot3), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));
  62. public Dictionary<string, StationPosition> StationPosition
  63. {
  64. get { return (Dictionary<string, StationPosition>)GetValue(StationPositionProperty); }
  65. set { SetValue(StationPositionProperty, value); }
  66. }
  67. // Using a DependencyProperty as the backing store for StationPosition2. This enables animation, styling, binding, etc...
  68. public static readonly DependencyProperty StationPositionProperty =
  69. DependencyProperty.Register("StationPosition", typeof(Dictionary<string, StationPosition>), typeof(AtmRobot3), new PropertyMetadata(null, StationPositionChangedCallback));
  70. public bool ShowDock
  71. {
  72. get { return (bool)GetValue(ShowDockProperty); }
  73. set { SetValue(ShowDockProperty, value); }
  74. }
  75. // Using a DependencyProperty as the backing store for ShowDock. This enables animation, styling, binding, etc...
  76. public static readonly DependencyProperty ShowDockProperty =
  77. DependencyProperty.Register("ShowDock", typeof(bool), typeof(AtmRobot3), new PropertyMetadata(false));
  78. public WaferInfo Wafer1
  79. {
  80. get { return (WaferInfo)GetValue(Wafer1Property); }
  81. set { SetValue(Wafer1Property, value); }
  82. }
  83. // Using a DependencyProperty as the backing store for Wafer1. This enables animation, styling, binding, etc...
  84. public static readonly DependencyProperty Wafer1Property =
  85. DependencyProperty.Register("Wafer1", typeof(WaferInfo), typeof(AtmRobot3), new PropertyMetadata(null));
  86. public WaferInfo Wafer2
  87. {
  88. get { return (WaferInfo)GetValue(Wafer2Property); }
  89. set { SetValue(Wafer2Property, value); }
  90. }
  91. // Using a DependencyProperty as the backing store for Wafer2. This enables animation, styling, binding, etc...
  92. public static readonly DependencyProperty Wafer2Property =
  93. DependencyProperty.Register("Wafer2", typeof(WaferInfo), typeof(AtmRobot3), new PropertyMetadata(null));
  94. private string CurrentPosition
  95. {
  96. get; set;
  97. }
  98. private List<MenuItem> menu;
  99. public List<MenuItem> Menu
  100. {
  101. get
  102. {
  103. return menu;
  104. }
  105. set
  106. {
  107. menu = value;
  108. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Menu"));
  109. }
  110. }
  111. public ICommand MoveCommand
  112. {
  113. get
  114. {
  115. return new DelegateCommand<string>(MoveTo);
  116. }
  117. }
  118. private AnimationQueue queue;
  119. public event PropertyChangedEventHandler PropertyChanged;
  120. static void StationPositionChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
  121. {
  122. var self = (AtmRobot3)d;
  123. var positions = (Dictionary<string, StationPosition>)e.NewValue;
  124. self.Menu = positions.Select(x => new MenuItem() { Header = x.Key, Command = self.MoveCommand, CommandParameter = x.Key }).ToList();
  125. }
  126. public AtmRobot3()
  127. {
  128. #if DEBUG
  129. System.Diagnostics.PresentationTraceSources.DataBindingSource.Switch.Level = System.Diagnostics.SourceLevels.Critical;
  130. #endif
  131. InitializeComponent();
  132. root.DataContext = this;
  133. queue = new AnimationQueue("Robot Animation");
  134. queue.StatusUpdated += Queue_StatusUpdated;
  135. canvas1.Rotate(90);
  136. canvas2.Rotate(180);
  137. canvas3.Rotate(180);
  138. canvas21.Rotate(90);
  139. canvas22.Rotate(180);
  140. canvas23.Rotate(180);
  141. CurrentPosition = "ArmA." + ModuleName.System.ToString();
  142. }
  143. protected override void OnRender(DrawingContext drawingContext)
  144. {
  145. base.OnRender(drawingContext);
  146. if (DesignerProperties.GetIsInDesignMode(this))
  147. {
  148. return;
  149. }
  150. if (RobotBladeTarget != null)
  151. {
  152. queue.EnqueueStatus(new AnimationParameter() { Target = RobotBladeTarget });
  153. }
  154. if (RobotBlade2Target != null)
  155. {
  156. queue.EnqueueStatus(new AnimationParameter() { Target = RobotBlade2Target });
  157. }
  158. }
  159. private void Queue_StatusUpdated(object sender, StatusUpdateArgs e)
  160. {
  161. string TargetPosition = CurrentPosition.Split('.')[0] + "." + e.Parameter.Target;
  162. LogMsg(string.Format("Target: {0} - {1}", CurrentPosition, TargetPosition));
  163. var nextEvent = new AutoResetEvent(false);
  164. var next = new Action(() =>
  165. {
  166. nextEvent.Set();
  167. });
  168. var wait = new Action(() =>
  169. {
  170. if (!nextEvent.WaitOne(AnimationTimeout))
  171. {
  172. LogMsg("Aniamtion time out!");
  173. }
  174. });
  175. var done = new Action(() =>
  176. {
  177. CurrentPosition = TargetPosition;
  178. e.Event.Set();
  179. });
  180. var needMove = CurrentPosition != TargetPosition;
  181. if (needMove)
  182. {
  183. Invoke(() => MoveRobot(TargetPosition, next));
  184. wait();
  185. }
  186. done();
  187. }
  188. private void MoveRobot(string target, Action onComplete = null)
  189. {
  190. MoveToStart(CurrentPosition, () => TranslateTo(target, () =>
  191. RetractArm(() =>
  192. MoveToStart(target, () => MoveToEnd(target, onComplete)))));
  193. }
  194. private void RetractArm(Action onComplete = null)
  195. {
  196. canvas2.Rotate(180, true, 50, 0, 0, onComplete);
  197. canvas3.Rotate(180, true);
  198. canvas2.Rotate(180, true);
  199. canvas3.Rotate(180, true);
  200. }
  201. private void MoveToStart(string station, Action onComplete = null)
  202. {
  203. //var position = StationPosition[station];
  204. StationPosition positionA = station.Contains("ArmA") ? StationPosition[station] : StationPosition[station.Replace("ArmB", "ArmA")];
  205. StationPosition positionB = station.Contains("ArmB") ? StationPosition[station] : StationPosition[station.Replace("ArmA", "ArmB")];
  206. canvas1.Rotate(positionA.StartPosition.Root, true, MoveTime, 0, 0, onComplete);
  207. canvas2.Rotate(positionA.StartPosition.Arm, true, MoveTime);
  208. canvas3.Rotate(positionA.StartPosition.Hand, true, MoveTime);
  209. canvas21.Rotate(positionB.StartPosition.Root, true, MoveTime);
  210. canvas22.Rotate(positionB.StartPosition.Arm, true, MoveTime);
  211. canvas23.Rotate(positionB.StartPosition.Hand, true, MoveTime);
  212. CurrentPosition = station;
  213. }
  214. private void MoveToEnd(string station, Action onComplete = null)
  215. {
  216. var position = StationPosition[station];
  217. if (station.Contains("ArmA"))
  218. {
  219. canvas1.Rotate(position.EndPosition.Root, true, MoveTime, 0, 0, onComplete);
  220. canvas2.Rotate(position.EndPosition.Arm, true, MoveTime);
  221. canvas3.Rotate(position.EndPosition.Hand, true, MoveTime);
  222. }
  223. if (station.Contains("ArmB"))
  224. {
  225. canvas21.Rotate(position.EndPosition.Root, true, MoveTime, 0, 0, onComplete);
  226. canvas22.Rotate(position.EndPosition.Arm, true, MoveTime);
  227. canvas23.Rotate(position.EndPosition.Hand, true, MoveTime);
  228. }
  229. CurrentPosition = station;
  230. }
  231. private void TranslateTo(string station, Action onComplete = null)
  232. {
  233. var position = StationPosition[station];
  234. if (position.StartPosition.X.HasValue)
  235. {
  236. Translate(position.StartPosition.X.Value, onComplete);
  237. }
  238. else
  239. {
  240. onComplete?.Invoke();
  241. }
  242. }
  243. private void Translate(int x, Action onComplete = null)
  244. {
  245. var storyBoard = new Storyboard();
  246. var oldX = translate.X;
  247. var animation = new DoubleAnimation(oldX, x, TimeSpan.FromMilliseconds(MoveTime));
  248. storyBoard.Children.Add(animation);
  249. Storyboard.SetTarget(animation, root);
  250. var propertyChain = new DependencyProperty[]
  251. {
  252. Canvas.RenderTransformProperty,
  253. TransformGroup.ChildrenProperty,
  254. TranslateTransform.XProperty
  255. };
  256. string thePath = "(0).(1)[1].(2)";
  257. PropertyPath myPropertyPath = new PropertyPath(thePath, propertyChain);
  258. Storyboard.SetTargetProperty(animation, myPropertyPath);
  259. storyBoard.Completed += (s, e) =>
  260. {
  261. //InvalidateVisual();
  262. if (onComplete != null)
  263. {
  264. onComplete();
  265. }
  266. };
  267. storyBoard.Begin();
  268. }
  269. private void MoveTo(string target)
  270. {
  271. MoveRobot(target);
  272. }
  273. private void Invoke(Action action)
  274. {
  275. Dispatcher.Invoke(action);
  276. }
  277. private void LogMsg(string msg)
  278. {
  279. var source = "Robot";
  280. Console.WriteLine("{0} {1}", source, msg);
  281. }
  282. }
  283. //public enum BladeStatusLP
  284. //{
  285. // Extend,
  286. // Retract
  287. //}
  288. //public class Robot2Position
  289. //{
  290. // public int? X;
  291. // public int Root;
  292. // public int Arm;
  293. // public int Hand;
  294. //}
  295. //public class StationPosition2
  296. //{
  297. // public Robot2Position StartPosition;
  298. // public Robot2Position EndPosition;
  299. //}
  300. }