CalculatePalletPosViewModel.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. using MathNet.Numerics.LinearAlgebra;
  2. using Prism.Commands;
  3. using Prism.Mvvm;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Windows;
  8. using TeamAAS_VP.Models;
  9. using TeamAAS_VP;
  10. using TeamAAS_VP.Resources.Languages;
  11. using TeamAAS_VP.Models.Robot;
  12. namespace TeamAAS_VP.ViewModels.Product
  13. {
  14. public class CalculatePalletPosViewModel : BindableBase
  15. {
  16. private Pallet _CurrentPallet;
  17. public Pallet CurrentPallet
  18. {
  19. get { return _CurrentPallet; }
  20. set { SetProperty(ref _CurrentPallet,value);
  21. if (value != null)
  22. {
  23. CalculateSpace(value);
  24. }
  25. }
  26. }
  27. private double _RowSpace;
  28. public double RowSpace
  29. {
  30. get { return _RowSpace; }
  31. set { SetProperty(ref _RowSpace,value); }
  32. }
  33. private double _ColSpace;
  34. public double ColSpace
  35. {
  36. get { return _ColSpace; }
  37. set { SetProperty(ref _ColSpace, value); }
  38. }
  39. private DelegateCommand _CalculateP1Command;
  40. public DelegateCommand CalculateP1Command =>
  41. _CalculateP1Command ?? (_CalculateP1Command = new DelegateCommand(ExecuteCalculateP1Command));
  42. private DelegateCommand _CalculateP2Command;
  43. public DelegateCommand CalculateP2Command =>
  44. _CalculateP2Command ?? (_CalculateP2Command = new DelegateCommand(ExecuteCalculateP2Command));
  45. void ExecuteCalculateP2Command()
  46. {
  47. try
  48. {
  49. Calculatet(RowSpace, false);
  50. NotificationEvent?.Invoke(Lang.完成, 1);
  51. }
  52. catch (Exception ex)
  53. {
  54. NotificationEvent?.Invoke(ex.Message, 1);
  55. }
  56. }
  57. public event Action<string, double> NotificationEvent;
  58. void ExecuteCalculateP1Command()
  59. {
  60. try
  61. {
  62. Calculatet(ColSpace, true);
  63. NotificationEvent?.Invoke(Lang.完成, 1);
  64. }
  65. catch (Exception ex)
  66. {
  67. NotificationEvent?.Invoke(ex.Message,1);
  68. }
  69. }
  70. public CalculatePalletPosViewModel()
  71. {
  72. }
  73. private void Calculatet(double Space,bool P1orP2)
  74. {
  75. try
  76. {
  77. //----------------------------------------计算旋转矩阵-----------------------------------------------------------------
  78. Vector<double> p1 = Vector<double>.Build.Dense(new double[] { CurrentPallet.P0.X, CurrentPallet.P0.Y });
  79. Vector<double> p2 = Vector<double>.Build.Dense(new double[] { CurrentPallet.P1.X, CurrentPallet.P1.Y });
  80. Vector<double> p3 = Vector<double>.Build.Dense(new double[] { CurrentPallet.P2.X, CurrentPallet.P2.Y });
  81. //计算正交时的X与Y轴的单位向量
  82. Vector<double> E1 = (p2 - p1) / (p2 - p1).L2Norm();
  83. Vector<double> E2 = (p3 - p1 - E1.DotProduct(p3 - p1) * E1) / (p3 - p1 - E1.DotProduct(p3 - p1) * E1).L2Norm();
  84. //得到旋转矩阵
  85. Matrix<double> R = Matrix<double>.Build.DenseOfColumnVectors(E1, E2);
  86. //--------------------------------------计算切变矩阵--------------------------------------------------------
  87. double a = (E1.DotProduct(p3 - p1) * E1).L2Norm() / (p3 - p1 - (E1.DotProduct(p3 - p1) * E1))[1];
  88. Matrix<double> Shear = Matrix<double>.Build.DenseOfArray(new double[,] { { 1, a }, { 0, 1 } });
  89. if (P1orP2)
  90. {
  91. //计算P1点位
  92. //切变前的坐标
  93. Vector<double> q = Vector<double>.Build.Dense(new double[] { Space * (CurrentPallet.Column - 1), 0 });
  94. //切变后的坐标
  95. Vector<double> h = Shear * q;
  96. //转换后的机器人坐标
  97. Vector<double> rp = R * h + p1;
  98. CurrentPallet.P1.X = (float)rp[0];
  99. CurrentPallet.P1.Y = (float)rp[1];
  100. }
  101. else
  102. {
  103. //计算P2点位
  104. //切变前的坐标
  105. Vector<double> q = Vector<double>.Build.Dense(new double[] { 0, Space * (CurrentPallet.Row - 1) });
  106. //切变后的坐标
  107. Vector<double> h = Shear * q;
  108. //转换后的机器人坐标
  109. Vector<double> rp = R * h + p1;
  110. CurrentPallet.P2.X = (float)rp[0];
  111. CurrentPallet.P2.Y = (float)rp[1];
  112. }
  113. }
  114. catch (Exception ex)
  115. {
  116. LogHelper.WriteLogError("计算Pallet的P1或者P2时出错!", ex);
  117. MessageBox.Show(ex.Message);
  118. }
  119. }
  120. private void CalculateSpace(Pallet pallet)
  121. {
  122. try
  123. {
  124. //----------------------------------------计算旋转矩阵-----------------------------------------------------------------
  125. Vector<double> p1 = Vector<double>.Build.Dense(new double[] { pallet.P0.X, pallet.P0.Y });
  126. Vector<double> p2 = Vector<double>.Build.Dense(new double[] { pallet.P1.X, pallet.P1.Y });
  127. Vector<double> p3 = Vector<double>.Build.Dense(new double[] { pallet.P2.X, pallet.P2.Y });
  128. //计算正交时的X与Y轴的单位向量
  129. Vector<double> E1 = (p2 - p1) / (p2 - p1).L2Norm();
  130. Vector<double> E2 = (p3 - p1 - E1.DotProduct(p3 - p1) * E1) / (p3 - p1 - E1.DotProduct(p3 - p1) * E1).L2Norm();
  131. //得到旋转矩阵
  132. Matrix<double> R = Matrix<double>.Build.DenseOfColumnVectors(E1, E2);
  133. //--------------------------------------计算切变矩阵--------------------------------------------------------
  134. double a = (E1.DotProduct(p3 - p1) * E1).L2Norm() / (p3 - p1 - (E1.DotProduct(p3 - p1) * E1))[1];
  135. Matrix<double> Shear = Matrix<double>.Build.DenseOfArray(new double[,] { { 1, a }, { 0, 1 } });
  136. //--------------------------------------计算托盘行列间距---------------------------------------------------------
  137. ColSpace = (p2 - p1).L2Norm() / (pallet.Column - 1);
  138. RowSpace = (p3 - p1 - E1.DotProduct(p3 - p1) * E1).L2Norm() / (pallet.Row - 1);
  139. }
  140. catch (Exception ex)
  141. {
  142. LogHelper.WriteLogError("计算Pallet的行列间距时出错!", ex);
  143. MessageBox.Show(ex.Message);
  144. }
  145. }
  146. }
  147. }