c#读取XML文件实现晶圆wafermapping显示demo计算电机坐标控制电机移动

c#读取XML文件实现晶圆wafermapping显示

功能:

1.读取XML文件,显示mapping图

2.在mapping视图图标移动,实时查看bincode,x,y索引与计算的电机坐标

3.通过设置wafer放在平台的位置x,y轴电机编码值,相机在wafer的中心位置,计算出所有芯片的电机坐标。 

4.mapping视图中,通过注册鼠标事件后,左键返回电机坐标,中键返回x,y索引值,右键返回索引值

5.通过2个左右对位点,计算dieszie宽,比实际xml文件的diesize精度更高。

6.电机移动每颗芯片的电机坐标,视图分析结果后,可修改对应坐标bincode的结果--

7.通过索引查询bincode的结果

8.计算wafer每颗芯片的电机坐标--则可按数组的值进行移动检测每颗芯片,

9.通过索引获取电机坐标

10.保存修改结果后的xml文件

11.显示局部预览图

 

6.通过2个上下对位点,计算dieszie高,比实际xml文件的diesize精度更高。

代码使用电机每个脉冲1um进行示范,所以移动精度更高

初始化:通过预设的wafer中心坐标(镜头视觉显示wafer的中心位置)与xml文件路径,完成mapping的初始化

private void button_initia_Click(object sender, EventArgs e)
        {
            //Mapping mapping = new Mapping();
            mapping2.CloseWindow();
            int x_axis_pulse = int.Parse(textBox_motor_value_x.Text); //wafer中心坐标x
            int y_axis_pulse = int.Parse(textBox_motor_value_y.Text); //wafer中心坐标y

            Point2d[] points_die_size = new Point2d[] { new Point2d(x_axis_pulse, y_axis_pulse), new Point2d(27, 106), new Point2d(1238, 102) } ;
            Point2d motor_xy_loc = points_die_size[0]; //wafer中心坐标(x与y轴电机脉冲),确定实际值后,一般不会变化。wafer在卡环中心,卡环每次放置的位置固定不变
            double theta = mapping2.GetTheta(points_die_size[1], points_die_size[2]);//默认,初始校准可忽略
            mapping2.Calibrate(motor_xy_loc, default(OpenCvSharp.Point)/*new Point(55, 82)*/, theta, textBox_xml_path.Text);
            AddToLogInfo("已完成初始化");
            button_set_result.Enabled = true;
            //button_to_txt.Enabled = true;
            button_to_XML.Enabled = true;
            button_get_result.Enabled = true;
            button_get_index_motor_loc.Enabled = true;

        }

 

校准:

 传入参数:

鼠标在mapping视图中移动到对位点,显示xy的索引与初始的电机坐标

参考参数注释 

 /// <summary>
        /// duiwei_mapping指的行列
        /// </summary>
        /// <param name="duiwei_coord ">移动x,y轴,相机显示对位点后,对准到芯片中心位置,记录电机的实际值编码值脉冲值</param>
        /// <param name="duiwei_mapping">mapping视图的显示比如32,225</param>
        /// <param name="theta">默认</param>
        /// <param name="芯片间距">xml的芯片尺寸,宽盒高</param>
        /// <param name="path_xml">xml文件的路径</param>
        public void Calibrate(Point2d duiwei_coord, Point duiwei_mapping, double theta, Size2d 芯片间距, string path_xml)
        {
            mapping.Calibrate(duiwei_coord, duiwei_mapping, theta, 芯片间距, path_xml);
        }

相机镜头下看到的对位点,移动xy轴把红色十字对准芯片中心,记录电机编码脉冲值。 

 

 依次传入参数:(电机实际值,mapping图索引值,默认角度,xml文件的diesize,xml文件路径)

