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); } } }