Edge Position 8
Overview
The mechanism of "Inner unit" enables creating new processing item by combining existing processing items.
This example shows the way to create new processing item with eight regions, using "Edge Position" item as inner unit.
Specification
Setting screen
This is same as standard Edge Position processing item. However the box for selecting region is added.
Figure setting
Edge Color
Reference Position
Measurement
Measurement
Execute measurement for all configured edge regions.
External reference data
The external reference data of this item are designed, that all the external reference data of inner units can be referred or modified via external reference data of this item.
External reference by number is defined as (region number + 1) * 200 + (external reference number of Edge Position item).
However external reference number 0 is a total judgement result of this item.
200 - 399
|
Region 0
|
400 - 599
|
Region 1
|
600 - 799
|
Region 2
|
800 - 999
|
Region 3
|
1000 - 1199
|
Region 4
|
1200 - 1399
|
Region 5
|
1400 - 1599
|
Region 6
|
1600 - 1799
|
Region 7
|
Also, external reference string is defined as RNXXXX (N: Region number, XXXX:external reference string of Edge Position item).
This is part of the external reference of this item.
Number
|
String
|
Data
|
Set/Get
|
Range
|
0
|
JG
judge
|
Total judgement result
|
Get only
|
0: No judgement (unmeasured)
1: Judgement result OK
-1: Judgement result NG
-10: Error (image)
-11: Error (model)
-12: Error (memory)
-20:Error (other error)
|
200
|
R0JG
R0judge
|
Region 0 Judgement result
|
Get only
|
0: No judgement (unmeasured)
1: Judgement result OK
-1: Judgement result NG
-10: Error (image)
-11: Error (model)
-12: Error (memory)
-20:Error (other error)
|
205
|
R0X
R0positionX
|
Region 0 Edge position X
|
Get only
|
0 - 99999.9999
|
206
|
R0Y
R0positionY
|
Region 0 Edge position Y
|
Get only
|
0 - 99999.9999
|
207
|
R0SX
R0referenceX
|
Region 0 Reference position X
|
Get only
|
0 - 99999.9999
|
208
|
R0SY
R0referenceY
|
Region 0 Reference position Y
|
Get only
|
0 - 99999.9999
|
301
|
R0outputCoordinate
|
Region 0 Output coordinates
|
Set/Get
|
0:After scroll
1:Before scroll
|
302
|
R0calibration
|
Region 0 Calibration
|
Set/Get
|
0:OFF, 1:ON
|
320
|
R0colorSpecification
|
Region 0 Edge color specification
|
Set/Get
|
0:OFF, 1:ON
|
321
|
R0colorR
|
Region 0 Edge color R
|
Set/Get
|
0 - 255
|
322
|
R0colorG
|
Region 0 Edge color G
|
Set/Get
|
0 - 255
|
323
|
R0colorB
|
Region 0 Edge color B
|
Set/Get
|
0 - 255
|
(abbreviated)
|
400
|
R1JG
R1judge
|
Region 1 Judgement result
|
Get only
|
0: No judgement (unmeasured)
1: Judgement result OK
-1: Judgement result NG
-10: Error (image)
-11: Error (model)
-12: Error (memory)
-20:Error (other error)
|
405
|
R1X
R1positionX
|
Region 1 Edge position X
|
Get only
|
0 - 99999.9999
|
(abbreviated)
|
Display image
Sub image number
|
Image
|
-1(Positions)
|
All edge regions and positions
|
0
|
All edge regions and positions
|
1
|
Detailed display of Region 0
|
2
|
Detailed display of Region 1
|
3
|
Detailed display of Region 2
|
4
|
Detailed display of Region 3
|
5
|
Detailed display of Region 4
|
6
|
Detailed display of Region 5
|
7
|
Detailed display of Region 6
|
8
|
Detailed display of Region 7
|
Implementation
1.Creating project
Create project according to tutorial
creating project.
The parameters are as below.
Application Template
|
Measure Process item
|
Identification name (Project name)
|
Edge Postion 8
|
After creation of the project, Visual Studio 2008 opens the project file.
2.Assining inner units
When the unit of this item is added to the flow, assing inner units for making them ready to use.
AssignProc.cpp
int CLASSNAME::AssignProc(ProcUnit *ptrProcUnit)
{
for (int i = 0; i < 8; i++) {
if (NORMAL != ptrProcUnit->AssignInnerUnit(i, _T("EdgePosition"))) {
return -1;
}
}
return(NORMAL);
}
3.Referring and Setting Figure data of inner units
It is not possible to manipulate figure data of innter unit directly from setting screen.
Therefore, it is required to convert the figure number of this item to inner unit number.
Figure number
of this item
|
Inner unit
number
|
Figure number
of inner unit
|
0
|
0
|
0 (Edge measurement region)
|
1
|
1
|
0 (Edge measurement region)
|
2
|
2
|
0 (Edge measurement region)
|
3
|
3
|
0 (Edge measurement region)
|
4
|
4
|
0 (Edge measurement region)
|
5
|
5
|
0 (Edge measurement region)
|
6
|
6
|
0 (Edge measurement region)
|
7
|
7
|
0 (Edge measurement region)
|
8
|
0
|
1 (Area for color extraction)
|
FigureData.cpp
int CLASSNAME::SetFigureType(ProcUnit *ptrProcUnit, int figureNo, int type)
{
int unitNo;
if (figureNo >= 0 && figureNo < 8) {
unitNo = figureNo;
figureNo = 0;
} else if (figureNo == 8) {
// get color data
unitNo = 0;
figureNo = 1;
}
if (ptrProcUnit->CheckInnerUnit(unitNo) != TRUE) {
return -1;
}
ProcUnit *targetUnit = ptrProcUnit->GetInnerUnit(unitNo);
return(ProcItem::SetFigureType(targetUnit, figureNo, type));
}
int CLASSNAME::GetFigureType(ProcUnit *ptrProcUnit, int figureNo)
{
int unitNo;
if (figureNo >= 0 && figureNo < 8) {
unitNo = figureNo;
figureNo = 0;
} else if (figureNo == 8) {
// get color data
unitNo = 0;
figureNo = 1;
}
if (ptrProcUnit->CheckInnerUnit(unitNo) != TRUE) {
return -1;
}
ProcUnit *targetUnit = ptrProcUnit->GetInnerUnit(unitNo);
return(ProcItem::GetFigureType(targetUnit, figureNo));
}
int CLASSNAME::SetFigureData(ProcUnit *ptrProcUnit, int figureNo, FIG_HEADER *ptrFigure)
{
int unitNo;
if (figureNo >= 0 && figureNo < 8) {
unitNo = figureNo;
figureNo = 0;
} else if (figureNo == 8) {
// get color data
unitNo = 0;
figureNo = 1;
}
if (ptrProcUnit->CheckInnerUnit(unitNo) != TRUE) {
return -1;
}
ProcUnit *targetUnit = ptrProcUnit->GetInnerUnit(unitNo);
int res = targetUnit->SetFigureData(figureNo, ptrFigure, 1);
return res;
}
int CLASSNAME::AddFigureData(ProcUnit *ptrProcUnit, int figureNo, FIG_TYPE *type, void *data)
{
int unitNo;
if (figureNo >= 0 && figureNo < 8) {
unitNo = figureNo;
figureNo = 0;
} else if (figureNo == 8) {
// get color data
unitNo = 0;
figureNo = 1;
}
if (ptrProcUnit->CheckInnerUnit(unitNo) != TRUE) {
return -1;
}
ProcUnit *targetUnit = ptrProcUnit->GetInnerUnit(unitNo);
return(ProcItem::AddFigureData(targetUnit, figureNo, type, data));
}
FIG_HEADER *CLASSNAME::GetFigureData(ProcUnit *ptrProcUnit, int figureNo)
{
int unitNo;
if (figureNo >= 0 && figureNo < 8) {
unitNo = figureNo;
figureNo = 0;
} else if (figureNo == 8) {
// get color data
unitNo = 0;
figureNo = 1;
}
if (ptrProcUnit->CheckInnerUnit(unitNo) != TRUE) {
return NULL;
}
ProcUnit *targetUnit = ptrProcUnit->GetInnerUnit(unitNo);
return(ProcItem::GetFigureData(targetUnit, figureNo));
}
4.Measurement initialization and measurement procedure of inner units
In order to execute measurement of inner units, it is necessary to call mesurement initalization and measurement procedure of inner units on the timing of measurement initialization and measuremnet procedure of processing item.
It is also necessary to implement to set total judge result of this item.
MeasureInit.cpp
int CLASSNAME::MeasureInit(ProcUnit *ptrProcUnit)
{
for (int i = 0; i < 8; i++) {
if (ptrProcUnit->CheckInnerUnit(i) != TRUE) {
return -1;
}
ProcUnit *ptrInnerUnit = ptrProcUnit->GetInnerUnit(i);
}
return(NORMAL);
}
MeasureProc.cpp
int CLASSNAME::MeasureProc(ProcUnit *ptrProcUnit)
{
int judge = JUDGE_OK;
SETUPDATA *ptrSetupData = ptrProcUnit->GetSetupData();
MEASUREDATA *ptrMeasureData = ptrProcUnit->GetMeasureData();
int meascount = 0;
for (int i = 0; i < 8; i++) {
ProcUnit *targetUnit = ptrProcUnit->GetInnerUnit(i);
FIG_HEADER *figData = targetUnit->GetFigureData(0);
if (figData == NULL) { // model is not registered
targetUnit->SetUnitJudge(JUDGE_NC, FALSE);
} else {
targetUnit->MeasureProc();
meascount++;
}
ptrMeasureData->judgeInnerUnit[i] = targetUnit->GetUnitJudge();
if (ptrMeasureData->judgeInnerUnit[i] != JUDGE_OK &&
ptrMeasureData->judgeInnerUnit[i] != JUDGE_NC) {
judge = ptrMeasureData->judgeInnerUnit[i];
}
}
if (meascount == 0) {
judge = JUDGE_NG;
}
ptrProcUnit->SetUnitJudge(judge, FALSE);
return(NORMAL);
}
5.Display prodecure of inner units
In order to show the image and graphic display on setting and measurement screen, at first convert sub inage number to inner unit number and sub image number of inner unit, and call display function of inner unit.
Display for setting
Sub image number
|
Display
|
0
|
(Only input image)
|
1
|
Sub image 1 (Edge projection) of inner unit 0
|
2
|
Sub image 1 (Edge projection) of inner unit 1
|
3
|
Sub image 1 (Edge projection) of inner unit 2
|
4
|
Sub image 1 (Edge projection) of inner unit 3
|
5
|
Sub image 1 (Edge projection) of inner unit 4
|
6
|
Sub image 1 (Edge projection) of inner unit 5
|
7
|
Sub image 1 (Edge projection) of inner unit 6
|
8
|
Sub image 1 (Edge projection) of inner unit 7
|
SetupDisp.cpp
int CLASSNAME::SetupDisp(ProcUnit *ptrProcUnit, int subNo, ImageWindow *ptrImageWindow)
{
IMAGE *image = ptrProcUnit->GetMeasureImage(0);
ptrImageWindow->ImageDisp(image);
if (subNo > 0 && subNo <= 8) {
ProcUnit *targetUnit = ptrProcUnit->GetInnerUnit(subNo - 1);
targetUnit->SetupDisp(1, ptrImageWindow);
}
return(NORMAL);
}
Display for measurement
Sub image number
|
Display
|
0
|
(Only input image)
|
1
|
Sub image 1 (Edge projection) of inner unit 0
|
2
|
Sub image 1 (Edge projection) of inner unit 1
|
3
|
Sub image 1 (Edge projection) of inner unit 2
|
4
|
Sub image 1 (Edge projection) of inner unit 3
|
5
|
Sub image 1 (Edge projection) of inner unit 4
|
6
|
Sub image 1 (Edge projection) of inner unit 5
|
7
|
Sub image 1 (Edge projection) of inner unit 6
|
8
|
Sub image 1 (Edge projection) of inner unit 7
|
MeasureDisp.cpp
int CLASSNAME::MeasureDispI(ProcUnit *ptrProcUnit, int subNo, ImageWindow *ptrImageWindow)
{
if (subNo > 0 && subNo <= 8) {
ProcUnit *targetUnit = ptrProcUnit->GetInnerUnit(subNo - 1);
targetUnit->MeasureDispI(1, ptrImageWindow);
} else {
IMAGE *image = ptrProcUnit->GetMeasureImage(0);
ptrImageWindow->ImageDisp(image);
}
return(NORMAL);
}
int CLASSNAME::MeasureDispG(ProcUnit *ptrProcUnit, int subNo, ImageWindow *ptrImageWindow)
{
if (subNo == 0) {
// display all regions
for (int i = 0; i < 8; i++) {
ProcUnit *targetUnit = ptrProcUnit->GetInnerUnit(i);
targetUnit->MeasureDispG(0, ptrImageWindow);
}
}
return(NORMAL);
}
int CLASSNAME::MeasureDispT(ProcUnit *ptrProcUnit, int subNo, TextWindow *ptrTextWindow)
{
MEASUREDATA *ptrMeasureData = ptrProcUnit->GetMeasureData();
int nJudge = ptrProcUnit->GetUnitJudge();
ptrTextWindow->DrawJudgeText(nJudge);
if (nJudge != JUDGE_NC) {
ptrProcUnit->SetMeasureProcMask(1);
for (int i = 0; i < 8; i++) {
ProcUnit *targetUnit = ptrProcUnit->GetInnerUnit(i);
ANYTYPE any;
targetUnit->GetUnitData(_T("positionX"), &any);
ptrMeasureData->coPos[i].x = any.dval;
targetUnit->GetUnitData(_T("positionY"), &any);
ptrMeasureData->coPos[i].y = any.dval;
nJudge = targetUnit->GetUnitJudge();
ptrTextWindow->DrawTextW(nJudge, TRUE, _T("Edge %d x:%.2f, y:%.2f"), i, ptrMeasureData->coPos[i].x, ptrMeasureData->coPos[i].y);
}
ptrProcUnit->SetMeasureProcMask(0);
}
return(NORMAL);
}
6.External reference data
Convert original external reference number or string to inner unit number and external reference of inner unit, and call
ProcUnit::GetUnitData or
ProcUnit::SetUnitData for inner units.
UnitData.cpp
static const TCHAR *regionPrefix[] = {
_T("R0"),
_T("R1"),
_T("R2"),
_T("R3"),
_T("R4"),
_T("R5"),
_T("R6"),
_T("R7")
};
int CLASSNAME::SetUnitData(ProcUnit *ptrProcUnit, int dataNo, ANYTYPE *data)
{
int res;
if (dataNo >= 200 && dataNo < 1800) {
int unitNo = dataNo / 200 - 1;
dataNo = dataNo - (200 * unitNo) - 200;
ProcUnit *targetUnit = ptrProcUnit->GetInnerUnit(unitNo);
res = targetUnit->SetUnitData(dataNo, data);
} else if (dataNo >= 5000) {
for (int i = 0; i < 7; i++) {
ProcUnit *targetUnit = ptrProcUnit->GetInnerUnit(i);
res = targetUnit->SetUnitData(dataNo, data);
if (res != NORMAL) {
break;
}
}
}
return(NORMAL);
}
int CLASSNAME::SetUnitData(ProcUnit *ptrProcUnit, TCHAR *dataIdent, ANYTYPE *data)
{
int res;
if (_tcslen(dataIdent) > 2) {
for (int i = 0; i < 8; i++) {
if (_tcsncmp(dataIdent, regionPrefix[i], 2) == 0) {
ProcUnit *targetUnit = ptrProcUnit->GetInnerUnit(i);
res = targetUnit->SetUnitData(dataIdent+2, data);
return res;
}
}
}
for (int i = 0; i < 7; i++) {
ProcUnit *targetUnit = ptrProcUnit->GetInnerUnit(i);
res = targetUnit->SetUnitData(dataIdent, data);
if (res != NORMAL) {
break;
}
}
return(res);
}
int CLASSNAME::GetUnitData(ProcUnit *ptrProcUnit, int dataNo, ANYTYPE *data)
{
int res = NORMAL;
if (dataNo == 0) {
data->SetVal(ptrProcUnit->GetUnitJudge());
} else if (dataNo >= 200 && dataNo < 1800) {
int unitNo = dataNo / 200 - 1;
dataNo = dataNo - (200 * unitNo) - 200;
ProcUnit *targetUnit = ptrProcUnit->GetInnerUnit(unitNo);
res = targetUnit->GetUnitData(dataNo, data);
} else if (dataNo >= 5000) {
ProcUnit *targetUnit = ptrProcUnit->GetInnerUnit(0);
res = targetUnit->GetUnitData(dataNo, data);
}
return(res);
}
int CLASSNAME::GetUnitData(ProcUnit *ptrProcUnit, TCHAR *dataIdent, ANYTYPE *data)
{
int res = NORMAL;
if (_tcscmp(dataIdent, _T("JG")) == 0) {
data->SetVal(ptrProcUnit->GetUnitJudge());
} else if (_tcslen(dataIdent) > 2) {
for (int i = 0; i < 8; i++) {
if (_tcsncmp(dataIdent, regionPrefix[i], 2) == 0) {
ProcUnit *targetUnit = ptrProcUnit->GetInnerUnit(i);
res = targetUnit->GetUnitData(dataIdent+2, data);
return res;
}
}
}
ProcUnit *targetUnit = ptrProcUnit->GetInnerUnit(0);
res = targetUnit->GetUnitData(dataIdent, data);
return(res);
}
7.Creating setting screen
Following the tutorial of
Creating the Setting Window User Interface (UI) , add tab pages and controls on setting form.