即可完成校准

 

  private void button_cali_Click(object sender, EventArgs e)
        {
            var p1 = new Point2d(27, 92);
            var p2 = new Point2d(1238, 73);
            var theta = mapping2.GetTheta(p1, p2);
          //  mapping2.Calibrate(new Point2d(-361129, -351128), new Point(50, 17), 0, @"D:\APS_Work\Work_Project\芯片切割道检测\program\WinFormsApp1\mapping融合\2KG026075JL-0.xml");
           // mapping.Show();
           // mapping.MouseMiddleClick += (coord) =>
            //{
                //mapping.SetResult(new Point(coord[0], coord[1]), 5);
           // };

            string die_size_w = textBox_die_size_w.Text; //已知实际尺寸-宽
            string die_size_h = textBox_die_size_h.Text; 已知实际尺寸-高
            string duiwei_x = textBox_duiwei_motor_loc_x.Text; //第一个对位点x  //电机x轴实际脉冲,通过读取PLC得到
            string duiwei_y = textBox_duiwei_motor_loc_y.Text; //第一个对位点y //电机y轴实际脉冲,通过读取PLC得到
            int xx_loc = Convert.ToInt32(duiwei_x);
            int yy_loc = Convert.ToInt32(duiwei_y);
            //mapping文件的x,y坐标
            OpenCvSharp.Point point_xy_row_colomn = new OpenCvSharp.Point(int.Parse(textBox_duiwei_index_x.Text), int.Parse(textBox_duiwei_index_y.Text));//获取xy,行列
            OpenCvSharp.Point2d motor_point2D_loc = new OpenCvSharp.Point2d(xx_loc, yy_loc);
            mapping2.Calibrate(motor_point2D_loc, point_xy_row_colomn, 0.1/*jog_mapping.d_wafer_angle*/, new Size2d(double.Parse(die_size_w), double.Parse(die_size_h)), textBox_xml_path.Text);
            AddToLogInfo("已校准");
        }

显示mapping图

  private void button_show_mapping_Click(object sender, EventArgs e)
        {
            // CloseMappingProcess();

           

            //Task.Run(() =>
            // {

            try
                {
                    mapping2.mapping_show();
                }
                catch (Exception ex)
                {
                    AddToLogInfo("请先初始化,再执行校准");
                    MessageBox.Show("请先初始化,再执行校准");
                    MessageBox.Show("请标定" + ex.Message + ex.StackTrace);
                }

          //  });





        }

批量设置结果:

 指定修改对应值:mapping中:NG对应05,OK对应01

 private void button_modify_Click(object sender, EventArgs e)
        {

           // FindAndKillWindow("mapping");
            //  mapping2.GetImgQualityScore("test11.jpg",0);
            Thread.Sleep(500);
            int ind_x = int.Parse(textBox_x.Text);
            int ind_y = int.Parse(textBox_y.Text);
            bool b_value = false;
            if(comboBox_result.Text.Trim()=="")
            {
                AddToLogInfo("请选择结果");
                MessageBox.Show("请选择结果","tips",MessageBoxButtons.OK,MessageBoxIcon.Information);
                return;
            }
            if(comboBox_result.Text == "OK")
            {
                mapping2.SetResult(new Point(ind_x, ind_y), 01);
                
            }
            else
            {
                mapping2.SetResult(new Point(ind_x, ind_y), 05);
            }
            AddToLogInfo("设置结果:" + comboBox_result.Text);
            button_show_mapping.PerformClick();


        }

 获取指定坐标点结果:

private void button_get_result_Click(object sender, EventArgs e)
        {
            //FindAndKillWindow("mapping");
            //  mapping2.GetImgQualityScore("test11.jpg",0);
            Thread.Sleep(500);
            int ind_x = int.Parse(textBox_x.Text);
            int ind_y = int.Parse(textBox_y.Text);
            textBox_get_result.Text = mapping2.GetBinCode(ind_x,ind_y).ToString();
            AddToLogInfo("已获取结果:"+textBox_get_result.Text);
            

        }

计算所有芯片的电机坐标:

private void button_calc_all_loc_Click(object sender, EventArgs e)
        {
           
             point2Ds_calc = GetMotorLocation(0, 0, 0, 0);
        }
private OpenCvSharp.Point2d[,] GetMotorLocation(int xx, int yy, int width2, int height2)
        {
            //  int xx = Convert.ToInt32(loc_x);
            //  int yy = Convert.ToInt32(loc_y);
            //OpenCvSharp.Point point_loc = new OpenCvSharp.Point(xx, yy);
            //Size size2 = new Size(width2, height2);
            OpenCvSharp.Point2d[,] motor_loc = mapping2.AllCoord();//.GetMotoCoord(point_loc, size2);
            return motor_loc;
        }

通过索引获取电机坐标:

