|
@@ -0,0 +1,254 @@
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.Linq;
|
|
|
+using System.Text;
|
|
|
+using System.Threading;
|
|
|
+using System.Threading.Tasks;
|
|
|
+using NLog;
|
|
|
+using SmartSEMControl;
|
|
|
+
|
|
|
+namespace MeasureThread
|
|
|
+{
|
|
|
+ class Locate : ILocate
|
|
|
+ {
|
|
|
+ NLog.Logger log;
|
|
|
+ private LocateParam prm;
|
|
|
+ private ISEMControl iSEM;
|
|
|
+
|
|
|
+ public Locate( LocateParam prm, ISEMControl iSEM)
|
|
|
+ {
|
|
|
+ this.log = NLog.LogManager.GetCurrentClassLogger();
|
|
|
+
|
|
|
+ this.log = log ?? throw new ArgumentNullException(nameof(log));
|
|
|
+ this.prm = prm ?? throw new ArgumentNullException(nameof(prm));
|
|
|
+ this.iSEM = iSEM ?? throw new ArgumentNullException(nameof(iSEM));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //移动到像素位置,这里要靠移动样品台实现,当位移量小于3um时,不予移动
|
|
|
+ bool MoveToPixByMoveStage(float xc, float yc)
|
|
|
+ {
|
|
|
+ //单位是m/pix
|
|
|
+ float XpixSize = iSEM.GetPixelSize();
|
|
|
+ log.Info("X像素尺寸=" + XpixSize.ToString() + "m/pixel", true);
|
|
|
+ float YpixSize = iSEM.GetPixelSize()/prm.PixelSize_Y_cur;///(float)MParam.PixelSizeCor);
|
|
|
+ log.Info("Y像素尺寸=" + YpixSize.ToString() + "m/pixel", true);
|
|
|
+
|
|
|
+ Thread.Sleep(500);
|
|
|
+ //0:width, 1:height
|
|
|
+ int[] imageSize = iSEM.GetImageStore();
|
|
|
+
|
|
|
+ int width = imageSize[0] / 2;
|
|
|
+ int height = imageSize[1] / 2;
|
|
|
+
|
|
|
+ log.Info("目标像素是(" + xc.ToString() + "," + yc.ToString() + ")", true);
|
|
|
+ log.Info("中心像素是(" + width.ToString() + "," + height.ToString() + ")", true);
|
|
|
+
|
|
|
+ float deltX = (xc - (float)width) * XpixSize;
|
|
|
+ float deltY = (yc - (float)height) * YpixSize;
|
|
|
+
|
|
|
+ log.Info("x位移量 = " + deltX.ToString() + "m", true);
|
|
|
+ log.Info("y位移量 = " + deltY.ToString() + "m", true);
|
|
|
+
|
|
|
+ float xpCur = iSEM.GetStageAtX();
|
|
|
+ float ypCur = iSEM.GetStageAtY();
|
|
|
+
|
|
|
+ log.Info("当前位置(" + xpCur.ToString() + "," + ypCur.ToString() + "),单位m", true);
|
|
|
+
|
|
|
+ float xpNew = xpCur - deltX;
|
|
|
+ float ypNew = ypCur + deltY;
|
|
|
+
|
|
|
+ log.Info("目标位置(" + xpNew.ToString() + "," + ypNew.ToString() + "),单位m", true);
|
|
|
+
|
|
|
+ //计算光束偏移值:
|
|
|
+ //if (deltX >= 0.000003 || deltX <= 0.000003)//大于3um使用移动样品台实现
|
|
|
+ {
|
|
|
+ log.Info("X方向移动样品台", true);
|
|
|
+
|
|
|
+ if (!iSEM.SetStageGotoX(xpNew))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ //判断是否移动完成
|
|
|
+ while (true)
|
|
|
+ {
|
|
|
+ Thread.Sleep(5000);
|
|
|
+ if (iSEM.GetStageIs() == 0)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //if (deltY >= 0.000003 || deltY <= -0.000003)//大于3um使用移动样品台实现
|
|
|
+ {
|
|
|
+ log.Info("Y方向移动样品台", true);
|
|
|
+
|
|
|
+ if (!iSEM.SetStageGotoY(ypNew))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ //判断是否移动完成
|
|
|
+ while (true)
|
|
|
+ {
|
|
|
+ Thread.Sleep(5000);
|
|
|
+ if (iSEM.GetStageIs() == 0)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ //移动到像素位置
|
|
|
+ bool MoveToPix(float xc, float yc)
|
|
|
+ {
|
|
|
+
|
|
|
+ //单位是m/pix
|
|
|
+ float XpixSize = iSEM.GetPixelSize();
|
|
|
+
|
|
|
+ log.Info("X像素尺寸=" + XpixSize.ToString() + "m/pixel", true);
|
|
|
+ float YpixSize = (XpixSize / prm.PixelSize_Y_cur);
|
|
|
+ log.Info("Y像素尺寸=" + YpixSize.ToString() + "m/pixel", true);
|
|
|
+
|
|
|
+ Thread.Sleep(200);
|
|
|
+ //0:width, 1:height
|
|
|
+ int[] imageSize = iSEM.GetImageStore();
|
|
|
+
|
|
|
+ int width = imageSize[0] / 2;
|
|
|
+ int height = imageSize[1] / 2;
|
|
|
+
|
|
|
+ log.Info("目标像素是(" + xc.ToString() + "," + yc.ToString() + ")", true);
|
|
|
+ log.Info("中心像素是(" + width.ToString() + "," + height.ToString() + ")", true);
|
|
|
+
|
|
|
+ float deltX = (xc - (float)width) * XpixSize;
|
|
|
+ float deltY = (yc - (float)height) * YpixSize;
|
|
|
+
|
|
|
+ log.Info("x位移量 = " + deltX.ToString() + "m", true);
|
|
|
+ log.Info("y位移量 = " + deltY.ToString() + "m", true);
|
|
|
+
|
|
|
+ float xpCur = iSEM.GetStageAtX();
|
|
|
+ Thread.Sleep(200);
|
|
|
+ float ypCur = iSEM.GetStageAtY();
|
|
|
+
|
|
|
+ log.Info("当前位置(" + xpCur.ToString() + "," + ypCur.ToString() + "),单位m", true);
|
|
|
+
|
|
|
+ float xpNew = xpCur - deltX;
|
|
|
+ float ypNew = ypCur + deltY;
|
|
|
+
|
|
|
+ log.Info("目标位置(" + xpNew.ToString() + "," + ypNew.ToString() + "),单位m", true);
|
|
|
+
|
|
|
+ //计算最大偏移量
|
|
|
+ float beamXCur = iSEM.GetBeamShiftX();//单位是%
|
|
|
+ Thread.Sleep(200);
|
|
|
+ iSEM.SetBeamShiftX(100);
|
|
|
+ Thread.Sleep(200);
|
|
|
+ float beamXMax = iSEM.GetBeamOffsetX();//单位是m
|
|
|
+ Thread.Sleep(200);
|
|
|
+ iSEM.SetBeamShiftX(beamXCur);
|
|
|
+ Thread.Sleep(200);
|
|
|
+ //计算光束偏移值:
|
|
|
+ float beamX = iSEM.GetBeamOffsetX();
|
|
|
+ log.Info("当前X方向光束偏移量=" + beamX.ToString() + "m", true);
|
|
|
+
|
|
|
+ beamX = (-deltX + beamX);
|
|
|
+ log.Info("X方向光束偏移量应为=" + beamX.ToString() + "m", true);
|
|
|
+
|
|
|
+ if (((beamX <= beamXMax) && (beamX >= 0)) ||
|
|
|
+ ((beamX >= -beamXMax) && (beamX < 0)))
|
|
|
+ {
|
|
|
+ log.Info("X方向移动光束", true);
|
|
|
+ float beamXShift = beamX * 100 / beamXMax;
|
|
|
+ log.Info("X方向光束偏移量应为=" + beamXShift.ToString() + "%", true);
|
|
|
+ if (!iSEM.SetBeamShiftX(beamXShift))//if (!iSEM.SetBeamOffsetX(beamX))
|
|
|
+ {
|
|
|
+ log.Info("X方向光束偏移量" + beamX.ToString() + "m失败", true);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (deltX > 0.000003 || deltX < -0.000003)//大于3um使用移动样品台实现
|
|
|
+ {
|
|
|
+ log.Info("X方向移动样品台", true);
|
|
|
+
|
|
|
+ if (!iSEM.SetStageGotoX(xpNew))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ //判断是否移动完成
|
|
|
+ while (true)
|
|
|
+ {
|
|
|
+ Thread.Sleep(4000);
|
|
|
+ if (iSEM.GetStageIs() == 0)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ float beamY = iSEM.GetBeamOffsetY();
|
|
|
+ log.Info("当前Y方向光束偏移量=" + beamY.ToString() + "m", true);
|
|
|
+
|
|
|
+ beamY = (-deltY + beamY);
|
|
|
+ log.Info("Y方向光束偏移量应为=" + beamY.ToString() + "m", true);
|
|
|
+
|
|
|
+ //计算最大偏移量
|
|
|
+ float beamYCur = iSEM.GetBeamShiftY();//单位是%
|
|
|
+ Thread.Sleep(200);
|
|
|
+ iSEM.SetBeamShiftY(100);
|
|
|
+ Thread.Sleep(200);
|
|
|
+ float beamYMax = iSEM.GetBeamOffsetY();//单位是m
|
|
|
+ Thread.Sleep(200);
|
|
|
+ iSEM.SetBeamShiftY(beamYCur);
|
|
|
+ Thread.Sleep(200);
|
|
|
+ if (((beamY <= beamYMax) && (beamY >= 0)) ||
|
|
|
+ ((beamY >= -beamYMax) && (beamY < 0)))
|
|
|
+ {
|
|
|
+ log.Info("Y方向移动光束", true);
|
|
|
+ float beamYShift = beamY * 100 / beamYMax;
|
|
|
+ log.Info("Y方向光束偏移量" + beamYShift.ToString() + "%", true);
|
|
|
+ //if(!iSEM.SetBeamOffsetY(beamY))
|
|
|
+ if (!iSEM.SetBeamShiftY(beamYShift))
|
|
|
+ {
|
|
|
+ log.Info("Y方向光束偏移量" + beamY.ToString() + "m失败", true);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (deltY > 0.000003 || deltY < -0.000003)//大于3um使用移动样品台实现
|
|
|
+ {
|
|
|
+ log.Info("Y方向移动样品台", true);
|
|
|
+
|
|
|
+ if (!iSEM.SetStageGotoY(ypNew))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ //判断是否移动完成
|
|
|
+ while (true)
|
|
|
+ {
|
|
|
+ Thread.Sleep(4000);
|
|
|
+ if (iSEM.GetStageIs() == 0)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ public bool DoLocateByMoveStage()
|
|
|
+ {
|
|
|
+ return MoveToPixByMoveStage(prm.PositionX, prm.PositionY);
|
|
|
+ }
|
|
|
+
|
|
|
+ public bool DoLocateByShiftBeam()
|
|
|
+ {
|
|
|
+ return MoveToPix(prm.PositionX, prm.PositionY);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|