diff --git a/WaferAlignment/Camera.cs b/WaferAlignment/Camera.cs index 0b75418..81441cc 100644 --- a/WaferAlignment/Camera.cs +++ b/WaferAlignment/Camera.cs @@ -161,7 +161,6 @@ namespace WaferAlignment _dev.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE); _dev.MV_CC_StartGrabbing_NET(); _dev.MV_CC_TriggerSoftwareExecute_NET(); - Thread.Sleep(100); } public void Stop() @@ -195,7 +194,7 @@ namespace WaferAlignment try { _startAcqToken.Cancel(); - Thread.Sleep(20); + Thread.Sleep(200); _imageAcquisitionTask.Wait(_stopAcqToken.Token); _imageAcquisitionTask.Dispose(); } diff --git a/WaferAlignment/DataPostbox.cs b/WaferAlignment/DataPostbox.cs index d814cad..ef69a56 100644 --- a/WaferAlignment/DataPostbox.cs +++ b/WaferAlignment/DataPostbox.cs @@ -16,7 +16,7 @@ namespace ConVX.VXData /// /// 判断线程状态 /// - private AutoResetEvent _autoReset = null; + //private AutoResetEvent _autoReset = null; /// /// 线程 /// @@ -53,7 +53,7 @@ namespace ConVX.VXData public DataPostbox() { _queue = new ConcurrentQueue(); - _autoReset = new AutoResetEvent(false);//线程非终止状态 + //_autoReset = new AutoResetEvent(false);//线程非终止状态 } /// /// 启动派发 @@ -72,7 +72,7 @@ namespace ConVX.VXData try { RuningToken.Cancel(); - _autoReset.Set();//为了避免线程正在执行或等待状态 + //_autoReset.Set();//为了避免线程正在执行或等待状态 await _task; } catch (OperationCanceledException ex) @@ -98,7 +98,7 @@ namespace ConVX.VXData //} _queue.Enqueue(envelope); - _autoReset.Set(); + //_autoReset.Set(); } #endregion @@ -110,7 +110,8 @@ namespace ConVX.VXData { if (_queue.IsEmpty) { - _autoReset.WaitOne(); + //_autoReset.WaitOne(); + Thread.Sleep(1); } else { diff --git a/WaferAlignment/FitCircleToolBlock.cs b/WaferAlignment/FitCircleToolBlock.cs new file mode 100644 index 0000000..a1ab1a9 --- /dev/null +++ b/WaferAlignment/FitCircleToolBlock.cs @@ -0,0 +1,101 @@ +using Cognex.VisionPro; +using Cognex.VisionPro.PMAlign; +using Cognex.VisionPro.ToolBlock; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Documents; + +namespace WaferAdjust +{ + public delegate void OnFitCircleResult(double x, double y, double r, double rms); + internal class FitCircleToolBlock + { + private CogToolBlock cogToolBlock; + private bool initialized = false; + public event OnToolReady OnToolReady; + public event OnFitCircleResult OnFitCircleResult; + public CogImage8Grey FitCircleImage; + public void Initialize(string vpp) + { + try + { + if (cogToolBlock != null) + { + cogToolBlock.Ran -= CogToolBlock_Ran; + cogToolBlock.Dispose(); + cogToolBlock = null; + } + initialized = false; + cogToolBlock = CogSerializer.LoadObjectFromFile(vpp) as CogToolBlock; + cogToolBlock.Ran += CogToolBlock_Ran; + initialized = true; + OnToolReady?.Invoke(initialized); + LogHelper.LogInfo("FitCircleToolBlock initialized successfully: " + vpp); + } + catch (Exception ex) + { + LogHelper.LogError(ex.Message); + } + } + private void CogToolBlock_Ran(object sender, EventArgs e) + { + try + { + FitCircleImage = cogToolBlock.Outputs["OutputImage"].Value as CogImage8Grey; + OnFitCircleResult?.Invoke(Math.Round((double)cogToolBlock.Outputs["CenterX"].Value, 3), + Math.Round((double)cogToolBlock.Outputs["CenterY"].Value, 3), + Math.Round((double)cogToolBlock.Outputs["Radius"].Value, 3), + Math.Round((double)cogToolBlock.Outputs["RMSError"].Value, 3)); + } + catch (Exception ex) + { + LogHelper.LogError(ex.Message + ex.StackTrace); + } + } + public void Run(Bitmap bmp, List pointInfos) + { + try + { + CogImage8Grey image8Grey = new CogImage8Grey(bmp); + Run(image8Grey, pointInfos); + } + catch (Exception ex) + { + LogHelper.LogError("ScanToolBlock Run Error: " + ex.Message); + } + } + public void Run(CogImage8Grey image8Grey, List pointInfos) + { + try + { + cogToolBlock.Inputs["OutputImage"].Value = image8Grey; + CogFitCircleTool fitCircleTool = cogToolBlock.Tools["CogFitCircleTool1"] as CogFitCircleTool; + fitCircleTool.RunParams.NumPoints = 0; + foreach (var item in pointInfos) + fitCircleTool.RunParams.AddPoint(item.X, item.Y); + cogToolBlock.Run(); + } + catch (Exception ex) + { + LogHelper.LogError("ScanToolBlock Run Error: " + ex.Message); + } + } + public bool Ready() + { + return initialized; + } + public void Stop() + { + if (cogToolBlock != null) + { + cogToolBlock.Ran -= CogToolBlock_Ran; + cogToolBlock.Dispose(); + cogToolBlock = null; + } + } + } +} diff --git a/WaferAlignment/Form1.Designer.cs b/WaferAlignment/Form1.Designer.cs index 80069f2..56f5ec1 100644 --- a/WaferAlignment/Form1.Designer.cs +++ b/WaferAlignment/Form1.Designer.cs @@ -68,6 +68,10 @@ this.nud_SizeX = new System.Windows.Forms.NumericUpDown(); this.btn_Action = new System.Windows.Forms.Button(); this.btn_ToZero = new System.Windows.Forms.Button(); + this.textBox2 = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.textBox3 = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); this.splitContainer1.Panel1.SuspendLayout(); this.splitContainer1.Panel2.SuspendLayout(); @@ -93,6 +97,10 @@ // // splitContainer1.Panel2 // + this.splitContainer1.Panel2.Controls.Add(this.textBox2); + this.splitContainer1.Panel2.Controls.Add(this.label1); + this.splitContainer1.Panel2.Controls.Add(this.textBox3); + this.splitContainer1.Panel2.Controls.Add(this.label2); this.splitContainer1.Panel2.Controls.Add(this.lbl_Time); this.splitContainer1.Panel2.Controls.Add(this.txt_Time); this.splitContainer1.Panel2.Controls.Add(this.lbl_Times); @@ -167,7 +175,7 @@ // lbl_Times // this.lbl_Times.AutoSize = true; - this.lbl_Times.Location = new System.Drawing.Point(234, 15); + this.lbl_Times.Location = new System.Drawing.Point(182, 17); this.lbl_Times.Name = "lbl_Times"; this.lbl_Times.Size = new System.Drawing.Size(89, 12); this.lbl_Times.TabIndex = 30; @@ -175,7 +183,7 @@ // // txt_Times // - this.txt_Times.Location = new System.Drawing.Point(326, 12); + this.txt_Times.Location = new System.Drawing.Point(274, 14); this.txt_Times.Name = "txt_Times"; this.txt_Times.ReadOnly = true; this.txt_Times.Size = new System.Drawing.Size(129, 21); @@ -383,9 +391,9 @@ // // btn_RunTest // - this.btn_RunTest.Location = new System.Drawing.Point(481, 12); + this.btn_RunTest.Location = new System.Drawing.Point(409, 14); this.btn_RunTest.Name = "btn_RunTest"; - this.btn_RunTest.Size = new System.Drawing.Size(161, 23); + this.btn_RunTest.Size = new System.Drawing.Size(119, 23); this.btn_RunTest.TabIndex = 9; this.btn_RunTest.Text = "启动检测"; this.btn_RunTest.UseVisualStyleBackColor = true; @@ -444,6 +452,7 @@ 0, 0, -2147483648}); + this.nud_SizeY.ValueChanged += new System.EventHandler(this.nud_SizeY_ValueChanged); // // lbl_X // @@ -458,8 +467,13 @@ // this.nud_SizeX.DecimalPlaces = 2; this.nud_SizeX.Location = new System.Drawing.Point(80, 137); + this.nud_SizeX.Maximum = new decimal(new int[] { + 6, + 0, + 0, + 0}); this.nud_SizeX.Minimum = new decimal(new int[] { - 100, + 8, 0, 0, -2147483648}); @@ -471,6 +485,7 @@ 0, 0, 0}); + this.nud_SizeX.ValueChanged += new System.EventHandler(this.nud_SizeX_ValueChanged); // // btn_Action // @@ -484,7 +499,7 @@ // // btn_ToZero // - this.btn_ToZero.Location = new System.Drawing.Point(17, 99); + this.btn_ToZero.Location = new System.Drawing.Point(17, 95); this.btn_ToZero.Name = "btn_ToZero"; this.btn_ToZero.Size = new System.Drawing.Size(161, 23); this.btn_ToZero.TabIndex = 0; @@ -492,6 +507,42 @@ this.btn_ToZero.UseVisualStyleBackColor = true; this.btn_ToZero.Click += new System.EventHandler(this.btn_ToZero_Click); // + // textBox2 + // + this.textBox2.Location = new System.Drawing.Point(534, 22); + this.textBox2.Name = "textBox2"; + this.textBox2.Size = new System.Drawing.Size(55, 21); + this.textBox2.TabIndex = 33; + this.textBox2.Text = "82"; + this.textBox2.TextChanged += new System.EventHandler(this.textBox2_TextChanged); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(532, 7); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(53, 12); + this.label1.TabIndex = 34; + this.label1.Text = "相机计数"; + // + // textBox3 + // + this.textBox3.Location = new System.Drawing.Point(595, 22); + this.textBox3.Name = "textBox3"; + this.textBox3.Size = new System.Drawing.Size(55, 21); + this.textBox3.TabIndex = 35; + this.textBox3.Text = "4096"; + this.textBox3.TextChanged += new System.EventHandler(this.textBox3_TextChanged); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(593, 7); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(41, 12); + this.label2.TabIndex = 36; + this.label2.Text = "总计数"; + // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); @@ -556,7 +607,10 @@ private System.Windows.Forms.DataGridViewTextBoxColumn Column4; private System.Windows.Forms.Label lbl_Time; private System.Windows.Forms.TextBox txt_Time; - + private System.Windows.Forms.TextBox textBox2; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox textBox3; + private System.Windows.Forms.Label label2; } } diff --git a/WaferAlignment/Form1.cs b/WaferAlignment/Form1.cs index 2b027bd..6accad2 100644 --- a/WaferAlignment/Form1.cs +++ b/WaferAlignment/Form1.cs @@ -19,6 +19,7 @@ using System.Windows.Forms; using System.Xml.Serialization; using System.Diagnostics; using Cognex.VisionPro.PMAlign; +using WaferAdjust; namespace WaferAlignment @@ -54,20 +55,12 @@ namespace WaferAlignment /// string arAngle = "DB7.DBD76";//设置触发拍照的偏转角度 + GetCircleToolBlock getCircleMachineToolBlock; + FitCircleToolBlock FitCircleMachineToolBlock; + TranslateCirclePoint translateCirclePoint; + CogGraphicCollection m_graphics; + CogGraphicCollection m_graphics2; - - string vppPath; - CogToolBlock mTB; - CogToolBlock mTB_1; - CogToolBlock mTB_2; - - - float R = 11.25F;//1024->12 - //CogImage8Grey OutputImg; - - //旋转中心的坐标应将标定的数据保存后获取 - double circleCenterX; - double circleCenterY; //XML文件读取与写入 ConfigStore _ConfigStore = new ConfigStore(); CenterOfRotation _center = new CenterOfRotation(); @@ -123,7 +116,6 @@ namespace WaferAlignment _s7.SetValue(arSizeX, (float)0); _s7.SetValue(arSizeY, (float)0); _s7.SetValue(arSizeR, (float)0); - _s7.SetValue(arAngle, Convert.ToSingle(R));//角度为10 lbl_CommunState.BackColor = Color.Lime; lbl_CommunState.Text = "已连接"; } @@ -150,9 +142,16 @@ namespace WaferAlignment try { // 加载VPP文件 - vppPath = Path.Combine(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "vpp", "ToolBlock.vpp"); + getCircleMachineToolBlock = new GetCircleToolBlock(); + getCircleMachineToolBlock.OnGetCircleResult += GetCircleMachineToolBlock_OnGetCircleResult; + getCircleMachineToolBlock.OnGetNashResult += GetCircleMachineToolBlock_OnGetNashResult; + getCircleMachineToolBlock.OnToolReady += GetCircleMachineToolBlock_OnToolReady; - mTB = CogSerializer.LoadObjectFromFile(vppPath) as CogToolBlock; + FitCircleMachineToolBlock = new FitCircleToolBlock(); + FitCircleMachineToolBlock.OnFitCircleResult += FitCircleMachineToolBlock_OnFitCircleResult; + FitCircleMachineToolBlock.OnToolReady += FitCircleMachineToolBlock_OnToolReady; + translateCirclePoint = new TranslateCirclePoint(); + m_graphics2 = new CogGraphicCollection(); } catch (Exception ex) { @@ -171,15 +170,117 @@ namespace WaferAlignment catch (Exception ex) { MessageBox.Show(ex.Message); + } + } + private void FitCircleMachineToolBlock_OnToolReady(bool ready) + { + LogHelper.LogInfo("FitCircleMachineToolBlock_OnToolReady"); + } + + private void FitCircleMachineToolBlock_OnFitCircleResult(double x, double y, double r, double rms) + { + TCP_X = x.ToString("F4"); + TCP_Y = y.ToString("F4"); + TCP_RMS = rms.ToString("F4"); + TCP_R = r.ToString("F4"); + + deviationX = Math.Round((x - translateCirclePoint.GetRotateX()), 3); + deviationY = Math.Round((y - translateCirclePoint.GetRotateY()), 3); + + AddPointMarker(m_graphics2, x, y); + AddPointMarker(m_graphics2, translateCirclePoint.GetRotateX(), translateCirclePoint.GetRotateY(), CogColorConstants.Red); + + PointInfo nPoint = translateCirclePoint.GetNashPoint(); + if (nPoint != null) + { + AddPointMarker(m_graphics2, nPoint.X, nPoint.Y, CogColorConstants.Yellow); + AddLineMarker(m_graphics2, x, y, x, y - r); + AddLineMarker(m_graphics2, x, y, nPoint.X, nPoint.Y, CogColorConstants.Yellow); + angle = GetCounterClockwiseAngle360(x, y, x, y - r, nPoint.X, nPoint.Y); + AddLabelMarker(m_graphics2, angle.ToString(), x, y, CogColorConstants.Yellow); + LogHelper.LogInfo($"nash degree:{angle}"); } - // 指定XML文件路径 - string filePath = Path.Combine(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "vpp", "CenterOfRotation.xml"); //@"D:\晶圆寻边机\XML文件\CenterOfRotation.xml"; - _center = _ConfigStore.ReadConfigFromFile(_center.GetType(), filePath) as CenterOfRotation; - circleCenterX = _center.Center_X; - circleCenterY = _center.Center_Y; + LogHelper.LogInfo($"X:{x}, Y:{y}, RMS:{rms}"); + LogHelper.LogInfo($"DiffX:{deviationX}, DiffY:{deviationY}, RMS:{rms}{Environment.NewLine}"); + ImageDisplay(FitCircleMachineToolBlock.FitCircleImage); + ImageDisplay(m_graphics); + ImageDisplay(m_graphics2); + ImageDisplayFit(); } + private void AddPointMarker(CogGraphicCollection graphicCollection, double x, double y, CogColorConstants color = CogColorConstants.Green) + { + CogPointMarker marker = new CogPointMarker(); + marker.X = x; + marker.Y = y; + marker.Color = color; + marker.Interactive = false; + graphicCollection.Add(marker); + } + private void AddLineMarker(CogGraphicCollection graphicCollection, double x1, double y1, double x2, double y2, CogColorConstants color = CogColorConstants.Green) + { + CogLineSegment line = new CogLineSegment(); + line.SetStartEnd((int)x1, (int)y1, (int)x2, (int)y2); + line.Color = color; + line.Interactive = false; + graphicCollection.Add(line); + } + private void AddLabelMarker(CogGraphicCollection graphicCollection, string text, double x, double y, CogColorConstants color = CogColorConstants.Green) + { + CogGraphicLabel label = new CogGraphicLabel(); + label.Text = text; + label.X = x; + label.Y = y; + label.Color = color; + graphicCollection.Add(label); + } + /// + /// 计算从 lineA 到 lineB 的逆时针有向角度(0-360度) + /// 坐标系:向右为正,向下为正(标准屏幕坐标系) + /// + public double GetCounterClockwiseAngle360(double x, double y, double x1, double y1, double x2, double y2) + { + // 2. 获取方向向量(dy 向下为正) + double dxA = x1 - x; + double dyA = y1 - y; + + double dxB = x2 - x; + double dyB = y2 - y; + + // 3. 将Y轴翻转,转换为标准数学坐标系(dy向上为正) + // 这样 Math.Atan2 返回的就是标准数学角度(逆时针为正) + double angleA = Math.Atan2(-dyA, dxA); // 注意:y取负号 + double angleB = Math.Atan2(-dyB, dxB); // 注意:y取负号 + + // 4. 计算逆时针角度差(弧度) + double angleDiff = angleB - angleA; + + // 5. 转换为角度并规范化为 [0, 360) + double angleDegrees = angleDiff * 180.0 / Math.PI; + angleDegrees = angleDegrees % 360.0; + if (angleDegrees < 0) angleDegrees += 360.0; + + return Math.Round(angleDegrees, 3); + } + private void GetCircleMachineToolBlock_OnToolReady(bool ready) + { + LogHelper.LogInfo("GetCircleMachineToolBlock_OnToolReady"); + } + + private void GetCircleMachineToolBlock_OnGetNashResult(double x, double y) + { + translateCirclePoint.AddNashPoint(x, y); + LogHelper.LogInfo($"Update Nash X:{x}, Y:{y}"); + } + + private void GetCircleMachineToolBlock_OnGetCircleResult(double x, double y, double r) + { + translateCirclePoint.AddCircleCenter(x, y, r); + translateCirclePoint.AddCirclePoint(getCircleMachineToolBlock.PointInfos); + LogHelper.LogInfo($"X:{x}, Y:{y}, R:{r}"); + } + /// /// 接收到TCP数据时,根据接收到的数据,进行不同操作 /// @@ -217,17 +318,11 @@ namespace WaferAlignment _tcp.SendData(e.ClientIp, "DetectionTime:" + TCP_time + " " + "X:" + TCP_X + " " + "Y:" + TCP_Y + " " + "Angle:" + TCP_R + " " + "RMS:" + TCP_RMS); } } - - } void _cam_OutputImageEvent(Bitmap obj) { - lstNasR.Add((acqNum + 1) * R); acqNum++; - //lstNasR.Add((testNum) * R); - //保存图像 - //SaveImage(new CogImage8Grey(obj)); ImageData.Mailing(new CogImage8Grey(obj)); Images.Add(new CogImage8Grey(obj)); @@ -235,10 +330,9 @@ namespace WaferAlignment void ImageData_ErrorEvent(string obj) { - //throw new NotImplementedException(); + } - private void Form1_FormClosing(object sender, FormClosingEventArgs e) { try @@ -300,7 +394,6 @@ namespace WaferAlignment this.splitContainer1.Invoke(new Action(() => this.splitContainer1.Panel2.Enabled = true)); }); } - public string ToZero() { if (_s7 != null) @@ -393,15 +486,7 @@ namespace WaferAlignment } } - List lstRotation; - List lstX; - List lstY; - List lstRadius; - List lstNasX; - List lstNasY; - List lstNasR; List Images; - int acqNum = 0; int testNum = 0; double angle = 0; @@ -411,9 +496,11 @@ namespace WaferAlignment private void btn_RunTest_Click(object sender, EventArgs e) { SavePath = Path.Combine(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "SaveImage", DateTime.Now.ToString("yyyyMMdd_HHmmss")); - + m_cameraCount = Convert.ToDouble(textBox2.Text); + m_codeCount = Convert.ToDouble(textBox3.Text); + m_roateX = Convert.ToDouble(nud_SizeX.Value); + m_roateY = Convert.ToDouble(nud_SizeY.Value); ClearDisplay(); - ////--------------------------------------- Task.Run(() => { this.splitContainer1.Invoke(new Action(() => this.splitContainer1.Panel2.Enabled = false)); @@ -423,8 +510,6 @@ namespace WaferAlignment this.splitContainer1.Invoke(new Action(() => this.splitContainer1.Panel2.Enabled = true)); }); - - //--------------------------------------- } public string RunTest() @@ -436,7 +521,6 @@ namespace WaferAlignment } else { - //R轴回0 if (_s7 != null) { @@ -480,13 +564,6 @@ namespace WaferAlignment angle = 0; acqNum = 0; testNum = 0; - lstRotation = new List(); - lstX = new List(); - lstY = new List(); - lstRadius = new List(); - lstNasX = new List(); - lstNasY = new List(); - lstNasR = new List(); Images = new List(); sw_1 = new Stopwatch();//检测时间 @@ -495,6 +572,7 @@ namespace WaferAlignment deviationY = 0; times = 0; //启动拍照 + translateCirclePoint.SetRotateXY(m_roateX, m_roateY, 360 * m_cameraCount / m_codeCount); if (_s7 != null) { @@ -529,9 +607,7 @@ namespace WaferAlignment } } //Thread.Sleep(100); - } - } _cam.SoftwareGrab(); @@ -644,327 +720,62 @@ namespace WaferAlignment return "NG_RUN"; } } - + private CogImage8Grey m_lastImage; //所有点 // 调整vpp中CogCaliperTool工具数据需要同时调整Y值与 for (double i = Y; i < 12; i = i + 0.5)中12的值 private void MonitorSpot(CogImage8Grey outputImg) { sw_1 = new Stopwatch();//检测时间 sw_1.Start(); - //double Y = -17; - //double X = 0; - double X = -15; - double Y = 0; - CogImage8Grey inputImg = new CogImage8Grey(); - CogGraphicCollection graphics = new CogGraphicCollection(); - CogImage8Grey _OutputImg = new CogImage8Grey(); - inputImg = outputImg; - mTB_1 = mTB.Tools["CogToolBlock1"] as CogToolBlock; - mTB_2 = mTB.Tools["CogToolBlock2"] as CogToolBlock; - mTB_1.Inputs["InputImage"].Value = inputImg; - mTB_1.Run(); - _OutputImg = mTB_1.Outputs["OutputImage"].Value as CogImage8Grey; + translateCirclePoint.AddCircleIndex(); + m_lastImage = outputImg; + getCircleMachineToolBlock.Run(outputImg); - CogCaliperTool mCT = mTB_1.Tools["CogCaliperTool1"] as CogCaliperTool; - - - - //x′= cx + (x−cx)⋅cos(r)−(y−cy)⋅sin(r) - //y′= cy + (x−cx)⋅sin(r) + (y−cy)⋅cos(r)​ - - int _count = 0; - - for (double i = X; i < 14; i = i + 0.5) - { - mCT.InputImage = _OutputImg; - mCT.Region.CenterX = i; - mCT.Run(); - _count = mCT.Results.Count; - - if (_count != 0) - { - Y = mCT.Results[0].Edge0.PositionY; - //旋转角度 - double r = lstNasR[testNum] / 180 * Math.PI; - //旋转移动到实际位置 - lstNasX.Add(i * Math.Cos(r) - Y * Math.Sin(r) + circleCenterX * (1 - Math.Cos(r)) + circleCenterY * Math.Sin(r)); - lstNasY.Add(i * Math.Sin(r) + Y * Math.Cos(r) - circleCenterX * Math.Sin(r) + circleCenterY * (1 - Math.Cos(r))); - - CogPointMarker marker_1 = new CogPointMarker();//圆 - - marker_1.X = i; - marker_1.Y = Y; - marker_1.Color = CogColorConstants.Blue; - marker_1.Interactive = false; - graphics.Add(marker_1); - } - else - { - OKorNG = false; - testNum++; - return; - } - if (i == X) - { - double r = lstNasR[testNum] / 180 * Math.PI; - lstX.Add(i * Math.Cos(r) - Y * Math.Sin(r) + circleCenterX * (1 - Math.Cos(r)) + circleCenterY * Math.Sin(r)); - lstY.Add(i * Math.Sin(r) + Y * Math.Cos(r) - circleCenterX * Math.Sin(r) + circleCenterY * (1 - Math.Cos(r))); - } - - } sw_1.Stop(); TimeSpan ts = sw_1.Elapsed; - ImageDisplay(_OutputImg, graphics); - DataDisplay(lstNasR[testNum], lstNasX[0], lstNasY[0], ts.TotalMilliseconds); + PointInfo pp = translateCirclePoint.GetFirstPoint(); + if (pp != null) + DataDisplay(translateCirclePoint.GetCurrentDegree(), pp.X, pp.Y, ts.TotalMilliseconds); + else + DataDisplay(translateCirclePoint.GetCurrentDegree(), 0, 0, ts.TotalMilliseconds); testNum++; times += ts.TotalMilliseconds; OKorNG = true; } - //比较半径和点间距,拟合圆 private void FitCircle() { if (OKorNG) { sw_2 = new Stopwatch();//检测时间 sw_2.Start(); - int Image_i = -1; - // 调整vpp中CogCaliperTool工具数据需要同时调整step为x点数*2 - int step = 58; - CogPMAlignTool mPM = mTB_2.Tools["CogPMAlignTool2"] as CogPMAlignTool; + LogHelper.LogInfo("转换机械坐标系下圆弧各点的原始坐标:\n"); + var points = translateCirclePoint.DoTranslatePoint(); + translateCirclePoint.DoTranslateNashPoint(); - - CogImage8Grey outputImg = mTB_1.Outputs["OutputImage"].Value as CogImage8Grey; - //添加找圆工具的 忽略点数 和 RMS偏差量 - CogFitCircleTool fitCircle_1 = new CogFitCircleTool(); - CogFitCircleTool fitCircle_2 = new CogFitCircleTool(); - - - CogGraphicCollection graphics = new CogGraphicCollection(); - - fitCircle_1.InputImage = outputImg; - for (int i = 0; i < lstX.Count; i++) + LogHelper.LogInfo("拟合机械坐标系下的圆中心:\n"); + m_graphics = new CogGraphicCollection(); + m_graphics2 = new CogGraphicCollection(); + foreach (PointInfo pointInfo in points) { - fitCircle_1.RunParams.AddPoint(lstX[i], lstY[i]); - - //CogPointMarker marker_1 = new CogPointMarker();//圆 - - //marker_1.X = lstNasX[i]; - //marker_1.Y = lstNasY[i]; - //marker_1.Color = CogColorConstants.White; - //marker_1.Interactive = false; - //graphics.Add(marker_1); - + AddPointMarker(m_graphics, pointInfo.X, pointInfo.Y); } - //fitCircle_1.RunParams.NumToIgnore = 0; - fitCircle_1.Run(); - if (fitCircle_1.Result != null) - { - double _RMS = fitCircle_1.Result.RMSError; - CogCircle circle_1 = new CogCircle(fitCircle_1.Result.GetCircle()); - circle_1.Color = CogColorConstants.Cyan; - circle_1.Interactive = false; + FitCircleMachineToolBlock.Run(m_lastImage, points); - CogFitLineTool fitLine = new CogFitLineTool(); + sw_2.Stop(); + TimeSpan ts = sw_2.Elapsed; - //晶圆圆心位置 - double _centerX = circle_1.CenterX; - double _centerY = circle_1.CenterY; - double _radius = circle_1.Radius; + times += ts.TotalMilliseconds; + TCP_time = ts.TotalMilliseconds.ToString(); - - fitCircle_2.InputImage = outputImg; - - CogDistancePointPointTool pTp = new CogDistancePointPointTool(); - pTp.InputImage = outputImg; - pTp.StartX = _centerX; - pTp.StartY = _centerY; - //double[] _DistanceMin = new double[lstNasX.Count]; - //int _distanceMin_i = 0; - for (int i = 0; i < lstNasX.Count; i += step) - { - - for (int j = i; j < i + step && j < lstNasX.Count; j++) - { - if (j < (i + step - 15))//忽略重合数据的末尾的15个点 - { - pTp.EndX = lstNasX[j]; - pTp.EndY = lstNasY[j]; - pTp.Run(); - double Distance = pTp.Distance; - if (Distance - _radius < 0.1 && Distance - _radius > -0.1) - { - fitCircle_2.RunParams.AddPoint(lstNasX[j], lstNasY[j]); - CogPointMarker marker_1 = new CogPointMarker();//圆 - - marker_1.X = lstNasX[j]; - marker_1.Y = lstNasY[j]; - marker_1.Color = CogColorConstants.Green; - marker_1.Interactive = false; - graphics.Add(marker_1); - } - else//忽略的点数 - { - if (!(Distance - _radius < 1 && Distance - _radius > -1)) - { - if (Image_i == -1) - { - Image_i = (int)(j / step); - } - } - - - CogPointMarker marker_1 = new CogPointMarker();//圆 - - marker_1.X = lstNasX[j]; - marker_1.Y = lstNasY[j]; - marker_1.Color = CogColorConstants.Yellow; - marker_1.Interactive = false; - graphics.Add(marker_1); - } - //_DistanceMin[i] = Distance; - } - else - { - CogPointMarker marker_1 = new CogPointMarker();//圆 - - marker_1.X = lstNasX[j]; - marker_1.Y = lstNasY[j]; - marker_1.Color = CogColorConstants.Red; - marker_1.Interactive = false; - //graphics.Add(marker_1); - } - } - - } - //忽略的拟合点数 - fitCircle_2.RunParams.NumToIgnore = 0; - fitCircle_2.Run(); - - double RMS = fitCircle_2.Result.RMSError; - CogCircle circle_2 = new CogCircle(fitCircle_2.Result.GetCircle()); - circle_2.Color = CogColorConstants.Cyan; - circle_2.Interactive = false; - //晶圆圆心位置 - double centerX = circle_2.CenterX; - double centerY = circle_2.CenterY; - double radius = circle_2.Radius; - - - double PM_X = 0; - double PM_Y = 0; - int _count = 0; - if (Image_i != -1) - { - mTB_2.Inputs["InputImage"].Value = Images[Image_i]; - mTB_2.Run(); - _count = mPM.Results.Count; - - if (_count != 0) - { - - double r = lstNasR[Image_i] / 180 * Math.PI; - PM_X = mPM.Results[0].GetPose().TranslationX * Math.Cos(r) - mPM.Results[0].GetPose().TranslationY * Math.Sin(r) + circleCenterX * (1 - Math.Cos(r)) + circleCenterY * Math.Sin(r); - PM_Y = mPM.Results[0].GetPose().TranslationX * Math.Sin(r) + mPM.Results[0].GetPose().TranslationY * Math.Cos(r) - circleCenterX * Math.Sin(r) + circleCenterY * (1 - Math.Cos(r)); - - } - } - //_distanceMin_i = DistanceMin(_DistanceMin); - - ////纳什口 - //CogLine line_ = new CogLine(); - //line_.SetFromStartXYEndXY(centerX, centerY, lstNasX[_distanceMin_i], lstNasY[_distanceMin_i]); - //line_.Color = CogColorConstants.Green; - //line_.Interactive = false; - //graphics.Add(line_); - //纳什口 - CogLine line_ = new CogLine(); - line_.SetFromStartXYEndXY(centerX, centerY, PM_X, PM_Y); - line_.Color = CogColorConstants.Green; - line_.Interactive = false; - graphics.Add(line_); - //角度值为0 - CogLine line_0 = new CogLine(); - line_0.SetXYRotation(centerX, centerY, 0); - line_0.Color = CogColorConstants.Blue; - line_0.Interactive = false; - graphics.Add(line_0); - CogAngleLineLineTool llTool = new CogAngleLineLineTool(); - llTool.InputImage = outputImg; - llTool.LineA = line_0; - llTool.LineB = line_; - llTool.Run(); - angle = CogMisc.RadToDeg(llTool.Angle); - - CogPointMarker marker_2 = new CogPointMarker();//圆心 - - marker_2.X = centerX; - marker_2.Y = centerY; - marker_2.Color = CogColorConstants.Green; - marker_2.Interactive = false; - graphics.Add(marker_2); - - CogPointMarker marker_3 = new CogPointMarker();//旋转圆心 - - marker_3.X = circleCenterX; - marker_3.Y = circleCenterY; - marker_3.Color = CogColorConstants.Orange; - marker_3.Interactive = false; - graphics.Add(marker_3); - graphics.Add(circle_2); - - - deviationX = centerX - circleCenterX; - deviationY = centerY - circleCenterY; - - sw_2.Stop(); - TimeSpan ts = sw_2.Elapsed; - - times += ts.TotalMilliseconds; - - - ImageDisplay(outputImg, graphics); - TCP_time = ts.TotalMilliseconds.ToString(); - TCP_X = centerX.ToString("F4"); - TCP_Y = centerY.ToString("F4"); - TCP_RMS = RMS.ToString("F4"); - TCP_R = angle.ToString("F4"); - ResultDisplay(times, ts.TotalMilliseconds, centerX, centerY, radius, RMS, deviationX, deviationY, angle); - - OKorNG = true; - } - else - { - //MessageBox.Show("检测结果为空。"); - OKorNG = false; - } + ResultDisplay(times, ts.TotalMilliseconds, TCP_X, TCP_Y, TCP_R, TCP_RMS, deviationX, deviationY, angle); } - - - } - //private int DistanceMin(double[] numbers) - //{ - // double number = numbers[0]; - // int num1 = 0; - // double num2 = ((IEnumerable)numbers).Sum() / (double)((IEnumerable)numbers).Count(); - // for (int index = 1; index < numbers.Length; ++index) - // { - // if (numbers[index] < number) - // { - // number = numbers[index]; - // num1 = index; - // } - // } - // //return Math.Abs(number - num2) > 0.0 ? num1 : -1; - // return num1; - //} - - private void ResultDisplay(double Times,double Time, double X, double Y, double R, double RMS, double dX, double dY, double dR) + private void ResultDisplay(double Times,double Time, string X, string Y, string R, string RMS, double dX, double dY, double dR) { if (this.InvokeRequired) { @@ -1013,7 +824,6 @@ namespace WaferAlignment return; } this.cogRecordDisplay1.StaticGraphics.AddList(graphics, ""); - this.cogRecordDisplay1.Fit(true); } private void ImageDisplay(CogImage8Grey img) { @@ -1023,9 +833,17 @@ namespace WaferAlignment return; } this.cogRecordDisplay1.Image = img; - this.cogRecordDisplay1.Fit(true); + cogRecordDisplay1.StaticGraphics.Clear(); + } + private void ImageDisplayFit() + { + if (InvokeRequired) + { + BeginInvoke(new Action(() => ImageDisplayFit())); + return; + } + cogRecordDisplay1.Fit(true); } - private void DataDisplay(double Rotation, double X, double Y, double Radius) { if (this.InvokeRequired) @@ -1041,18 +859,6 @@ namespace WaferAlignment } string SavePath; - private void SaveImage(ICogImage img) - { - if (!Directory.Exists(SavePath)) - { - Directory.CreateDirectory(SavePath); - } - using (CogImageFile imgFile = new CogImageFile()) - { - imgFile.Open(Path.Combine(SavePath, DateTime.Now.ToString("yyyyMMdd_HHmmss_fff") + ".bmp"), CogImageFileModeConstants.Write); - imgFile.Append(img); - } - } private void Save() { if (!Directory.Exists(SavePath)) @@ -1068,5 +874,27 @@ namespace WaferAlignment } } } + private double m_cameraCount = 82; + private double m_codeCount = 4096; + private void textBox2_TextChanged(object sender, EventArgs e) + { + m_cameraCount = Convert.ToDouble(textBox2.Text); + } + + private void textBox3_TextChanged(object sender, EventArgs e) + { + m_codeCount = Convert.ToDouble(textBox3.Text); + } + private double m_roateX = 1; + private double m_roateY = -1; + private void nud_SizeX_ValueChanged(object sender, EventArgs e) + { + m_roateX = Convert.ToDouble(nud_SizeX.Value); + } + + private void nud_SizeY_ValueChanged(object sender, EventArgs e) + { + m_roateY = Convert.ToDouble(nud_SizeY.Value); + } } } diff --git a/WaferAlignment/Form1.resx b/WaferAlignment/Form1.resx index b3e563c..5714ba7 100644 --- a/WaferAlignment/Form1.resx +++ b/WaferAlignment/Form1.resx @@ -140,4 +140,16 @@ True + + True + + + True + + + True + + + True + \ No newline at end of file diff --git a/WaferAlignment/GetCircleToolBlock.cs b/WaferAlignment/GetCircleToolBlock.cs new file mode 100644 index 0000000..2e92685 --- /dev/null +++ b/WaferAlignment/GetCircleToolBlock.cs @@ -0,0 +1,117 @@ +using Cognex.VisionPro; +using Cognex.VisionPro.Caliper; +using Cognex.VisionPro.ToolBlock; +using QWhale.Common; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WaferAdjust +{ + public delegate void OnGetCircleResult(double x, double y, double r); + public delegate void OnToolReady(bool ready); + public delegate void OnGetNashResult(double x, double y); + internal class GetCircleToolBlock + { + private CogToolBlock cogToolBlock; + private bool initialized = false; + public event OnToolReady OnToolReady; + public event OnGetCircleResult OnGetCircleResult; + public event OnGetNashResult OnGetNashResult; + public List PointInfos; + public void Initialize(string vpp) + { + try + { + if (cogToolBlock != null) + { + cogToolBlock.Ran -= CogToolBlock_Ran; + cogToolBlock.Dispose(); + cogToolBlock = null; + } + initialized = false; + PointInfos = new List(); + cogToolBlock = CogSerializer.LoadObjectFromFile(vpp) as CogToolBlock; + cogToolBlock.Ran += CogToolBlock_Ran; + initialized = true; + OnToolReady?.Invoke(initialized); + LogHelper.LogInfo($"{vpp} initialized successfully: " + vpp); + } + catch (Exception ex) + { + LogHelper.LogError(ex.Message); + } + } + private void CogToolBlock_Ran(object sender, EventArgs e) + { + try + { + CogFindCircleTool cogFindCircleTool = cogToolBlock.Tools["CogFindCircleTool1"] as CogFindCircleTool; + PointInfos.Clear(); + + if (cogFindCircleTool.Results != null) + { + foreach (CogFindCircleResult item in cogFindCircleTool.Results) + { + if (item.Found && item.Used) + PointInfos.Add(new PointInfo(item.X, item.Y, item.DistanceToCircle)); + } + } + + OnGetCircleResult?.Invoke(Math.Round((double)cogToolBlock.Outputs["CenterX"].Value, 3), + Math.Round((double)cogToolBlock.Outputs["CenterY"].Value, 3), + Math.Round((double)cogToolBlock.Outputs["Radius"].Value, 3)); + + if ((int)cogToolBlock.Outputs["Results_Count"].Value == 1) + { + OnGetNashResult?.Invoke(Math.Round((double)cogToolBlock.Outputs["TranslationX"].Value, 3), + Math.Round((double)cogToolBlock.Outputs["TranslationY"].Value, 3)); + } + } + catch (Exception ex) + { + LogHelper.LogError(ex.Message + ex.StackTrace); + } + } + public void Run(Bitmap bmp) + { + try + { + CogImage8Grey image8Grey = new CogImage8Grey(bmp); + Run(image8Grey); + } + catch (Exception ex) + { + LogHelper.LogError("ScanToolBlock Run Error: " + ex.Message); + } + } + public void Run(CogImage8Grey image8Grey) + { + try + { + cogToolBlock.Inputs["OutputImage"].Value = image8Grey; + cogToolBlock.Run(); + } + catch (Exception ex) + { + LogHelper.LogError("ScanToolBlock Run Error: " + ex.Message); + } + } + public bool Ready() + { + return initialized; + } + public void Stop() + { + if (cogToolBlock != null) + { + cogToolBlock.Ran -= CogToolBlock_Ran; + cogToolBlock.Dispose(); + cogToolBlock = null; + } + } + } +} diff --git a/WaferAlignment/LogHelper.cs b/WaferAlignment/LogHelper.cs new file mode 100644 index 0000000..da64197 --- /dev/null +++ b/WaferAlignment/LogHelper.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NLog; + +namespace WaferAdjust +{ + public class LogHelper + { + private static readonly ILogger Logger = LogManager.GetCurrentClassLogger(); + public static void LogInfo(string message) + { + Logger.Info(message); + } + public static void LogError(string message) + { + Logger.Error(message); + } + } +} diff --git a/WaferAlignment/Nlog.config b/WaferAlignment/Nlog.config new file mode 100644 index 0000000..3635098 --- /dev/null +++ b/WaferAlignment/Nlog.config @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/WaferAlignment/PointInfo.cs b/WaferAlignment/PointInfo.cs new file mode 100644 index 0000000..4e3a830 --- /dev/null +++ b/WaferAlignment/PointInfo.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WaferAdjust +{ + internal class PointInfo + { + public double X; + public double Y; + public double Radius; + public PointInfo(double x, double y, double radius) + { + X = x; + Y = y; + Radius = radius; + } + } +} diff --git a/WaferAlignment/Rotation2D.cs b/WaferAlignment/Rotation2D.cs new file mode 100644 index 0000000..d310406 --- /dev/null +++ b/WaferAlignment/Rotation2D.cs @@ -0,0 +1,176 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WaferAdjust +{ + /// + /// 二维坐标旋转计算器(支持自定义坐标系方向) + /// + public class Rotation2D + { + #region 正向旋转:求旋转后的坐标 + + /// + /// 点A绕点B逆时针旋转指定角度(角度制) + /// + /// 点A的X坐标 + /// 点A的Y坐标 + /// 旋转中心B的X坐标 + /// 旋转中心B的Y坐标 + /// 旋转角度(角度制,逆时针) + /// X轴正方向是否向右(默认true) + /// Y轴正方向是否向上(默认true) + /// 旋转后的点A'坐标 (x', y') + public static (double x, double y) RotatePointDegrees( + double ax, double ay, + double bx, double by, + double angleDegrees, + bool isRight = true, + bool isUp = true) + { + return RotatePointRadians(ax, ay, bx, by, + DegreesToRadians(angleDegrees), isRight, isUp); + } + + /// + /// 点A绕点B逆时针旋转指定角度(弧度制) + /// + /// 点A的X坐标 + /// 点A的Y坐标 + /// 旋转中心B的X坐标 + /// 旋转中心B的Y坐标 + /// 旋转角度(弧度制,逆时针) + /// X轴正方向是否向右(默认true) + /// Y轴正方向是否向上(默认true) + /// 旋转后的点A'坐标 (x', y') + public static (double x, double y) RotatePointRadians( + double ax, double ay, + double bx, double by, + double angleRadians, + bool isRight = true, + bool isUp = true) + { + // 1. 转换为标准数学坐标系(向右为正,向上为正) + double mathAx = isRight ? ax : -ax; + double mathAy = isUp ? ay : -ay; + double mathBx = isRight ? bx : -bx; + double mathBy = isUp ? by : -by; + + // 2. 在标准坐标系中执行旋转 + double cosR = Math.Cos(angleRadians); + double sinR = Math.Sin(angleRadians); + + double dx = mathAx - mathBx; + double dy = mathAy - mathBy; + + double rotatedDx = dx * cosR - dy * sinR; + double rotatedDy = dx * sinR + dy * cosR; + + double mathNewX = mathBx + rotatedDx; + double mathNewY = mathBy + rotatedDy; + + // 3. 转换回用户指定的坐标系 + double outputX = isRight ? mathNewX : -mathNewX; + double outputY = isUp ? mathNewY : -mathNewY; + + return (outputX, outputY); + } + + #endregion + + #region 反向旋转:求旋转前的原始坐标 + + /// + /// 已知旋转后的点A',求绕点B逆时针旋转前的原始点A(角度制) + /// + /// 旋转后的点A'的X坐标 + /// 旋转后的点A'的Y坐标 + /// 旋转中心B的X坐标 + /// 旋转中心B的Y坐标 + /// 旋转角度(角度制,逆时针) + /// X轴正方向是否向右(默认true) + /// Y轴正方向是否向上(默认true) + /// 原始的未旋转点A坐标 (x, y) + public static (double x, double y) GetOriginalPointDegrees( + double rotatedX, double rotatedY, + double bx, double by, + double angleDegrees, + bool isRight = true, + bool isUp = true) + { + return GetOriginalPointRadians(rotatedX, rotatedY, bx, by, + DegreesToRadians(angleDegrees), isRight, isUp); + } + + /// + /// 已知旋转后的点A',求绕点B逆时针旋转前的原始点A(弧度制) + /// + /// 旋转后的点A'的X坐标 + /// 旋转后的点A'的Y坐标 + /// 旋转中心B的X坐标 + /// 旋转中心B的Y坐标 + /// 旋转角度(弧度制,逆时针) + /// X轴正方向是否向右(默认true) + /// Y轴正方向是否向上(默认true) + /// 原始的未旋转点A坐标 (x, y) + public static (double x, double y) GetOriginalPointRadians( + double rotatedX, double rotatedY, + double bx, double by, + double angleRadians, + bool isRight = true, + bool isUp = true) + { + // 1. 转换为标准数学坐标系 + double mathRotatedX = isRight ? rotatedX : -rotatedX; + double mathRotatedY = isUp ? rotatedY : -rotatedY; + double mathBx = isRight ? bx : -bx; + double mathBy = isUp ? by : -by; + + // 2. 在标准坐标系中执行反向旋转 + double cosR = Math.Cos(angleRadians); + double sinR = Math.Sin(angleRadians); + + double dx = mathRotatedX - mathBx; + double dy = mathRotatedY - mathBy; + + // 反向旋转(相当于顺时针旋转) + double originalDx = dx * cosR + dy * sinR; + double originalDy = -dx * sinR + dy * cosR; + + double mathOriginalX = mathBx + originalDx; + double mathOriginalY = mathBy + originalDy; + + // 3. 转换回用户指定的坐标系 + double outputX = isRight ? mathOriginalX : -mathOriginalX; + double outputY = isUp ? mathOriginalY : -mathOriginalY; + + return (outputX, outputY); + } + + #endregion + + #region 辅助方法 + + /// + /// 角度转弧度 + /// + private static double DegreesToRadians(double degrees) + { + return degrees * Math.PI / 180.0; + } + + /// + /// 弧度转角度(公共方法,供外部使用) + /// + public static double RadiansToDegrees(double radians) + { + return radians * 180.0 / Math.PI; + } + + #endregion + } + +} diff --git a/WaferAlignment/TranslateCirclePoint.cs b/WaferAlignment/TranslateCirclePoint.cs new file mode 100644 index 0000000..c699d09 --- /dev/null +++ b/WaferAlignment/TranslateCirclePoint.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WaferAdjust +{ + internal class TranslateCirclePoint + { + private double rotateX; + private double rotateY; + List totalPoints; + List totalCenters; + private int circleIndex; + private double perAngle; + PointInfo nashPoint; + PointInfo firstPoint; + public void SetRotateXY(double x, double y, double angle) + { + rotateX = x; rotateY = y; + totalPoints = new List(); + totalCenters = new List(); + circleIndex = 0; + perAngle = angle; + nashPoint = null; + firstPoint = null; + } + public double GetRotateX() + { + return rotateX; + } + public double GetRotateY() + { + return rotateY; + } + public void AddCirclePoint(List pointInfos) + { + if (pointInfos == null || pointInfos.Count == 0) return; + foreach (var item in pointInfos) + { + totalPoints.Add(new PointInfo(item.X, item.Y, circleIndex * perAngle)); + } + firstPoint = pointInfos[0]; + } + public PointInfo GetFirstPoint() + { + return firstPoint; + } + public void AddCircleIndex() + { + circleIndex++; + } + public double GetCurrentDegree() + { + return circleIndex * perAngle; + } + public void AddNashPoint(double x, double y) + { + nashPoint = new PointInfo(x, y, circleIndex * perAngle); + } + public void AddCircleCenter(double x, double y, double r) + { + totalCenters.Add(new PointInfo(x, y, r)); + } + public List DoTranslatePoint() + { + List trans = new List(); + foreach (var item in totalPoints) + { + var res = Rotation2D.GetOriginalPointDegrees(item.X, item.Y, + rotateX, rotateY, item.Radius, true, false); + trans.Add(new PointInfo(res.x, res.y, item.Radius)); + } + return trans; + } + public void DoTranslateNashPoint() + { + if (nashPoint == null) + return; + + var res = Rotation2D.GetOriginalPointDegrees(nashPoint.X, nashPoint.Y, + rotateX, rotateY, nashPoint.Radius, true, false); + + nashPoint = new PointInfo(res.x, res.y, nashPoint.Radius); + } + public PointInfo GetNashPoint() + { + return nashPoint; + } + } +} diff --git a/WaferAlignment/WaferAlignment.csproj b/WaferAlignment/WaferAlignment.csproj index 66e7eaf..72ef79e 100644 --- a/WaferAlignment/WaferAlignment.csproj +++ b/WaferAlignment/WaferAlignment.csproj @@ -79,6 +79,9 @@ ..\..\..\..\..\..\Program Files (x86)\MVS\Development\DotNet\win64\net40\MvCameraControl.Net.dll + + ..\packages\NLog.6.0.6\lib\net46\NLog.dll + @@ -86,6 +89,7 @@ + @@ -104,15 +108,21 @@ + Form Form1.cs + + + + + Form1.cs @@ -126,6 +136,10 @@ Resources.resx True + + PreserveNewest + + SettingsSingleFileGenerator Settings.Designer.cs diff --git a/WaferAlignment/packages.config b/WaferAlignment/packages.config new file mode 100644 index 0000000..e772309 --- /dev/null +++ b/WaferAlignment/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file