Locate.cs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7. using NLog;
  8. using SmartSEMControl;
  9. namespace MeasureThread
  10. {
  11. class Locate : ILocate
  12. {
  13. NLog.Logger log;
  14. private LocateParam prm;
  15. private ISEMControl iSEM;
  16. public Locate( LocateParam prm, ISEMControl iSEM)
  17. {
  18. this.log = NLog.LogManager.GetCurrentClassLogger();
  19. this.log = log ?? throw new ArgumentNullException(nameof(log));
  20. this.prm = prm ?? throw new ArgumentNullException(nameof(prm));
  21. this.iSEM = iSEM ?? throw new ArgumentNullException(nameof(iSEM));
  22. }
  23. //移动到像素位置,这里要靠移动样品台实现,当位移量小于3um时,不予移动
  24. bool MoveToPixByMoveStage(float xc, float yc)
  25. {
  26. //单位是m/pix
  27. float XpixSize = iSEM.GetPixelSize();
  28. log.Info("X像素尺寸=" + XpixSize.ToString() + "m/pixel", true);
  29. float YpixSize = iSEM.GetPixelSize()/prm.PixelSize_Y_cur;///(float)MParam.PixelSizeCor);
  30. log.Info("Y像素尺寸=" + YpixSize.ToString() + "m/pixel", true);
  31. Thread.Sleep(500);
  32. //0:width, 1:height
  33. int[] imageSize = iSEM.GetImageStore();
  34. int width = imageSize[0] / 2;
  35. int height = imageSize[1] / 2;
  36. log.Info("目标像素是(" + xc.ToString() + "," + yc.ToString() + ")", true);
  37. log.Info("中心像素是(" + width.ToString() + "," + height.ToString() + ")", true);
  38. float deltX = (xc - (float)width) * XpixSize;
  39. float deltY = (yc - (float)height) * YpixSize;
  40. log.Info("x位移量 = " + deltX.ToString() + "m", true);
  41. log.Info("y位移量 = " + deltY.ToString() + "m", true);
  42. float xpCur = iSEM.GetStageAtX();
  43. float ypCur = iSEM.GetStageAtY();
  44. log.Info("当前位置(" + xpCur.ToString() + "," + ypCur.ToString() + "),单位m", true);
  45. float xpNew = xpCur - deltX;
  46. float ypNew = ypCur + deltY;
  47. log.Info("目标位置(" + xpNew.ToString() + "," + ypNew.ToString() + "),单位m", true);
  48. //计算光束偏移值:
  49. //if (deltX >= 0.000003 || deltX <= 0.000003)//大于3um使用移动样品台实现
  50. {
  51. log.Info("X方向移动样品台", true);
  52. if (!iSEM.SetStageGotoX(xpNew))
  53. {
  54. return false;
  55. }
  56. //判断是否移动完成
  57. while (true)
  58. {
  59. Thread.Sleep(5000);
  60. if (iSEM.GetStageIs() == 0)
  61. {
  62. break;
  63. }
  64. }
  65. }
  66. //if (deltY >= 0.000003 || deltY <= -0.000003)//大于3um使用移动样品台实现
  67. {
  68. log.Info("Y方向移动样品台", true);
  69. if (!iSEM.SetStageGotoY(ypNew))
  70. {
  71. return false;
  72. }
  73. //判断是否移动完成
  74. while (true)
  75. {
  76. Thread.Sleep(5000);
  77. if (iSEM.GetStageIs() == 0)
  78. {
  79. break;
  80. }
  81. }
  82. }
  83. return true;
  84. }
  85. //移动到像素位置
  86. bool MoveToPix(float xc, float yc)
  87. {
  88. //单位是m/pix
  89. float XpixSize = iSEM.GetPixelSize();
  90. log.Info("X像素尺寸=" + XpixSize.ToString() + "m/pixel", true);
  91. float YpixSize = (XpixSize / prm.PixelSize_Y_cur);
  92. log.Info("Y像素尺寸=" + YpixSize.ToString() + "m/pixel", true);
  93. Thread.Sleep(200);
  94. //0:width, 1:height
  95. int[] imageSize = iSEM.GetImageStore();
  96. int width = imageSize[0] / 2;
  97. int height = imageSize[1] / 2;
  98. log.Info("目标像素是(" + xc.ToString() + "," + yc.ToString() + ")", true);
  99. log.Info("中心像素是(" + width.ToString() + "," + height.ToString() + ")", true);
  100. float deltX = (xc - (float)width) * XpixSize;
  101. float deltY = (yc - (float)height) * YpixSize;
  102. log.Info("x位移量 = " + deltX.ToString() + "m", true);
  103. log.Info("y位移量 = " + deltY.ToString() + "m", true);
  104. float xpCur = iSEM.GetStageAtX();
  105. Thread.Sleep(200);
  106. float ypCur = iSEM.GetStageAtY();
  107. log.Info("当前位置(" + xpCur.ToString() + "," + ypCur.ToString() + "),单位m", true);
  108. float xpNew = xpCur - deltX;
  109. float ypNew = ypCur + deltY;
  110. log.Info("目标位置(" + xpNew.ToString() + "," + ypNew.ToString() + "),单位m", true);
  111. //计算最大偏移量
  112. float beamXCur = iSEM.GetBeamShiftX();//单位是%
  113. Thread.Sleep(200);
  114. iSEM.SetBeamShiftX(100);
  115. Thread.Sleep(200);
  116. float beamXMax = iSEM.GetBeamOffsetX();//单位是m
  117. Thread.Sleep(200);
  118. iSEM.SetBeamShiftX(beamXCur);
  119. Thread.Sleep(200);
  120. //计算光束偏移值:
  121. float beamX = iSEM.GetBeamOffsetX();
  122. log.Info("当前X方向光束偏移量=" + beamX.ToString() + "m", true);
  123. beamX = (-deltX + beamX);
  124. log.Info("X方向光束偏移量应为=" + beamX.ToString() + "m", true);
  125. if (((beamX <= beamXMax) && (beamX >= 0)) ||
  126. ((beamX >= -beamXMax) && (beamX < 0)))
  127. {
  128. log.Info("X方向移动光束", true);
  129. float beamXShift = beamX * 100 / beamXMax;
  130. log.Info("X方向光束偏移量应为=" + beamXShift.ToString() + "%", true);
  131. if (!iSEM.SetBeamShiftX(beamXShift))//if (!iSEM.SetBeamOffsetX(beamX))
  132. {
  133. log.Info("X方向光束偏移量" + beamX.ToString() + "m失败", true);
  134. return false;
  135. }
  136. }
  137. else if (deltX > 0.000003 || deltX < -0.000003)//大于3um使用移动样品台实现
  138. {
  139. log.Info("X方向移动样品台", true);
  140. if (!iSEM.SetStageGotoX(xpNew))
  141. {
  142. return false;
  143. }
  144. //判断是否移动完成
  145. while (true)
  146. {
  147. Thread.Sleep(4000);
  148. if (iSEM.GetStageIs() == 0)
  149. {
  150. break;
  151. }
  152. }
  153. }
  154. float beamY = iSEM.GetBeamOffsetY();
  155. log.Info("当前Y方向光束偏移量=" + beamY.ToString() + "m", true);
  156. beamY = (-deltY + beamY);
  157. log.Info("Y方向光束偏移量应为=" + beamY.ToString() + "m", true);
  158. //计算最大偏移量
  159. float beamYCur = iSEM.GetBeamShiftY();//单位是%
  160. Thread.Sleep(200);
  161. iSEM.SetBeamShiftY(100);
  162. Thread.Sleep(200);
  163. float beamYMax = iSEM.GetBeamOffsetY();//单位是m
  164. Thread.Sleep(200);
  165. iSEM.SetBeamShiftY(beamYCur);
  166. Thread.Sleep(200);
  167. if (((beamY <= beamYMax) && (beamY >= 0)) ||
  168. ((beamY >= -beamYMax) && (beamY < 0)))
  169. {
  170. log.Info("Y方向移动光束", true);
  171. float beamYShift = beamY * 100 / beamYMax;
  172. log.Info("Y方向光束偏移量" + beamYShift.ToString() + "%", true);
  173. //if(!iSEM.SetBeamOffsetY(beamY))
  174. if (!iSEM.SetBeamShiftY(beamYShift))
  175. {
  176. log.Info("Y方向光束偏移量" + beamY.ToString() + "m失败", true);
  177. return false;
  178. }
  179. }
  180. else if (deltY > 0.000003 || deltY < -0.000003)//大于3um使用移动样品台实现
  181. {
  182. log.Info("Y方向移动样品台", true);
  183. if (!iSEM.SetStageGotoY(ypNew))
  184. {
  185. return false;
  186. }
  187. //判断是否移动完成
  188. while (true)
  189. {
  190. Thread.Sleep(4000);
  191. if (iSEM.GetStageIs() == 0)
  192. {
  193. break;
  194. }
  195. }
  196. }
  197. return true;
  198. }
  199. public bool DoLocateByMoveStage()
  200. {
  201. return MoveToPixByMoveStage(prm.PositionX, prm.PositionY);
  202. }
  203. public bool DoLocateByShiftBeam()
  204. {
  205. return MoveToPix(prm.PositionX, prm.PositionY);
  206. }
  207. }
  208. }