Note
To hide or show tab page according to input image mode, set these value to "Tag" property of tab pages.
COLOR
The tab is shown only when input image is color image.
MONO
The tab is shown only when input image is monochrome image.
Else
The tab is shown in any time.
Add the codes to set "DataIdent" property of each control, according to the value of ValueSetControl (vscRegion) for selecting region number.
For displaying image (imgMain), when Measurement tab (index is 3 or 4) is shown, set the value of region number + 1 as sub image number in order to show projection data of each region.
(Refer to the description of Setting Display)
Private Sub vscRegion_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles vscRegion.ValueChanged
setDataIdent()
Dim index As Integer = Me.tcNormal.SelectedIndex
If (index = 3 Or index = 4) Then
Me.imgMain.subNo = vscRegion.Value + 1
Else
Me.imgMain.subNo = 0
End If
End Sub
Private Sub setDataIdent()
figureset.DataIdentNum_Figure = vscRegion.Value
Me.cbColorSpecification.DataIdent = "R" + CStr(vscRegion.Value) + "colorSpecification"
Me.colorSet.DataIdent_R = "R" + CStr(vscRegion.Value) + "colorR"
Me.colorSet.DataIdent_G = "R" + CStr(vscRegion.Value) + "colorG"
Me.colorSet.DataIdent_B = "R" + CStr(vscRegion.Value) + "colorB"
....
For details, check source codes.
Source codes
You can download full set of source codes of this item from this link.
Source codes