VPLC711硬件介紹
VPLC711是正運(yùn)動(dòng)推出的一款基于x86平臺(tái)和Windows操作系統(tǒng)的高性能機(jī)器視覺EtherCAT運(yùn)動(dòng)控制器,具備強(qiáng)大的運(yùn)算能力和靈活性。它具有出色的實(shí)時(shí)性能和多路高速硬件輸入與多路高速PSO輸出,能夠精準(zhǔn)控制多軸同步運(yùn)動(dòng),并與外部設(shè)備實(shí)現(xiàn)多協(xié)議的高速通信。

VPLC711支持多種硬件接口和通信協(xié)議,方便與其他設(shè)備的連接和集成。除此之外,VPLC711還具備視覺處理功能,能夠?qū)崟r(shí)處理圖像數(shù)據(jù),實(shí)現(xiàn)視覺檢測(cè)、測(cè)量和定位等應(yīng)用。

VPLC711內(nèi)置Windows運(yùn)動(dòng)控制實(shí)時(shí)內(nèi)核MotionRT7,形成一種開放式IPC形態(tài)實(shí)時(shí)軟控制器/軟PLC,為用戶提供靈活集成的運(yùn)動(dòng)控制+視覺一體化解決方案。

VPLC711硬件參數(shù)
1.采用x86高性能CPU,EtherCAT可支持1ms 64軸同步運(yùn)行;
2.板載RS232,RS485,EtherNet*5,EtherCAT,USB3.0*4硬件接口;
3.板載20DI,其中4個(gè)高速色標(biāo)鎖存,2組高速單端編碼器;
4.板載20DO,其中4個(gè)高速單端脈沖軸,4組高速PWM;
5.支持DVI-D,HDMI顯示,支持雙網(wǎng)口不同IP設(shè)置。
想要了解更多關(guān)于VPLC711的詳情介紹,可以點(diǎn)擊 “ x86平臺(tái)實(shí)時(shí)Windows機(jī)器視覺EtherCAT運(yùn)動(dòng)控制器VPLC711 ” 查看。
C#語言進(jìn)行Delta并聯(lián)機(jī)械手的開發(fā)之運(yùn)動(dòng)庫和視覺庫的添加
1.在VS2010菜單“文件”→“新建”→“項(xiàng)目”,啟動(dòng)創(chuàng)建項(xiàng)目向?qū)А?/p>

2.選擇開發(fā)語言為“Visual C#”和.NET Framework 4以及Windows窗體應(yīng)用程序。

3.找到廠家提供的光盤資料里面的C#函數(shù)庫,路徑如下(32位庫為例)。
1)進(jìn)入廠商提供的光盤資料找到“04PC函數(shù)”文件夾,并點(diǎn)擊進(jìn)入。

2)選擇“函數(shù)庫2.1”文件夾。

3)選擇“Windows平臺(tái)”文件夾。

4)根據(jù)需要選擇對(duì)應(yīng)的函數(shù)庫,這里選擇32位庫。

5)解壓C#壓縮包,里面有C#對(duì)應(yīng)的函數(shù)庫。

6)函數(shù)庫具體路徑如下。

4. 將廠商提供的C#庫文件以及相關(guān)文件復(fù)制到新建的項(xiàng)目中(注意這里面的PC函數(shù)庫默認(rèn)提供的是運(yùn)動(dòng)庫,如果使用視覺功能還需要獲取視覺庫,視覺庫可以找廠商的相關(guān)銷售或技術(shù)人員獲。
1) 將Zmcaux.cs(運(yùn)動(dòng)庫)和Zvision.cs(視覺庫)文件復(fù)制到新建的項(xiàng)目里面中。

2) 將zauxdll.dll、zmotion.dll和zvision.dll文件放入bin\debug文件夾中。

5. 用vs打開新建的項(xiàng)目文件,在右邊的解決方案資源管理器中點(diǎn)擊顯示所有文件,然后鼠標(biāo)右擊Zmcaux.cs與 Zvision.cs文件,點(diǎn)擊包括在項(xiàng)目中。