得到了电机坐标,则可进行电机移动,对每颗芯片进行图像采集与分析,修改对应的结果

private void button_get_index_motor_loc_Click(object sender, EventArgs e)
        {
            button_calc_all_loc.PerformClick();
            int x = int.Parse(textBox_x.Text);
            int y = int.Parse(textBox_y.Text);
            string motor_loc_x = "";
            string motor_loc_y = "";

            motor_loc_x = point2Ds_calc[x, y].X.ToString();
            motor_loc_y = point2Ds_calc[x, y].Y.ToString();

            textBox_get_motor_loc_x.Text = int.Parse( motor_loc_x).ToString();
            textBox_get_motor_loc_y.Text = int.Parse(motor_loc_y).ToString();
        }

或许会出现使用xml默认的diesize 宽和高计算的电机坐标进行移动,每颗芯片并没有再芯片中心位置。此时需要校准dieszie的宽和高

左右偏移有偏差则计算宽:

private void button_recal_w_Click(object sender, EventArgs e)
        {
            try
            {

            
            OpenCvSharp.Point map1 = new OpenCvSharp.Point(int.Parse(textBox_middle_loc_x.Text), int.Parse(textBox_middle_loc_y.Text));
            var s = ",".Split(',');
            s[0] = textBox_recal_loc_x1.Text;
            s[1] = textBox_recal_loc_y1.Text;
            OpenCvSharp.Point2d coord1 = new OpenCvSharp.Point(double.Parse(s[0]), double.Parse(s[1]));
            OpenCvSharp.Point map2 = new OpenCvSharp.Point(int.Parse(textBox_right_loc_x.Text), int.Parse(textBox_right_loc_y.Text));
            var s2 = ",".Split(',');
            s2[0] = textBox_recal_loc_x2.Text;
            s2[1] = textBox_recal_loc_y2.Text;
            OpenCvSharp.Point2d coord2 = new OpenCvSharp.Point(double.Parse(s2[0]), double.Parse(s2[1]));


            var dieSizeX = mapping2.CalDieSize(map1, coord1, map2, coord2);
            // label_DieSizeX.Text = (dieSizeX / 1000).ToString();//0.259425476439132
            textBox_die_size_w.Text = (dieSizeX / 1000).ToString();//0.259425476439132
            AddToLogInfo("校准后的diesize_宽:" + textBox_die_size_w.Text);
            }
            catch(Exception ex)
            {
                AddToLogInfo(ex.Message+ "在mapping视图第一个对位点点击中键(左边),然后移动鼠标在mapping视图第二个对位点点击右键(右边)");
                MessageBox.Show(ex.Message+ "在mapping视图第一个对位点点击中键(左边),然后移动鼠标在mapping视图第二个对位点点击右键(右边)");
            }
        }

校准方法:

鼠标移动到第一个对位点,点击中键,这里是32,225,(不同xml不是值),会记录到编辑中

 在32,225位置点击左键,回传对位点的电机坐标,这个可以写入PLC寄存器,执行移动到实际位置附近。此时通过相机查看,控制电机左右微调到芯片中心,并记录电机值

 

 鼠标移动到第二个对位点,点击右键,这里是380,225,(不同xml不是值),会记录到编辑中

在38,225位置点击左键,回传对位点的电机坐标,这个可以写入PLC寄存器,执行移动到实际位置附近。此时通过相机查看,控制电机左右微调到芯片中心,并记录电机值到编辑框 

 

完成校准。

上下偏移有偏差则计算高:

