The value of Zmotion is to bring customers more success!
VPLC711硬件介绍
VPLC711是正运动推出的一款基于x86平台和Windows操作系统的高性能机器视觉EtherCAT运动控制器,具备强大的运算能力和灵活性。它具有出色的实时性能和多路高速硬件输入与多路高速PSO输出,能够精准控制多轴同步运动,并与外部设备实现多协议的高速通信。
VPLC711支持多种硬件接口和通信协议,方便与其他设备的连接和集成。除此之外,VPLC711还具备视觉处理功能,能够实时处理图像数据,实现视觉检测、测量和定位等应用。
VPLC711内置Windows运动控制实时内核MotionRT7,形成一种开放式IPC形态实时软控制器/软PLC,为用户提供灵活集成的运动控制+视觉一体化解决方案。
1.采用x86高性能CPU,EtherCAT可支持1ms 64轴同步运行;
5.支持DVI-D,HDMI显示,支持双网口不同IP设置。
C#语言进行Delta并联机械手的开发之运动库和视觉库的添加
1.在VS2010菜单“文件”→“新建”→“项目”,启动创建项目向导。
3.找到厂家提供的光盘资料里面的C#函数库,路径如下(32位库为例)。
PC函数介绍
C#例程建设之视觉相机标定与形状匹配
1.视觉配置文件的下载
//下载相关脚本到控制器,进行视觉变量的定义 string BasPath = ""; BasPath = string.Format(@"{0}", Application.StartupPath) + @"\Icon\视觉变量定义.bas"; //.bas文件下载到控制器 zmcaux.ZAux_BasDown(g_Handle,BasPath,0);
/************************************************************************************ '任务编号:无 '函数功能:视觉提取标定板上实心圆的像素坐标,获取标定板圆心的像素坐标的矩阵 'Input:无 'Output:无 '返回值:无 **************************************************************************************/ private void GetPictureMark() { float[] temp_thresh = new float[2]; int Err = 0; //提取圆心图像坐标,得到像素坐标矩阵Inppts Err = Zvision.ZV_CALGETSCAPTS(form.g_Handle, grabimg, inppts, Convert.ToUInt32(C_CalibThresh.Text), Convert.ToUInt32(C_CalibPolar.Text), Convert.ToUInt32(C_CalibMinArea.Text), Convert.ToUInt32(C_CalibMaxArea.Text)); int[] inppts_info = { 0, 0, 0 }; //获取矩阵行数和列数,行数表示识别到实心圆的个数 Err = Zvision.ZV_MATINFO(form.g_Handle, inppts, inppts_info); int row, col; row = (int)inppts_info[0]; col = (int)inppts_info[1]; //视觉识别到9个实心圆和标定板的实心圆数目一致 if (row == 9) { Err = Zvision.ZV_GRAYTORGB(form.g_Handle, grabimg, calibshowimg); //inppts排好序输出排好序的像素坐标矩阵ppts Err = Zvision.ZV_CALGETPTSMAP(form.g_Handle, inppts, ppts, wpts, Convert.ToSingle(C_CalibDis.Text)); Err = Zvision.ZV_MATINFO(form.g_Handle, ppts, inppts_info); row = (int)inppts_info[0]; col = (int)inppts_info[1]; if (row >= 9) { uint i; DataGridView1.Rows.Clear(); for (i = 0; i < row; i++) { //像素坐标在WinFrom的UI界面是显示出来 string[] tempstr = new string[4]; float[] outvalue = { 0, 0 }; Zvision.ZV_MATGETROW(form.g_Handle, wpts, i, 2, outvalue); tempstr[2] = "0"; tempstr[3] = "0"; Zvision.ZV_MATGETROW(form.g_Handle, ppts, i, 2, outvalue); tempstr[0] = outvalue[0].ToString(); tempstr[1] = outvalue[1].ToString(); DataGridView1.Rows.Add(tempstr); //在原图是画出识别到的实心圆,并标记,然后在Ui界面上显示出图像 Zvision.ZV_MARKER(form.g_Handle, calibshowimg, outvalue[0], outvalue[1], 0, 40, 0, 255, 0); Zvision.ZV_TEXT(form.g_Handle, calibshowimg, i.ToString(), outvalue[0] - 20, outvalue[1] - 20, 40, 0, 255, 0); Zvision.ZV_LATCHCLEAR(form.g_Handle, 0); Zvision.ZV_LATCHSETSIZE(form.g_Handle, 0, Convert.ToUInt32(pictureBox5.Width), Convert.ToUInt32(pictureBox5.Height)); pictureBox5.Image = Zvision.ZV_LATCH(form.g_Handle, calibshowimg, 0); } } else { MessageBox.Show("提取mark点失败!", "提示"); } } else { MessageBox.Show("提取mark点失败!", "提示"); } } /************************************************************************************ '任务编号:无 '函数功能:相机标定 'Input:无 'Output:无 '返回值:无 '备注:计算像素坐标和世界坐标的转换关系 '备注:标定板圆心的世界坐标可以通过示教的方式获取 **************************************************************************************/ private void CamCalib() { //矩阵行和式 uint row, col; row = 9; col = 2; //从Ui界面上获取世界坐标的矩阵数据 float[] wPontsValue = new float[row * col]; for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { wPontsValue[col * i + j] = float.Parse(DataGridView1.Rows[i].Cells[j + 2].Value.ToString()); } } //重新生成世界坐标矩阵 Zvision.ZV_MATGENDATA(form.g_Handle, wpts, row, col, wPontsValue); //图像坐标矩阵数据 float[] pPontsValue = new float[row * col]; for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { pPontsValue[col * i + j] = float.Parse(DataGridView1.Rows[i].Cells[j].Value.ToString()); } } //重新生成图像坐标矩阵 Zvision.ZV_MATGENDATA(form.g_Handle, ppts, row, col, pPontsValue); float[] outimginfo = { 0, 0, 0, 0, 0 }; //获取图像信息 Zvision.ZV_IMGINFO(form.g_Handle, grabimg, outimginfo); //进行相机标定 Zvision.ZV_CALCAM(form.g_Handle, ppts, wpts, ZmotionCalPara, (ushort)outimginfo[0], (ushort)outimginfo[1], (uint)Convert.ToInt32(C_CalibType.Text)); float[] outcaliberror = { 0, 0, 0 }; //获取标定误差 Zvision.ZV_CALERROR(form.g_Handle, ZmotionCalPara, ppts, wpts, outcaliberror); //平均误差小于0.5内算是优,0.5--1为良,1--1.5为一般,1.5以上建议重新标定 if (outcaliberror[0] >= 1.5) { MessageBox.Show("标定平均误差过大请重新标定"); } else { //保存标定参数 Zvision.ZV_CALWRITE(form.g_Handle, ZmotionCalPara, form.CalFileDir); } }
/************************************************************************************ '任务编号:无 '函数功能:通过相机采集图像 'Input:无 'Output:无 '返回值:无 **************************************************************************************/ public Image CameAcquisition() { float Temp = 0; Image ImageBuff = null; Zvision.CAM_COUNT(form.g_Handle, ref Cam_Num); //选择相机 Zvision.CAM_SEL(form.g_Handle, 0); //采集一张图像 Zvision.CAM_TRIGGER(form.g_Handle); //更新皮带位置 zauxBrr = zmcaux.ZAux_Direct_GetMpos(form.g_Handle, form.ConveyorAxisId, ref Temp); form.BeltMpos = Temp; //从相机缓存取里面获取刚刚采集的图像 Zvision.CAM_GET(form.g_Handle, grabimg, 0); //RGB转灰度 Zvision.ZV_RGBTOGRAY(form.g_Handle, grabimg, grabimg); //锁存数据清空 Zvision.ZV_LATCHCLEAR(form.g_Handle, 0); //设置锁存的大小为图片显示控件的大小 Zvision.ZV_LATCHSETSIZE(form.g_Handle, 0, Convert.ToUInt32(ImgShow1.Width), Convert.ToUInt32(ImgShow1.Height)); //获取锁存中的图像 ImgShow1.Image = Zvision.ZV_LATCH(form.g_Handle, grabimg, 0); //导出获取到的图像信息 return ImgShow1.Image; } /************************************************************************************ '任务编号:无 '函数功能:创建形状模版 'Input:无 'Output:无 '返回值:无 **************************************************************************************/ private void CreateTemplate() { //通过图像创建模板 Zvision.ZV_SHAPECREATERE(form.g_Handle, SubImg, mod_re, shape_mod, Convert.ToInt32(modStartAngle.Text), Convert.ToInt32(modEndAngle.Text), Convert.ToInt32(modMinScale.Text), Convert.ToInt32(modMaxScale.Text), Convert.ToUInt32(modThresh.Text), Convert.ToUInt32(modNum_Level.Text), Convert.ToUInt32(modPt_Reduce.Text), Convert.ToInt32(modAngle_Step.Text), Convert.ToInt32(modScale_Step.Text), 20); //获取模板轮廓 Zvision.ZV_SHAPECONTOURS(form.g_Handle, shape_mod, modconlist, 0); //灰度转rgb Zvision.ZV_GRAYTORGB(form.g_Handle, cutimg, modimg); float[] getimginfo = { 0, 0, 0, 0, 0 }; //图像信息 Zvision.ZV_IMGINFO(form.g_Handle, modimg, getimginfo); //刚性变换 Zvision.ZV_GETRIGIDVECTOR(form.g_Handle, mod_matrigid, 0, 0, 0, getimginfo[0] / 2, getimginfo[1] / 2, 0); //仿射变换 Zvision.ZV_CONTAFFINE(form.g_Handle, modconlist, mod_matrigid, tsmodconlist); //绘制轮廓到图像上 Zvision.ZV_CONTLIST(form.g_Handle, modimg, tsmodconlist, 0, 255, 0, 1); //清空控制器的锁存缓冲区 Zvision.ZV_LATCHCLEAR(form.g_Handle, 1); //设置锁存缓冲区大小,设置锁存通道大小和显示控件picgbox控件一样大 Zvision.ZV_LATCHSETSIZE(form.g_Handle, 1, Convert.ToUInt32(pictureBox2.Width), Convert.ToUInt32(pictureBox2.Height)); //显示图像 pictureBox2.Image = Zvision.ZV_LATCH(form.g_Handle, modimg,1); //截取图像显示到ui上 pictureBox3.Image = pictureBox2.Image; //清空控制器的锁存缓冲区 Zvision.ZV_LATCHCLEAR(form.g_Handle, 1); //设置锁存缓冲区大小 Zvision.ZV_LATCHSETSIZE(form.g_Handle, 1, Convert.ToUInt32(pictureBox4.Width), Convert.ToUInt32(pictureBox4.Height)); //设置锁存通道大小和picgbox控件一样大 //显示图像 pictureBox4.Image = Zvision.ZV_LATCH(form.g_Handle, modimg, 1);//截取图像显示到Ui上 } /************************************************************************************ '任务编号:无 '函数功能:形状匹配,在图像是查找模板 'Input:无 'Output:无 '返回值:无 **************************************************************************************/ public Image ShapeFind() { //结果数组清空 for (int m = 0; m < 10; m++) { for (int n = 0; n < 5; n++) { form.VisionRst[m, n] = 0; } } //形状模板匹配 Zvision.ZV_SHAPEFIND(form.g_Handle, shape_mod, grabimg, find_outlist, Convert.ToInt32(findminscore.Text), Convert.ToUInt32(findnum.Text), Convert.ToInt32(findmindis.Text), Convert.ToInt32(findthresh.Text), Convert.ToUInt32(findaccuracy.Text), Convert.ToInt32(findspeed.Text), Convert.ToUInt32(findpolar.Text)); int[] mat_info = { 0, 0, 0 }; //输出信息 Zvision.ZV_MATINFO(form.g_Handle, find_outlist, mat_info); //生成绘制彩图 Zvision.ZV_GRAYTORGB(form.g_Handle, grabimg, show_img); //匹配到目标了 if ((int)mat_info[0] > 0) { for (uint i = 0; i < (int)mat_info[0]; i++) { float[] rst_value = { 0, 0, 0, 0, 0 }; Zvision.ZV_MATGETROW(form.g_Handle, find_outlist, i, 5, rst_value); rstScore.Text = rst_value[0].ToString(); rstPixX.Text = rst_value[1].ToString(); rstPixY.Text = rst_value[2].ToString(); rstAngle.Text = rst_value[3].ToString(); rstScale.Text = rst_value[4].ToString(); //分数筛选 if (rst_value[0] >= form.VisionScore) { //输出结果 for (int k = 0; k < 5; k++) { form.VisionRst[i, k] = rst_value[k]; } float[] outworldpos = { 0, 0 }; //像素转世界坐标 Zvision.ZV_CALTRANSW(form.g_Handle, ZmotionCalPara, rst_value[1], rst_value[2], outworldpos); rstWorldX.Text = outworldpos[0].ToString(); rstWorldY.Text = outworldpos[1].ToString(); //输出世界坐标 for (int k = 1; k < 3; k++) { form.VisionRst[i, k] = outworldpos[k - 1]; } //显示匹配结果 string RstWorldStr; RstWorldStr = "OK_坐标(" + rstWorldX.Text + "," + rstWorldY.Text + ")"; Zvision.ZV_TEXT(form.g_Handle, show_img, RstWorldStr, rst_value[1], rst_value[2], 50, 0, 255, 0); //计算刚性变换矩阵 Zvision.ZV_GETRIGIDVECTOR(form.g_Handle, find_matrigid, 0, 0, 0, rst_value[1], rst_value[2], rst_value[3]); //轮廓序列仿射变换 Zvision.ZV_CONTAFFINE(form.g_Handle, modconlist, find_matrigid, tsmodconlist2); //绘制轮廓数列 Zvision.ZV_CONTLIST(form.g_Handle, show_img, tsmodconlist2, 0, 255, 0, 1); Zvision.ZV_TEXT(form.g_Handle, show_img, i.ToString(), rst_value[1], rst_value[2], 40, 255, 0, 0); } } } else { //显示匹配结果 string RstWorldStr; RstWorldStr = "NG"; Zvision.ZV_TEXT(form.g_Handle, show_img, RstWorldStr, 20, 120, 100, 0, 255, 0); } //清空缓冲区显示图片 Zvision.ZV_LATCHCLEAR(form.g_Handle, 0); Zvision.ZV_LATCHSETSIZE(form.g_Handle, 0, Convert.ToUInt32(ImgShow1.Width), Convert.ToUInt32(ImgShow1.Height)); //设置锁存通道大小和picgbox控件一样大 ImgShow1.Image = Zvision.ZV_LATCH(form.g_Handle, show_img, 0);//截取图像显示到图像上 return ImgShow1.Image; }
更多精彩内容请关注“ 正运动小助手 ”公众号,需要相关开发环境与例程代码,请咨询正运动技术销售工程师:400-089-8936。
正运动技术专注于运动控制技术研究和通用运动控制软硬件产品的研发,是国家级高新技术企业。正运动技术汇集了来自华为、中兴等公司的优秀人才,在坚持自主创新的同时,积极联合各大高校协同运动控制基础技术的研究,是国内工控领域发展最快的企业之一,也是国内少有、完整掌握运动控制核心技术和实时工控软件平台技术的企业。主要业务有:运动控制卡_运动控制器_EtherCAT运动控制卡_EtherCAT控制器_运动控制系统_视觉控制器__运动控制PLC_运动控制_机器人控制器_视觉定位_XPCIe/XPCI系列运动控制卡等等。