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

news2024/12/28 5:31:02

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

        }

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

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

相关文章

C# 任务的异常和延续处理

写在前面 当Task在执行过程中出现异常或被取消等例外的情况时&#xff0c;为了让执行流程能够继续进行&#xff0c;可以使用延续方法实现这种链式处理&#xff1b;还可以针对前置任务不同的执行结果&#xff0c;选择执行不同的延续分支方法。子任务执行过程中的任何异常都会被…

Centos7云服务器上安装cobalt_strike_4.7。附cobalt_strike_4.7安装包

环境这里是阿里的一台Centos7系统。 开始安装之前首先要确保自己安装了java11及以上环境。 安装java11步骤&#xff1a; sudo yum update sudo yum install java-11-openjdk-devel把服务器端&#xff08;CS工具分服务器端和客户端&#xff09;的CS安装到服务器上后给目录下的…

OpenEuler_22.03升级mongdb到7.0.4

使用命令&#xff1a;lscpu&#xff0c;查看cpu架构为aarch64为arm架构的一种执行状态。 所以我们直接下载arm的包安装即可。无需自己编译源码。 下载地址&#xff1a;https://www.mongodb.com/try/download/community 下载解压 wget https://fastdl.mongodb.org/linux/mong…

【LVGL】STM32F429IGT6(在野火官网的LCD例程上)移植LVGL官方的例程(还没写完,有问题 排查中)

这里写目录标题 前言一、本次实验准备1、硬件2、软件 二、移植LVGL代码1、获取LVGL官方源码2、整理一下&#xff0c;下载后的源码文件3、开始移植 三、移植显示驱动1、enable LVGL2、修改报错部分3、修改lv_config4、修改lv_port_disp.c文件到此步遇到的问题 Undefined symbol …

C语言中的一维数组与二维数组

目录 一维数组数组的创建初始化使用在内存中的存储 二维数组创建初始化使用在内存中的存储 数组越界 一维数组 数组的创建 数组是一组相同类型元素的集合。 int arr1[10]; char arr3[10]; float arr4[10]; double arr5[10];下面这个数组能否成功创建&#xff1f; int count…

python简易学生管理 + MySQL

