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

news2024/11/15 13:39:53

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.显示局部预览图

示范工程代码:

https://download.csdn.net/download/txwtech/88623150?spm=1001.2014.3001.5503icon-default.png?t=N7T8https://download.csdn.net/download/txwtech/88623150?spm=1001.2014.3001.5503

 

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);
         
           // 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视图第二个对位点点击右键(右边)");
            }
        }

12.校准方法宽:

12.1

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

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

12.2 

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

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

 

12.3点击计算芯片宽

完成芯片宽校准。

更新到此处

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

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视图第二个对位点点击右键(下边)");
            }

        }

12.校准方法高:

13.1

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

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

如下示范,实际采集图像略有不同

13.2

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

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

13.3点击计算芯片高

 最后点击校准,可提高电机坐标计算的精度。

示范工程代码:

https://download.csdn.net/download/txwtech/88623150?spm=1001.2014.3001.5503icon-default.png?t=N7T8https://download.csdn.net/download/txwtech/88623150?spm=1001.2014.3001.5503

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

jstree组件的使用详细教程,部分案例( PHP / fastAdmin )

jstree 组件的使用。 简介&#xff1a;JsTree是一个jquery的插件&#xff0c;它提交一个非常友好并且强大的交互性的树&#xff0c;并且是完全免费或开源的&#xff08;MIT 许可&#xff09;。Jstree技持Html 或 json格式的的数据&#xff0c; 或者是ajax方式的动态请求加载数…

基于ssm的汽车服务商城系统设计与实现论文

摘 要 本课题是根据用户的需要以及网络的优势建立的一个基于Vue的汽车服务商城系统&#xff0c;来更好的为用户提供服务。 本基于Vue的汽车服务商城系统应用Java技术&#xff0c;MYSQL数据库存储数据&#xff0c;基于SSMVue框架开发。在网站的整个开发过程中&#xff0c;首先对…

关于响应式布局,你需要了解的知识点

什么是响应式布局&#xff1f; 响应式布局&#xff0c;就是根据不同设备展示不同的布局&#xff0c;以免更方便用户浏览页面。 举个很简单的例子&#xff0c;我们在电脑上浏览网页&#xff0c;屏幕非常大&#xff0c;这时候可能采用的是如下图所示的布局方式。这种布局方式很宽…

[陇剑杯 2021]日志分析

[陇剑杯 2021]日志分析 题目做法及思路解析&#xff08;个人分享&#xff09; 问一&#xff1a;单位某应用程序被攻击&#xff0c;请分析日志&#xff0c;进行作答&#xff1a; 网络存在源码泄漏&#xff0c;源码文件名是_____________。(请提交带有文件后缀的文件名&…

vue项目debugger调试看不到源码

vue项目debugger调试看不到源码 引用地址&#xff1a;vue项目debugger调试看不到源码_hua_ban_yu的博客-CSDN博客_vue项目网页源代码查看不了 在开发vue项目时&#xff0c;不知为啥进行debug但是查看不到页面源代码&#xff0c;尝试过很多方法&#xff0c;最后在看到大神相关…

WSL的安装与使用 (超详细图文版安装教程)

安装与使用 Windows Subsystem for Linux - WSL 安装&#xff08;两种方式均可实现WSL的安装&#xff09;图文版安装文字版安装步骤1&#xff1a;启用 WSL 功能步骤2&#xff1a;选择并安装 Linux 发行版步骤3&#xff1a;配置和使用 WSL步骤4&#xff1a;与 Windows 的互操作性…

探索高级AJAX技术:深入研究异步请求和响应处理

大家有关于JavaScript知识点不知道可以去 &#x1f389;博客主页&#xff1a;阿猫的故乡 &#x1f389;系列专栏&#xff1a;JavaScript专题栏 &#x1f389;ajax专栏&#xff1a;ajax知识点 &#x1f389;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 目录…

Docker-consul容器服务自动发现与注册

什么叫微服务或者注册与发现&#xff1f; 是一种分布式管理系统&#xff0c;定位服务的方法。 在传统的架构中&#xff0c;应用程序之间直连到已知的服务。 已知的服务&#xff1a;设备提供的网络、IP地址、基于tcp/ip端口 基于现微服务部署&#xff0c;服务的动态性&#…

在MDK开发调试过程中,发现程序正常运行,但是打断点无法进入。

在MDK开发调试过程中&#xff0c;发现程序正常运行&#xff0c;但是打断点无法进入。 打断点无法进入&#xff1a; 程序无法进行&#xff1a; 查找问题&#xff1a;这些都已经配置 上面都已经配置&#xff0c;最终发现: 勾选后进入断点成功。

以csv为源 flink 创建paimon 临时表相关 join 操作

目录 概述配置关键配置测试启动 kyuubi执行配置中的命令 bug解决bug01bug02 结束 概述 目标&#xff1a;生产中有需要外部源数据做paimon的数据源&#xff0c;生成临时表&#xff0c;以使用与现有正式表做相关统计及 join 操作。 环境&#xff1a;各组件版本如下 kyuubi 1.8…

Redis 过期删除策略、内存回收策略、单线程理解

不知从何开始Redis的内存淘汰策略也开始被人问及&#xff0c;卷&#xff01;真的是太卷了。难不成要我们去阅读Redis源码吗&#xff0c;其实问题的答案&#xff0c;在Redis中的配置文件中全有&#xff0c;不需要你阅读源码、这个东西就是个老八股&#xff0c;估计问这个东西是想…

微信小程序识别小程序码并传参

一、场景 连续看到几个类似关于小程序生成二维码场景的问题&#xff0c;分销的场景和单商品购买的页面居多 二、思路 #mermaid-svg-8CjFXSzutuF1OvO8 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-8CjFXSzutuF1…

中小企业业财融合策略(2):财务赋能,如何支持业务经营?

上一文《中小企业业财融合(1):把财务从琐碎的凭证处理、核算中解放出来!》&#xff0c;我们提出了财务升级的背景以及必要性&#xff0c;本篇我们就财务赋能&#xff0c;如何支持业务经营&#xff1f;提出一些简要的看法&#xff0c;希望对大家有所帮助。 一、财务赋能&#x…

com.sun.org.apache.xerces.internal.impl.dv.util.Base64

com.sun.org.apache.xerces.internal.impl.dv.util.Base64 Access restriction: The type Base64 is not API (restriction on required library D:\Java\jdk1.8.0_341\jre\lib\rt.jar) Maven Update Project 虽然没错误了&#xff0c;但是有警告&#xff0c;好奇&#xff1f;…

TCL实业,在智能时代风中起舞

从惠州的一个磁带厂起步&#xff0c;成长为智能终端、半导体显示、新能源光伏三大业务齐头并进的制造业大鳄&#xff0c;TCL是中国制造业穿越周期的一面旗帜。而作为国内电视品牌中唯一拥有上游供应链自主权的企业&#xff0c;C端用户往往更熟悉那个总是在电视终端领域拿出好产…

RT-DETR优化:ASF-YOLO提取多尺度特征 | 2023年12月最新成果

🚀🚀🚀本文改进: ASF-YOLO一种新的特征融合网络架构,该网络由两个主要的组件网络组成,可以为小目标分割提供互补的信息:(1)SSFF模块,它结合了来自u;(2)TFE模块,它可以捕获小目标的局部精细细节等 🚀🚀🚀YOLOv8改进专栏:http://t.csdnimg.cn/hGhVK 学姐带你学…

网络协议 - TCP 协议详解

网络协议 - TCP 协议详解 简述TCP头格式TCP的状态机数据传输中的Sequence NumberTCP重传机制超时重传机制快速重传机制SACK 方法Duplicate SACK – 重复收到数据的问题示例一&#xff1a;ACK丢包示例二&#xff0c;网络延误 TCP的RTT算法经典算法Karn / Partridge 算法Jacobson…

记录 | Microsoft Remote Desktop for mac安装

Microsoft Remote Desktop for mac安装 网上一些教程的下载安装老是跳转来跳转去&#xff0c;而且下载了的也不一定适用于 mac&#xff0c; 这里直接提供 Microsoft Remote Desktop for mac 的安装包的下载地址&#xff1a; microsoft-remote-desktop-for-mac

f盘隐藏的文件夹怎么找出来?介绍几种有效方法

在计算机中&#xff0c;我们经常会遇到隐藏的文件或文件夹&#xff0c;在F盘中隐藏的文件夹也不例外。隐藏的文件夹可能是由系统生成的&#xff0c;或者是用户自行设定的隐私文件夹。无论是因为误操作还是出于其他原因&#xff0c;如果你想找出F盘中的隐藏文件夹&#xff0c;本…

用EXCEL计算NTC、BS、电压等AD参数

前言 之前计算NTC的AD值算得很麻烦&#xff0c;因为51内核的单片机不支持除法运算&#xff0c;更别说浮点运算了。 EXCEL自动算出参数就显得很方便了。 有纰漏请指出&#xff0c;转载请说明。 学习交流请发邮件 1280253714qq.com 理论基础 参考这篇文章NTC热敏电阻温度采集…