6. 雙擊Form1.cs里面的Form1,出現(xiàn)代碼編輯界面,在文件開頭寫入using cszmcaux,using ZVision并聲明控制器句柄g_handle 。

PC函數(shù)介紹
1.PC函數(shù)手冊(cè)可在光盤資料查看,具體路徑如下。

2.鏈接控制器,獲取鏈接句柄。

3. 相機(jī)掃描接口說明 。

4.相機(jī)采集圖像。

5.用圖像創(chuàng)建模板。

6.形狀匹配并輸出輪廓狀態(tài)。

C#例程建設(shè)之視覺相機(jī)標(biāo)定與形狀匹配
1.視覺配置文件的下載
因?yàn)檎\(yùn)動(dòng)的視覺算法是在控制器里面執(zhí)行的,所以上位機(jī)開發(fā)前需要先在控制器里面定義好視覺處理的相關(guān)變量。
正運(yùn)動(dòng)控制器里面的視覺變量統(tǒng)一使用ZVOBJECT來修飾,我們可以新建一個(gè).bas的文件,然后輸入“GLOBAL ZVOBJECT ZVOBJ(1000)”進(jìn)行視覺變量數(shù)組的定義,保存后通過上位機(jī)接口在上位機(jī)系統(tǒng)初始化的時(shí)候把這個(gè).bas文件下載到控制器即可。

//下載相關(guān)腳本到控制器,進(jìn)行視覺變量的定義
string BasPath = "";
BasPath = string.Format(@"{0}", Application.StartupPath) + @"\Icon\視覺變量定義.bas";
//.bas文件下載到控制器
zmcaux.ZAux_BasDown(g_Handle,BasPath,0);
2.相機(jī)標(biāo)定

1)相機(jī)標(biāo)定操作步驟

2)相關(guān)功能代碼
/************************************************************************************
'任務(wù)編號(hào):無
'函數(shù)功能:視覺提取標(biāo)定板上實(shí)心圓的像素坐標(biāo),獲取標(biāo)定板圓心的像素坐標(biāo)的矩陣
'Input:無
'Output:無
'返回值:無
**************************************************************************************/
private void GetPictureMark()
{
float[] temp_thresh = new float[2];
int Err = 0;
//提取圓心圖像坐標(biāo),得到像素坐標(biāo)矩陣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 };
//獲取矩陣行數(shù)和列數(shù),行數(shù)表示識(shí)別到實(shí)心圓的個(gè)數(shù)
Err = Zvision.ZV_MATINFO(form.g_Handle, inppts, inppts_info);
int row, col;
row = (int)inppts_info[0];
col = (int)inppts_info[1];
//視覺識(shí)別到9個(gè)實(shí)心圓和標(biāo)定板的實(shí)心圓數(shù)目一致
if (row == 9)
{
Err = Zvision.ZV_GRAYTORGB(form.g_Handle, grabimg, calibshowimg);
//inppts排好序輸出排好序的像素坐標(biāo)矩陣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++)
{
//像素坐標(biāo)在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);
//在原圖是畫出識(shí)別到的實(shí)心圓,并標(biāo)記,然后在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點(diǎn)失敗!", "提示");
}
}
else
{
MessageBox.Show("提取mark點(diǎn)失敗!", "提示");
}
}
/************************************************************************************
'任務(wù)編號(hào):無
'函數(shù)功能:相機(jī)標(biāo)定
'Input:無
'Output:無
'返回值:無
'備注:計(jì)算像素坐標(biāo)和世界坐標(biāo)的轉(zhuǎn)換關(guān)系
'備注:標(biāo)定板圓心的世界坐標(biāo)可以通過示教的方式獲取
**************************************************************************************/
private void CamCalib()
{
//矩陣行和式
uint row, col;
row = 9;
col = 2;
//從Ui界面上獲取世界坐標(biāo)的矩陣數(shù)據(jù)
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());
}
}
//重新生成世界坐標(biāo)矩陣
Zvision.ZV_MATGENDATA(form.g_Handle, wpts, row, col, wPontsValue);
//圖像坐標(biāo)矩陣數(shù)據(jù)
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());
}
}
//重新生成圖像坐標(biāo)矩陣
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);
//進(jìn)行相機(jī)標(biāo)定
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 };
//獲取標(biāo)定誤差
Zvision.ZV_CALERROR(form.g_Handle, ZmotionCalPara, ppts, wpts, outcaliberror);
//平均誤差小于0.5內(nèi)算是優(yōu),0.5--1為良,1--1.5為一般,1.5以上建議重新標(biāo)定
if (outcaliberror[0] >= 1.5)
{
MessageBox.Show("標(biāo)定平均誤差過大請(qǐng)重新標(biāo)定");
}
else
{
//保存標(biāo)定參數(shù)
Zvision.ZV_CALWRITE(form.g_Handle, ZmotionCalPara, form.CalFileDir);
}
}
3)形狀匹配后根據(jù)標(biāo)定系數(shù)可獲得匹配到目標(biāo)點(diǎn)的實(shí)際世界坐標(biāo)。