数据库表 Python代码部分 import pymysqlclass StMgmt(object):def tips(self):"""提示用户选择的操作"""print("""学生管理系统 1.01.查看所有信息2.查看学生信息3.修改学生信息4.增加学生信息5.退出学生系统"""…

SPI 通信-stm32入门

本节我们将继续学习下一个通信协议 SPI&#xff0c;SPI 通信和我们刚学完的 I2C 通信差不多。两个协议的设计目的都一样&#xff0c;都是实现主控芯片和各种外挂芯片之间的数据交流&#xff0c;有了数据交流的能力&#xff0c;我们主控芯片就可以挂载并操纵各式各样的外部芯片&…

C语言-枚举

常量符号化 用符号而不是具体的数字来表示程序中的数字 枚举 用枚举而不是定义独立的const int变量 枚举是一种用户定义的数据类型&#xff0c;他用关键词enum以如下语法来声明&#xff1a; enum枚举类型名字{名字0&#xff0c;…&#xff0c;名字n}&#xff1b; 枚举类型名…

Q_GDW1819-2013电压监测装置协议结构解析

目录 一 专业术语二 基本功能2.1 基础功能2.2 数据存储2.3 显示功能&#xff08;设备能够看到的&#xff09;2.4 参数设置与查询2.5 事件检测与告警功能 三 其他内容3.1 通信方式3.2 通信串口 四 帧结构解析4.1 传输方式4.2 数据帧格式4.2.1 报文头&#xff08;2字节&#xff0…

《深入理解计算机系统》学习笔记 - 第四课 - 浮点数

Floating Point 浮点数 文章目录 Floating Point 浮点数分数二进制示例能代表的数浮点数的表示方式浮点数编码规格化值规格化值编码示例 非规格化的值特殊值 示例IEEE 编码的一些特殊属性四舍五入&#xff0c;相加&#xff0c;相乘四舍五入四舍五入的模式二进制数的四舍五入 浮…

如何通过SPI控制Peregrine的数控衰减器

概要 Peregrine的数控衰减器PE4312是6位射频数字步进衰减器(DSA,Digital Step Attenuator)工作频率覆盖1MHz~4GHz,插入损耗2dB左右,衰减步进0.5dB,最大衰减量为31.5dB,高达59dBm的IIP3提供了良好的动态性能,切换时间0.5微秒,供电电源2.3V~5.5V,逻辑控制兼容1.8V,20…

【Python】修改pip 默认安装位置

使用pip安装的时候&#xff0c;一般是默认安装在c盘里的。这样做很容易会让c盘的文件堆满。那么如何让pip安装的包放入d盘呢&#xff1f; 查看pip默认安装的位置 在cmd里输入python -m site&#xff0c;这里可以看到&#xff0c;安装包会默认下载到c盘中 从这里可以看到&am…

openGauss学习笔记-152 openGauss 数据库运维-备份与恢复-物理备份与恢复之PITR恢复

文章目录 openGauss学习笔记-152 openGauss 数据库运维-备份与恢复-物理备份与恢复之PITR恢复152.1 背景信息152.2 前提条件152.3 PITR恢复流程152.4 recovery.conf文件配置**152.4.1 归档恢复配置****152.4.2 恢复目标设置** openGauss学习笔记-152 openGauss 数据库运维-备份…

AICore 带来了 Android 专属的 AI 能力,它要解决什么?采用什么架构思路?

前言 Google 最近发布的 Gemini 模型在全球引起了巨大反响&#xff0c;其在多模态领域的 Video demo 无比震撼。对于 Android 开发者而言&#xff0c;其中最振奋人心的消息莫过于 Gemini Nano 模型将内置到 Android 系统当中&#xff0c;并开放给开发者使用。 事实上&#xf…

三哥的黑科技,印度发布无线加热服装专利,冬季神器要来了

众所周知风和自由在冬天是不存在的&#xff0c;冬天只剩下冰冷的像刀子一样的风刮在你的脸上&#xff0c;哪怕穿的很厚&#xff0c;戴上全盔&#xff0c;也无法阻挡冰冷的风带走你身体温度&#xff0c;如果穿的特别多&#xff0c;骑车时候的舒适感和穿脱衣物的繁琐也是一大头疼…

用23种设计模式打造一个cocos creator的游戏框架----(十三)模板方法模式

1、模式标准 模式名称&#xff1a;模板方法模式 模式分类&#xff1a;行为型 模式意图&#xff1a;定义一个操作中的算法骨架&#xff0c;而将一些步骤延迟到子类中。Template Method 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 结构图&#xff1a…

LIS检验系统,涵盖实验室全部管理流程,适合各种实验机构的业务流程

LIS检验系统源码&#xff0c;云LIS医学检验系统源码 LIS检验系统涵盖实验室的全部管理流程&#xff0c;包括从检验申请、标本采集、实验检测、报告发布的、质控管理、科室事务、试剂管理等完整流程的功能&#xff0c;实现智能化、自动化、规范化管理&#xff0c;遵循医学实验室…

人工智能的技术演进与未来趋势

人工智能的技术演进与未来趋势 一、引言 人工智能&#xff08;AI&#xff09;已经成为当今科技领域的热门话题&#xff0c;其在各个行业的应用越来越广泛。从智能语音助手到自动驾驶汽车&#xff0c;从智能家居系统到医疗诊断&#xff0c;AI技术已经深入到我们的日常生活。在…

排序算法:【插入排序】

一、插入排序&#xff1a;时间复杂度、原地排序 原理&#xff1a;可以想象成打扑克牌时候&#xff0c;发到手里的牌&#xff0c;我们一张一张拿起来插到手里牌的适当位置。 将待排序列表的第一个元素看作是一个有序序列&#xff08;或叫有序区&#xff09;&#xff0c;然后从第…

坚守数字化创新烽火之地 百望云入选新华社“品牌信用建设典型案例”

潮起海之南&#xff0c;风好正扬帆。2023年12月2日-5日&#xff0c;南海之滨&#xff0c;由新华通讯社、海南省人民政府、中国品牌建设促进会主办的主题为“聚焦新质生产力&#xff0c;增强发展新动能”的2023中国企业家博鳌论坛在海南博鳌隆重举行。 群贤毕至&#xff0c;高朋…