Measure.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. //时间:20200610
  2. //作者:郝爽
  3. //功能:测量线程
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using SmartSEMControl;
  10. using MeasureData;
  11. namespace MeasureThread
  12. {
  13. public enum FMode
  14. {
  15. Manual,
  16. Auto
  17. }
  18. public class Measure
  19. {
  20. //全局只有一个fatorySEM
  21. static FactoryHardware factorySEM = FactoryHardware.Instance;
  22. ISEMControl iSEM = factorySEM.ISEM;
  23. //测量文件
  24. private MeasureFile m_measureFile;
  25. public MeasureFile MeasureFile
  26. {
  27. get { return this.m_measureFile; }
  28. set { this.m_measureFile = value; }
  29. }
  30. //测量的切割孔
  31. private List<MeasureData.CutHole> m_cutHoles;
  32. public List<MeasureData.CutHole> cutHoles
  33. {
  34. get { return this.m_cutHoles; }
  35. set { this.m_cutHoles = value; }
  36. }
  37. //工作文件夹
  38. private string m_WorkingFolder;
  39. public string WorkingFolder
  40. {
  41. get { return this.m_WorkingFolder; }
  42. set { this.m_WorkingFolder = value; }
  43. }
  44. //线程状态
  45. private ThreadStatus m_ThreadStatus;
  46. public ThreadStatus TStatus
  47. {
  48. get { return this.m_ThreadStatus; }
  49. set { this.m_ThreadStatus = value; }
  50. }
  51. //对焦模式
  52. private FMode m_bFocusMode;
  53. public FMode FocusMode
  54. {
  55. get { return this.m_bFocusMode; }
  56. set { this.m_bFocusMode = FocusMode; }
  57. }
  58. //// SEM data general
  59. //CSEMDataGnrPtr m_pSEMDataGnr;
  60. ////MeasureAppFormName
  61. //CString m_strMAppFormName;
  62. //HWND m_hWnd;
  63. //构造函数
  64. public Measure()
  65. {
  66. Init();
  67. }
  68. public void Init()
  69. {
  70. FocusMode = FMode.Manual;
  71. }
  72. //初始化测量业务, 读测量文件,判断是否有可测试的切孔
  73. public bool InitMeas(MeasureFile a_measureFile)
  74. {
  75. m_measureFile = a_measureFile;
  76. List<CutHole> listHoles = m_measureFile.ListCutHole;
  77. foreach (CutHole h in listHoles )
  78. {
  79. if (h.SWITCH == true)
  80. {
  81. m_cutHoles.Add(h);
  82. }
  83. }
  84. if(m_cutHoles.Count == 0)
  85. return false;
  86. return true;
  87. }
  88. //测量流程
  89. public void DoMeasure()
  90. {
  91. //创建线程的测量状态的更新
  92. this.TStatus.ComputeTime(THREAD_TIME_TYPE.START);
  93. //将这个开始时间传递给主界面
  94. //检查硬件连接是否正常
  95. if (!ConnectHardware())
  96. {
  97. return;
  98. }
  99. //设置工作文件夹
  100. if (!SetWorkingFolderStr())
  101. {
  102. return;
  103. }
  104. //第一个孔的测试
  105. FirstHole();
  106. //非第一个孔的测试
  107. OtherHole();
  108. }
  109. //检查硬件连接是否正常
  110. public bool ConnectHardware()
  111. {
  112. //返回硬件的连接状态
  113. return iSEM.ConnectStatus();
  114. }
  115. //设置工作文件夹
  116. public bool SetWorkingFolderStr()
  117. {
  118. //获取工作文件路径
  119. string pathName = m_measureFile.FilePath;
  120. //判断工作文件路径是否为空或无效
  121. if (string.IsNullOrEmpty(pathName))
  122. {
  123. return false;
  124. }
  125. //文件未保存
  126. else if (pathName.CompareTo(MeasureFile.UNTITLED_FILE_NAME) == 0)
  127. {
  128. return false;
  129. }
  130. //获取工作文件所在文件夹
  131. string folder = System.IO.Path.GetDirectoryName(pathName);
  132. if (string.IsNullOrEmpty(folder))
  133. {
  134. return false;
  135. }
  136. WorkingFolder += @"\\";
  137. return false;
  138. }
  139. //第一个孔的测试过程
  140. public void FirstHole()
  141. {
  142. MeasureData.CutHole firstHole = m_cutHoles[0];
  143. //12.根据样品类型参数确定是否需要PT沉积,控制PT针插入
  144. if (firstHole.PT == true)
  145. {
  146. if (!iSEM.InsertPT())
  147. {
  148. return;
  149. }
  150. }
  151. //13.自动定位切割
  152. {
  153. //1.控制SEM放大600X
  154. if (!iSEM.SetMagnification(600))
  155. {
  156. return;
  157. }
  158. //2.控制SEM自动对焦、亮度、对比度
  159. if (FocusMode == FMode.Manual)
  160. {
  161. //弹出手动对焦的窗口
  162. }
  163. else if (FocusMode == FMode.Auto)
  164. {
  165. //调用自动对焦模块
  166. }
  167. else
  168. {
  169. return;
  170. }
  171. //3.设置SEM进行角度补偿54度
  172. if (!TiltCorrection(54))
  173. {
  174. return;
  175. }
  176. //4.控制SEM拍照
  177. Boolean GrabImage(String filename, short xoff, short yoff, short width, short height, short type);
  178. //5.保存照片
  179. {
  180. //1. 创建目录,已经完成
  181. //2. 设置图片名称
  182. //3. 保存图片1
  183. }
  184. //6.设置FIB拍照参数——扫描时间、束流等
  185. //7.控制FIB自动亮度、对比度
  186. //8.控制FIB拍照
  187. //9.保存照片
  188. {
  189. //1. 设置图片名称
  190. //2. 保存图片2
  191. }
  192. //10.将照片传给客户,返回梯形位置坐标,及样品类型参数(是否需要PT沉积,PT坐标位置,PT宽度、PT高度、梯形上、下边及深度、扫描时间、束流、样品放大倍数1、样品放大倍数2等切割参数)
  193. //11.自动工具样品类型参数确定是否需要PT沉积
  194. {
  195. //1. 根据客户PT沉积坐标控制FIB调整到中心位置
  196. //2. 验证移动准确性:获取当前FIB中心位置坐标,与客户返回坐标对比,验证是否一定正确
  197. //3. 根据坐标进行PT沉积
  198. }
  199. //12.根据梯形坐标控制FIB调整到中心位置
  200. //13.验证移动准确性:获取当前FIB中心位置坐标,与客户返回坐标对比,验证是否移动正确
  201. //14.保存样品1第1号孔中心位置6轴坐标1 XYZMRT到数据库,保存客户返回值信息到数据库
  202. }
  203. //14.自动控制FIB切割
  204. {
  205. //1.根据参数设置FIB草率时间(使图清晰),设置梯形上下边及深度、设置束流
  206. //2.控制FIB进行切割
  207. //3.控制FIB拍照600X
  208. //4.保存图片
  209. {
  210. //1.设置图片名称
  211. //2.保存图片3
  212. }
  213. //5.验证切割准确性:与切割前对比,如果对比误差大,则停止自动执行,进行报警
  214. //6.设置FIB解冻:先读取状态,如果冻结状态则进行解冻
  215. }
  216. //15.根据样品类型决定是否撤出PT针
  217. //16.自动调整SEM找到切割位置
  218. {
  219. //1.控制SEM放大到300倍
  220. //2.控制SEM自动对焦、亮度、对比度-接口
  221. //3.控制SEM拍照
  222. //4.将照片传给客户,获取偏移坐标,以及偏移角度
  223. //5.根据坐标控制SEM移动到切孔位置,居中
  224. //6.验证移动准确性:获取当前SEM中心位置坐标,与客户返回坐标对比,验证是否移动正确
  225. }
  226. //17.自动控制SEM拍截面照
  227. {
  228. //1.控制SEM放大到指定参数大小范围,6000x
  229. //2.控制SEM自动对焦、消像散、亮度、对比度
  230. //3.设置SEM角度补偿cos36度
  231. //4.控制SEM拍照
  232. //5.保存照片4
  233. //6.将照片传给客户,获取偏移坐标
  234. //7.根据坐标控制SEM移动到分析位置
  235. //8.验证移动准确性:获取当前SEM中心位置坐标,与客户返回坐标对比,验证是否移动正确
  236. //9.控制SEM平行校正,并记录校正前初始值
  237. //10.控制SEM放大到指定参数大小范围
  238. //11.控制SEM自动对焦、消像散、亮度、对比度
  239. //12.控制SEM对分析位置拍照
  240. //13.保存照片
  241. //14.控制SEM取消电子束校正,回到初始值
  242. }
  243. //18.自动层高分析
  244. {
  245. //1.获取SEM Pixel Size给客户传入参数
  246. //2.将照片传给客户,客户进行层高分析(返回分析后的图像、相对坐标、分辨率、各层编号以及各层对应的层高数据),如果客户自行出分析报告则无需返回数据
  247. }
  248. //19.自动能谱分析
  249. {
  250. //1. 确定能谱位置
  251. //2. 控制牛津打能谱
  252. //3. 能谱分析——面扫+线扫描
  253. }
  254. }
  255. //非第一个孔的测试过程
  256. public void OtherHole()
  257. {
  258. }
  259. //角度补偿
  260. public bool TiltCorrection(float a_fAngle)
  261. {
  262. //记录原来电镜的状态
  263. bool bTilt = false;
  264. float fOldTilt = iSEM.GetTiltCorrection();
  265. if (fOldTilt == float.NaN)
  266. {
  267. return false;
  268. }
  269. else if (fOldTilt == 1)
  270. {
  271. bTilt = true;
  272. }
  273. else if (fOldTilt == 0)
  274. {
  275. bTilt = false;
  276. }
  277. float fOldAngle = iSEM.GetTiltAngle();
  278. if (fOldAngle == float.NaN)
  279. {
  280. return false;
  281. }
  282. //开启校正
  283. if (!iSEM.SetTiltCorrectionOn())
  284. {
  285. return false;
  286. }
  287. //设置校正角度
  288. if (!iSEM.SetTiltAngle(fOldAngle))
  289. {
  290. return false;
  291. }
  292. //恢复原始状态
  293. if (!iSEM.SetTiltAngle(a_fAngle))
  294. {
  295. return false;
  296. }
  297. if (bTilt)
  298. {
  299. if (!iSEM.SetTiltCorrectionOn())
  300. {
  301. return false;
  302. }
  303. }
  304. else
  305. {
  306. if (!iSEM.SetTiltCorrectionOff())
  307. {
  308. return false;
  309. }
  310. }
  311. return true;
  312. }
  313. //SEM拍图
  314. public bool GetSEMImage()
  315. {
  316. //1. 图像解冻
  317. //2. 确认是SEM图像
  318. //3. 获取分辨率
  319. //4. 抓图
  320. Boolean GrabImage(String filename, short xoff, short yoff, short width, short height, short type);
  321. return true;
  322. }
  323. }
  324. }