private void button_recal_h_Click(object sender, EventArgs e)
        {
            try
            {


                OpenCvSharp.Point map1 = new OpenCvSharp.Point(int.Parse(textBox_middle_loc_x.Text), int.Parse(textBox_middle_loc_y.Text));
                var s = ",".Split(',');
                s[0] = textBox_recal_loc_x1.Text;
                s[1] = textBox_recal_loc_y1.Text;
                OpenCvSharp.Point2d coord1 = new OpenCvSharp.Point(double.Parse(s[0]), double.Parse(s[1]));
                OpenCvSharp.Point map2 = new OpenCvSharp.Point(int.Parse(textBox_right_loc_x.Text), int.Parse(textBox_right_loc_y.Text));
                var s2 = ",".Split(',');
                s2[0] = textBox_recal_loc_x2.Text;
                s2[1] = textBox_recal_loc_y2.Text;
                OpenCvSharp.Point2d coord2 = new OpenCvSharp.Point(double.Parse(s2[0]), double.Parse(s2[1]));


                var dieSizeX = mapping2.CalDieSize(map1, coord1, map2, coord2);
                // label_DieSizeX.Text = (dieSizeX / 1000).ToString();//0.259425476439132
                textBox_die_size_h.Text = (dieSizeX / 1000).ToString();//0.259425476439132
                AddToLogInfo("校准后的diesize_高:" + textBox_die_size_h.Text);
            }
            catch (Exception ex)
            {
                AddToLogInfo(ex.Message + "在mapping视图第一个对位点点击中键(上边),然后移动鼠标在mapping视图第二个对位点点击右键(下边)");
                MessageBox.Show(ex.Message+ "在mapping视图第一个对位点点击中键(上边),然后移动鼠标在mapping视图第二个对位点点击右键(下边)");
            }

        }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/237205.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

类与接口常见面试题

抽象类和接口的对比 抽象类是用来捕捉子类的通用特性的。接口是抽象方法的集合。 从设计层面来说&#xff0c;抽象类是对类的抽象&#xff0c;是一种模板设计&#xff0c;接口是行为的抽象&#xff0c;是一种行为的规范。 相同点 接口和抽象类都不能实例化都位于继承的顶端…

每日一题,头歌平台c语言题目

任务描述 题目描述:输入一个字符串&#xff0c;输出反序后的字符串。 相关知识&#xff08;略&#xff09; 编程要求 请仔细阅读右侧代码&#xff0c;结合相关知识&#xff0c;在Begin-End区域内进行代码补充。 输入 一行字符 输出 逆序后的字符串 测试说明 样例输入&…

老师们居然这样把考试成绩发给家长

教育是一个复杂而多元的过程&#xff0c;其中考试成绩的发布和沟通是教育过程中的一个重要环节。然而&#xff0c;有些老师在发布考试成绩时&#xff0c;采取了一些不恰当的方式&#xff0c;给家长和学生带来了不必要的困扰和压力。本文将探讨老师们不应该采取的发布考试成绩的…

六级高频词组1

目录 词组 参考链接 词组 1. abide by&#xff08;be faithful to &#xff1b;obey&#xff09;忠于&#xff1b;遵守。 2. be absent from… 缺席&#xff0c;不在 3. absence or mind&#xff08;being absent-minded&#xff09; 心不在焉 4. absorb&#xff08;take …

进程的同步和异步、进程互斥

一、进程同步和异步 同步&#xff08;Synchronous&#xff09;&#xff1a; 同步指的是程序按照顺序执行&#xff0c;一个操作完成后才能进行下一个操作。在多进程或多线程的环境中&#xff0c;同步意味着一个进程&#xff08;或线程&#xff09;在执行某个任务时&#xff0c;…

大致人类应该是短时记忆和利用短时记忆控制利用周围环境达到长期记忆的吧

