Visionscape .NET Programmer's Manual
Visionscape .NET Programmer's Manual
NET Programmer’s
Manual
84-100023-02 Rev B
Copyright ©2014
Microscan Systems, Inc.
Tel: +1.425.226.5700 / 800.762.1149
Fax: +1.425.226.8250
ISO 9001 Certified
Issued by TüV USA
All rights reserved. The information contained herein is proprietary and is provided solely for the purpose of
allowing customers to operate and/or service Microscan manufactured equipment and is not to be released,
reproduced, or used for any other purpose without written permission of Microscan.
Throughout this manual, trademarked names might be used. We state herein that we are using the names to the
benefit of the trademark owner, with no intention of infringement.
Disclaimer
The information and specifications described in this manual are subject to change without notice.
Technical Support
For technical support, e-mail: [email protected].
Warranty
For current warranty information, see: www.microscan.com/warranty.
PREFACE Welcome! xi
Purpose of This Manual xi
Manual Conventions xi
PREFACE Welcome
Manual Conventions
The following typographical conventions are used throughout this manual.
Introduction
CHAPTER 1 Introduction
Visionscape® Architecture
The Visionscape® architecture is open, allowing multi-level access to a
wide variety of users ranging from factory-floor operators who monitor
vision operation, to engineers who set up, install, and/or modify vision
applications, to system integrators and low-level software developers who
develop custom vision applications.
The next level down shows the Visionscape® Display Components layer.
These high level visual components can be dropped onto a Windows
Form to provide high level functionality such as displaying images at
runtime, providing setup capabilities for your vision job, or viewing
uploaded vision results and report queue data.
Introduction
components contained within each.
Introduction
software libraries that provide access to the core vision system
functionality required to develop and deploy vision applications. They
have no user interface associated with them. The following table lists the
available .NET software libraries:
Library
Visionscape.DLL
Visionscape.Steps.DLL
Visionscape.Communications.DLL
Visionscape.Devices.DLL
The .NET Libraries talk directly to the next layer down, which is the
Visionscape Native layer. This layer includes the actual tools, such as
image acquisition, image pre-processing, feature extraction,
measurement computation, expression evaluation, control, and I/O.
These tools can run either directly on AVP hardware (Vision HAWKs) or
on the host PC with Visionscape® GigE cameras. There is no need to
programmatically interact directly with this layer, as the .NET library layer
provides all the functionality you will need.
Visionscape® Devices
Historically we have used the name “Visionscape® Device” to refer to the
piece of hardware that you purchased from us. In the past, this was either
one of our frame grabber boards, or a smart camera. Starting with
Visionscape 4.0, we also support GigE cameras. The Visionscape
framework will create a special GigE “Device” to collect and provide
access to all of the GigE cameras discovered on your network. This GigE
system is a virtual device however, it does not represent a single piece of
hardware, but instead represents a collection hardware (your GigE
cameras). So consider a “Device” to be a Vision System, an object that
can acquire and inspect images, sometimes from more than one camera.
In this section, we want to try and give you a very general overview of the
key concepts involved with creating a typical user interface. This will
hopefully give you the “Big Picture” before you continue on through the
manual.
Jobs:
A Job is another name for your Vision program. Jobs are always saved to
disk with the AVP extension. So we will often refer to Job and AVP
interchangeably. A Job is made up of a series of “Steps”, which provide
vision and logic functionality. Jobs and Steps are covered in depth in
Chapter 2.
Introduction
As mentioned above, the term “Device” is used to represent a piece of
Visionscape hardware, or in the case of GigE, a collection of GigE
cameras. Devices are represented by the VsDevice object, which is
covered in depth in Chapter 3.
2. Get a reference to the Visionscape Device that you want to run on. You
will need to wait for the Device to be discovered.
Note: You should understand that you absolutely can download a new
Job to your smart camera each time your UI starts up, if that’s the
behavior you want.
Steps
A Step is a single “tool” in a Vision Program. A user inserts Steps into the
Job in order to add functionality. A Step may run a vision algorithm like the
Blob Step or Fast Edge Step, it may perform measurements like the Pt to
Line Distance Step, or it may perform logical operations like the IF Step or
the VarAssign Step. Each Step contains a collection of Datums that
configure its specific functionality.
Datums
A Datum is a generic representation of a Step parameter. It encapsulates
all types of data, such as integers, floating point values, arrays, etc. The
“High Threshold” parameter of the Blob Step is an example of a Datum.
FIGURE 2–1. Example of a Job and the Steps and Datums Within It
Datums
Vision System Step
Inspection Step
Snapshot Step
Acquire Step
JobStep:
The JobStep is the top-most Step in the Job hierarchy. It acts as the
container for your Job, and therefore provides no direct functionality at
runtime. You can only have one JobStep loaded at a time. A JobStep can
hold the vision programs for multiple devices or just one.
VisionSystemStep:
The VisionSystemStep represents your hardware, and it holds the vision
program for one device. So only one VisionSystemStep can run on a
Device. A Job that contains multiple VisionSystem Steps is a Job that
contains the vision programs for multiple Visionscape Devices. Each
VisionSystemStep in your Job must be connected to a Device before it
can run, this is done by either downloading it to the device, or calling the
SelectSystem method (more on this in Chapter 3). When you build a Job
in FrontRunner, you are only allowed to build a Job for a single Device, so
these Jobs will only ever contain a single VisionSystem Step. Our I-PAK
product can create Jobs that contain multiple VisionSystemSteps, and
programmatically you can create a Job with multiple VisionSystemSteps.
The example Job tree above shows a VisionSystem Step attached to the
Device “GigEVision1”.
Inspection Step:
The Inspection Step contains all of the Steps that constitute an Inspection.
It is this Step that manages running all of the Steps in your vision
program. When you want to receive images and results from a running
device, it is the Inspection Steps that will produce these reports. Each
Inspection runs in a separate thread, independently from the others. The
VisionSystemStep must contain at least one Inspection Step, but it can
contain many.
Snapshot Step:
The Snapshot Step handles image acquisition in your inspection. You will
generally insert one Snapshot Step for each camera you are using. You
insert all of your vision tools inside of the Snapshot Step, as this Step
produces an output buffer for your vision tools to run in. Although the
Snapshot Step handles image acquisition, the parameters that govern
image acquisition are not configured here, they are configured in the child
Acquire Step.
Acquire Step:
Every Snapshot Step has a child Acquire Step. You can not add or delete
this Step. The parameters that govern Image Acquisition are controlled
via the datums of the Acquire Step. The selected camera, the I/O point to
use as the Trigger, the image exposure time and many other parameters
are all controlled by the datums of this Step. If you need to modify these
parameters in your user interface, you will need to access the Acquire
Steps in your Job.
To provide easy access to the objects within this namespace, add the
following statement to the top of your C# files (all sample code assumes
this using statement is present):
using Visionscape.Steps;
Datums
As we said above, the JobStep acts as the container for your vision
programs, so the JobStep object will be used to load and save Jobs from
disk. Here’s a C# example of how you would load the sample
“example_datamatrix.avp” file (installed with Visionscape) in your Form
Load event:
private JobStep m_Job = new JobStep();
So, let’s assume that the Job we loaded from disk matches the Job tree
shown in Figure 2–2. As you can see, the Job Step is always the top-most
Step in the tree. The Job will always contain one or more VisionSystem
steps in its collection. So, if we wanted to access the first VisionSystem
step in the Job, we could simply do the following:
//Get the first Vision System Step in the Job
VisionSystemStep vs = (VisionSystemStep)m_Job[1];//1-based
collection
Datums
the Step
These include the Step’s Name, Symbolic Name, the type of Step (Blob,
Snapshot, Flaw, etc.), what category it falls under, is it trainable, is it
trained, etc. For more information, see “The Major Properties That
Describe A Step” on page 2-5 and “Step Object Properties” on page 2-35.
The Step Object can Add and Remove Steps From Your
Job
The Step Object provides methods that allow you to create new steps and
delete existing ones. It’s actually possible to create an entire Job from
code if you wish (though this is not generally recommended). Refer to
“Adding and Removing Steps” on page 2-10 for more information.
• Name — Holds the name the user assigned to the step. You can
change this name via code, or the user may change it while in
FrontRunner.
• Trained — Returns True for steps that are Trainable and are currently
trained.
• Type — Returns a string that identifies the type of the Step. This will
always come in the format:
Step.<type>.1
Where “<type>” would be replaced by the actual type of the Step. Some
examples:
Snapshot Step = “Step.Snapshot.1”
Inspection Step = “Step.Inspection.1”
Fast Edge Step = “Step.Edgefast.1”
Datums
foreach (Step child in insp)
{ //is this a Snapshot Step?
if (child.Type == "Step.Snapshot.1")
{
Console.WriteLine("Found a Snapshot named " +
child.Name);
}
}
– Private — This is a Step that was created by its parent Step, and
is private to that Step. The owner of a Private Step is responsible
for running it. You are not permitted to delete the step. Examples
of this category are the AutoThreshold step in Blob, and the
OutputValid step in the Inspection step.
name: The symbolic name of the step you are searching for.
Calling this method causes the Step to search all of it’s children for the
child step with the given symbolic name. If successful, a reference to the
located Step is returned, if not successful, an exception is thrown.
name: The user assigned name of the step you are searching for.
Calling this method causes the Step to search all of it’s children for the 1st
child step with the given user name. If successful, a reference to the
located Step is returned, if not successful, an exception is thrown.
Step mystep = m_Job.FindByName("My Snapshot");
type: This string specifies the type of step to search for, in the form
“Step.type”.
Calling this method causes the Step to search all of it’s child steps for the
1st Step that matches the specified type. If successful, a reference to the
located Step is returned, if not successful, an exception is thrown.
Step snap = m_Job.FindByType("Step.Inspection");
Datums
– nameOrType — A string that specifies either the user name,
symbolic name or step type that you are searching for.
Calling this method causes the Step to search only its child Steps for the
first one that matches the search criteria. You can search for Steps by
user name, symbolic name or by step Type, as specified using the Option
parameter. You can also specify the Step category that you want
searched using the whichCategory parameter. If successful, a reference
to the located Step is returned. An exception is thrown if the Step cannot
be found.
Examples:
Step insp, onept, blob;
//find the first Inspection step under the Job
insp = (Step)m_Job.Find("Step.Inspection",
EnumAvpFindOption.FIND_BY_TYPE,
EnumAvpStepCategory.S_ALL);
//find Step named "OnePt Locator" under the inspection
onept = (Step)insp.Find("OnePt Locator",
EnumAvpFindOption.FIND_BY_USERNAME,
EnumAvpStepCategory.S_ALL);
//find step with Symbolic Name "Blob1" under locator
blob = (Step)onept.Find("Blob1",
EnumAvpFindOption.FIND_BY_SYMNAME,
EnumAvpStepCategory.S_ALL);
Note: You may notice that when searching for the first Inspection step, we
used the string “Step.Inspection” and not “Step.Inspection.1”. Either string
will work, all of the find methods are smart enough to recognize when the
“.1” is present or not.
– type: A string that specifies the type of string to search for. This is
in the form “Step.type”.
Searches the children of the Step for ALL steps that match the specified
type. A reference to a StepList object is returned that contains all
matches. Following is an example of finding all of the snapshot steps in a
Job:
StepList allSnaps = m_Job.GetStepList("Step.Snapshot");
foreach(Step snap in allSnaps)
{
Console.WriteLine("Snapshot Name = " + snap.Name);
}
Datums
immediate children should be searched, and not all levels of child Steps.
This version also returns a reference to an IAvpCollection interface rather
than a StepList. In general you should prefer GetStepList to this method.
Following is an example of using FindByType to find all of the snapshots
under a Job Step.
IAvpCollection snaps = m_Job.FindByType("Step.Snapshot", 1);
foreach (Step snap in snaps)
{
Console.WriteLine("Snapshot Name = " + snap.Name);
}
This method walks up through the Job tree, searching the parents of the
Step for the type specified in the stepType parameter. Typically, you would
use this method when you want to find the parent Snapshot or Inspection
of a given Step.
Examples:
//find the first fast edge step in the Job
Step fedge = m_Job.FindByType("Step.EdgeFast");
//find the parent Snapshot and Inspection steps of the
//FastEdge step
Step parentSnap = (Step)fedge.FindParent("Step.Snapshot");
Step parentInsp = (Step)
fedge.FindParent("Step.Inspection");
Use these properties as a quick and easy way to access the parent
Inspection Step or parent Vision System Step of a given Step object.
Step insp = (Step)mystep.ParentInspection;
Step vs = (Step)mystep.ParentVisionSystem;
– type: The type of step that you wish to add. This is in the form
“Step.Type”
Adds a child step of the specified Step type to the calling Step’s list of
children. The new step will be added at the end of the child list. A
reference to the newly added step is returned. You should understand
that a Step can only add steps to it’s own list of children. So if you want to
add steps under one of the snapshot steps in your Job, then you must first
locate that Snapshot Step, and call AddStep on it. You can not use the
JobStep for instance to add steps to an Inspection Step. The following
example illustrates this as we create the basic framework of a Job.
m_Job = new JobStep();
//add a Vision System step to our Job
VisionSystemStep vs =
(VisionSystemStep)m_Job.AddStep("Step.VisionSystem");
//now add an Inspection under the Vision System Step
Step insp = vs.AddStep("Step.Inspection");
//lastly, add a snapshot under the inspection
Step snap = insp.AddStep("Step.Snapshot");
The resulting Job would look like this (NOTE: The Acquire step is added
automatically by the Snapshot Step):
Datums
– type: The type of step that you wish to add. This is in the form
“Step.Type”
This version of AddStep allows you to specify the user name of the Step,
so the Steps can be created and named in one shot. Using our previous
example, we could assign our own names to each of the Steps like this:
m_Job = new JobStep();
//add a Vision System step to our Job
VisionSystemStep vs =
(VisionSystemStep)m_Job.AddStep("Step.VisionSystem",
"Device1");
//now add an Inspection under the Vision System Step
Step insp = vs.AddStep("Step.Inspection", "Defect
Inspection");
//lastly, add a snapshot under the inspection
Step snap = insp.AddStep("Step.Snapshot", "Camera 1");
– type : The type of step that you wish to add. This is in the form
“Step.Type”
– relativeStep: This is the child Step that the new step will be added
after.
Adds a new Step of the specified type into the calling Step’s child list, but
instead of being added at the end, the new step is added immediately
after the Step specified by the relativeStep parameter.
– type: The type of step that you wish to add. This is in the form
“Step.Type”
– relativeStep: This is the child Step that the new step will be added
before.
Adds a new Step of the specified type into the calling Step’s child list, but
instead of being added at the end, the new step is added immediately
before the Step specified by the relativeStep parameter.
Examples:
If we wanted to add a Flaw tool at the end of the Snapshot’s child list, we
could run the following code:
//find the first snapshot step in the Job
Step snap = m_Job.FindByType("Step.Snapshot");
//add a new Flaw tool into the snapshot
snap.AddStep("Step.FlawTool", "My New FlawTool");
Datums
FIGURE 2–5. Job with Flaw Tool Added
What if you wanted to add a new Blob tool under the Snapshot step, but
you wanted it to be inserted before the One Pt Locator? Then, we could
do the following:
//find the first snapshot step in the Job
Step snap = m_Job.FindByType("Step.Snapshot");
//find the One Pt locator under the snapshot
Step onept = snap.FindByName("OnePt Locator");
//add a new blob step into the snapshot, before the one
//pt locator
Step blob = snap.AddStepBefore("Step.Blob", onept);
blob.Name = "My New Blob Tool";
What if we wanted to add a new Fast Edge Step to the OnePt Locator
step, but we wanted it to come immediately after the Fast Edge_Right
Step? Then, we would do the following:
//find the 'Fast Edge_Right' step
Step fedge_right = onept.FindByName("Fast Edge_Right");
//add a new step into One Pt Locator,but After the Fast
Edge_Right step
Step fedge_new = onept.AddStepAfter("Step.EdgeFast",
fedge_right);
fedge_new.Name = "My New Fast Edge Step";
Datums
FIGURE 2–7. Job with Fast Edge Added
– relative — If you want your new Step to be added into the tree
“relative” to some other Step, say just before or just after that
Step, then you must use this parameter to pass in a reference to
that “relative” Step. The value you specify in the option parameter
determines where it’s inserted relative to this Step. Set to null for
default behavior, which will insert the new Step at the end of the
child list.
This version of AddStep provides the most options, but is also the most
difficult to use. You would use this version when you want very precise
control over how your new step will be added. Most situations can be
handled with the previously documented versions of AddStep, but this
version is still supported if needed. A reference to the newly added Step is
returned if the function is successful. An exception will be thrown if
unsuccessful. All of the examples shown previously can be accomplished
with this version.
This method can be used to insert an already existing Step into the calling
Step’s list of children. Assuming we had a VisionSystem Step variable
named ‘vs’, we could add an Inspection Step to it like this:
InspectionStep insp2 = new InspectionStep();
vs.InsertStep((Step)insp2);
This is equivalent to this:
vs.AddStep("Step.Inspection");
– index — This is the 1 based index of the Step you wish to remove
from the Step’s collection.
Example:
Datums
and then use its index property:
//Find the step named “Pt to Line Distance” (under onept)
Step ptlinedist = onept.FindByName("Pt to Line Distance");
//use the index from the step itself to remove it
onept.Remove(ptlinedist.Index);
– index — This is the 1 based index of the Step you wish to remove
from the Step’s collection.
– delChildStep —
Datums
Datum Datum(string datumSymName)
This method takes the symbolic name of the datum you want to access,
and it returns a reference to that Datum object if it is found. An exception
is thrown if not found. You would typically use this method when you want
to read or write the value of an individual Datum within a Step. You can
use the StepBrowser utility to look up the Symbolic Names of every
Datum for every Step. For more information, see “Using StepBrowser to
Look Up Symbolic Names” on page 2-30.
Example:
Continuing our AddStep example, we could take the newly added Blob
Step and find its AutoTheshold and High Threshold Datums. We can then
modify the values of each in order to turn the Auto Threshold capability
off, and then set our own High Threshold.
//add a new blob step into the snapshot, before the one pt
//locator
Step blob = snap.AddStepBefore("Step.Blob", onept);
blob.Name = "My New Blob Tool";
//find the Autothreshold Datum
Datum AutoThresh = blob.Datum("UseAutoThr");
//find the High Threshold Datum
Datum HiThr = blob.Datum("HiThr");
//now turn off AutoThreshold, and set High Threshold
AutoThresh.Value = false;
HiThr.Value = 150;
Example:
//iterate through all of the datums in our blob step
foreach(Datum d in blob.Datums)
{
This method allows you to specify a Datum category, and it will then only
return a collection of the Datums that are within that category. Typically
you would use this property when you wanted to analyze just a Step’s
Output or Input Datums.
Example:
IAvpCollection outs =
blob.DatumList(EnumAvpDatumCategory.D_OUTPUT);
foreach(Datum outDat in outs)
{
Console.WriteLine("Datum Name = " + outDat.Name);
Console.WriteLine("Datum Type = " + outDat.Type);
}
Datums
//assume ‘blob’ is a reference to a blob step
//find the High Threshold Datum
Datum HiThrDatum = blob.Datum("HiThr");
//Get the high threshold value as an integer
int hiThresh = (int)HiThrDatum.Value;
Setting Datum values is just as easy. You simply assign your new value to
the value property.
roi[3] = 200;
//now set the modified array back into the datum
ROI.Value = roi;
In the above example, we moved the Blob’s ROI 20 pixels to the right and
50 pixels up, and we set the width to 80 and the height to 200 pixels. The
easiest way to modify a Datum that takes an array is to get its current
value, modify it, and set it back into the value property. This insures that
the dimensions of your array will be correct.
Datums
expected when you try to set the value property.
Datums
Datum.CompList Array of handles and names for (x,2) array where x is the number
all items of
in the list. Each item could be a entries in this list
Step or a (x,0) = Either the handle of the
Datum. Array is (x,2), where x is item (Step
number or Datum) or its complete
of entries in the list. symbolic name
(x,0) = Handle to a Step. If the path (Step or Step.Datum) unique
item in the to the
list is a Step, the handle belongs Datum.CompList search root (set
to the by the
Step. If the item is a Datum, the owner of the datum)
handle is (x,1) = True or False to Add or
to the owning Step of the datum. Remove
(x,1) = Symbolic name of the Step the entry from the list.
or
Datum.
Datum.DblDmList Array of double values Set not supported
Datum.DblList Array of double values Array of double values
Datum.Distance Double Double
Datum.DMRResults Array sized (n, 38), where n is the Set not supported
number of Matrices found + 1.
The first row of the array is
always
populated with text labels that
identify the
data in each column, the actual
matrix
data then follows in each
successive
row.
(n,0) = Decoded String
(n,1) = Decoded? (boolean)
(n,2) = Linked (boolean)
(n,3) = found symbol type (int)
(n,4) = num rows
(n,5) = num cols
(n,6) = ecc type
(n,7) = format ID
(n,8) = crc expected
(n,9) = crc actual
(n,10) = matrix angle
(n,11) = error code
(n,12) = total num linked
(n,13) = Linked Position
(n,14) = Pixels per Cell
(n,15) = Symbol Height
(n,16) = Symbol Width
(n,17) = X1
(n,18) = Y1
(n,19) = X2
(n,20) = Y2
(n,21) = X3
(n,22) = Y3
(n,23) = X4
(n,24) = Y4
(n,25) = Locate Time
(n,26) = Extent Time
(n,27) = Size Time
(n,28) = Warp Time
Datums
Datum.DMRResults (n,29) = Sample Time Set not supported
(cont.) (n,30) = Decode Time
(n,31) = Contrast
(n,32) = Error Bits
(n,33) = Damage %
(n,34) = Border Match %
(n,35) = Threshold Value
(n,36) = Symbol Polarity
(n,37) = Img Style
Datum.Double Double Double, Integer
Datum.Enum Array containing the current Integer value containing index of
selection in current selection or the string
the first item (long) and the set of identifying
available selections (string) in the the new selection.
following items. Example: To change the
Example: The Acquire Step's CameraNumber
“CameraNumber” Datum, in selection to Camera 3, you could
which say:
“Camera 2” was selected, would .value = 2 'select 3rd item
return OR
an array that looks like this: .value = “Camera 3”.
(0) = 1 '0 based index of cur sel
(1) = “Camera 1”
(2) = “Camera 2”
(3) = “Camera 3”
(4) = “Camera 4”
Datum.Expression Via the generic Datum interface, String value that contains the new
the expression.
Value property returns a Double
that
contains the last value of the
evaluated
expression.
In order to retrieve the expression
itself.
You must use the ExpressionDm:
Dim expr as ExpressionDm
Dim strExpr as string
'get Inspection Step's 'criteria for
inspection 'pass datum
Set expr =
insp.Datum(“PassCrit”)
strExpr = expr.Expression
Datum.FileSpec String array containing a list of file String value containing a file
names, or if the list is < 1, a single name or
string wildcard, or an array of strings
containing
files to add to the list. The
value(s) you
send are always added to the list,
they
do not replace the current list. To
clear
the list, pass an empty string ("").
Datum.FlexArray Array sized (x,4) where x is the Array sized (x,2) where x is the
number number
of datums stored in the FlexArray of datums stored in the FlexArray
plus 1. plus 1.
(0,0) contains the number of (0,0) contains the number of
pages pages
stored for each datum. Each of stored for each datum. Each of
the the
remaining rows correspond to remaining rows correspond to
one one
variable: (x,0) is the handle of the variable: (x,0) is the handle of the
datum, datum
(x,1) is the symbolic name, (x,2) and (x,1) is a boolean indicating
is the Add or
user name, and (x,3) is the Remove.
category of
the datum (output or resource).
Datums
Datum.InspectionRe Array sized (x,3) where x is the Array sized (x,3). Where x is the
sults number number
of ALL possible results, not just of results you are adding to the
those upload
selected for upload. list. The contents are different
(x,0) = Handle of the Datum that then for
is Get:
available for upload (not the Step) (x,0) = Handle of the Step
(x,1) = Symbolic Name of the (x,1) = Symbolic Name of the
datum. Datum
(x,2) = True if the datum is to be (x,2) = True if you want to upload
uploaded, False if not. this
To determine which results are datum, False if you are removing
selected it from
for upload, you must iterate upload list.
through the
array, checking for those entries
where
(x,2) = True.
Datum.Int Int Int
Datums
Datum.LayoutInfo Array sized (x, 6) where x is the Same format as Get Value. The
number input
of symbols in the layout, (x, 0) = data replaces the current
symbol LayoutData.
ID
(x, 1) = x location of the symbol
(x, 2) = y location of the symbol
(x, 3) = correlation score for the
symbol
that was calculated when the
layout was
trained
(x, 4) = width of the symbol in
pixels
(x, 5) = height of the symbol in
pixels.
Datum.Line Array of Doubles containing Array of Doubles containing
A,B,C. A,B,C.
This is from the line equation
Ax + By + C = 0
Datum.Matrix Array of Doubles sized (x,y) Array of Doubles sized (x,y)
Datums
Datum.OCVResults (x, 16)-The area of the largest Set not supported
(cont.) blob as a
percentage of the symbol's
trained area
(x, 17)-The trained area
Datum.Point Array of four floats. Array of either 2 floats or 4 floats.
(0) = x Specify
(1) = y just X,Y if you want, or specify all
(2) = Angle in radians 4
(3) = scale values. Format of the array
Note: Most tools will return data should be the
for just same as for Get Value.
the X and Y values, and the angle
and
scale will default to 0 and 1
respectively.
Datum.PtList Array of double point values (x,2) Array of double point values (x,2)
where where
x is the number of points, (x,0) is x is the number of points, (x,0) is
the the
point-x value, and (x,1) is the point-x value, and (x,1) is the
point-y point-y
value. value.
Datum.Rect Array of four Floats containing Array of four
left, top, Floats/Double/Integer
right, and bottom values. values containing left, top, right,
and
bottom values.
Datum.Statistics Datum.Statistics Single Single dimensional array with the
dimensional array with the following members:
following members: 0 - Owner Step Status (pass/fail)
0 - Owner Step Status (pass/fail) 1 - Measured value
1 - Measured value 2 - Nominal value
2 - Nominal value 3 - Minimum value
3 - Minimum value 4 - Average value
4 - Average value 5 - Maximum value
5 - Maximum value 6 - Standard Deviation
6 - Standard Deviation 7 - Count
7 - Count
Datum.Status Boolean Boolean
Datum.Strelem Array of size (x,y) containing a set Array of size (x,y) containing a set
of of Boolean values.
Boolean values.
Datums
Datum.VerifyResults (21) = Global good grade Set not supported (cont.)
(cont.)
(22) = Global fair grade
(23) = Contrast parameter active
(process control)
(24) = Contrast grade
(25) = Contrast score
(26) = Contrast grade required for
“good” rating
(27) = Contrast grade required for
“fair” rating
(28) = Modulation parameter
active (process control)
(29) = Modulation grade
(30) = Modulation grade required
for “good” rating
(31) = Modulation grade required
for “fair” rating
(32) = Reflectance Margin active
(process control)
(33) = Reflectance Margin grade
(34) = Reflectance Margin grade
required for “good”
(35) = Reflectance Margin grade
require for “fair”
(36) = Fixed Pattern Damage
active (process control)
(37) = Fixed Pattern Damager
grade
(38) = Fixed Pattern Damage
grade required for “good”
(39) = Fixed Pattern Damage
grade required for “fair”
(40) = Axial NonUniformity active
(process control)
(41) = Axial NonU grade
(42) = Axial NonU score
(43) = Axial NonU grade required
for “good”
Datum.VerifyResults (44) = Axial NonU grade required Set not supported (cont.)
(cont.) for “fair”
(45) = Grid NonUniformity active
(process control)
(46) = Grid NonU grade
(47) = Grid NonU score
(48) = Grid NonU grade required
for “good”
(49) = Grid NonU grade required
for “fair”
(50) = Unused Error Correction
active (process control)
(51) = Unused Error Correction
grade
(52) = Unused Error Correction
score
(53) = Unused Error Correction
grade required for “good”
(54) = Unused Error Correction
grade required for “fair”
(55) = Minimum Reflectance
active (process control)
(56) = Min Reflectance grade
(57) = Min Reflectance score
(58) = Min Reflectance grade
required for “good”
(59) = Min Reflectance grade
required for “fair”
(60) = Print Growth active
(process control)
(61) = Print Growth grade
(62) = Print Growth X
(63) = Print Growth Y
(64) = Print Growth grade
required for “good”
(65) = Print Growth grade require
for “fair”
(66) = Edge Determination active
(process control)
(67) = Edge Determination grade
Datums
Datum.VerifyResults (68) = Edge Determination score Set not supported (cont.)
(cont.)
(69) = Quiet Zone active (process
control)
(70) = Quiet Zone grade
(71) = Quiet Zone score
(72) = Quiet Zone grade required
for “good”
(73) = Quiet Zone grade required
for “fair”
(74) = Good Status (true if symbol
was rated “good”)
(75) = Fair Status (true if symbol
was rated “fair”)
(76) = Poor Status (true is symbol
was rated “poor”)
(77) = Decodability active
(process control)
(78) = Decodability grade
(79) = Decodability grade
required for “good”
(80) = Decodability grade
required for “fair”
(81) = Units
(82) = Cell size
(83) = Max exposure time used
for calibration
(84) = Global range active for
process control parameters
(85) = Global good grade
(86) = Global fair grade
(87) = Contrast parameter active
(process control)
(88) = Contrast grade
(89) = Contrast score
(90) = Contrast grade required for
“good” rating
Datum.VerifyResults (91) = Contrast grade required for Set not supported (cont.)
(cont.) “fair” rating
(92) = Modulation parameter
active (process control)
(93) = Modulation grade
(94) = Modulation grade required
for “good” rating
(95) = Modulation grade required
for “fair” rating
(96) = Reflectance Margin active
(process control)
(97) = Reflectance Margin grade
(98) = Reflectance Margin grade
required for “good”
(99) = Reflectance Margin grade
require for “fair”
(100) = Fixed Pattern Damage
active (process control)
(101) = Fixed Pattern Damager
grade
(102) = Fixed Pattern Damage
grade required for “good”
(103) = Fixed Pattern Damage
grade required for “fair”
(104) = Axial NonUniformity
active (process control)
(105) = Axial NonU grade
(106) = Axial NonU score
(107) = Axial NonU grade
required for “good”
(108) = Axial NonU grade
required for “fair”
(109) = Grid NonUniformity active
(process control)
(110) = Grid NonU grade
(111) = Grid NonU score
(112) = Grid NonU grade required
for “good”
Datums
Datum.VerifyResults (113) = Grid NonU grade required Set not supported (cont.)
(cont.) for “fair”
(114) = Unused Error Correction
active (process control)
(115) = Unused Error Correction
grade
(116) = Unused Error Correction
score
(117) = Unused Error Correction
grade required for “good”
(118) = Unused Error Correction
grade required for “fair”
(119) = Minimum Reflectance
active (process control)
(120) = Min Reflectance grade
(121) = Min Reflectance score
(122) = Min Reflectance grade
required for “good”
(123) = Min Reflectance grade
required for “fair”
(124) = Print Growth active
(process control)
(125) = Print Growth grade
(126) = Print Growth X
(127) = Print Growth Y
(128) = Print Growth grade
required for “good”
(129) = Print Growth grade
require for “fair”
(130) = Edge Determination
active (process control)
(131) = Edge Determination
grade
(132) = Edge Determination
score
(133) = Quiet Zone active
(process control)
(134) = Quiet Zone grade
(135) = Quiet Zone score
Datums
Datum.Verify1D (12) = Global threshold Set not supported (cont.)
ResultsDm (cont.)
(13) = Decode Grade
(14) = Decodability Grade
(15) = Edge Determination Grade
(16) = Symbol Contrast Grade
(17) = Minimum Reflectance
Grade
(18) = Minimum Edge Contrast
Grade
(19) = Modulation Grade
(20) = Defects Grade
(21) = Quiet Zone Grade
(22) = Calibration status
(23) = Cal target size 1
(24) = Cal target size 2
(25) = Cal target Rmin value
(26) = Cal target Rmax value
(27) = Cal Max exposure
(28) = Process control on
(29) = Global range active for
process control parameters
(30) = Global good grade
(31) = Global fair grade
(32) = Edge Determination active
(process control)
(33) = Edge Determ grade
required for “good” rating
(34) = Edge Determ grade
required for “fair” rating
(35) = Decode active (process
control)
(36) = Decode grade required for
“good” rating
(37) = Decode grade required for
“fair” rating
Datums
Datum.Verify1D (57) = Quiet Zone grade required Set not supported (cont.)
ResultsDm (cont.) for “good”
(58) = Quiet Zone grade required
for “fair”
(59) = Good Status (true if symbol
was rated “good”)
(60) = Fair Status (true if symbol
was rated “fair”)
(61) = Poor Status (true is symbol
was rated “poor”)
(62) = Units
(63) = Bar Width
Datum.Verify1D A 2-Dimensional array that Set not supported
ScanResultsDm provides the grades and scores
for each of the 10 scans
performed by ISO15416 symbol
verification.
Size of array is (10,19). Where n
= scan index:
(n,0) = Final Grade for scan
(n,1) = Edge Determination
Grade for this scan
(n,2) = Decode grade for this
scan
(n,3) = Symbol Contrast grade
(n,4) = Modulation grade
(n,5) = Minimum Edge Contrast
grade
(n,6) = Minimum Reflectance
grade
(n,7) = Defects grade
(n,8) = Decodability grade
(n,9) = Quiet Zone grade
(n,10) = Symbol Contrast score
(n,11) = Modulation score
(n,12) = Min Edge Contrast score
(n,13) = Min reflectance min
score
Datums
The StepBrowser utility is very useful for looking up information on the
various Steps available in Visionscape. Specifically, it allows you to select
any type of step from a drop-down list, and then all relevant programming
information for that Step is displayed in the window. Specifically, it
displays the strings that represent its Step.type and symbolic name, and
most importantly, a list of all of its Datums. The Datum list includes the
standard name, symbolic name and datum type of each. StepBrowser
can be found in Start > Programs > Microscan Visionscape > Tools > Step
Browser.
Using the combo box at the top left of the window, you can select any type
of Visionscape Step. In the example in Figure 2–9, we've selected the
Fast Edge Step. Once selected, StepBrowser shows you the default user
name, the symbolic name, and the type in the first row of the grid for the
selected Step. All subsequent rows contain a list of every Datum for the
selected Step. This list also provides the default user name, symbolic
name and Datum Type for each. This information is very useful when you
are writing code to find and/or modify the values of many different Datums
in many different Steps.
– filename — A string that specifies the path to the AVP file you
wish to load. All of the VisionSystemSteps in the specified AVP
will be added to this JobStep. So, if you already have an AVP file
loaded, and you now want to replace that AVP with a new one,
you must remember to delete all the existing VisionSystemSteps
in your Job (using the Remove method) before calling Load.
//loop until the Job Step has no children
while(m_Job.Count > 0)
{
m_Job.Remove(1);
}
//now we can load our new job
m_Job.Load(strAvpPath);
Saves the entire contents of the Job Step to disk. If your Job contains
multiple Vision System Steps, they will all be saved in one file. The Job is
saved to the file path specified by the filename parameter.
Saves only the specified Vision System Step to the file specified by
fileName.
Connects the first VisionSystem Step in the Job to the specified Device.
Refer to the VisionSystemStep documentation for more information on
SelectSystem.
Connects the first VisionSystemStep in the Job to the device with the
name specified by the sysName parameter.
VisionSystemStep VisionSystemStep()
This method will return the first VisionSystemStep in the Job. This allows
you to write code that is more easly read.
This:
VisionSystemStep vs = m_Job.VisionSystemStep();
Pass this function the name of an AVP file, and it will read the header of
that file, and return you an 8 element object array with the following
information:
AvpInfo (6) = String. Identifies the AVP type. There are 3 possible values.
This utility function provides an easy way to modify the process priority of
your user interface. Options are:
Datums
– PP_CLASS_HIGH High Process Priority
When you are running with Visionscape Host based System, you should
always run your process at Realtime in order to prevent timing spikes. If,
however, you are not concerned about timing spikes, and you would
rather not run your user interface as a Realtime process, then use this
property to lower the process priority to either High or Normal.
VisionSystem Step
Datums
string SystemLastSavedAs { get; }
This read-only property returns the name of the Device that was selected
the last time this Job was saved. Typically, you would use this property to
tell your application which Device it should connect to after you have
loaded a Job from disk, since it’s likely that your Job will always run on the
same Device.
Read-only. Returns the input buffer Datum (if any) in the form of a
BufferDm object.
Read-only. Returns the output buffer Datum (if any) in the form of a
BufferDm object.
Read-only. Returns True if the Step can run untrained. For example, the
Data Matrix step is a trainable step, but it can run untrained.
Allows you to attach custom string data to a Step. This data is not saved
with the Step when you save your Job to disk. Use the Tag property if you
need your string to be saved to disk.
Read-only. Returns the list of Datums for this Step for a specific category.
Datums
Read-only. Returns the list of all Datums for this Step. Refer to “Accessing
a Step’s Datum Values” on page 2-15 for more information on the Datum,
DatumList and Datums properties.
Returns/sets the Editability Flags. You can combine the available options
to get/set how the Step is handled in the Setup environment. This
property is available for both the Step and Datum objects. Not all of the
available flags apply to the Step object; the following are the only ones
that do:
Read-only. Returns the index of this Step in the collection of its Parent.
Read-only. Returns the error code from the last time the Step ran. This will
be 0 when there is no error.
Returns/sets the Name of the Step. This is also referred to as the user
name, as the user is free to change this name at will.
Returns/sets custom string data for this Step. Similar to the Cookie
property, only this data will be saved to disk with the Step when you save
your Job.
Datums
Read-only. Gets train information for this step.
Examples:
Adds a Step of the specified type to the calling Step’s child list. A
reference to the newly added Step is returned.
Adds a Step of the specified type to the calling Step’s child list, but adds it
BEFORE the step specified by relativeStep. The relativeStep parameter
must be a child of the calling Step. Refer to “Adding and Removing Steps”
on page 2-10 for a more detailed description.
Adds a Step of the specified type to the calling Step’s child list, but adds it
immediately AFTER the step specified by relativeStep. The relativeStep
parameter must be a child of the calling Step. Refer to “Adding and
Removing Steps” on page 2-10 for a more detailed description
Call to apply the set of changed data to the Step. When you are modifying
a Step’s Datum values from code, it’s a good idea to call this method after
you are done. This method tells the Step that it should update it's internal
data accordingly.
Returns True if the calling Step can be contained by the Step specified by
the thisStep parameter.
Returns True if the calling Step can contain the Step specified by the
thisStep parameter.
Finds the first child Step with the specified symbolic name. Throws an
exception if the Step does not exist. Please refer to “Finding Steps in the
Step Tree” on page 2-8 for a more detailed description.
Finds the first child Step with the specified user name. Throws an
exception if the Step does not exist. Please refer to “Finding Steps in the
Step Tree” on page 2-8 for a more detailed description.
Finds the first child Step of the specified type. Type is in the form
“Step.Inspection”. Returns a reference to the Step if found, throws an
exception if not found. Please refer to “Finding Steps in the Step Tree” on
page 2-8 for a more detailed description.
Datums
Returns an AvpCollection of all children that match the given type. Can
choose to search all child steps or only immediate children using the
findInAllChildren parameter. Refer to “Finding Steps in the Step Tree” on
page 2-8 for a more detailed description.
Finds the Parent Step that matches the specified type. The stepType
parameter is in the form “Step.Type”. Please refer to “Finding Steps in the
Step Tree” on page 2-8 for a more detailed description.
Finds the first child Step that matches the specified criteria. You can
choose to search for child Steps based on their symbolic name, user
name or type. Can also select the specific Step category to search. Refer
to “Finding Steps in the Step Tree” on page 2-8 for a more detailed
description
Returns a list of all child Steps that are of the specified type. Prefer this
method over the FindByType method.
int IsTimingEnabled()
Removes the child Step at the specified index from the calling Step’s
collection. The removed Step is always deleted. Please refer to “Adding
and Removing Steps” on page 2-10 for more information.
Removes a Step from the set of children, optionally delete it. Refer to
“Adding and Removing Steps” on page 2-10 for more information.
When calling this method the Step will first run it’s PreRun function (it’s
initialization routine), then it’s UIAction function (where it responds to
changes to specific Datum values), and then Runs the step. This function
returns true if the Step executed successfully ( not necessarily passed).
Typically, you would call this method when you have changed a datum
value, and then want to run the Step to see the effect. Pass in a reference
to the modified datum, or pass in null if you simply want to run the Step.
int Train()
Sends UIAction 'Apply' notification to the step for the given datum. If you
are changing Datums in code, it is good practice to call this method
because the Step may perform special initialization based on the value of
the Datum you are modifying.
int Untrain()
Datums
Categories are defined by the EnumAvpDatumCategory constants.
Allows you to store custom string data in this datum. This data will NOT
be saved to disk. Use the Tag property if you want to save custom data
along with the datum or Step.
You will query the bits of this property to determine the editability settings
for the datum. The values defined by EnumEditabilityFlags indicate the
meaning of each bit. The following options are available for datums:
– EF_CANMOVE
– EF_CANROTATE
– EF_CANSCALE
– EF_CANSIZE
– EF_CANSTRETCH
These options all apply to shapes only (e.g. the ROI), and indicate
whether the shape can be moved, rotated, scaled, sized or stretched.
YOU SHOULD NEVER CHANGE THE STATE OF THIS FLAG.
Read-only. Returns the error code from the last time the parent step ran.
Read-only. If Datum holds array data, returns size of array. Returns 1 for
simple types(int, double, string, etc.).
Datums
IComposite Parent { get; }
Datum ReferenceGet()
Valid for INPUT datums only, returns the Datum that is referenced by this
Datum.
Valid for INPUT Datums only, causes this Datum to point to, or reference,
the Datum specified by the refDatum parameter.
Allows you to get/set the value of the datum as a string. Some of the
complex datum types do not implement this property and may return an
empty string.
Use this property when you want to retrieve a Datum’s value in calibrated
units. The Job must have been calibrated first in order for this to have any
effect. If the Job has not been calibrated, then this property returns the
same data as the Value property.
– VF_NEVER — The datum is not visible. This means that the datum will
not show up in the Datum page of the Setup Manager, or in the Datum
Grid control. When applied to ROIs, this means that the ROI will not show
up in the buffer and, therefore, cannot be moved by the user.
Allows easy manipulation of the Visibility flag when you simply want to
show or hide a Datum. Set to 0 to hide a Datum, 1 to show it. Returns 0 if
the Datum is not visible, non 0 if it is Visible.
Finds the Parent Step that matches the specified type. The stepType
parameter is in the form “Step.Type”. Please refer to “Finding Steps in the
Step Tree” on page 2-8 for a more detailed description.
Regenerates the datum, and optionally takes a picture while doing so.
“Regenerate” means to PreRun and then Run every Step that this Datum
Datums
those Steps would also be PreRun and Run.
If bAdd is true, this Datum is added to the parent Inspection Step’s list of
Result to Upload. If bAdd is false, it is removed.
Talking to Visionscape
Hardware
CHAPTER 3 Talking to Visionscape
Hardware: VsCoordinator
and VsDevice
Namespace:Visionscape.Devices
Add the following statement to the top of your C# files in order to make
access to this namespace easier:
using Visionscape.Devices;
VsCoordinator
The primary purpose of the VsCoordinator object is to discover the
Visionscape hardware that is available to your PC, and to collect that
hardware into “Devices”. As we explained in Chapter 1, a “Device”
represents a single smart camera or a collection of GigE cameras.
VsCoordinator will discover all available smart cameras on your network,
and create a VsDevice object to represent each. It will also discover all
available GigE cameras and (by default) create one VsDevice object to
talk to all of them. The discovered Devices are maintained in a list, and
you will need to access this list in your code whenever you wish to
communicate with a particular device. Access is provided via the Devices
property, which is a collection of VsDevice objects.
VsDevice
The VsDevice object is a programmer’s interface to any Visionscape
device. Its API includes methods to start, stop, upload, download, take
control, query status, and configure a device. It also contains properties
that describe the device, such as the device type (GigE device, smart
camera, etc), the digitizer type, etc. Therefore, the VsDevice object is
central to writing your own Visionscape UI.
Talking to Visionscape
added to the Devices collection first, and smart cameras will always be
Hardware
added at the end of the list. The following example illustrates iterating
through the VsCoordinator’s Devices collection, and outputing the name
of each Device to the output window:
VsCoordinator coord = new VsCoordinator();
foreach (VsDevice dev in coord.Devices)
{
Console.WriteLine(dev.Name);
}
To find a particular device in the list by name, you can use the
FindDeviceByName method. For example, the first GigE system
discovered in your PC will always be assigned the name “GigeVision1”,
so you can find this device with the following code:
VsCoordinator coord = new VsCoordinator();
VsDevice gigeDev = coord.FindDeviceByName("GigeVision1");
Note: To see the names of the GigE systems and Software Systems in
your PC, double-click on the Visionscape Backplane icon in the Windows
System Tray.
This will open the AvpBackplane window, which will provide you with a list
of all available GigE and Software Systems. But NOT smart cameras. To
see a list of all discovered smart cameras, use the Visionscape Network
Browser utility.
When the Visionscape Backplane process first starts it will try to detect
what devices are present. This is handled as follows:
GigE Systems:
A command is sent out across your network connection asking all GigE
cameras to announce themselves. If any GigE cameras are present, they
will respond to this request. When the Visionscape Backplane process
receives a response, it knows that it has GigE cameras, and will therefore
go ahead and create a GigE System that will own each GigE camera.
This system will be added to the front of the Devices Collection.
Software Systems:
Software Systems are not added to the Devices Collection until after the
GigE System(s) have all been discovered. Software systems are always
added after GigE systems, but before smart cameras.
Smart Cameras:
Talking to Visionscape
Waiting for Device Discovery by Using “Device Focus”
Hardware
So as we just discussed, when your application first starts, there may be a
delay before all devices have been discovered and placed in the Devices
collection of VsCoordinator. This means that your application will need to
wait for its chosen Device to be discovered before it tries to access it. This
is done by using the DeviceFocusSetOnDiscovery method of
VsCoordinator. You simply pass in the name of the device you are looking
for, and then the OnDeviceFocus event will be fired when that device is
discovered. The following example demonstrates how we would wait for
the discovery of the smart camera named “MyHawkEye_1600T”:
VsCoordinator m_coord;
private void frmMain_Load(object sender, EventArgs e)
{
m_coord = new VsCoordinator();
//wire up our event handler to the OnDeviceFocus event
m_coord.OnDeviceFocus += OnDeviceFocusEventHandler;
//tell coordinator to fire the OnDeviceFocus event when
//the device MyHawkEye_1600T is discovered
m_coord.DeviceFocusSetOnDiscovery("MyHawkEye_1600T", -1);
}
private void OnDeviceFocusEventHandler(VsDevice objDevice)
{
Console.WriteLine("Our Device has been Discovered and is
Ready to use");
//Continue your UI initialization here…
}
So as you can see, when our application starts up, we call the
DeviceFocusSetOnDiscovery method in the Form_Load event, and then
we wait for the OnDeviceFocus event to be fired. When
OnDeviceFocusEventHandler is called, we know that the device
“MyHawkEye_1600T” has been discovered and is ready to use. At that
point, you would continue with whatever application initialization you need
to perform, such as downloading a job, establishing report connections,
etc.
Talking to Visionscape
The previous example instructs the VsCoordinator to call our
Hardware
OnDeviceFocusEventHandler() function when the Device named
“GigEVision1” is discovered. Once the Device is discovered, we load a
Job from disk, connect the VisionSystemStep to the Device, and start all
of the inspections running. We also make sure to call the Devices’ StopAll
method in the Form_Unload event to stop all inspections before the
application exits. This is important when running with Host based
Systems. A “Host based System” is one in which your PC acts as the
primary vision processor, such as with GigE and Software Systems, and
previously our framegrabber boards. On a Host based System, your
application may crash if it attempts to shut down while inspections are still
running. You do not need to worry about stopping inspections on exit
when dealing with smart cameras. So, the previous example works well
for Host based Systems.
But what about smart cameras? For these devices, it’s not enough to
simply select the hardware; you must also download your Job to the
Device. In that case, the following code could be used. Assume we want
to load a Job onto a smart camera named “MyHawkEye_1600T”.
In other words, the Download method will call the SelectSystem method
for you. Thus, if you are trying to write a generic UI that will work with all
Visionscape Devices, we recommend that you use the call to Download
rather than SelectSystem.
One last point, you must remember that you need to stop all inspections
from running when you exit your application if you are running on a Host
System.
Talking to Visionscape
The previous examples showed, with a small amount of code, how to get
Hardware
a Visionscape Job loaded to a particular Device and running. We haven’t
showed you how to view the images and results yet, that's coming in the
next chapter. But, how about an even easier way to get a Job loaded and
running? Consider this modification to our previous example:
private VsDevice m_dev;
private VsCoordinator m_coord;
//The Load event of our main form
private void frmMain_Load(object sender, EventArgs e)
{
m_coord = new VsCoordinator();
//wire up our event handler to the OnDeviceFocus event
m_coord.OnDeviceFocus += OnDeviceFocusEventHandler;
//tell coordinator to fire the OnDeviceFocus event when
// the device MyHawkEye_1600T is discovered
m_coord.DeviceFocusSetOnDiscovery("MyHawkEye_1600T", -
1);
}
//This event handler will be called when our device is
discovered
private void OnDeviceFocusEventHandler(VsDevice objDevice)
{
//We've discovered our Device....
m_dev = objDevice;
try
{ //Load the AVP and download it in one step, wait
until its done
TransferStatus stat =
m_dev.DownloadAVP("C:\Vscape\Jobs\SampleJob.avp",
true);
//check status of the download
if(stat == TransferStatus.TransferOK)
{ //download was successful, so start the
inspections
m_dev.StartAll();
}
}
catch (Exception e)
{
Console.WriteLine("Download Failed for the following
Reason: " + e.Message);
}
}
Talking to Visionscape
What Else Can I Do With Device Objects?
Hardware
Table 3–1 Acts as a quick reference of example code for common
situations. For important additional details, please refer to the detailed
documentation later on in this chapter.
Talking to Visionscape
TABLE 3–1. How Do I...
Hardware
Download a Job Step that 1. Get a VsDevice reference for the Visionscape
is already loaded Device you wish to download to.
2. Use the DownloadAVP method of VsDevice
TransferStatus stat =
m_dev.DownloadAVP("SampleJob.avp", false);
3. Check the transfer status in a loop while
calling DoEvents to allow other UI events to
continue while waiting for the download to finish
while(m_dev.CheckXferStatus(20) ==
tagXFERSTATUS.XFER_IN_PROGRESS)
{
Application.DoEvents();
}
4. Step 3 can be skipped by passing ‘true’ as the 2nd
parameter of Download. For more information about
downloading a Job, see “Downloading a Job” on page 3-14
Get information on the 1. Tell Device to update its Namespace information
running Job by calling QueryNamespace.
m_dev.QueryNamespace();
2. Access the NameSpace property, which holds
a VsNameNode object with child VsNameNode
objects arranged in a tree structure that is identical
to the Loaded Job.
VsNameNode nnJob = m_dev.Namespace;
Getting information on a 1. Tell device to update its IO information by calling
Device's IO capabilities the QueryIOCaps method.
m_dev.QueryIOCaps();
2. Access the IOCaps property. This is a VsIOCaps object,
the properties of which describe the IO capabilities of the
device.
VsIOCaps iocaps = m_dev.IOCaps;
Console.WriteLine("Num Physcial IO Pts: " +
iocaps.CountPhysical);
When dealing with smart cameras, your user interface should “Take
Control” of these devices before you perform any operation that may
affect their behavior. Although it’s not required that you take control of a
device before downloading to it or starting and stopping inspections, we
strongly recommended that you do. This insures that your application
does not conflict with another user on another PC who may currently be
connected to the same smart camera (via FrontRunner or AppRunner,
perhaps). The TakeControl method requires a user id and password:
Talking to Visionscape
(NOTE: The TakeControl method is relevant only to smart cameras, and
Hardware
does not apply to other Device types).
bool InControl = m_dev.TakeControl("UserID", "Pwd");
if(InControl)
{
//safe to download, start, stop, etc
}
You can check whether you already have control by using the VsDevice
HaveControl property:
if(m_dev.HaveControl)
{
//we already have control
}
Downloading a Job
You must download a VisionSystemStep to a device, as the
VisionSystemStep represents the vision program for one device. To
download a vision job to a device, you can either call Download, or you
can call DownloadAVP. The Download method will download the
VisionSystemStep that you pass to it. You can either pass it a
VisionSystemStep directly, or you can pass it a reference to your JobStep,
in which case it will find the first VisionSystemStep for you and download
it. The DownloadAVP method takes the file name of an .AVP file, opens it
for you, and then downloads. For each method you can choose to wait
until the download is complete by passing true as the second parameter:
Each method returns a TransferStatus enum value which will notify you of
the success or failure of the download. The TransferStatus values are as
follows:
TransferStatus.TransferOK //Successful download
TransferStatus.TransferNotStarted //Failed to start the
//download
TransferStatus.TransferError//An error occurred //during
transfer
– Your Job fails PreRun, and is not ready to run. This often
happens when trying to load a Job that was created on a different
type of device. You should load the Job into FrontRunner and be
sure that it runs there before trying to load it from your
application.
Talking to Visionscape
Application.DoEvents();
Hardware
}
• nState — This Long value represents the overall state of the transfer.
The following values are possible:
– -1 — Transfer error
– 0 — Transfer started
– 1 — Transfer complete
– 3 — Transfer message
• msg — This string value describes the current status of the download.
You may prefer to simply printout these messages for your user rather
than implementing a progress bar.
Uploading a Job
Using the Upload method of VsDevice is slightly more involved, as we will
be receiving a new VisionSystemStep, and must prepare the job to
receive it. You will get the new VisionSystemStep from the
OnUploadComplete event, as shown in the following example:
//declare a global VisionSystemStep because we will receive
//this Step
//in an event and need to stash it somewhere
private VisionSystemStep m_UploadedVSStep;
private void UploadJob()
{
//delete the contents of the existing job 1st
while(m_Job.Count > 0)
{
m_Job.Remove(1);
}
//wire up our event handler,
// to notify us when the upload is complete
m_dev.OnUploadComplete += m_dev_OnUploadComplete;
//start the asynchronous upload
m_dev.Upload(m_Job);
//waiting for an upload to complete is the same as for a
//download
while(m_dev.CheckXferStatus(20) ==
tagXFERSTATUS.XFER_IN_PROGRESS)
{
Application.DoEvents();
}
//upload is complete, do we have a Vision System Step?
if(m_UploadedVSStep != null)
{
//Yes, we successfully received the job
}
Talking to Visionscape
}
Hardware
//This event is fired when the Upload is complete, and it
//will return
//the uploaded VisionSystem step to you
void m_dev_OnUploadComplete(int nStatus, VisionSystemStep
pVS)
{
if(nStatus == 0)
{ m_UploadedVSStep = pVS;
}
else
m_UploadedVSStep = null;
}
DeviceClass Property
The DeviceClass field identifies what type of Device you are dealing with.
It returns an enumeration value of type tagDEVCLASS. The values of the
enumeration are as follows:
DEVCLASS_UNKNOWN=0
DEVCLASS_SOFTWARE_EMULATED=1
DEVCLASS_HOST_BOARD=2
DEVCLASS_PROCESSOR_BOARD=3
DEVCLASS_SMART_CAMERA=4
DEVCLASS_SMART_CAMERA_OLDER=5
DEVCLASS_SMART_CAMERA_UNREACHABLE=6
DEVCLASS_CAMERA=7
DEVCLASS_GIGE_VISION_SYSTEM= 8
• DEVCLASS_SMART_CAMERA_UNREACHABLE — A smart
camera that, due to network topology, cannot be connected to via a
TCP connection. Perhaps it’s on a different subnet or has an
incompatible IP address.
IsHostBased Property
You can use the IsHostBased property to determine if there is no target
processor for the device; in other words, if the device is a GigE System,
host based board or software emulated.
Talking to Visionscape
Determining if a Particular Inspection is Running
Hardware
This is easily accomplished via the IsInspectionRunning method.
bool IsInspectionRunning(nInsp As Long)
nInsp — 0 based index of the inspection. If you pass in -1, the function
check all inspections to see if ANY are running.
Device States
It is often valuable to find out what state a device is in. This information is
obtained via the DeviceState property of VsDevice. This property returns
an enumerated value of type tagDEVSTATE. The enumeration values
are:
DEVSTATE_UNKNOWN=0
DEVSTATE_RUNNING=1
DEVSTATE_STOPPED=2
DEVSTATE_NOJOB=3
DEVSTATE_NOCOMM=4
DEVSTATE_ERROR=100
DEVSTATE_FILE_XFER=101
DEVSTATE_TRYOUT=102
DEVSTATE_EDIT=103
DEVSTATE_LIVE=104
DEVSTATE_FUNCTION=105
DEVSTATE_ACQUIRE=106
Talking to Visionscape
Console.WriteLine("MAX NER Axis = " +
Hardware
iocaps.MaxNERLightAxis);
}
Because UDPInfo is only available for networked devices, it’s a good idea
to always check if the object exists before using it:
Visionscape.Internals.VsUDPInfo udp;
udp = m_dev.UDPInfo;
if(udp != null)
{
Console.WriteLine("Seconds Since Last Updated " +
m_dev.TimeSinceLastRefresh);
Console.WriteLine( "Cycle Count 1st inspection " +
udp.CountCycles1);
Console.WriteLine( "Cycle Count 2st inspection " +
udp.CountCycles2);
Console.WriteLine( "Passed Count 1st inspection " +
udp.CountPassed1);
Console.WriteLine( "Passed Count 2st inspection " +
udp.CountPassed2);
Console.WriteLine( "Name of First Inspection " +
udp.FirstInspectionName);
Console.WriteLine( "Use DHCP " + udp.NetDHCP);
Console.WriteLine( "Net Mask " + udp.NetMask);
Console.WriteLine( "Controlling PC " +
udp.IPAddressOfController);
Console.WriteLine( "AVP Name of loaded program " +
udp.ProgramName);
Console.WriteLine( "Software Version " +
udp.SoftwareVersion);
Console.WriteLine( "Number of Inspections " +
udp.NumInspections);
Console.WriteLine("Number of Network Connections " +
udp.NumConnections);
Namespace Information
VsDevice allows you to query the namespace of a device in order to
extract information about the Job that it’s currently running. This is
particularly useful when dealing with smart cameras in a user interface
where you do not have the Job loaded locally. By calling the
QueryNamespace method of VsDevice, you will cause a command to be
sent to the device, which will cause it to construct a description of every
Step in the Job. This description will be sent back to the VsDevice object,
and it will construct a tree of VsNameNode objects that mimics the Job on
the Device.
dev.QueryNamespace();
After this call, you can use various methods and properties to access the
namespace data. As we mentioned above, this functionality is primarily
used in applications that will deal with smart cameras, but it works with
Talking to Visionscape
ALL devices. If you already have the Job loaded in memory (in a
Hardware
JobStep), it’s more efficient to analyze the actual Job rather than dealing
with Namespaces. The following are the methods and properties used to
access the Namespace.
VsNameNodeCollection ListInspections()
Provides you with a list of the running inspections on the device. This is in
the form of a VsNameNodeCollection object, which is a collection of
VsNameNodes. There will be one VsNameNode for each inspection step
in the Job. The VsNameNodes will provide you with useful information
that describes the Inspection Steps. Refer to the following section for
more info on the VsNameNode object.
Provides a list of Snapshots that live under the specified Inspection. You
must pass in a VsNameNode object that represents an Inspection Step,
and it will return you a list of VsNameNodes, one for every Snapshot Step
under the specified Inspection. The following is an example of how you
might walk through all of the Inspections and Snapshots of a remote
device:
private void AnalyzeNamespace()
{
//tell the device to send us updated namespace
//information
m_dev.QueryNamespace();
//if no namespace information, just exit
if(m_dev.Namespace == null)
return;
//get a list of namenodes for each inspection step
VsNameNodeCollection nnAllInsp =
m_dev.ListInspections();
//iterate through the inspection namenodes
foreach(VsNameNode nnInsp in nnAllInsp)
{ //dump some information on the inspection step
Console.WriteLine("Inspection Info: " +
nnInsp.UserName + ", "
+ nnInsp.NameType);
//get a list of all snapshots under this inspection
VsNameNodeCollection nnAllSnaps =
m_dev.ListSnapshots(nnInsp);
foreach (VsNameNode nnSnap in nnAllSnaps)
{
VsNameNode
The VsNameNode object represents either a Step or Datum object. It’s
the object used to provide Namespace information for a Device, typically
a remote Device like a smart camera. When we say Namespace
information, we are primarily talking about the Job that is loaded on the
Device. You will access a Device’s Namespace via the VsDevice object’s
Namespace property, or the ListInspections and ListSnapshots functions
(refer to the previous section for more information). The following
example shows how you would access the Namespace of a given Device:
m_dev.QueryNamespace();
VsNameNode nnJob = m_dev.Namespace;
Talking to Visionscape
represents. This means that you can walk through the elements of the
Hardware
VsNameNode object, just as you can walk through the elements of a Job
tree. The next most obvious question is, what information does the
VsNameNode object provide?
VsNameNode Properties
As we've already said, a VsNameNode represents either a Step or a
Datum. Therefore, the properties are intended to describe that Step or
Datum.
This property returns a value that identifies the type of object represented
by the NameNode. Possible values are:
Returns a value that indicates the category of the Step or Datum. This is
roughly equivalent to the Category property of Step and Datum. Possible
values for Datums:
– VS_INPUT_DATUM
– VS_OUTPUT_DATUM
– VS_RESOURCE_DATUM
– VS_POSTPROC_STEP
– VS_PREPROC_STEP
– VS_PRIVATE_STEP
– VS_SETUP_STEP
– VS_PART_STEP
Returns a string that is equivalent to the Step and Datum object’s Type
property. This is in the form “Step.type.1” or “Datum.type.1” where “type”
would represent the actual type of the Step or Datum.
Only applies to Datums. Returns 1 if this Datum has been selected for
upload, 0 if not. In other words, this Datum was added to the Inspection
Step’s “Select Results to Upload” list and will, therefore, show up in the list
of results in each inspection report.
The user assigned name of the Step or Datum. This is equivalent to the
Name property of Step and Datum. Return value is a string.
Talking to Visionscape
VsDevice Device { set; get; }
Hardware
Returns a reference to the VsDevice object that produced this
VsNameNode.
VsNameNode Methods
VsNameNodeCollection SearchForType(string bstrType)
Allows you to search for all of the child nodes that are of the type
specified by the bstrType parameter. A VsNameNodeCollection is
returned that contains all of the nodes found.
//get a list of all fast edge steps under this namenode
VsNameNodeCollection allFastEdge =
nnSnap.SearchForType("Step.EdgeFast.1");
//iterate the list of fast edge steps
foreach(VsNameNode nnFastEdge in allFastEdge)
{
Console.WriteLine("Fast Edge Step Name: " +
nnFastEdge.UserName);
}
Allows you to search for a parent Step or Datum that is of the type
specified by the ProgId parameter. A VsNameNode reference is returned.
//find the parent inspection of this namenode
VsNameNode parentInsp =
nnSnap.FindParentOfType("Step.Inspection.1");
Builds a path string from the current node up to the first parent node that
is of the type specified by the StopAtType parameter. If StopAtType is an
empty string, the routine defaults to the Inspection step.
Returns a collection of name nodes that are selected for upload. This only
applies to Datums, so only VsNameNodes that represent Datums will be
in the list. The strTypeIn parameter can be used when you only want your
list to include datums of a certain type, pass an empty string to return all
Datum types.
VsNameNode nnJob = m_dev.Namespace;
//get a list of all datums selected for upload
VsNameNodeCollection uploadList = nnJob.SearchForTagged("");
//get a list of only Point List Datums that are selected for Upload
uploadList = nnJob.SearchForTagged("Datum.PtList.1");
Device Collection
All devices are accessible via the Devices collection property of
VsCoordinator. You can iterate over accessible devices using code such
as:
VsCoordinator m_coord = new VsCoordinator();
foreach(VsDevice dev in m_coord.Devices)
{
Console.WriteLine("Name = " + dev.Name);
}
DeviceFocusSet
VsCoordinator maintains a list of all available Devices, but you can
specify one of those Devices to be the “Focus” device. This is done by
calling the DeviceFocusSet method, which will cause the OnDeviceFocus
event to be fired. This is an advanced method that you can use in your
application to allow multiple forms and controls to all synchronize
themselves to a given Device. If each form and control in your application
has it’s own instance of a VsCoordinator object, then you could call the
DeviceFocusSet method in one place in your code, and then the
OnDeviceFocusEvent would be fired in each of those VsCoordinator
instances. You could then add logic to each of your forms and controls to
respond to the event, and automatically update themselves whenever the
selected Device changes. This is how the Device focus is set:
Talking to Visionscape
//dev is a VsDevice object that we want
Hardware
//to be the "focus" device
m_coord.DeviceFocusSet(m_dev, -1);
To clear the device focus, pass null to signify that no device is selected:
m_coord.DeviceFocusSet(null, -1);
You can retrieve the device with the focus at any time by calling the
DeviceFocusGet method. Be sure to always check if the device is valid,
by always writing code such as:
VsDevice dev = m_coord.DeviceFocusGet(-1);
if(dev != null)
{
//do something
}
DeviceFocusSetOnDiscovery
If you know the name of the Device that you want to set the focus to, but
you don’t have the device object, you can use the
DeviceFocusSetOnDiscovery method. Earlier in this chapter we
discussed how to use this method to wait for your smart camera to be
discovered when your application is first starting up. For example, to set
the device focus to “MyCamera”:
m_coord.DeviceFocusSetOnDiscovery("MyCamera", -1);
If you do not know the name of the device, but know the IP Address, use
the FindDeviceByIP method. For example:
VsDevice dev = m_coord. FindDeviceByIP("10.2.1.198");
You can also get the IP address of a device with a given name by using
the LookupIPAddress function.
string devIP = m_coord.LookupIPAddress("MyHawkEye_1600T");
OnDeviceDiscovered Event
The OnDeviceDiscovered event is fired whenever a new device has been
found. This event is useful when you are trying to display a list of current
devices to the user.
Talking to Visionscape
components. The most useful of these is the Broadcast mechanism. By
Hardware
using the methods BroadcastMessage or BroadcastObj, you can cause
the OnBroadcastMessage or OnBroadcastObj events to be raised for all
other VsCoordinators. For example, let’s say you have a button on a form,
and when you press it you want all other forms to receive an event. You
can do this as follows:
private void MyButton_Click(object sender, EventArgs e)
{
m_coord.BroadcastMessage(this.Name, "MyPrivateMessage",
"param");
}
Notice the first statement that exits if the bstrSender parameter is the
same as the name of the form. This is simply a way of checking if the
broadcast came from this form or from somewhere else. This may not be
necessary depending on what you are doing, but it’s often the case that
the originator of a message does not want to handle the message
themselves. After that you would simply enter an ‘if’ or ‘switch’ statement
to check if the message is something you want to process.
UpdateUI Method
Calling the UpdateUI of VsCoordinator causes the OnUpdateUI event to
be raised for every VsCoordinator reference. You can use this method as
a way to inform every form or control that something has changed that
requires a display update. For more complex projects, the
BroadcastMessage approach is preferred because you can define your
own messages.
Talking to Visionscape
m_coord.LogMessage("Something important happened!", false);
Hardware
The second parameter should be set to True if you are reporting an error
condition (and will appear red in the display), and False if the message is
for information purposes only. You can show or hide the debug window
using the function ShowLogWindow:
m_coord.ShowLogWindow(true); // to show the display
m_coord.ShowLogWindow(false); // to hide the display
You can check for changes to the network adapters by calling the
RefreshNetworkAdapters method. If the list of network adapters has
changed since your application started, or since the last time you called
RefreshNetworkAdapters, then the OnNICChange event will be raised.
For example, if a wireless connection has been made or dropped, or a
change has been made to the network configuration via the control panel.
VsCoordinator Reference
VsCoordinator is part of the Visionscape.Devices namespace. Following
is a complete list of all properties, methods and events.
This property is a collection of all vision devices that can be connected to.
This function looks up a device using the specified name. This function
returns a VsDevice object if found, and returns null if not found.
This property sets/gets the focus device. If you need to use a GroupID, to
allow more than one focus device, then use DeviceFocusGet instead.
Looks up the IP address of the device with the specified name. It returns
the device's IP address if found, and an empty string if not found.
This method sets the focus to the specified VsDevice object. Use the
GroupID parameter in situations where multiple focus devices are
required. Use the DeviceFocus property if don’t need multiple focus
Devices.
This function returns the current focus device. Use the GroupID
parameter if multiple focus devices have been specified.
This function searches the Device collection for the supplied IP Address
string. It returns a VsDevice if found, and null if not found.
This event occurs when a new network device (i.e., smart camera) is
discovered.
Talking to Visionscape
Event OnDeviceFocus (VsDevice newDevice)
Hardware
This event occurs whenever the current focus device changes. The focus
device is selected via the DeviceFocus property, or the DeviceFocusSet
method.
This event is sent just before the device focus is about to change.
UI Coordination
void UpdateUI()
This method sends the OnUpdateUI event from all VsCoordinators. Use
this to force various controls to refresh.
This function retrieves a Global String that was set via the SetGlobalString
function.
Event OnUpdateUI()
Event OnNICChange()
This event occurs if a change has been made to any Network Interface
Controller settings (for example, the host PC's IP address or Net Mask).
Miscellaneous
void ShowLogWindow(bool bShow)
This property gets/sets the currently loaded Job. Please refer to the
detailed documentation for further information about the Job property. For
more information, see “Connecting Jobs to Visionscape Devices” on page
3-6.
Talking to Visionscape
VsNetworkAdapterCollection NetworkAdapters { get; }
Hardware
This property returns a collection of VsNetworkAdapter objects,
containing information about the Network Interface Controllers on the PC.
VsDevice Reference
The VsDevice object is part of the Visionscape.Devices namespace.
Following is a complete list of all properties, methods and events.
This function downloads the specified Job to the device. If the Job
contains multiple VisionSystem Steps, the first is downloaded. If the bWait
parameter is true, the function will not return until the download is
complete. If false, an asynchronous download is started and the function
returns immediately. The status of the download is returned in the
enumerated TransferStatus value. This function can also throw an
exception.
Talking to Visionscape
TransferStatus DownloadAVP( string JobPath, bool bWait)
Hardware
This function downloads the Job contained in the specified AVP file. If the
bWait parameter is true, the function will not return until the download is
complete. If false, an asynchronous download is started and the function
returns immediately. The status of the download is returned in the
enumerated TransferStatus value. This function can also throw an
exception.
This function uploads the Job that is currently loaded on the device. This
function uploads a VisionsSystem step (and all of its child steps), and
inserts it into the specified JobStep. Refer to the detailed documentation
for further information on uploading. For more information, see
“Uploading a Job” on page 3-15.
Control
bool TakeControl(string bstrUID, string bstrPWD)
void ReleaseControl()
void StartAll()
This method starts the specified inspection (0 based index) on the device.
If nInsp is set to -1, all inspections are started. You can use the nCycles
parameter to specify the number of cycles to run, set this to 0 to run for an
infinite number of cycles.
void StopAll()
This method stops the specified inspection (0 based index) on the device.
Pass in -1 to stop all inspections.
This method resets the inspection counters for the specified inspection.
This function reboots the Network Device. It requires that you specify a
username and password. Has no effect on Host based Devices.
Advanced
VsioCaps QueryioCaps()
This function queries the device for a structure that describes the I/O
capabilities, such as the number of each type of I/O supported.
Talking to Visionscape
VsUDPInfo UDPInfo { get; }
Hardware
This property returns a structure with all the information contained in the
UDP info packet sent by smart camera network devices.
Use this method to directly read a buffer out of a device and copy the data
into the supplied BufferDm. The bstrPath parameter should be the
symbolic name path of the Buffer desired.
Report Connections
Receiving Data with
CHAPTER 4 Receiving Data with Report
Connections
Namespace:Visionscape.Communications
Add the following statement to the top of your C# files in order to make
access to this namespace easier (all sample code in this chapter
assumes the following statement is presnt):
using Visionscape.Communications;
ReportConnection Object:
The ReportConnection object can connect to any Visionscape Device,
and it allows you to receive inspection results, inspection stats, and
images while the Device is running. Key points to understand:
Report Connections
Receiving Data with
//connect to the 1st inspection on the device “GigeVision1”
m_RepCon.Connect("GigeVision1", 1);
//wire up our event handler
m_RepCon.NewReport += m_RepCon_NewReport;
}
//You will now receive this event whenever a new
// Inspection report is available
void m_RepCon_NewReport(object sender,
ReportConnectionEventArgs e)
{
Console.WriteLine("Received a New Inspection Cycle
Report");
}
Connection Details
As we just demonstrated, the Connect method of ReportConnection
establishes a report connection to one of the inspections on a running
device. We provide several overloaded versions of the Connect function:
• ConnectOptions.STATS |
ConnectOptions.TAGGED_FOR_UPLOAD
• The following two options are rarely used, but are available.
• ConnectOptions.IGNORE_UPLOAD_QUALIFIER: The
Inspection Step has a Datum named “Results Upload
Qualified Condition”. This datum allows you to enter an
expression that determines when results should be uploaded.
Report Connections
Receiving Data with
Setting this flag will cause that expression to be ignored, and
results will be uploaded after each cycle.
Identical to the Connect method just documented, only this version takes
a reference to the VsDevice object you are connecting to, rather than it’s
name.
bool Connect(string deviceName, int inspIndex)
bool Connect(Visionscape.Devices.VsDevice device, int inspIndex)
The default for this property is true, which means your reports will be
dropped if the Inspection is too busy to send them. This means your
connection will be lossy. If you require a lossless connection, meaning
you don’t want any reports to be dropped, then you must set this property
to false. You should understand however that a lossless connection may
Use this property to set the maximum number of reports that can be sent
per second. The default is 0, which means to send the maximum number
of reports possible, no limit. A setting of 2 would mean no more than 2 per
second. Using 2 as an example, the connection would translate this
setting into a number of milliseconds (1000ms / 2 = 500ms). Whenever
the connection sends a report, it will start timing, and if another report is
ready for transfer in less than 500ms, then it will be thrown away. In other
words, your running inspection will only send one report every 500ms.
By default, your report connection will try to send a report after every
inspection cycle. You can use this property to change that behavior by
specifying one of the enumerated values in
ReportConnection.FreezeModeOptions :
Report Connections
Receiving Data with
– FreezeModeOptions.FREEZE_NEXT_QUAL — This option only
applies if you are using the “Freeze Qualified Condition” datum in
the Inspection Step. The datum allows you to specify an
inspection condition which, if evaluated as True, will freeze the
connection. Without this setting, the datum in the inspection step
has no effect on your report connection.
The default is False. When set to True, any images buffers that have
been added to the list of results to upload will be excluded from the report.
This property has the same effect as specifying
ConnectOptions.NO_IMAGES when calling the Connect method.
The default is True. When set to False, any images included in the report
will not include graphics.
We will cover the InspectionReport object and it’s contents in more detail
later on in this chapter.
datumToAdd: The datum that you want to add to the list of uploaded
results.
This method adds the specified datum to the end of the list of results to
upload. It must be called after your call to Connect. You would use this
method when you are loading the Job in your application, and you can
then locate the datums you want to add. Refer to Chapter 2 and the
“Finding Steps in the Step Tree” section for more information on how to
locate steps and datums.
void DataRecordAdd(Visionscape.Devices.VsNameNode
nnForStep, string DatumName)
nnForStep: A VsNameNode object that represents the parent Step of the
datum you wish to add.
Report Connections
Receiving Data with
This method adds a datum to the list of results to upload. It must be called
after your call to Connect. The Datum is specified by passing in a
VsNameNode object that represents the parent Step, and a string that
holds the name of the Datum. You would use this method when you are
writing a monitoring application, and you do not have the actual Job
loaded in your process. Refer to Chapter 3 and the “Namespace
Information” section for more information.
DataRecordAdd Examples:
Consider the Job tree shown below; this is from the
ProgSample_MultiCam.avp file installed with the Visionscape VSKit.NET
Programmers Toolkit:
The Job Tree shown here is displaying the symbolic names for each Step.
The first Fast Edge Step under the second Snapshot Step is highlighted.
Let’s say we wanted to add the output edge point from this Fast Edge
Step to our list of uploaded results. The symbolic name for the “Edge
Point” datum is EdgePt (remember, you can look up the symbolic name of
any datum using the StepBrowser utility, refer to “Using StepBrowser to
Look Up Symbolic Names” on page 2-30 for details). The symbolic name
of the step is EdgeFast1, and its parent Snapshot Step’s symbolic name
is Snapshot2. So, we could make the following call to DataRecordAdd:
m_RepCon.DataRecordAdd("Snapshot2.EdgeFast1.EdgePt");
Report Connections
Receiving Data with
In this case, we specified the complete path string of the Datum. If you
have the Job loaded in memory, then you could also add the Datum by
directly passing it to DataRecordAdd, like this:
//locate the fast edge step in our job
Step fastedge = m_Job.FindByName("Left Fast Edge");
//pass the EdgePt datum to DataRecordAdd
m_RepCon.DataRecordAdd(fastedge.Datum("EdgePt"));
If you don’t know the symbolic name of the Datum you want to add, and
you don’t have the Job loaded in memory, you can still add a Datum to the
result upload list by analyzing the Namespace of the Device. You would
typically need to do this when your application is simply monitoring a
running device. The following example adds the same EdgePt datum to
the report, but does so using the Namespace information.
//Tell the VsDevice object to update its namespace information
m_dev.QueryNamespace();
//Search the Namespace for all of the Fast Edge Steps
VsNameNodeCollection fedgeNodes =
m_dev.Namespace.SearchForType("Step.Edgefast.1");
//Loop through all of the Fast Edge Nodes
foreach(VsNameNode fedgeNode in fedgeNodes)
{
//is this the Fast Edge step named "Left Fast Edge"?
if(fedgeNode.UserName == "Left Fast Edge")
{
//Add the "EdgePt" datum of this Step to the Report
m_RepCon.DataRecordAdd(fedgeNode, "EdgePt");
}
}
The first option should be self explanatory, so let’s focus on the second
option. In the previous section, we explained how to add datums to your
inspection report using the DataRecordAdd method. You should
understand that the images in your Job are contained within Buffer Datum
objects and are, therefore, added to the inspection report just like any
other datum. Each Snapshot Step has an output Datum named
“SnapOutputBuffer”, symbolic name “BufOut”. This datum always holds
the most recent image acquired by the Snapshot. So, the call to include
the image from a Snapshot would look something like this:
m_RepCon.DataRecordAdd("Snapshot1.BufOut");
job: A reference to the Job Step that is currently loaded on the Device.
This function will scan the specified Job for the Inspection that you are
currently connected to. It will then find all of the Snapshot steps witin that
Inspection, and automatically add their output buffers to the report. You
must successfully connect before calling this function. If successful, the
number of snapshot output buffers added to the report is returned, 0 is
returned on a failure.
Report Connections
Receiving Data with
int AddSnapBuffers(Visionscape.Devices.VsNameNode
devNamespace)
This version scans the namespace for the Inspection you are currently
connected to, and will also add all of its snapshot output buffers to your
report. You must have successfully connected first. If successful, the
number of snapshot output buffers added to the report is returned, 0 is
returned on a failure.
AddSnapBuffers Examples
Assume you have the current job loaded into a JobStep named m_Job,
and you are connecting to a VsDevice object named m_dev. The
following example creates and connects a ReportConnection object, and
then adds all snapshot buffers to the report.
//connect to the 1st inspection on this device
m_RepCon = new ReportConnection();
m_RepCon.Connect(m_dev);
//Add all snapshot buffers in the inspection to the report
m_RepCon.AddSnapBuffers(m_Job);
control in this tab. Drag a BufferView control onto your form and rename it
to ctlBufView (refer to Chapter 6 for a complete description of the
BufferView control).
When you receive the NewReport event, the Images collection of the
InspectionReport object will contain the images from every snapshot you
added to the report. The Images property is a collection of BufferDm
objects. Visionscape always uses the BufferDm object to represent an
image buffer. The BufferView control displays BufferDms; you simply
need to set its Buffer property to the BufferDm you wish to display. The
following example shows how you would extract the first image from your
report, and display it in the BufferView control named ctlBufView in your
NewReport event handler.
//The Event handler for the NewReport event
void m_RepCon_NewReport(object sender,
ReportConnectionEventArgs e)
{
//get the Inspection report from the
//ReportConnectionEventArgs object
InspectionReport report = e.Report;
//does our report contain any images?
if(report.Images.Count > 0)
{
//extract the image as a BufferDm,
// and set it into the Buffer View
ctlBufView.Buffer = (BufferDm)report.Images[0];
}
}
If your report contains multiple images, then you would add multiple
BufferView controls to your form, and iterate through the Images
collection in order to display them all.
Performance Considerations
The ReportConnection is very flexible and can be deployed in a number
of ways to handle most application scenarios. How it is deployed depends
on your situation. In this section we list several important topics that
impact the performance of your ReportConnection, and your running
inspections. Keep these issues in mind when deciding how best to
configure your ReportConnections.
Report Connections
Receiving Data with
Lossy vs Lossless
The DropWhenBusy property governs whether or not your
ReportConnection is Lossy or Lossless. When set to true, your
connection is lossy, if false, it is lossless.
Lossy: Your report connections are “lossy” by default. This means that
you will not necessarily receive a report from every inspection cycle.
Cycle reports (represented by the InspectionReport object) may be
thrown away at the end of a cycle if your application is still busy handling
the report from the previous cycle. This prevents the Inspection thread
from being blocked while it waits for you to handle the new report, and
insures that your application will not negatively impact the speed of your
inspections. You should choose a lossy connection when you don’t need
to receive data from every inspection cycle, and it is most critical that your
application not impact the speed of your inspections.
Lossless: This means that your running inspections will NOT throw away
cycle reports when your application is busy. Your inspection will block if
your application is still busy handling the previous report. This means that
your application could cause your inspections to run slower. Choose a
lossless connection when it is critical that you receive data from every
inspection cycle, and you are not concerned with the potential impact on
the inspection speed.
Report Connections
Receiving Data with
ReportMemoryInfo Memory { get; }
A list of BufferDm objects. This collection holds all image buffers that were
added to the report, if any. The default report connection does not contain
images, so this collection will be empty unless you have added images to
the report. Refer to the previous section “Adding Images to your Report”
for a description of how to do this.
IEnumerable<InspectionReportValue> GetResults(string
typeString)
typeString: The type of datum you want to retrieve.
This method allows you to iterate through only the results that are of a
certain type. The typeString is used to specify the Datum type you want to
retrieve. The following example demonstrates how you might iterate
through only the Status datums in your result list:
foreach(InspectionReportValue val in
report.GetResults("Status"))
{
Console.WriteLine(val.Name + " : " + val.NameSym);
Console.WriteLine("Status Value = " + val.AsBool);
}
string
ReportString(Visionscape.Communications.ReportLogOptions
logOptions).
This function converts your report data into a string based on the options
you specify in the logOptions parameter. Refer to “Logging Results to
File” on page 4-14 for a complete description of the ReportLogOptions
object.
bool FileSave(string bszName)
bool FileLoad(string bszName)
Report Connections
Receiving Data with
ReportInspectionStats Object
The properties of this object provide information on the inspection you are
connected to, the cycle counts, inspection timing, overruns, buffer usage,
etc. A description of each property follows:
Contains a count of the number of Fifo Overrun errors for this snapshot.
This property returns the time in msecs spent creating graphics metafile.
Report Connections
Receiving Data with
int RatePPMMax { get; }
This property returns the maximum Inspection rate as parts per minute.
InspectionReportValue Object
This object wraps a single result in the list of uploaded results. You are
provided with properties that allow you to access the result data, its name,
its error code, etc. The result data can be of any type, including array
data, so various accessor properties are provided that will return the data
to you as the correct type, rather than just return an object type.
Gets the type of the uploaded result. This is a string which identifies the
type of datum. You can use this value to determine which of the accessor
methods you should use:
InspectionReportValue rec5 = report.Results[5];
if (rec5.Type == "Distance")
{
Console.WriteLine(rec5.AsDistance.Dist);
}
This property returns the error code of the datum. This will be 0 when the
Step ran successfully, non-zero indicates an error. In many cases, an
error will mean that the data was not updated, so you should not trust the
data if Error is non-zero.
This property returns the user name of the datum that generated this
record. Will be in the form Step.Datum.
This property returns the symbolic name of the datum that generated this
record. It will be in the form Step1.Dm.
Returns the value of the uploaded datum as a double. This property can
be used to extract the data from any result that produces a scalar floating
point value, such as Distance, Angle, Area and of course Double. A
WrongTypeException will be thrown if the result’s data is not floating
point.
Report Connections
Receiving Data with
string AsString { get; }
Report Connections
Receiving Data with
//extract the 3rd result from the InspectionReport object
//'report'
InspectionReportValue rec2 = report.Results[2];
//get the area value
double theArea = rec2.AsArea.Area;
Use this property to retrieve the result data when uploading the Blob Tree
from a Blob Step. The data is returned in the form of a ReportBlobTree
object. You can loop through all of the blobs in the tree and analyze their
contents as shown in the sample below:
if(rec.Type == "BlobTree")
{
ReportBlobTree btree = rec.AsBlobTree;
foreach(ReportBlob blob in btree)
{//The ReportBlob object provides property access to
// all blob data
double fval = blob.XCenter;
fval = blob.YCenter;
int nval = blob.Color;
fval = blob.UnrotWidth;
}
}
Use this property when you are uploading the SymResults datum from a
Data Matrix tool. It returns an array of ReportDMR objects, one for every
Data Matrix decoded by the DMR tool. The ReportDMR object provides
property access the DMR result data.
Use this property when you are uploading the SymResults datum from a
Bar Code tool. It returns an array of ReportBCR objects, one for every
Barcode decoded by the tool. The ReportBCR object provides property
access to the decoded barcode result data.
ReportMemoryInfo object:
This object provides information on the state of a remote Device's
memory. You should understand that the data in this object is only valid
when dealing with a smart camera (Vision HAWK, for example). The data
is not valid when dealing with host based devices, (GigE and Soft
Systems) as your inspections are running under Windows in that case,
and there are many Windows API calls available that will provide you with
information on the current state of PC memory. The properties of this
object provide the following information:
This property returns the size in bytes of available memory in the general
memory heap.
This property returns the size in bytes of the largest contiguous block of
memory in the general heap.
This property returns the overall size in bytes of the general memory
heap.
This property returns the size in bytes of the amount of used general
memory.
This property returns the maximum general memory used ever (in bytes).
Report Connections
Receiving Data with
Handling Reports on Separate Threads
The .NET languages make it relatively easy to create multi-threaded
programs. In general, multi-threading should be avoided unless
absolutely necessary. Issues such as thread synchronization and thread
deadlocks make your program considerably more complex than a single
threaded implementation. That being said, there are many times when a
multi-threaded approach is the best solution to performance issues. In a
Visionscape .NET application, the most likely reason you would want to
use multiple-threads would be to handle your report connections. C# and
VB.NET provide all of the functionality you need to do this. You need to
understand a couple of things:
2. If you need to display the results or images in the report, you can
NOT access the controls on your Form from your worker thread, this
is not allowed by .NET. You will need to create a delegate, and Invoke
it from your thread in order to callback to the Form on the main
thread.
Item 2 above is perhaps the most complicated issue. If you are not
displaying the contents of your reports, then you do not need to worry
about this. But most people want to display their results and images, so in
this section we will demonstrate how you might handle the NewReport
event on a separate thread, and then pass the report data back to the
owning Form on the main thread.
NewReportDelegate which we will define in our class. Our class looks like
this:
class ThreadedResults
{
//member variables
private VsDevice _device;
private int _inspIndex;
private ReportConnection _repcon;
private Thread _thread;
private bool _bConnected = false;
private ISynchronizeInvoke _owner;
public AutoResetEvent _connectComplete = new
AutoResetEvent(false);
//define the delegate that will be used to callback to
//owner form
public delegate void NewReportDelegate(InspectionReport
report,
int inspIndex);
private NewReportDelegate _notifyOwner;
//constructor takes a reference to the form and a ref
//to the callback function(delegate)
public ThreadedResults(ISynchronizeInvoke owner,
NewReportDelegate receiveResultsDelegate)
{
_owner = owner;
_notifyOwner = receiveResultsDelegate;
}
public bool Connect(VsDevice dev, int inspindex)
{
_device = dev;
_inspIndex = inspindex;
//create thread to handle our results
if(_thread == null)
_thread = new Thread(ThreadedConnect);
else
{
_thread.Abort();
}
//start the thread
_connectComplete.Reset();
_thread.Start(this);
//wait for the function to complete, so we can return
//the status
_connectComplete.WaitOne();
Report Connections
Receiving Data with
return _bConnected;
}
public void Disconnect()
{
if(_thread != null)
_thread.Abort();
if(_repcon != null && _repcon.IsConnected)
_repcon.Disconnect();
}
private void ThreadedConnect(object obj)
{
if (_repcon != null && _repcon.IsConnected)
_repcon.Disconnect();
else
_repcon = new ReportConnection();
try
{ //Connect our report connection
_repcon.Connect(_device, _inspIndex);
//wire up the delegate
_repcon.NewReport += _repcon_NewReport;
//try to add all of the snapshot buffers to our
//report
//Tell the device to update it's namespace
//information first
_device.QueryNamespace();
//now add all snapshot buffers to the report
_repcon.AddSnapBuffers(_device.Namespace);
_bConnected = true;
}
catch (Exception)
{
_bConnected = false;
}
//signal that connection is complete
_connectComplete.Set();
}
//The NewReport event. This will be received on a
//separate thread
void _repcon_NewReport(object sender,
ReportConnectionEventArgs e)
{
if (_owner != null)
{ //Pass the report back to our owning form by
//invoking the delegate that was passed in
object[]args = { e.Report, _inspIndex};
_owner.Invoke(_notifyOwner, args);
}
}
We need to create a function in our main form that matches the signature
of the NewReportDelegate delegate defined in the
ThreadedResultsClass. This function will be called whenever the thread
has a new report to be displayed. So add the following function to your
main form:
public void ReceiveResults(InspectionReport report, int
inspIndex)
{
//prevent multiple threads from coming in here
//simultaneously
lock(_synchObject)
{
if(report.Images.Count > 0)
{
BufferDm buf = report.Images[0];
ctlBufView.Buffer = buf;
}
}
}
Report Connections
Receiving Data with
_resultHandler.Connect(m_dev, 1);
Note: If you are unfamiliar with the Part Queue, see the Visionscape
FrontRunner User’s Manual for more information.
2. Use the Summary method to determine if there are any records in the
Part Queue.
3. If any, retrieve them all using the RecordGetAll method, which returns
you an InspectionReportList object, which is a list of InspectionReport
objects, which we have already covered at length.
}
}
}
}
return qSize; //return the number of records uploaded
}
Report Connections
Receiving Data with
viewer by adding a BufferView to a form (for image display) and any
controls you wish to display the results.
ReportQueueConnection Object
Let’s take a closer look at the methods and properties of this object,
starting with the Connect method:
void Disconnect()
ReportQueueSummary Summary()
InspectionReportList RecordGetAll()
Retrieves all the records in the Part Queue. They are returned in the form
of an InspectionReportList object, which is simply a list of
InspectionReport objects. Each record will contain the images, results
and stats from the inspection cycle in which it was entered into the Part
Queue. The Part Queue is cleared after this call.
Retrieves all of the part queue records in the specified range. The first
and last parameters are 0 based indexes into the queue. The records are
removed from the queue after they are uploaded.
void RecordClearAll()
Read-only. This property returns the device that the object is connected
to. Returns null if no connection.
I/O Capabilities
CHAPTER 5 I/O Capabilities
Add the following statement to the top of your C# files in order to make
access to this namespace easier (all sample code in this chapter
assumes the following statement is present):
using Visionscape.Communications;
I/O Basics
The IOConnection object allows you to interface to both Physical I/O and
Virtual I/O.
Physical I/O: Actual, physical I/O points that can be wired to an external
logic controller. The amount of physical I/O that is available is determined
by the hardware that you are using.
GigE Systems: Support Virtual I/O only. However, if you use the
Visionscape PCIe Digital I/O board, the inputs and outputs on that board
will be mapped to Virtual I/O points. This means that you can use Virtual
I/O points to read and write the physical I/O points on the Visionscape
Digial I/O board. The I/O is mapped as follows:
I/O Capabilities
//declare our global IOConnection object
private IOConnection m_IO = new IOConnection();
//Turn Virtual IO 2 on
//(if not type is specified, Virtual IO is default)
m_IO.PointWrite(1,true);
}
//this function will pulse the specified virtual IO point,
//this could be used to generate a software trigger
private void GenerateVirtualTrigger(int ioNum)
{
if(m_IO.IsConnected())
{
//turn it on
m_IO.PointWrite(ioNum, true);
//turn it off
m_IO.PointWrite(ioNum, false);
}
}
I/O Capabilities
Properties and Methods of IOConnection
bool Connect(Visionscape.Devices.VsDevice dev)
This method will connect your object to the specified VsDevice object.
Returns true if successful, false if not. Once connected, you can read and
write I/O values.
bool IsConnected()
These two functions allow you to enable or disable I/O transition events
for a range of Virtual I/O points.
bool PointRead(VsIoType ioType, int ioNum)
Reads the current state for the I/O of the specified type and index. The
ioNum parameter is a 0 based index.
bool PointRead(int ioNum)
This overloaded version of PointRead will read the current state of the
specified Virtual I/O value.
void PointWrite(VsIoType ioType, int ioNum, bool bOn)
Sets the specified I/O Point to the specified state. The type and index of
the I/O point are specified by ioType and ioNum. If bOn is true, the I/O
point is turned on, if it is false, the I/O point is turned off.
void PointWrite(int ioNum, bool bOn)
This overloaded version of PointWrite sets the specified Virtual I/O point
to the state specified by bOn.
bool[] BlockRead(int ioNum, int ioCount)
bool[] BlockRead(VsIoType ioType, int ioNum, int ioCount)
ioNum: The 0 based index of the starting I/O point.
ioCount: The number of I/O points to read.
ioType: The type of I/O to read.
The BlockRead functions allow you to read a range of I/O points all at
once. An array of Boolean values is returned that will hold the state of
each of the I/O points. One version allows you to specify the type of I/O
you want to read, while the other defaults to Virtual I/O.
void BlockWrite(int ioNum, bool[] boolArray)
void BlockWrite(VsIoType ioType, int ioNum, bool[] boolArray)
ioNum: The 0 based index of the starting I/O point.
boolArray: This is the array of Boolean values that will be written.
ioType: The type of I/O to be written.
The BlockWrite functions allow you to write a range of I/O points all at
once. You specify the starting I/O point, and a Boolean array of values to
be written. The size of the array determines how many I/O points are
written. One version allows you to specify the type of I/O you want to
write, while the other defaults to Virtual I/O.
int StartTrigger(int ioNum, int pulseInterval)
int StartTrigger(int ioNum, int pulseInterval, int pulseWidth, bool
pulseLowToHigh)
ioNum: 0 based index of the Virtual I/O point to pulse.
pulseInterval: Time in milliseconds between pulses.
pulseWidth: Time that I/O point should stay on before turning off.
pulseLowToHigh: Set to true if you want a low to high pulse, false if you
want high to low.
Stops the timer specified by the idTimer value. This is the trigger ID value
returned by the StartTrigger function.
Events
IOTransition: This event is fired when a transition has occurred on a
specific I/O point.
I/O Capabilities
Event Handler Function Signature:
void IOTransition(object sender,
IOConnectionEventArgs e)
Image Display
Controls
CHAPTER 6 Image Display Controls
Namespace: Visionscape.Display
Controls:
Start -> Programs -> Microscan Visionscape -> Tools -> Install Controls to
Visual Studio Toolbox
This will install all Visionscape controls to the Toolbox. If you prefer to only
install the controls that you need, you can always install the controls
manually by simply dragging the DLL and dropping it on the Toolbox.
Assuming you have installed Visionscape to the folder C:\Vscape, go to
the folder C:\Vscape\Assembly\Display, and find the file
visionscape.display.image.dll:
Image Display
//does our report contain any images?
Controls
if(report.Images.Count > 0)
{
//extract the image as a BufferDm,
//and set it into the Buffer View
ctlBufView.Buffer = (BufferDm)report.Images[0];
}
}
That’s all there is to it. The BufferView control also provides methods to
control the scrolling and zooming of the image. Following is a complete
list of all methods and properties provided by the BufferView control:
Gets/Sets the autozoom state of the control. When true, the control will
automatically scale the image to fit within its bounds. Set this property to
false when you want to control the zooming yourself.
long ZoomIn( )
long ZoomOut( )
Zooms the image to the specified scale factor. The scale factor is
specified by passing the numerator and denominator of the value you
wish to be applied. Has no effect if AutoZoom is true.
//turn off autozoom
ctlBufView.AutoZoom = false;
//zoom to 1/3 the size
ctlBufView.ZoomTo(1, 3);
//zoom to 3x the size
ctlBufView.ZoomTo(3, 1);
Scrolls the image such that image is displayed with the input point (x,y) at
the upper left corner of the view.
These properties get/set the current X and Y scroll position. This is the
position of the image at the upper left corner of the view.
When true, the status bar at the bottom of the control is shown. If false, it
is hidden.
Opens the specified image file and displays it in the control. This only
works with images of type TIFF and Bitmap.
The Filmstrip control can also be used to display images. It differs from
the BufferView in that it displays a running “filmstrip” of the last n images
that were displayed in the control. The images in the Filmstrip are always
Image Display
autosized, there is no ability to scroll or zoom the images as there is in the
Controls
BufferView control. The layout of the filmstip depends upon the
dimensions of the control. If you want a vertical filmstrip, make your
control tall and thin, as shown below:
If you want a horizontal filmstrip, make your control short and wide, as
shown below:
If you size the control to be more “square”, then it will display a large
version of the most recent image with a filmstrip running across either the
right or bottom edge of the screen, depending on the height to width ratio
of the control.
Just like the BufferView control, the Filmstrip displays BufferDm objects.
To add images to the Filmstrip control you simply call the NewBufferDm
method. If we added a FilmStrip control to our form named ctlFilmStrip,
we could modify our earlier BufferView example to display images in the
FilmStrip like this:
//The Event handler for the NewReport event
void m_RepCon_NewReport(object sender,
ReportConnectionEventArgs e)
{
//get the Inspection report from the
//ReportConnectionEventArgs object
InspectionReport report = e.Report;
//does our report contain any images?
if(report.Images.Count > 0)
{
//extract the image as a BufferDm,
//and add it to the FilmStrip control
ctlFilmStrip.NewBufferDm((BufferDm)report.
Images[0]);
}
}
Image Display
There is also an overloaded version of the NewBufferDm method that
Controls
takes a bool value specifying the pass/fail state of the image. The
Filmstrip will then display a green border around images that pass, and a
red border around those that fail. The pass fail state can easily be
extracted from the report data, so our earlier example could be modified
to look like this instead:
ctlFilmStrip.NewBufferDm((BufferDm)report.Images[0],
report.InspectionStats.Pa
ssed);
Displays the specified buffer datum in the filmstrip. All previous images
are shifted one position in the filmstrip.
Device Selection
Controls
CHAPTER 7 Device Selection Controls
Namespace:Visionscape.Display.Devices
Controls:
Start -> Programs -> Microscan Visionscape -> Tools -> Install Controls to
Visual Studio Toolbox
This will install all Visionscape controls to the Toolbox. If you prefer to only
install the controls that you need, you can always install the controls
manually by simply dragging the DLL and dropping it on the Toolbox.
Assuming you have installed Visionscape to the folder C:\Vscape, go to
the folder C:\Vscape\Assembly\Display, and find the file
visionscape.display.devices.dll:
Device Selection
The DeviceSelected event is raised when the user selects a device in the
Controls
list. Several properties, methods and events are provided to control the
behavior of the DeviceDropdown control.
Events:
FilterDevice: Fired before a Device is added to the list. You can apply
your own logic to prevent certain devices from being added to the list by
setting the bApproved parameter to false.
Event Handler Function Signature:
void deviceDropdown1_FilterDevice(VsDevice dev,
ref bool bApproved)
dev: The device to be added to the list.
bApproved: Set to false if you want to remove this device
from the list.
Properties:
Gets/Sets the group ID assigned to this control. This is used along with
the AutoConnect feature. This group ID will be included in the
Methods:
Returns the name of the device at the specified index in the list.
void ResetList( )
Device Selection
The ToolStripDeviceDropdown Control
Controls
The ToolStripDeviceDropdown control provides the same functionality as
the DeviceDropDown control, however it is intended for use only in
ToolStrips. This control does NOT show up in the Visual Studio Toolbox,
as it can not be dropped onto a form, it can only be used in a ToolStrip
control. When adding a control to your ToolStrip, you will see the
DeviceDropdown as one of the options:
Report Display
Controls
CHAPTER 8 Report Display Controls
Namespace: Visionscape.Display.Reporting
Controls:
IOView: Allows you to both view and set the current state of a range of
I/O points.
Start -> Programs -> Microscan Visionscape -> Tools -> Install Controls to
Visual Studio Toolbox
This will install all Visionscape controls to the Toolbox. If you prefer to only
install the controls that you need, you can always install the controls
manually by simply dragging the DLL and dropping it on the Toolbox.
Assuming you have installed Visionscape to the folder C:\Vscape, go to
the folder C:\Vscape\Assembly\Display, and find the file
visionscape.display.reporting.dll.
Report Display
InspectionReport, and then displaying it’s results in a ResultsView control
Controls
named resultsView1:
//Event handler for the NewReport event of ReportConnection
void m_RepCon_NewReport(object sender,
ReportConnectionEventArgs e)
{
After the Report property is set, the control will look something like this:
You can clear the control by setting the Report property to null.
AutoSizing Behavior:
The ResultsView control will automatically adjust it’s height to encompass
the list of results it is displaying. When you need to display the results
from multiple inspections, you can insert multiple ResultsView controls
into a .NET container control (Panel, SplitContainer, etc), set the Dock
property for each to “Top”, and the controls will be autosized and
positioned tightly up against each other. This frees you from having to
right tedious sizing and positioning code.
Properties:
Visionscape.Communications.InspectionReport Report { set; get; }
Set to true if you want the width of the grid cells to automatically be
expanded to fit the displayed data. If you set to false, the grid cells to not
change widths.
Set to true if you want the result data to be displayed in calibrated units.
This will have no effect if the inspection that produced the
InspectionReport has not been calibrated.
Report Display
int NumStatsDms { get; }
Controls
The total number of Statistic Datums being displayed in the control.
Methods:
The ResultsView control has no methods.
Once updated, the StatsView control would look something like this:
Properties:
Visionscape.Communications.InspectionReport Report { set; get; }
Methods:
The StatsView control has no methods.
Report Display
The ReportView Control:
Controls
The ReportView control combines the ResultsView and StatsView
controls into a single control, and adds a tool bar at the top to display the
inspection counts, and to allow you to show or hide either the results or
stats. So this control is intended to display all of the important report data
in a single control. You update the dislay of this control by setting it’s
Report property to an InspectionReport. This would typically be done
when responding to the NewReport event of a ReportConnection (Refer
to Chapter 4 for a full description of ReportConnections and the
InspectionReport object). In the following example, we demonstrate
handling the NewReport event, retrieving the InspectionReport, and then
displaying all of it’s relevant data in a ReportView control named
reportView1:
void m_RepCon_NewReport(object sender,
ReportConnectionEventArgs e)
{
//get the Inspection report from the
//ReportConnectionEventArgs object
InspectionReport report = e.Report;
Once updated, the ReportView control would look something like this:
The toolbar at the top displays the current inspection counts (inspected,
passed and rejected), and also provides two buttons that can be used to
show/hide the StatsView or ResultsView.
AutoSizing Behavior:
The ReportView control will automatically adjust it’s height to encompass
the list of results it is displaying, as well as the controls that your user has
chosen to show or hide. When you need to display the reports from
multiple inspections, you can insert multiple ReportView controls into a
.NET container control (Panel, SplitContainer, etc), set the Dock property
for each to “Top”, and the controls will be autosized and positioned tightly
up against each other. If your user shows or hides the stats or results in
one of the controls, the height of that conrol will automatically update, and
the positions of all other controls will then automatically adjust so that they
remain docked up against each other. This frees you from writing a lot of
tedious sizing and positioning logic.
Properties:
Visionscape.Communications.InspectionReport Report { set; get; }
Report Display
stats and results that are embedded in the InspectionReport. Set this
Controls
property to null if you want to clear the report display.
When true, results will be displayed in calibrated units. This property has
no effect if the inspection that produced the InspectionReport has not
been calibrated.
Methods:
void ClearCounts()
Sets the displayed counter values to 0. Understand that this does not
clear the counts on your Visionscape Device, it only updates the display
of the control. If you want to clear the result and stats data as well, set the
Report property to null.
The IOView control allows you to view the current state of a range of
Virtual I/O points for a particular device. Each point is represented with a
button, so you can also toggle the state of each I/O point. To use the
IOView control:
– Set the I/OFirst property to the index of the first I/O point you want
to view.
– Set the I/OCount property to the number of I/O points you want to
view.
With the above settings, the control would look something like this:
Report Display
In the above example, Virtual I/O points 11 and 13 are ON, while the other
Controls
are off. If you prefer to use different colors to signify the ON and OFF
states, you can modify them via the control properties.
Properties:
int IOFirst { set; get; }
Gets/Sets the 1 based index of the first Virtual I/O point to be displayed in
the control.
Gets/Sets the text color that is used when an I/O point is ON.
Gets/Sets the text color that is used when an I/O point is OFF.
Gets/Sets the text color that is used when an I/O point is disabled.
Methods:
bool Connect(Visionscape.Devices.VsDevice dev)
bOn: If true, the I/O point is turned ON, if false, it is turned OFF.
void Disconnect()
Disconnects the control from the device. The control will be non-functional
after this call completes.
Report Display
The IOTriggerView Control
Controls
The IOTriggerView control provides one or more sub Trigger controls that
allow you to pulse a Virtual I/O point at a specified interval. You can use
this control to simulate triggers to your Inspections. To use the control:
Once connected, you use the combo box to select the Virtual I/O point
you want to pulse, and then enter the time in milliseconds between
triggers in the text box. Press the “Start Trigger” button to start the trigger
pulses, press it again to shut the pulses off. Below is an example of the
control set up to pulse Virtual I/O point’s 3 and 6.
Properties:
int NumTriggers { set; get; }
Gets/Sets the text that is displayed in the I/O button when a trigger can be
started.
Gets/Sets the text that is displayed in the I/O button when an I/O point has
not yet been selected.
Gets/Sets the text that is displayed in the I/O button when the control is
not connected to a Device.
Gets/Sets the text color that is used when an I/O point is ON.
Gets/Sets the text color that is used when an I/O point is OFF.
Gets/Sets the text color that is used when an I/O point is disabled.
Report Display
Color ColorDisabled { set; get; }
Controls
Gets/Sets the color that is used when an I/O point is disabled.
Gets/Sets the font used to draw button text when the control is triggering.
Methods:
bool Connect(Visionscape.Devices.VsDevice dev)
void Disconnect()
bool IsConnected()
void UpdateAll()
Runtime Utility
Controls
CHAPTER 9 Runtime Utility Controls
Namespace:Visionscape.Display.Runtime
Controls:
Start -> Programs -> Microscan Visionscape -> Tools -> Install Controls to
Visual Studio Toolbox
This will install all Visionscape controls to the Toolbox. If you prefer to only
install the controls that you need, you can always install the controls
manually by simply dragging the DLL and dropping it on the Toolbox.
– Upload the Part Queue data from a running inspection, this will
produce an InspectionReportList object.
Runtime Utility
In the following example, we demonstrate how you might upload Part
Controls
Queue data, and then display it in the QueueView control named
queueView1:
//Upload the Queue from the specified inspection on the
//specified device, and display in a QueueView control
private int UploadAndDisplayPartQ(VsDevice dev, int
inspIndex)
{
int qSize = 0;
qSize = reports.Count;
}
}
return qSize; //return the number of records uploaded
}
The QueueView would look something like this when records are being
displayed:
Runtime Utility
Properties:
Controls
Visionscape.Communications.InspectionReportList Reports { set; get; }
Gets/Sets the index of the Snapshot whose images are being displayed in
the control. This is only relevant when the Inspection contains more than
one Snapshot.
Methods:
bool SaveAllImages(string strFolder,
Visionscape.Steps.EnumImgFileType
fType, bool bDisplayFirstFileName)
strFolder: The path to the folder where the images will be saved.
fType: Specifies the format in which the images should be saved. TIFF or
BMP.
InspectionSymbolicName_snapshotindex_cyclecount
Namespace: Visionscape.Display.Setup
Controls:
Start -> Programs -> Microscan Visionscape -> Tools -> Install Controls to
Visual Studio Toolbox
This will install all Visionscape controls to the Toolbox. If you prefer to only
install the controls that you need, you can always install the controls
manually by simply dragging the DLL and dropping it on the Toolbox.
Assuming you have installed Visionscape to the folder C:\Vscape, go to
the folder C:\Vscape\Assembly\Display, and find the file
visionscape.display.setup.dll.
Toolbar:
Wizard Next: Pressing this button will run the current Step, and then
move the selection to the next Step. By repeatedly clicking this button,
you can step through your inspection one vision tool at a time.
Tryout Start: Press this button to start a Tryout of your inspection. This
will run your inspection for one cycle, and then the tryout will end. Each
Step in the Job will be run in order, and it’s status will be updated in the
Setup Step List on the left side of the control. If a Step passes, a green
check mark is displayed next to it’s name, if it fails, a red X is displayed.
Tryout Stop: This button is only active when a Tryout has been started.
Press this button to stop the Tryout.
Tryout This Step: Pressing this button will run only the currently selected
Step. Its pass/fail status will be updated in the Setup Step List.
Train Step: This button is used to train the currently selected Step. It is
only enabled if the selected Step is trainable (e.g. One Pin Find,
DataMatrix tool, OCV Fontless Step, etc) and is disabled for those Steps
that do not need to be trained (Blob tool, Flaw tool, Fast Edge, etc). When
a trainable Step is selected, the background color of the button will
indicate whether it is currently trained or not. A green background means
the Step is trained, red indicates that it needs to be trained.
Live Video: Clicking this option puts the Setup Manager into Live Video
mode. If the “Use Triggers” option is enabled, and you have a trigger
assigned in your Acquire Step, then Setup Manager will wait for a trigger
before acquiring an image. If you want Live Video mode to not wait for the
trigger, click on the Tryout and Acquisition options button, and turn off the
“Use Triggers” option.
Zoom In/Out Buttons: Use these buttons to zoom the current image
either in or out.
Zoom Auto: Automatically zooms the image so that it fits within the
current image view.
Displayed on the left side of the control, this is a flat list of all the Steps in
your Job that may need to be set up. This list will not contain all of the
Steps in your Job, only those that have an ROI (region of interest) and
those that have a Status that you might want to watch when running
tryouts (like the IF step, VarAssign step, Digital Output Step, etc).
Selecting a Step in this list will also cause it to be selected in the Image
View and in the Datum Grid View. When running Tryouts, a check mark
will be displayed next to each Step in this list that passes, and a red X will
be placed next to those Steps that fail.
Image View:
Displayed at the top right of the control, this is where you will view your
images. The ROI (region of interest) for each Vision tool in the currently
selected Inspection will be displayed here as well. You can reposition any
ROI by clicking and dragging, and you can resize them by grabbing the
control points on the corners of the ROI, and dragging. Selecting any ROI
Datum View:
Displayed at the bottom right of the control, the Datum View displays the
list of parameters for the currently selected Step. You would come here to
adjust the performance of your vision tools.
AllowMouseToolInsertion:
Allow tools to be inserted into the job by clicking and dragging in the
image view. On by default.
AutoRegenerate:
When set, Steps will be automatically run whenever you adjust their ROI
size or position, or when you change a parameter in the Datum View. On
by default.
AutoRetrain:
AllowContextMenu:
When the user right-clicks on the Image View, a context menu will pop-up
providing various options. Clear this bit to disable the context menu. This
is on by default.
EditGraphics:
RunGraphics:
AllowToolMovement:
On by default, clear this bit if you want to disable the movement of tools in
the Image View.
ShowDatumGrid:
Set this bit to show the Datum grid view, clear it to hide it. On by default.
ShowDatumGridOnRight:
Set this bit to position the Datum grid view on the right side of the control,
rather than at the bottom. This bit is off by default.
ShowStepTree:
Set this bit to show the Step Tree view of the Job. This bit is ff by default.
ShowToolbar:
Clear this bit to hide the toolbar, which is shown by default. You would
hide the toolbar when you want to create your own.
ShowView:
Clear this bit if you want to hide the image view. On by default.
ShowItemList:
Clear this bit if you want to hide the Setup Step List. On by default.
ShowStatusbar:
Clear this bit if you want to hide the status bar at the bottom of the control.
On by default.
ShowInspErrorStatusbar:
ShowBufStatusbar:
Clear this bit to hide the status bar that is show at the bottom of the Image
View. On by default.
This set of options provides you with a view that can be used to edit the
Job.
This set of options allows you to edit the Job, and also see the image at
the same time.
Rather than have to perform complex bit math on this property, you can
use the OptionLayoutSet function to turn options on or off. Following are
some examples:
//use the standard layout
ctlSetup.OptionsLayout =
SetupManagerLayoutOptions.DefaultLayout;
//hide the toolbar
ctlSetup.OptionLayoutSet(SetupManagerLayoutOptions.ShowToolb
ar, false);
//hide the Setup list, and instead show the Step Tree
ctlSetup.OptionLayoutSet(SetupManagerLayoutOptions.ShowItemL
ist, false);
ctlSetup.OptionLayoutSet(SetupManagerLayoutOptions.ShowStepT
ree, true);
//show the Datum Grid on the right side of the control,
//rather than the bottom
ctlSetup.OptionLayoutSet(SetupManagerLayoutOptions.ShowDatum
GridOnRight, true);
DoAcquire
When set, a new image will be acquired when a Tryout is run. Clear this
bit if you want to run on the current image and not acquire a new one.
This bit is on by default.
UseTriggers
When set, an Acquire operation, Live Video and Tryouts will stop on all
Snapshots on which a Trigger has been assigned. It will block and wait for
a trigger before acquiring an image and running the rest of the Steps. This
is useful when a part can not be placed stationary in front of the camera.
This bit is off by default.
UseIO
Similar to UseTriggers, but when this option is set, Tryouts will block on
any Digital Input Steps that have their “Data Valid Signal I/O” values
assigned to an I/O point. This option is off by default.
TackImage
When running a Tryout, Setup Manager will always update the Image
View to show the parent buffer of the current Step that is running. Set this
bit when you want the control to just show the current buffer. This bit is off
by default.
DefaultOptions = DoAcquire
This will set the control to the default options, which is currently to have
just the DoAcquire bit set.
Acquisition Methods:
In this section we’ll describe the methods that allow you to start and stop
image acquisitions and live video.
Note: While an asynchronous acquisition is active, you can not start live
video or a tryout.
private void frmMain_Load(object sender, EventArgs e)
{
//wire up our event handler when the app starts up,
//so we can receive AcquireDone notifications
ctlSetup.StateChanged += ctlSetup_StateChanged;
}
UpdateButtons();
}
UpdateButtons();
}
You must call LiveVideoStop to exit live video mode. While live video is
active, you can not run a tryout, or start an acquisition.
//Stop live video
ctlSetup.LiveVideoStop();
To check if live video is currently active or not, you can check the “Can”
property of SetupManager.
//if we "can" start live video, it's not currently on
if (ctlSetup.Can.LiveVideoStart)
{
}
//if we "can" stop live video, that means it is currently on
if(ctlSetup.Can.LiveVideoStop)
{
}
Tryout Functionality:
SetupManager provides several methods that allow you to “Try out” your
inspection(s). When we say tryout, we mean to run your inspection for the
purposes of debugging and or testing. Running your inspection in tryout
mode is not as fast as running in a full fledged run-mode, so you should
never use the tryout functionality to run your inspections on the factory
floor. When you start a tryout, each Step in the Setup List is run
sequentially, and a green check mark is placed next to those Steps that
You can run the current Step by simply calling the TryoutCurrentItem()
method:
ctlSetup.TryoutCurrentItem();
This will run the currently selected Step, update it’s run graphics in the
image, and update the pass/fail status of the Step in the Setup List by
displaying a green check for a pass, and a red X for a fail. This is an
asynchronous method, meaning it will start the run of the selected Step,
and immediately return. The StateChanged event will be sent with the
TryoutDone notification when the run is complete.
When you are building and testing a vision inspection, it is typical that you
will want to run all of the Steps in the inspection for one cycle to see how it
is performing. There are two ways that you can do this.
1. Call the TryoutStart() method, and specify you want to run for 1
iteration.
To run your inspection continuously in a loop, you simply need to call the
TryoutStart() method, specifying nothing for the number of iterations.
ctlSetup.TryoutStart();
This will run your inspection until you call the TryoutStop() method as
shown in the example above.
As demonstrated earlier, you can also use this property to tell you if Live
Video is currently active. The LiveVideoStop property will only be true
when live video has been turned on, so if you needed to make sure that
Live Video was off before performing some action, you could do the
following:
//if live video is On, turn it off
if (ctlSetup.Can.LiveVideoStop)
ctlSetup.LiveVideoStop();
Console.WriteLine("Aquisition is complete");
break;
case StateChangedEvents.AcquireStarted:
Console.WriteLine("Aquisition has been started");
break;
case StateChangedEvents.LiveDone:
Console.WriteLine("Live Mode has exited");
break;
case StateChangedEvents.LiveStarted:
Console.WriteLine("Live Mode started");
break;
case StateChangedEvents.TryoutDone:
Console.WriteLine("Tryout is complete");
break;
case StateChangedEvents.TryoutStarted:
Console.WriteLine("Tryout has been started");
break;
case StateChangedEvents.WizardNext:
Console.WriteLine("User pressed Wizard Next button");
break;
case StateChangedEvents.WizardPrev:
Console.WriteLine("User pressed Wizard Previous
button");
break;
}
}
Properties:
SetupManagerCan Can { get; }
Returns true if the currently selected Step can be untrained. This typically
only applies to Data Matrix tools.
List<SetupItem> ItemList
Returns a List of all of the items in the Setup List. Each item is
represented by a SetupItem object, which has properties identifying the
Step for this item, as well as the next Step and the previous Step in the
list.
Gets/Sets the size of the splitter pane in which the List View is contained.
ShowToolbar: Clear this bit when you want to hide the toolbar and
create your own.
Gets/Sets a bitfield that controls how Tryouts and Image acquisitions are
performed. Multiple options can be combined. The available options are
represented by the values in the SetupManagerTryoutOptions enum,
which has the following fields:
DoAcquire: When set, a new image will be acquired everytime you run a
Tryout. Clear this bit if you want to run a tryout repeatedly on the current
image. This bit is on by default.
UseTriggers: When set, tryouts, acquire and live video will all wait for a
trigger (if one is set in the Snapshot) before acquiring an image. Clear
this bit if you don’t want to wait for triggers before acquring an image.
This bit is off by default.
UseIO: Similar to UseTriggers, but this only effects Tryouts, and will
cause you to block on DigitalInput Steps that have an I/O point assigned
to their “Data Valid Signal I/O” datums. Off by default.
Use this property to connect the SetupManager control to your Job. You
will typically set the RootStep property to one of the Inspection Steps in
your Job, though you may also connect to the VisionSystem Step or a
Snapshot Step. Once you have assigned a Step to this property,
SetupManager will update itself, and you will be ready to acquire images,
run tryouts, adjust job parameters, etc.
Methods:
bool Acquire()
bool AcquireActive()
bool AcquireStart()
bool LiveVideoStart()
Puts SetupManager into Live Video mode, and then returns immediately.
Returns true if able to start Live Video, false if not. Images will be
acquired and displayed as fast as possible, all other operations will be
disabled while Live Video is active, i.e., you can’t run tryouts or call one of
the Acquire methods while Live Video is active. Call LiveVideoStop to exit
Live Video mode.
bool LiveVideoStop()
Checks the Options bitfield property to see if the specified option is on,
and returns true if so, false if not.
Returns true if the specified tryout option is currently turned on, false if it is
not.
SetupManagerTryoutOptions
OptionTryoutSet(SetupManagerTryoutOptions op,bool bSet)
bool SelectNextItemInList()
bool SelectPrevItemInList()
void TrainCurrentItem()
Trains the currently selected Step. Has no effect if the currently selected
Step is not trainable.
Performs a tryout on the currently selected Step. This will cause the
current Step to run, as well as any other Steps that it is dependent upon.
bool TryoutOneCycle()
Starts an asynchronous tryout operation that will run all of the Steps in the
Setup List for one cycle and then stop. The tryout is started, and then
control is immediately returned to you. Returns true if the tryout was
successfully started. You will receive the TryoutIterationDone event as
well as a StateChanged event when the tryout is complete. The event
handler for the StateChanged event will be passed a
StateChangedEventArgs parameter, and the StateChangedEvent
property will be set to TryoutDone.
The pass/fail status of each Step will be displayed in the Setup List (green
check for pass, red X for fail). All other operations are not allowed while a
Tryout is in process, i.e., you can’t call one of the Acquire methods, or
start Live Video.
bool TryoutStart()
Starts an asynchronous tryout operation that will run all of the Steps in the
Setup List repeatedly until TryoutStop is called. The tryout is started, and
then control is immediately returned to you. Returns true if the tryout was
successfully started. You will receive the TryoutIterationDone event after
each completed cycle. When the tryout is stopped by a call to TryoutStop,
you will receive the StateChanged event when the tryout is fully stopped.
The event handler for the StateChanged event will be passed a
StateChangedEventArgs parameter, and the StateChangedEvent
property will be set to TryoutDone.
The pass/fail status of each Step will be displayed in the Setup List (green
check for pass, red X for fail). All other operations are not allowed while a
Tryout is in process, i.e., you can’t call one of the Acquire methods, or
start Live Video.
bool TryoutStop()
void UntrainCurrentItem()
Untrains the currently selected Step. This currently only applies to Data
Matrix tools.
bool WizardNext()
Runs the current Step, then selects the next Step in the list.
bool WizardPrev()
Changes the selection from the currently selected Step the previous Step
in the list.
void ZoomAuto()
Puts the ImageView into Auto Zoom mode. This will automatically zoom
the image so that it fits entirely within the visible area.
void ZoomIn()
void ZoomOne()
void ZoomOut()
Events:
DatumChanged
DatumSelected
Fired whenever the user selects a datum in the Datum View. The selected
Datum is specified in the DatumEventArgs parameter.
JobChanged
Fired whenever the job is modified. How the job was modified is identified
by the JobChangedEventArgs parameter, which has a JobChangedEvent
property of the type JobChangedEvents. This enum has the following
possible values:
RootStepChanged
ToolInserted
ToolMoved
ToolToBeDeleted
ToolTrained
LayoutChanged
OptionsChanged
StateChanged
StepSelected
Fired whenever the selected Step is changed. The newly selected step is
specified in the SelectionChangedEventArgs parameter.
TryoutIterationDone
TryoutOptionsChanged
ZoomEvent
Fired whenever the user zooms in or out, or changes the zoom mode to
Auto or 1 to 1 mode.
The StepTreeEditor control allows you to view your Job in its hierarchical
tree structure, and to add or remove Steps. So you would use this control
when you want to allow your users to edit their Jobs. To use this control
you simply connect its RootStep property to one of the Steps in your Job.
The StrepTreeEditor will then display the RootStep and all of the children
beneath it. You would typically connect the RootStep to either your
JobStep or to one of the VisionSystemSteps in your Job. Assuming we
had a JobStep variable named _job, we would connect the
StepTreeEditor to it like this:
//Connect our StepTreeEditor to our JobStep
ctlStepTree.RootStep = (Step)_job;
When the user selects a Step in the tree, all of the Datums for that Step
are displayed in the DatumView on the right side of the control. You can
hide the DatumView if you wish using the ShowDatums property.
The user can add or remove Steps by right-clicking on the tree. This will
bring up a context menu that provides options to insert into, before or
after the current Step. Selecting one of these options will cause the “Insert
Step” dialog to be displayed. This dialog allows the user to select which
type of Step they want to add to their Job. Once the Step type is selected,
and OK is pressed, the new Step is added relative to the currently
selected Step. If Insert Into was chosen, the new Step is inserted into the
selected Step (always at the end of the child list). If Insert Before or Insert
After are chosen, the new Step is inserted immediately before or after the
selected Step. The context menu also allows you to rename the current
Step, or delete the current Step.
Properties:
Visionscape.Steps.Step RootStep { set; get; }
Connect the StepTreeEditor to your Job using this property. When this
property is set, the control will update to display this Step as the root of
the tree, with all of its child Steps displayed hierarchically beneath it. You
would typically set the RootStep to either your JobStep or to a
VisionSystemStep.
Set to true if you want the Datum View to be displayed, set to false if you
want it hidden.
Gets/sets the distance in pixels from the left edge of the control to the
splitter that separates the tree from the Datum View.
Methods:
void EditStep(Visionscape.Steps.Step step)
Connects the control to the specified Step. This is identical to setting the
RootStep property.
Starts an Insert Step opertation. This causes the “Insert Step” dialog to be
launched, which allows your user to select the type of Step they want to
insert. The selected Step will then be created and added to the Job
relative to the currently selected Step. Where the newly added Step is
inserted depends on the option parameter. The option parameter is of
type InsertStepOption, which provides 3 options.
void RefreshTree()
Forces the control to rebuild and redisplay its tree. You might call this if
you are modifying the Job programmatically outside of the
StepTreeEditor, and want to force your changes to be seen in the tree.
Events:
DatumChanged
Fired whenever the user changes a Datum value in the Datum view. The
Datum that was modified, and its owning Step, are passed to your event
handler.
DatumSelected
Fired whenever the user selects a Datum in the Datum view. The Datum
that was selected, and its owning Step, are passed to your event handler.
StepInserted
Fired whenever a new Step is inserted into the Job. A reference to the
newly inserted Step is passed to your event handler.
StepRenamed
StepSelected
Getting Started
– Launch Visual Studio 2008.
– Go to the View menu and select “Toolbox”. This will show the
toolbox panel on the left-hand side of the window. If Visual Studio
2008 was installed on your PC when you installed Visionscape,
then you should have a tab named “Visionscape”, and it will
contain all of the visual components provided by Visionscape. If
you don’t have this tab, you can run the InstallCtrlsToToolbox.bat
utility to install them.
Jobs
– Change the name of “Form1.cs” in your Project to “frmMain.cs”
Jobs
Go to the frmMain code window. At the top of the file, we will add the
following “using” statements for the various Visionscape namespaces we
will be accessing:
using Visionscape;
using Visionscape.Steps;
using Visionscape.Devices;
using Visionscape.Communications;
At the top of the frmMain class, add the following member variables:
public partial class frmMain : Form
{ /////////////////////
//CONSTANTS
const int RESULTS_ROW = 6;
//////////////////////
//MEMBER VARIABLES
//VsCoordinator tells us what hardware is available
VsCoordinator m_Coord;
VsDevice m_Dev; //will hold a ref to the chosen Device
JobStep m_Job; //A JobStep loads and saves AVPs
VisionSystemStep m_VS; //the VisionSystem step
//We will use this object to receive images and results
//from the inspection
ReportConnection m_repcon;
//reference to the most recent inspection report
InspectionReport m_report;
//We will use this to save/restore application settings
Properties.Settings m_appsettings;
Application Startup
When our application starts up, we will load one of the Sample Jobs that
is installed with Visionscape. We will connect it to the Software System in
your PC (always created) and then prepare it to run. In frmMain’s Load
event, we will need to do the following:
Add an event handler for frmMain’s Load event, and add the following
code:
private void frmMain_Load(object sender, EventArgs e)
{
//instantiate our coordinator and Job Step
m_Coord = new VsCoordinator();
m_Job = new JobStep();
try
{
//load the sample AVP
m_Job.Load("C:\\Vscape\\Tutorials and samples\\
Sample Jobs\\Wrench
Gauge\\example_wrenchgauge.avp
");
//Now get a reference to the Software system
m_Dev = _coord.FindDeviceByName("SoftSys1");
}
catch (Exception ex)
{
MessageBox.Show("Exception thrown while starting up:
" + ex.Message);
this.Close();
}
}
Jobs
Add the ConnectReport function that we are calling from frmMain_Load.
This function will instantiate our ReportConnection, connect it to our
device, and configure it to upload images.
private void ConnectReport()
{
//Create a report connection
m_repcon = new ReportConnection();
//Connect it to the first inspection on our device
m_repcon.Connect(_device, 1);
Handling Reports
Now that we can receive reports, in this section we will add the code to
handle them. Our NewReport event handler will receive an inspection
cycle report, and we will then display the first image in our BufferView
control, and display the inspection data in our ReportView.
//This event will be received after every inspection cycle
void _m_repcon_NewReport(object sender,
ReportConnectionEventArgs e)
{
InspectionReport report = e.Report;
ctlReportView.Report = report;
}
Jobs
This application is obviously not production level, but it hopefully
illustrates the fundamentals involved with creating a Visionscape runtime
user interface. If you would like to look at a more complete sample, look at
the two samples that are installed with VsKit.NET
LoadAndRun:
This sample is a basic runtime user interface that provides the following
features:
• Provides a toolbar that lists all available devices, and allows you to
choose the device you want to work with.
• Provides a toolbar button that allows you to load any AVP file to your
chosen device. This illustrates the cleanup that is required when
switching from one job to another.
LoadRunAndSetup: