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

示范工程代码:

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

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

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

相关文章

IDEA删除最近打开的文件记录

IDEA删除最近打开的文件记录 遇见问题&#xff1a;如何删除IDEA中最近打开的文件记录 解决方法 先关闭IDEA 找到 recentProjects.xml 文件 windows 位置&#xff1a;&#xff08;AppData是隐藏文件夹&#xff09; 1.C:\Users\电脑用户名\AppData\Roaming\JetBrains\IntelliJIde…

jpa 修改信息拦截

实现目标springbootJPA 哪个人&#xff0c;修改了哪个表的哪个字段&#xff0c;从什么值修改成什么值 Component // 必须加 Slf4j Configurable(autowire Autowire.BY_TYPE) public class AuditingEntityListener {// 线程变量&#xff0c;保存修改前的 objectprivate Thre…

SpringBoot运维中的高级配置

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开心好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…

Navicat16 无限试用 亲测有效

Navicat16 无限试用 亲测有效 亲测有效&#xff01;&#xff01;&#xff01; 吐槽下&#xff0c;有的用不了&#xff0c;有的是图片&#xff0c;更甚者还有收费的&#xff0c;6的一批 粘贴下面的代码&#xff0c;保存到桌面&#xff0c;命名为 trial-navicat16.bat echo off…

Web安全-SQL注入常用函数(二)

★★实战前置声明★★ 文章中涉及的程序(方法)可能带有攻击性&#xff0c;仅供安全研究与学习之用&#xff0c;读者将其信息做其他用途&#xff0c;由用户承担全部法律及连带责任&#xff0c;文章作者不承担任何法律及连带责任。 1、MySQL数据库构成 初始化安装MySQL数据库后(…

从零开始搭建企业管理系统(七):RBAC 之用户管理

RBAC 之用户管理 创建表&#xff08;Entity&#xff09;用户表角色表权限表用户角色表关系注解ManyToMany 角色权限表 接口开发UserControllerUserServiceUserServiceImplUserRepository 问题解决update 更新问题懒加载问题JSON 循环依赖问题 根据上一小结对表的设计&#xff0…

基于ssm高校食堂订餐系统论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本高校食堂订餐系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息…

服务器数据恢复-EqualLogic PS存储硬盘坏道导致存储不可用的数据恢复案例

服务器数据恢复环境&#xff1a; 一台DELL EqualLogic PS系列存储&#xff0c;存储中有一组由16块SAS硬盘组成的RAID5。上层是VMFS文件系统&#xff0c;存放虚拟机文件。存储上层分了4个卷。 服务器故障&检测&#xff1a; 存储上有2个硬盘指示灯显示黄色&#xff0c;磁盘出…

51单片机的外部中断的以及相关寄存器的讲解

中断系统 本文主要涉及8051单片机的中断系统的讲解与使用 其中包括中断相关寄存器的介绍与使用以及外部中断初始化的代码分析。 文章目录 中断系统一、 中断的介绍二、 中断结构及相关寄存器2.1 中断源 2.2 中断请求控制器2.2.1 TCON寄存器2.2.2 SCON寄存器2.2.3 中断允许寄存器…

Spark与PySpark(1.概述、框架、模块)

目录 1.Spark 概念 2. Hadoop和Spark的对比 3. Spark特点 3.1 运行速度快 3.2 简单易用 3.3 通用性强 3.4 可以允许运行在很多地方 4. Spark框架模块 4.1 Spark Core 4.2 SparkSQL 4.3 SparkStreaming 4.4 MLlib 4.5 GraphX 5. Spark的运行模式 5.1 本地模式(单机) Local运行模…

智能优化算法应用:基于模拟退火算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于模拟退火算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于模拟退火算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.模拟退火算法4.实验参数设定5.算法结果6.…

2036开关门,1109开关门

一&#xff1a;2036开关门 1.1题目 1.2思路 1.每次都是房间号是服务员的倍数的时候做处理&#xff0c;所以外层&#xff08;i&#xff09;枚举服务员1~n&#xff0c;内层&#xff08;j&#xff09;枚举房间号1~n&#xff0c;当j % i0时&#xff0c;做处理 2.这个处理指的是&…

module ‘tensorflow‘ has no attribute XXX 报错解决

问题描述&#xff1a; 粘了别人的tensorflow项目&#xff0c;运行总是报错module ‘tensorflow’ has no attribute什么什么 问题解决&#xff1a; 导入tensorflow的代码如下 import tensorflow as tf此时&#xff0c;某个某块报错&#xff0c;比如下面这个 那么就直接把tf.…

【【ZYNQ 7020显示 图片 实验 】】

ZYNQ 7020显示 图片 实验 关键配置 BRAM 因为本次 我想显示的 图片是 400*400 所以在 内部 的 ROM 存储单元选择 了160000 ZYNQ7020的内部资源 最多是 大概 200000左右的 大小 大家可以根据 资源选择合适的像素 此处存放 内部的 图片转文字的COE文件 PLL设置 我选用的是按…

言简意赅的 el-table 跨页多选

步骤一 在<el-table>中:row-key"getRowKeys"和selection-change"handleSelectionChange" 在<el-table-column>中type"selection"那列&#xff0c;添加:reserve-selection"true" <el-table:data"tableData"r…

第二证券:京沪楼市松绑,地产板块强势拉升,京能置业等涨停

地产板块15日盘中强势拉升&#xff0c;到发稿&#xff0c;上实开展、京能置业、大龙地产、新黄浦等涨停&#xff0c;京投开展涨逾6%&#xff0c;保利开展、招商蛇口等涨超3%。 消息面上&#xff0c;12月14日&#xff0c;北京发布调整优化一般住所标准和个人住所告贷政策的告诉…

MIT_线性代数笔记:第 17 讲 正交矩阵和施密特正交化

目录 正交向量 Orthonormal vectors标准正交矩阵 Orthonormal matrix标准正交列向量的优势 Orthonormal columns are good施密特正交化 Gram-Schmidt 本讲我们完成对“正交”的介绍。Gram-Schmidt 过程可以将原空间的一组基转变为标准正交基。 正交向量 Orthonormal vectors 满…

PyQt6 一个简单的例子

PyQt6简单例子 需求代码目录代码实现代码运行效果 需求 1、通过PyQt6实现一个小的应用程序&#xff0c;并设置应用程序的图标&#xff0c;应用程序的标题&#xff0c;然后再提示一个气泡框&#xff0c;不过显示一会就会消失不见。 代码目录 在PyQt文件夹下新建一个包&#x…

五、Shell 注释

一、单行注释 以井号&#xff08;#&#xff09;来注释单行&#xff0c;Shell 并不会处理 Shell 脚本中的注释行。然而 Shell 脚本第一行是个例外&#xff0c;# 号后面的感叹号&#xff08;!&#xff09;是用来告诉系统用哪个解释器来运行脚本。示例和运行结果如图所示&#xf…

基于Java SSM框架实现在线课程教育资源考试管理系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架实现在线课程教育资源考试管理系统演示 摘要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线教育资源管理系统&#xff0c;主要的模块包括管理员&#xff1b;个人中心、学生…