3.形狀匹配

1)形狀匹配操作步驟

2)相關(guān)功能代碼
/************************************************************************************
'任務(wù)編號(hào):無
'函數(shù)功能:通過相機(jī)采集圖像
'Input:無
'Output:無
'返回值:無
**************************************************************************************/
public Image CameAcquisition()
{
float Temp = 0;
Image ImageBuff = null;
Zvision.CAM_COUNT(form.g_Handle, ref Cam_Num);
//選擇相機(jī)
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;
//從相機(jī)緩存取里面獲取剛剛采集的圖像
Zvision.CAM_GET(form.g_Handle, grabimg, 0);
//RGB轉(zhuǎn)灰度
Zvision.ZV_RGBTOGRAY(form.g_Handle, grabimg, grabimg);
//鎖存數(shù)據(jù)清空
Zvision.ZV_LATCHCLEAR(form.g_Handle, 0);
//設(shè)置鎖存的大小為圖片顯示控件的大小
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);
//導(dǎo)出獲取到的圖像信息
return ImgShow1.Image;
}
/************************************************************************************
'任務(wù)編號(hào):無
'函數(shù)功能:創(chuàng)建形狀模版
'Input:無
'Output:無
'返回值:無
**************************************************************************************/
private void CreateTemplate()
{
//通過圖像創(chuàng)建模板
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);
//灰度轉(zhuǎn)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);
//清空控制器的鎖存緩沖區(qū)
Zvision.ZV_LATCHCLEAR(form.g_Handle, 1);
//設(shè)置鎖存緩沖區(qū)大小,設(shè)置鎖存通道大小和顯示控件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;
//清空控制器的鎖存緩沖區(qū)
Zvision.ZV_LATCHCLEAR(form.g_Handle, 1);
//設(shè)置鎖存緩沖區(qū)大小
Zvision.ZV_LATCHSETSIZE(form.g_Handle, 1, Convert.ToUInt32(pictureBox4.Width), Convert.ToUInt32(pictureBox4.Height)); //設(shè)置鎖存通道大小和picgbox控件一樣大
//顯示圖像
pictureBox4.Image = Zvision.ZV_LATCH(form.g_Handle, modimg, 1);//截取圖像顯示到Ui上
}
/************************************************************************************
'任務(wù)編號(hào):無
'函數(shù)功能:形狀匹配,在圖像是查找模板
'Input:無
'Output:無
'返回值:無
**************************************************************************************/
public Image ShapeFind()
{
//結(jié)果數(shù)組清空
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);
//匹配到目標(biāo)了
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();
//分?jǐn)?shù)篩選
if (rst_value[0] >= form.VisionScore)
{
//輸出結(jié)果
for (int k = 0; k < 5; k++)
{
form.VisionRst[i, k] = rst_value[k];
}
float[] outworldpos = { 0, 0 };
//像素轉(zhuǎn)世界坐標(biāo)
Zvision.ZV_CALTRANSW(form.g_Handle, ZmotionCalPara, rst_value[1], rst_value[2], outworldpos);
rstWorldX.Text = outworldpos[0].ToString();
rstWorldY.Text = outworldpos[1].ToString();
//輸出世界坐標(biāo)
for (int k = 1; k < 3; k++)
{
form.VisionRst[i, k] = outworldpos[k - 1];
}
//顯示匹配結(jié)果
string RstWorldStr;
RstWorldStr = "OK_坐標(biāo)(" + rstWorldX.Text + "," + rstWorldY.Text + ")";
Zvision.ZV_TEXT(form.g_Handle, show_img, RstWorldStr, rst_value[1], rst_value[2], 50, 0, 255, 0);
//計(jì)算剛性變換矩陣
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);
//繪制輪廓數(shù)列
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
{
//顯示匹配結(jié)果
string RstWorldStr;
RstWorldStr = "NG";
Zvision.ZV_TEXT(form.g_Handle, show_img, RstWorldStr, 20, 120, 100, 0, 255, 0);
}
//清空緩沖區(qū)顯示圖片
Zvision.ZV_LATCHCLEAR(form.g_Handle, 0);
Zvision.ZV_LATCHSETSIZE(form.g_Handle, 0, Convert.ToUInt32(ImgShow1.Width), Convert.ToUInt32(ImgShow1.Height)); //設(shè)置鎖存通道大小和picgbox控件一樣大
ImgShow1.Image = Zvision.ZV_LATCH(form.g_Handle, show_img, 0);//截取圖像顯示到圖像上
return ImgShow1.Image;
}
本次,正運(yùn)動(dòng)技術(shù)C#之Delta并聯(lián)機(jī)械手的視覺相機(jī)標(biāo)定與形狀匹配,就分享到這里。
更多精彩內(nèi)容請(qǐng)關(guān)注“ 正運(yùn)動(dòng)小助手 ”公眾號(hào),需要相關(guān)開發(fā)環(huán)境與例程代碼,請(qǐng)咨詢正運(yùn)動(dòng)技術(shù)銷售工程師:400-089-8936。
本文由正運(yùn)動(dòng)技術(shù)原創(chuàng),歡迎大家轉(zhuǎn)載,共同學(xué)習(xí),一起提高中國(guó)智能制造水平。文章版權(quán)歸正運(yùn)動(dòng)技術(shù)所有,如有轉(zhuǎn)載請(qǐng)注明文章來源。
正運(yùn)動(dòng)技術(shù)專注于運(yùn)動(dòng)控制技術(shù)研究和通用運(yùn)動(dòng)控制軟硬件產(chǎn)品的研發(fā),是國(guó)家級(jí)高新技術(shù)企業(yè)。正運(yùn)動(dòng)技術(shù)匯集了來自華為、中興等公司的優(yōu)秀人才,在堅(jiān)持自主創(chuàng)新的同時(shí),積極聯(lián)合各大高校協(xié)同運(yùn)動(dòng)控制基礎(chǔ)技術(shù)的研究,是國(guó)內(nèi)工控領(lǐng)域發(fā)展最快的企業(yè)之一,也是國(guó)內(nèi)少有、完整掌握運(yùn)動(dòng)控制核心技術(shù)和實(shí)時(shí)工控軟件平臺(tái)技術(shù)的企業(yè)。主要業(yè)務(wù)有:運(yùn)動(dòng)控制卡_運(yùn)動(dòng)控制器_EtherCAT運(yùn)動(dòng)控制卡_EtherCAT控制器_運(yùn)動(dòng)控制系統(tǒng)_視覺控制器__運(yùn)動(dòng)控制PLC_運(yùn)動(dòng)控制_機(jī)器人控制器_視覺定位_XPCIe/XPCI系列運(yùn)動(dòng)控制卡等等。

|