CalculatePalletPosViewModel.cs 6.6 KB

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