这里写目录标题 图代码代码解析图 代码 import timedef route_llm(route_text):passdef write_to_dask(one_sum, one_text, one_path

每日一题 1631. 最小体力消耗路径(中等,最小最大值)

最小最大值问题&#xff0c;二分答案搜索heights的最大值为106&#xff0c;所以右边界为106&#xff0c;左边界为0&#xff0c;通过dfs来判断是否存在一条路径&#xff0c;其中所有的相邻格子的高度差绝对值小于左右边界的中点 class Solution:def minimumEffortPath(self, he…

AI自动生成代码工具

AI自动生成代码工具是一种利用人工智能技术来辅助或自动化软件开发过程中的编码任务的工具。这些工具使用机器学习和自然语言处理等技术&#xff0c;根据开发者的需求生成相应的源代码。以下是一些常见的AI自动生成代码工具&#xff0c;希望对大家有所帮助。北京木奇移动技术有…

记录 | linux静态库和动态库的理解

hello.cpp&#xff1a; #include <cstdio>void hello() {printf("Hello, world!\n"); }main.cpp&#xff1a; #include <cstdio>void hello();int main() {hello();return 0; }静态库编译配置&#xff1a; cmake_minimum_required(VERSION 3.12) proj…

Xmanager

什么是 XManager Xmanager 是市场上领先的 PC X 服务器&#xff0c;可将X应用程序的强大功能带入 Windows 环境。 提供了强大的会话管理控制台&#xff0c;易于使用的 X 应用程序启动器&#xff0c;X 服务器配置文件管理工具&#xff0c;SSH 模块和高性能 PC X 服务器。 Xman…

果然,做年终报告还是得看大数据分析工具

一年一度的年终报告比拼有要开始了。听一句劝&#xff0c;今年的年终报告还是用大数据分析工具来做吧&#xff01;将年终报告做成BI大数据分析报表&#xff0c;能直截了当总结分析过去一年的数据情况不说&#xff0c;还能在会议上随时切换分析维度&#xff0c;随时从不同的维度…

java--LocalDate、LocalTime、LocalDateTime、ZoneId、Instant

1.为什么要学习JDK8新增的时间 LocalDate&#xff1a;代表本地日期(年、月、日、星期) LocalTime&#xff1a;代表本地时间(时、分、秒、纳秒) LocalDateTime&#xff1a;代表本地日期、时间(年、月、日、星期、时、分、秒、纳秒) 它们获取对象的方案 2.LocalDate的常用API(…

软件测试之缺陷管理

一、软件缺陷的基本概念 1、软件缺陷的基本概念主要分为&#xff1a;缺陷、故障、失效这三种。 &#xff08;1&#xff09;缺陷&#xff08;defect&#xff09;&#xff1a;存在于软件之中的偏差&#xff0c;可被激活&#xff0c;以静态的形式存在于软件内部&#xff0c;相当…

Vue快速入门教程

什么是Vue&#xff1f; 1&#xff0c;vue是一套前端框架&#xff0c;免除原生JavaScrip中dom操作&#xff0c;简化书写。 2&#xff0c;给予MVVM&#xff08;Model-View-ViewModel&#xff09;思想&#xff0c;实现数据的双向绑定&#xff0c;将编程的关注点放在数据上 官网&a…

漏洞复现--速达进存销管理系统任意文件上传

免责声明&#xff1a; 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直…

python:六种算法(DBO、RFO、WOA、GWO、PSO、GA)求解23个测试函数(python代码)

一、六种算法简介 1、蜣螂优化算法DBO 2、红狐优化算法RFO 3、鲸鱼优化算法WOA 4、灰狼优化算法GWO 5、粒子群优化算法PSO 6、遗传算法GA 二、6种算法求解23个函数 &#xff08;1&#xff09;23个函数简介 参考文献&#xff1a; [1] Yao X, Liu Y, Lin G M. Evolution…

关于粒子群算法的一些简单尝试

粒子群算法核心思想&#xff1a;&#xff08;鸟 粒子&#xff09; &#xff08;1&#xff09;许多的鸟站在不同的地方&#xff1b; &#xff08;2&#xff09;每一只鸟都有自己寻找食物的初始飞行方向、飞行速度&#xff1b; &#xff08;3&#xff09;这些鸟儿每隔一段时间…

0013Java安卓程序设计-ssm酒品移动电商平台app

文章目录 **摘要**目录系统实现5.1 APP端5.2管理员功能模块开发环境 编程技术交流、源码分享、模板分享、网课分享 企鹅&#x1f427;裙&#xff1a;776871563 摘要 首先,论文一开始便是清楚的论述了系统的研究内容。其次,剖析系统需求分析,弄明白“做什么”,分析包括业务分析…

PHP基础 - 循环与条件语句

循环语句 1)for循环: 重复执行一个代码块指定的次数。 for ($i = 0; $i < 5; $i++) { // 初始化 $i 为 0,每次循环后将 $i 值增加 1,当 $i 小于 5 时执行循环echo "The number is: $i \n"; // 输出当前 $i 的值并换行 }// 循环输出结果为: // The number …

美颜技术讲解:视频美颜SDK的开发与集成

如今&#xff0c;美颜技术的应用愈发成为吸引用户的一项重要功能。本文将深入探讨视频美颜SDK的开发与集成&#xff0c;揭示其背后的技术原理和实现步骤。 一、美颜技术的背后 美颜技术并非仅仅是简单的滤镜效果&#xff0c;而是一项涉及复杂图像处理和算法的技术。在视频美颜…