You are on page 1of 45

CGTech Post-Processor

Help

Table of Contents
CGTECH POST-PROCESSOR HELP
INTRODUCTION TO THE CGTECH POST-PROCESSOR ................................. 4
POST-PROCESSOR LANGUAGE ...................................................................... 6
Post-Processor Language Files .........................................................................................6
Statements, Continuations and Comments ..................................................................7
Continuations .........................................................................................................................................7
Comments..............................................................................................................................................8

Variables ....................................................................................................................10
Variables .................................................................................................................................. 10
Numbers ..........................................................................................................................................11
Strings .............................................................................................................................................11
Mixing.............................................................................................................................................11

Registers ................................................................................................................................... 12
Properties.........................................................................................................................................13

Reserved Variable Names........................................................................................................... 15


Numbers ..........................................................................................................................................15

Strings ...................................................................................................................................... 16
Registers ................................................................................................................................... 16
Language Keywords .................................................................................................................. 17

Functions.....................................................................................................................18
Math Functions.....................................................................................................................................18

String Manipulation ................................................................................................................... 19


Register Related ........................................................................................................................ 20
Input Related............................................................................................................................. 20
Output Related .......................................................................................................................... 21

Subroutines..................................................................................................................22
Before & After .....................................................................................................................................23

Calls ......................................................................................................................................... 25

Assignment and Operators .............................................................................................27


Assignment ..........................................................................................................................................27
Arithmetic Operators.............................................................................................................................27

String Operators ........................................................................................................................ 28


Logical Operators ...................................................................................................................... 28

Branching ....................................................................................................................30
If ... Then ... Else ..................................................................................................................................30
Select ... Case .......................................................................................................................................31

Looping.......................................................................................................................33
For ... Next...........................................................................................................................................33

Do ... Loop...........................................................................................................................................33
While ... Wend .....................................................................................................................................34

Post-Processor Output ...................................................................................................35


Post-Processor Debugging .............................................................................................39

PROBE CYCLE PROGRAMMING .................................................................... 40


Introduction .............................................................................................................................. 40
#Init.......................................................................................................................................... 40
#End......................................................................................................................................... 41
#Rapid ...................................................................................................................................... 41
#Move ...................................................................................................................................... 42
#Approach ................................................................................................................................ 43
#Retract .................................................................................................................................... 43
#Cycle ...................................................................................................................................... 44
#Save ....................................................................................................................................... 45

Introduction to the CGTech Post-Processor


A CAM system generates toolpaths that are largely independent of the machines that will
be used to manufacture a design. The syntax, or language, of these toolpaths is typically a
variant of APT CL. The machine controllers require files with a different syntax, often
referred to as machine code or G-Code. The purpose of an NC post-processor is to
convert the machine independent toolpaths to G-Code files.
An early strategy for creating post-processors was to have a tailored program for each
machine/control combination needed. Such a program required no input from the user
other than the machine independent toolpath files. But development of these postprocessors was time consuming and maintenance of a full suite of them quickly became a
nightmare in large organizations.
The next step in the evolution of post-processors was the "generalized post". With this
approach a single program would access a file of parameters for a given machine/control
combination, then process machine independent toolpaths according to the values and
settings of the parameters. As machines became more complex and controllers
correspondingly more capable, the parameter files grew rapidly from a few flags and
limit values to a very complex set of inter-related choices. Effectively the parameter files
were required to express some logic handling abilities.
So the next required evolutionary step became clear. The machine/control parameter files
were enhanced with the syntax of their own language, so that they could express the
complex logic required for modern machines and controls. The post-processor program
became simpler as the language got more powerful, so that now the principal role of the
post-processor is to interpret the language.
Unfortunately post-processor technology has not matured to the point that there is just
one language for describing how to convert machine independent toolpaths to G-Code.
Each post-processor vendor requires a different syntax and language. The language of the
CGTech Post-Processor borrows heavily from the syntax of BASIC (Beginner's Allpurpose Symbolic Instruction Code).
Why BASIC? The CAD/CAM world doesn't need another new language, so why not
BASIC? There is an inherent danger in borrowing the syntax of an established generalpurpose language for a specific task. Users who are familiar with the language can be
irritated by minor departures from the "standard". On the other hand, the fact that there
are users who don't have to learn the language from scratch, is a big plus. We have
attempted to minimize departures from BASIC syntax as much as possible. Where there
are extensions, we have borrowed from Visual-Basic's syntax.
The post-processor reads a machine independent toolpath, usually in some flavor of APT
CL, and processes one statement at a time. A statement can span several lines of the input
file. For each statement it invokes a "Sub" or subroutine which is a section of a
nominated machine/control dependent language file. Which "Sub" gets called depends on
the statement's major word. If there is no "Sub" for a particular major word, nothing
happens and no error message is generated. More typically the "Sub" will format a GCode line or lines, for output to a machine dependent toolpath and a log.

If you are new to the CGTech Post-Processor, it is suggested that you browse the PostProcessor Language topics in the order they are presented. If you are already familiar
with the language and only need to apply it to VERICUT's Inspection Programming
capabilities, you could jump directly to the Probe Cycle Programming topic.

Post-Processor Language
Post-Processor Language Files
The file that contains all of the post-processor language to define how machine
independent toolpaths are to be converted to G-Code files for a single machine/control
combination, is often incorrectly referred to as a "Post". It is the logic embedded in such a
file, together with the CGTech Post-Processor program that performs the processing task,
but we have no intention of fighting the nomenclature.
A "post" file must contain all the language needed for a machine/control combination. It
cannot make reference to other language files, even for subroutines that are common to
many machine/control combinations. Each subroutine needed must be present in the
single file that will be accessed by the CGTech post-processor. The default file extension
for a "post" file is ".VcPost".
A VcPost file is typically encoded with ASCII. The language does not require the use of
any non-ASCII characters, but if a user needs to generate comments in the output GCode, or in the post-processor's log, with accented vowels or Eastern languages, a VcPost
file can be encoded with UTF-8 or Unicode. Any suitable text editor can be used to create
and maintain VcPost files. A word-processor can be used if you take great care to avoid
saving the files with any formatting information. The text editor embedded in VERICUT
is viable.
It is strongly recommended that you follow good programming practice in terms of
indenting blocks of logic to make the code more legible. Recognizing that we haven't yet
explained any of the language's syntax, the following snippet may make it clear what is
meant by indenting.
Sub GOTO
If (G = 0) Then
If (Z < Z.Previous) Then
Out "<N><G><X><Y>"
Out "<N><G><Z>"
Else
Out "<N><G><Z>"
Out "<N><G><X><Y>"
End If
Else
Out "<N><G><X><Y><Z><F>"
End If
End Sub

Statements, Continuations and Comments


Elements of the post-processor language are organized in statements to create a VcPost.
Very often a statement and a line of the file are the same thing. Using a piece of the same
code snippet from the previous page to illustrate this, still without any explanation of the
contents of the statements, ...
If (Z < Z.Previous) Then
Out "<N><G><X><Y>"
Out "<N><G><Z>"
Else
Out "<N><G><Z>"
Out "<N><G><X><Y>"
End If
... has seven statements. Many programming languages use a particular character to
denote the end of a statement, such as the semi-colon in C and Java. This is not the case
in BASIC, nor in our post-processor language. The end of a statement is the end of the
line, unless the rightmost pair of characters indicate a continuation.
Continuations

The continuation characters are a space followed by an underscore, " _". It is easy to
think of the underscore alone as being the continuation character, but an underscore can
be used at the end of a variable name, such as "Radius_". We are not recommending this
because it would make the code more difficult to read. But if a name like this appeared at
the end of a line, the post-processor would treat the next line as the first of another
statement. An underscore which is intended to signify a continuation of the current line's
statement should be separated from the rest of the characters by at least one space. For
example;
Radius = squareRoot((X.Current - X.Previous) ^ 2 _
+ (Y.Current - Y.Previous) ^ 2)
Trying to split a function name or variable name between two lines of a statement is a
bad idea. It makes the code hard to read, and won't work. We haven't covered the topic of
string constants yet, but they consist of any characters between double-quotation marks.

"Any" includes the underscore character, so a single string constant cannot span two lines
of a statement. It is necessary to split the string into two or more, and concatenate them as
follows;
Sentence = "The quick brown fox jumps" _
& " over the lazy dog."
Strictly it is not necessary to use continuation characters at all. There is no practical limit
on the length of a line of code. But it makes sense to restrict lines to the width that can be
displayed by your text editor without having to scroll horizontally.
Comments

A comment can be appended to any line of code, simply by adding a single-quotation


mark and any characters for the comment.
Radius = 0.5 * Diameter 'This is a comment
It is also possible for a line to contain nothing but a comment, and this may well be the
better style to adopt for legibility.
' This line is just a comment
Radius = 0.5 * Diameter
A line with the continuation characters can also end with a comment, but this really gets
ugly because it makes it more difficult to see the continuations.
Sentence = "The quick" _ 'This sentence
& " brown fox" _ 'contains all
& " jumps over" _ 'the letters of
& " the lazy dog." 'the alphabet
It would be much better to give the comment its own line.
' This sentence contains all the letters of the alphabet
Sentence = "The quick brown fox jumps over the lazy dog."

While you can append comments to continued lines, it is not possible, nor necessary, to
split extensive comments into continuation lines. Since a comment can contain any
characters, a space and underscore on the right end will not cause the next line to be
treated as a continuation. If you need a multi-line comment, just use several individual
comment lines.

' Check for RAPID and perform horizontal or vertical


'
moves, or vice versa, to "square" the motion.
No other syntax to denote a comment is supported. In particular the "Rem" style that
appears in some flavors of BASIC cannot be used.

Variables
Variables
There are just three types of variable in the post-processor language; numeric values, text
strings and an object analogous to a control's register that has both numeric and text
properties. We will refer to these three variable types as simply numbers, strings and
registers. There is no boolean variable type.
Variable names can be any combination of letters of the alphabet, numerals and the
underscore character, but must begin with a letter. There is no practical limit to their
length, so you can make them very descriptive. Names are case insensitive, so "radius",
"Radius" and "RADIUS" are synonyms. This slack attitude also applies to reserved words
in the language such as "If", "Then" and "Else", and also to subroutine and function
names. There are two schools of thought when it comes to compound names. One uses
uppercase for the first letter of each word, such as "CircleRadius", while the other
separates the words with an underscore, such as "circle_radius". We suggest that you pick
a style and stick with it. Having both in the same VcPost would be an invitation to bugs,
since "CircleRadius" and "circle_radius" are not synonyms.
Unlike BASIC, the post-processor language has no declaration statements, such as
"Dim". There are no arrays. We will leave the topic of registers for a while, but if the
following statements are the first to be executed that refer to "Radius" and "Tool", then
their types will be number and string respectively.
Radius = 0.125
Tool = "Drill"
Once a variable has been defined, its type cannot be altered. So
Tool = 5
would generate an error if it followed the prior lines.
This may not mean much yet, but also unlike BASIC, all variables are global in scope. If
you define a variable in one segment of your VcPost file, it is accessible from all others,
without the need to pass it as an argument between subroutines.
Variable names must be unique across all variable types, so you cannot have a number
and a string both called "Turret". There are reserved variable names which you must
avoid using for anything but their intended purpose.

10

Numbers

A number variable retains a 64bit precision numeric value. 64bit precision is good for
about 15 significant decimal digits. There is no distinction between fixed point values,
sometimes called integers, and floating point values, sometimes called floats or doubles.
Numeric constants can use integer, decimal or scientific notation. Thus the following are
all valid; 2, +3, -4, 1.625, -3.75, 1.E6, 2.25e-3, -4.125E+3. Note that embedded spaces in
a numeric constant are a bad idea. Use of a thousands separator, as in "1,000,000" would
not produce the desired result.
If you want to format a number variable for output, it should instead be defined as a
register. There are numerous functions for performing mathematical operations on
number variables.
Strings

A string variable retains a sequence of characters. There is no practical limit on the


number of characters. A string constant is a sequence of characters enclosed by doublequotation marks.
Sample = "This is a sample string constant."
If a string constant needs to contain a double-quotation mark, then two such marks should
be used. For example;
Exclaim = """Hey!"", he said, ""Get off!"""
There are many functions for manipulating string variables.
Mixing

Number and string variable types cannot be mixed in arithmetic, string concatenation or
logical expressions. Thus if "Radius1" and "Radius2" are defined by;
Radius1 = 3.5
Radius2 = "1.25"
then any of the following statements will generate an error;
Sum = Radius1 + Radius2
Range = Radius1 & " to " & Radius2
If (Radius1 > Radius2) Then

11

Registers
A register is analogous to a control or machine register. It contains current and previous
floating point numeric values. It also carries information on how its current value is to be
formatted in a G-code file and the post-processor log. The numeric values are limited to
lie in a range, either dictated by the number of digits in the formatting, or specified by
tighter constraints. A scale can be applied to the current value prior to formatting.
Syntactically a register is treated like an Object in Visual Basic. It has several properties
but no methods. Samples of the properties and syntax used to access them are;
X.Prefix = "X"
X.Format = "s3.3sm"
X.Minimum = -499.999
X.Maximum = 500
If (X.Scale < 0) Then
DeltaX = X.Current - X.Previous
Message = "Set vernier to " & X.Output
A new variable is defined as a register as soon as the variable name is encountered with a
trailing period. Many registers are predefined and have reserved names, such as X, Y and
Z for the first 3 machine axes.
To shorten code and perhaps make it more comprehensible, a register variable name can
appear without a trailing period. If it appears in an arithmetic expression, an unqualified
register name implies its .Current property, thus the following lines of code have the
same effect;
Diameter = 2.0 + Z
Diameter = 2.0 + Z.Current
If an unqualified register name appears where a string is expected, such as in
concatenation, its formatted .Output property is assumed. So the following lines of code
have the same effect;
Message = "Raise to " & Z & " now."
Message = "Raise to " & Z.Output & " now."
There is one function of note for use with registers;
Zap R
will reset the previous value of register R to an undefined state. This is useful for a modal
12

register when it is necessary to force output of the current value even when it may not
have changed, perhaps after a tool change.

Properties

Description
Name Type
Current number Current value of the register.
Format

Access
Read/Wri
te
Read/Wri
te

string {+}{s}#{.|,}#{s}{m|i}
y optional "+" is for plus sign
preceding positive value.
y first optional "s" is to suppress
leading zeros.
y first "#" is maximum number of
leading digits.
y optional "." or "," is decimal point
character Other characters are
unusual but permitted.
y second "#" is maximum number of
decimal places.
y second optional "s" is to suppress
trailing zeros.
y optional "m" is for a modal value,
which will only be output when it
has changed.
y optional "i" is for an incremental
value, which will always be output
when it is non-zero. "m" and "i" are
mutually exclusive.
Format characters are case insensitive.
Incremen number Increment to be applied to Current value
Read/Wri
each time the register is output.
t
te
Normally only non-zero for the sequence
number register, N.
Restricted to be a fixed-point value.
Maximu number Maximum value that register can attain.
Read/Wri
If not defined explicitly, will be implied by
m
te
the number of leading and trailing digits in
the Format.
Minimu number Minimum value that register can attain.
Read/Wri
If not defined explicitly, will be implied by
m
te
the number of leading and trailing digits in
the Format.

13

Output

string Formatted current value.

Prefix

string Prefix used in formatted output.


For example, "X" for the X register.
Previous number Previous value of the register.
Scale

14

number Scale to be appled to value before


formatting.
Can be used to adjust units or to reverse an
axis.

Read
Only
Read/Wri
te
Read/Wri
te
Read/Wri
te

Reserved Variable Names


Numbers

Description
Name
ArcRadius Radius of current arc.
ClearRetract Default clearance plane retract distance.
HomeRetract GOHOME retract distance. Zero if GOHOME without axis minor
words should use FROM point.
NurbsKnot Cumulative value of NURBS knot at current point (CATIA style
NURBS only).
NurbsOrder Order of current NURBS.
NurbsWeigh Weight for current NURBS control point.
t
PathX
Current X coordinate transformed by toolpath matrix.
PathY
Current Y coordinate transformed by toolpath matrix.
PathZ
Current Z coordinate transformed by toolpath matrix.
PathI
Current I coordinate transformed by toolpath matrix.
PathJ
Current J coordinate transformed by toolpath matrix.
PathK
Current K coordinate transformed by toolpath matrix.
PathCenterX Current X coordinate of arc center, transformed by toolpath matrix.
PathCenterY Current Y coordinate of arc center, transformed by toolpath matrix.
PathCenterZ Current Z coordinate of arc center, transformed by toolpath matrix.
PathCenterI Current I coordinate of arc axis, transformed by toolpath matrix.
PathCenterJ Current J coordinate of arc axis, transformed by toolpath matrix.
PathCenterK Current K coordinate of arc axis, transformed by toolpath matrix.
RawX
Current raw X coordinate from APT source.
RawY
Current raw Y coordinate from APT source.
RawZ
Current raw Z coordinate from APT source.
RawI
Current raw I coordinate from APT source.
RawJ
Current raw J coordinate from APT source.
RawK
Current raw K coordinate from APT source.
RawCenterX Current raw X coordinate of arc center, from APT source.
RawCenterY Current raw Y coordinate of arc center, from APT source.
RawCenterZ Current raw Z coordinate of arc center, from APT source.
RawCenterI Current raw I coordinate of arc axis, from APT source.
RawCenterJ Current raw J coordinate of arc axis, from APT source.
RawCenterK Current raw K coordinate of arc axis, from APT source.

15

Strings

Description
Current APT statement.
All of the statement's parameters are concatenated into a single line, even if
the source has continuation lines.
APTNext Next APT statement.
All of the statement's parameters are concatenated into a single line, even if
the source has continuation lines.
Comment Current APT statement's comment.
If the statement has text following "$$" characters, this variable is that text
with any leading and trailing spaces trimmed. For a DISPLY, HEADER,
INSERT, PARTNO, PPRINT or REMARK statement, this variable is the
text following the major word and its delimiter, with leading and trailing
spaces trimmed.
Date
Today's date.
In the localized "short" format, so for example in the USA, Christmas day
would be "12/25/04".
Time
Current time of day.
In the localized "medium" format, so for example in the UK, tea-time
would be "16:00:00".
Unit
Linear unit, "in" or "mm".
Name
APTLine

Registers

Name
A
B
C
F
G
H
I
J
K
M
N
R
S
T
U
V
W
16

Description
Machine A axis.
Machine B axis.
Machine C axis.
Feed rate.
G-code.
Head number.
Machine X of arc axis.
Machine Y of arc axis.
Machine Z of arc axis.
M-code.
Sequence number.
Radius.
Spindle speed.
Tool number.
Machine U axis.
Machine V axis.
Machine W axis.

X
Y
Z

Machine X axis.
Machine Y axis.
Machine Z axis.

Language Keywords

(Cannot be used as variable names.)


And
Exit
Not
For
Or
Cas
If
Out
Log
e
Sele
Loo
Deb
ct
ug
p
Do
Step
mod
Sub
Else
Nex
The
Else
t
n
If
End

To
Unti
l
Wen
d
Whi
le
Xor
Zap
zap
Fro
m

17

Functions
There is no provision for user-written functions in the post-processor language. You can
however write subroutines which are not named to match APT major words, and use
them anywhere.
Math Functions

Signature
number = abs(number)
number = acos(number)
or
number =
inverseCosine(number)
number = alogE(number)
or
number =
antiLogarithm(number)
or
number = exp(number)
number = alog10(number)
number = asin(number)
or
number =
inverseSine(number)
number = atn(number)
or
number = atan(number)
or
number =
inverseTangent(number)
number = atan2(number,
number)
number = cos(number)
or
number = cosine(number)
number = fix(number)
or
number = int(number)
number = logE(number)
or
number =
logarithm(number)
number = log10(number)

18

Description
Absolute value.
Inverse cosine (result in degrees).

Natural anti-logarithm.

Base 10 anti-logarithm.
Inverse sine (result in degrees).

Inverse tangent (result in degrees).

Inverse tangent of first argument divided


by second argument (result in degrees).
Cosine (argument in degrees).

Integer part.

Natural logarithm.

Base 10 logarithm.

number = root(number)
or
number = sqr(number)
or
number = sqrt(number)
or
number =
squareRoot(number)
number = round(number)
or
number = nint(number,)
number = sgn(number)
or
number = sign(number)
number = sin(number)
or
number = sine(number)
number = tan(number)
or
number = tangent(number)

Square root.

Round to nearest integer.

Sign (-1, 0, or +1).

Sine (argument in degrees).

Tangent (argument in degrees).

String Manipulation

(all positions are base 1)


Signature
number = Asc(string)
or
number = Ascii(string)
string = Chr(number)
or
string = Char(number)
number = InStr(string,
string)
or
number =
inString(string, string)
string = LCase(string)
or
string =
lowercase(string)
string = Left(string,
number)
number = Len(string)

Description
Returns ASCII code of first character in argument.

Returns string containing just the character with the


specified ASCII code.
Returns position of first occurrence of second argument
in first argument. If there is no such occurrence, returns
zero.

Produces lowercase version of argument.

Returns characters from left of first argument, the


number of them being specified by the second
argument.
Returns number of characters in first argument.

19

or
number =
Length(string)
string = LTrim(string)
or
string =
leftTrim(string)
string = Mid(string,
number, number)
or
string = Middle(string,
number, number)
string = Right(string,
number)
string = RTrim(string)
or
string =
rightTrim(string)
string = Trim(string)
string = UCase(string)
or
string =
uppercase(string)

Trims whitespace from left of argument.

Returns characters from middle of first argument, from


position specified by second argument, the number of
them being defined by the third argument.

Returns characters from right of first argument, the


number of them being specified by the second
argument.
Trims whitespace from right of argument.

Trims whitespace from left and right of argument.


Produces uppercase version of argument.

Register Related

Signature
Zap register

Description
Sets previous value of register to an undefined state.

Input Related

Description
Gets the word at the specified parameter position in the
current APT line.
Parameters are numbered from 1 for the major word.
If the requested parameter is numeric, its text is returned.
Gets the numeric value at the specified parameter
number =
position in the current APT line.
getValue(number)
Parameters are numbered from 1 for the major word.
If the requested parameter is not numeric, zero is
returned.
Gets the n'th non-numeric parameter in the current APT
string =
getNthWord(number) line.
If there are not enough non-numeric parameters, an
Signature
string =
getWord(number)

20

empty string is returned.


Gets the n'th numeric parameter in the current APT line.
number =
getNthValue(number) If there are not enough numeric parameters, a zero is
returned.
Gets the cumulative knot value at the specified NURBS
number =
getKnotValue(number) point.
Points are numbered from 1.
If there are not enough points, a zero is returned.
Sets a flag so that the next FROM or GOTO point will
zapFrom
become the new HOME position.
Typically used during a tool change or tool axis
adjustment.
Output Related

Signature
Debug
or
Debug string
Log string
Out string

Description
Displays a dialog box with the current state of all
numbers, strings and registers.
The string in the statement, if present, is used for the
dialog title.
Sends a string to the log.
Sends a string to both the output G-Code file and the log.

21

Subroutines
As the post-processor reads each APT statement from the input toolpath, it attempts to
invoke a subroutine, or "Sub", from the VcPost file. The names of the subroutines are
simply the corresponding APT major words. So when the post-processor encounters a
RAPID statement, it will try to call the RAPID subroutine. The syntax of the start and
end of such a subroutine is;
Sub RAPID
....
....
End Sub
Note that a subroutine has no arguments. Because all variables are global in scope, there
is no need to pass them as arguments between subroutines. The code between the "Sub"
and "End Sub" statements will be executed each time a RAPID statement is read.
If at some point within a subroutine you wish to bypass the remaining code, you can use
an "Exit" statement.
Sub PPRINT
....
....
If (display = 0) Then
Exit Sub
End If
....
....
End Sub
It is not necessary to write a subroutine for every APT major word that the post-processor
may encounter. If there is no subroutine for a particular major word, the post-processor
does nothing, and does not generate an error message.
Do not be surprised to see code statements in a VcPost file that are not in any subroutine.
While such lines can appear anywhere in the file, it is good practice to put them up front.
They get executed by the post-processor before any statements are read from the input
toolpath. Typically they are used to establish the output format of registers and specify
initial values.

22

For example;
X.Prefix = "X"
X.Format = "s3.4sm"
Y.Prefix = "Y"
Y.Format = "s3.4sm"
Machine = "Horizontal Lathe"
Author = "I. B. Nutz"
Before & After

Depending on a statement's major word, the post-processor may perform some activities
before invoking the appropriate subroutine, and it may perform more afterwards. Using a
GOTO statement as an example, the post-processor will first convert the statement's X, Y
and Z coordinates, and I, J and K if present, to machine axis positions, load these into the
reserved machine axis registers, X, Y, Z and others, then invoke the GOTO subroutine.
Finally it will set the current value of the G register to 1. Performing this last activity
after the subroutine call allows the G register to be tested within the subroutine to check
for RAPID motion. The following table details the before and after activities for each
major word, in alphabetic order. If a major word is not in this list, there are no associated
before or after activities, but a subroutine will still be invoked if one is supplied.
Sub
Before
ARCMOV
If the minor word "CLW" is present,
reverses the axis of the current arc.
For a BEGIN NURBS statement, sets the BEGIN
NURBS order and the F register's current
value, adjusts the tool axis, updates the
toolpath coordinates, converts to machine
axis positions and sets the machine axis
registers' current values. Each subsequent
NURBS point, until an END NURBS
statement is reached, has no major word
but is treated as if it has the major word
NURBSTO.
For a $$*CATIA0 statement, sets the G CATIA0
register's current value to 0.
CATMAT
Sets the G register's current value to 0.
Updates the arc variables, and sets the G CIRCLE,
ARCDAT,
register's current value to 2 (CW) or 3
MOVARC,
(CCW). For a statement with just 4
numeric parameters (x, y, z, r), the arc axis ARC or
SURFACE
and the G value cannot be trusted.
Direction should be deduced from the

After

For a statement that includes


the arc end-point (9 numeric
parameters), sets the G
register's current value to 1.

23

following GOTO point.


Updates the toolpath coordinates, and sets CNTRL
the NURBS weight (defaulting to 1.0).
FEDRAT
Sets the F register's current value to the
first numeric parameter.
FROM
Sets the G register's current value to 0,
updates the toolpath coordinates, converts
to machine axis positions, and sets the
machine axis registers' current values.
Adjusts the toolpath coordinates, converts GODLTA
to machine axis positions, and sets the
machine axis registers' current values.
Adjusts the toolpath coordinates, converts GOHOME
or HOME
to machine axis positions, and sets the
machine axis registers' current values. If
the statement has no axis minor words,
motion will be to the FROM position
unless the reserved variable, HomeRetract
is defined and non-zero.
Updates the toolpath coordinates, converts GOTO,
CONT or
to machine axis positions, and sets the
VECTOR
machine axis registers' current values.
Builds a list of cumulative NURBS knot KNOT
values which can be accessed by the
getKnotValue function.
If the first minor word in the statement is LOAD
"TOOL" or "WIRE", sets the T register's
current value to the first numeric
parameter.
LOADTL or
Sets the T register's current value to the
CHGTOOL
first numeric parameter.
MSYS
Sets the G register's current value to 0.
NURBS
Sets the NURBS order (defaulting to 4)
and sets the weight to 1.0 for the current
point, which is assumed to be the first knot
(with a value of 0.0).
NURBSTO
Each NURBS point between a BEGIN
NURBS and END NURBS statement is
treated as if it had this major word. Sets
the knot and weight values, updates the
toolpath coordinates, converts to machine
axis positions and sets the machine axis
registers' current values.
PPRINT
For a PPRINT/METRIC or
24

Sets the G register's current


value to 1.

Sets the G register's current


value to 1.

PPRINT/INCH statement, sets the


reserved string Unit to "mm" or "in".
For a PPRINT/TOOL AXIS or $$TOOL PPRINT
AXIS statement, updates the toolpath
coordinates, converts to machine axis
positions and sets the machine axis
registers' current values.
PPRINT
For a PPRINT/VERICUT-MATRIX
statement, sets the G register's current
value to 0.
PPRINT
For a PPRINT/VERICUT-TOOLID
statement, sets the T register's current
value to the first numeric parameter.
RAPID
Sets the G register's current value to 0.
RETRCT
Sets the G register's current value to 0,
updates the toolpath coordinates, converts
to machine axis positions, and sets the
machine axis registers' current values.
SPINDL
Provided the first minor word in the
or SPNDL
statement is not ORIENT, sets the S
register's current value. If the minor word
is OFF, LOCK or NEUTRAL the value
will be 0. Otherwise it will be the first
numeric parameter, or if there isn't one, the
prior non-zero spindle speed.
TLAXIS
Adjusts tool axis, updates the toolpath
coordinates, converts to machine axis
positions and sets the machine axis
registers' current values.
Updates the arc variables, and sets the G TLON or
GOFWD
register's current value to 2 (CW) or 3
(CCW).
Sets the reserved string Unit to "mm" or UNIT
"in".
If the first minor word in the statement is UNLOAD
"TOOL" or "WIRE", sets the T register's
current value to 0.

Sets the G register's current


value to 1.

Calls

It is not normally necessary for a subroutine named for a major word to invoke one
named for another major word. But you can do so. You can also write a subroutine which
is not associated with a major word, which will never be invoked directly by the postprocessor. To call such a subroutine, you simply place its name in a statement on its own.

25

There are no arguments because all variables are global in scope. For example you could
write a subroutine to calculate rotate the current X and Y machine axis locations through
an angle.
Sub RotateXY
ca
= cos(Angle)
sa
= sin(Angle)
XRotated = X * ca - Y * sa
YRotated = Y * ca + X * sa
End Sub
Then to use this subroutine you would need to set up the "Angle" variable, invoke the
Sub and access the results.
Angle = 5
RotateXY
NewX = XRotated
NewY = YRotated

26

Assignment and Operators


Assignment

Assignment of a value to a variable is achieved using the equal sign, "=". The variable's
name goes on the left of the equal sign, and an expression that generates the required
value goes on the right. This is true for numbers, strings and register properties.
Diameter = R.Current * 2
Message = "Load tool " & T.Current
F.Prefix = " F"
If the variable or register on the left of the equal sign does not already exist, it will be
created by the assignment statement. If it does exist, its value or the value of its property,
will be adjusted.
Arithmetic Operators

Order of precedence is from top to bottom.


Operato Description
r
^
Exponentiation.
The first number is raised to the
power of the second.
*
Multiplication.
Multiplies two numbers
/
Division.
Divides first number by second.
\
Integer Division.
Both numbers are rounded to the
nearest integer value,
the first is divided by the second,
and the result is truncated to its
integer part.
mod Modulus.
The remainder after dividing the
first number by the second.
+
Addition.
Adds two numbers.
Subtraction.
Subtracts second number from
first.

Example Result
2^3

2*3

7/2

3.5

7\2

7 mod 3

2+2

5-3

27

String Operators

Operato Description
r
&
Concatenation.
Second string is appended
to first.

Example

Result

"tool" & "path" toolpath

Logical Operators

Order of precedence is from top to bottom.


Operator Description
=
True if both expressions are the same.
Can be used with numbers or strings
but not a mix.
String comparisons are case
insensitive.
< > True if the expressions are different.
Can be used with numbers or strings
but not a mix.
String comparisons are case
insensitive.
<
True if the first number is smaller than
the second,
or if the first string collates before the
second.
String comparisons are case
insensitive.
>
True if the first number is greater than
the second,
or if the first string collates after the
second.
String comparisons are case
insensitive.
<= True if the first number is smaller than
or equal to the second,
or if the first string collates before or is
equal to the second.
String comparisons are case
insensitive.
>= True if the first number is greater than
or equal to the second,
or if the first string collates after or is

28

Example
X=Y

X<>Y

X<Y

X>Y

X <= Y

X >= Y

Not
And
Or
Xor

equal to the second.


String comparisons are case
insensitive.
Changes true to false, or false to true.
True if both expressions are true.
True if either or both expressions are
true.
True if one expression is true but not
both.

Not (Z > 0)
(X > 2) And (X
<10)
(X = 5) Or (X =
6)
(X = 5) Xor (Y =
5)

Note that the "Like", "Is", "Eqv" and "Imp" operators available in some flavors of
BASIC, are not supported by the post-processor language.

29

Branching
There are two types of logic branching available in the post-processor language, the "If ...
Then ... Else" technique, and the "Select ... Case method.
If ... Then ... Else

Using "[" and "]" to bracket optional elements, the syntax is;
If condition Then
statements
[ElseIf condition Then
statements]
[ElseIf condition Then
statements]
[Else
statements]
End If
Note that a statement never appears on the same line following "Then", in an "If" or
"ElseIf". This is possible in BASIC but we have chosen not to support it, to encourage
more easily maintainable code. An "If" branch can be as simple as;
If (Offset < 0) Then
Offset = -Offset
End If
The parentheses around the condition are not strictly necessary but help improve
legibility. Stepping up in complexity, an "If" can represent an either/or condition;
If (word = "Off") Then
M.Current = 11
Else
M.Current = 10
End If

30

Or it can cover any number of options;


If (word = "Off") Then
display = 0
ElseIf (word = "On" ) Then
display = 1
Else
Out "<N>(" & Comment & ")"
End If
Select ... Case

Using "[" and "]" to bracket optional elements, the syntax is;
Select Case expression
Case condition[,condition][,condition]
statements
[Case condition[,condition][,condition]
statements]
[Case condition[,condition][,condition]
statements]
[Case Else
statements]
End Select
The expression can be a number, string or register property. Each condition should
involve the same variable type, with numeric register properties treated as numbers, and
text register properties treated as strings. There is a wide choice of condition syntax as
defined in the following table, in which variable denotes an expression that evaluates to
a number or string.
Actioned if ...
expression and variable are equal.
expression is less than variable.
expression is greater than variable.
expression is less than or equal to variable.
expression is greater than or equal to
variable.
variable To variable expression is within the inclusive range.
Syntax
variable
< variable
> variable
<= variable
>= variable

31

Note that the operator "Is", available in some flavors of BASIC, is not supported by the
post-processor language. Nor are compound conditions that would require use of the
logical operators "Not", "And", "Or" or "Xor". At most one block of statements will be
executed during a pass through the "Select" construct, regardless of the value of the
expression and the conditions. If the expression matches more than one of the conditions,
only the statements following the first such condition will be executed.
Following is an example of the use of "Select ... Case" which parallels the last example
for the "If ... Then ... Else" technique.
Select Case word
Case "Off"
display = 0
Case "On"
display = 1
Case Else
Out "<N>(" & Comment & ")"
End Select
And here is an example that uses a number variable and illustrates more of the possible
conditions.
Select Case ShankDiameter
Case < 0.25
Chuck = "A"
Case 0.25 To 1
Chuck = "B"
Case 1 To 2.5
Chuck = "C"
Case > 2.5
Chuck = "D"
End Select

32

Looping
There are three types of looping available in the post-processor language, "For ... Next",
"Do ... Loop" and "While ... Wend.
For ... Next

Using "[" and "]" to bracket optional elements, the syntax is;
For counter = start To end [Step step]
statements
[Exit For
statements]
[Exit For
statements]
Next [counter]
The counter must be a number, or a register if its current value is to be used. The
elements start, end and step, if present, must all be expressions that evaluate to a number.
The value of the count and components of any of the expressions, can be altered within
the loop, but this tends to make debugging much more difficult. If step is missing, a value
of -1 is assumed if start is greater than end, otherwise +1 is used.
For a positive or zero step, the contents of the loop are executed provided counter is less
than or equal to end, and the counter gets increased by step. For a negative step, the
contents of the loop are executed provided counter is greater than or equal to end, and the
counter gets decreased by step. It is possible for the content of the loop to never be
executed, as would be the case with the following example.
For Count = 1 To 5 Step -2
...
Next
Do ... Loop

Using "[" and "]" to bracket optional elements, and "|" to indicate a choice of keywords,
the syntax is;
Do [While|Until condition]
statements
[Exit Do
statements]
[Exit Do
statements]
33

Loop [While|Until condition]


It would be very unusual to have While or Until conditions at both ends of the same
loop. With a While in the Do statement, the content of the loop will be executed if the
condition is true. With an Until in the Do statement, a false condition is required for the
loop content to be processed. A While in the Loop statement needs a true condition for
control to return to the Do, and an Until would require a false condition.
You can write a "Do ... Loop" with no conditions at either end, but you had better have an
"Exit Do" somewhere within it, or you could wait a while for the post-processor to finish.
While ... Wend

The syntax is;


While condition
statements
Wend
There is no "Exit" statement for a "While ... Wend" so it is vital that condition is changed
within the loop, and that it becomes false at some point.

34

Post-Processor Output
There are two types of post-processor language statement that generate output to files,
"Log" and "Out". "Log" only writes to a log file of the post-processor's activities, but
"Out" directs output both to the log file and to the G-Code file. Input lines from the APT
source are also sent to the log file, but this does not require any language statements in
the VcPost. The syntax for the output statements is;
Log string_expression
Out string_expression
But in each case the string_expression can take advantage of some extra features of the
language. In its simplest form an expression could be a string constant;
Out "(Load Palette)"
or it could involve concatenation of constants, string variables and textual register
properties.
Log "Job " & jobName & ", Spindle Speed " & S.Output
Remember that a string expression cannot contain a number variable, because there is no
way to specify the format required. If you need to output a number, you should probably
be using a register instead. If necessary, you could use a register just for this purpose;
Temp.Format = "s4.2"
Temp.Current = toolDia
Log "Tool Diameter = " & Temp.Output & "mm"
A reference to a register variable that does not have a property qualifier will use the
.Current property if a number is expected, and the .Output property when a string
would make sense. Thus this last example could be simplified to;
Temp.Format = "s4.2"
Temp = toolDia
Log "Tool Diameter = " & Temp & "mm"

35

To explore this topic further, let's use a sample that will be much more common. The
GOTO subroutine for a 3-axis machine needs to output lines similar to the following;
N12 G01 X1.25 Y2.375 Z4.5 F200
Probably the G, X, Y, Z and F registers will be modal, so that their values will only be
output when they have changed. The N register will always change so it doesn't matter
whether we think of this as being modal or not. Let's assume that the .Prefix property for
each register except N includes a leading space. With the rules that we have introduced so
far, you could write a statement to generate the required G-Code lines as follows;
Out N.Output & G.Output & X.Output & Y.Output & Z.Output & F.Output
Or more concisely;
Out N & G & X & Y & Z & F
Here is another way, that may not initially seem to have any advantage over the prior
implementation.
Out "<N><G><X><Y><Z><F>"
The key here is that the register references are now embedded in a string constant, using
the "<" and ">" characters. So if the output line has some constant elements and some
register values, it can be specified without using concatenation. The last line of our earlier
example could be written;
Log "Tool Diameter = <Temp>mm"
It is sometimes necessary to force output of a modal register's value whether it has
changed or not. A good example would be the need to re-specify the feed rate after a tool
change, even though the feed rate for the new tool may be the same as the that for the
prior one. There are two ways to do this. The first involves artificially changing the
register's .Previous property so that it doesn't match the .Current value. The Zap
function is provided for this purpose and you could have;
Zap F

36

somewhere in one of the subroutines involved in a tool change. The other technique is a
variant of the "<register>" syntax. By placing an exclamation point in front of the
register name, "<!register>", you will force output of that register's value.
The .Increment property of the N register should always be set to a positive value, in the
segment of your VcPost that is outside all subroutines.
N.Increment = 1
Each time an "Out" statement includes the N register, its value will automatically be
incremented. If the balance of the output line is modal registers, and none of them have
changed, then no output is generated and the N register will not be changed. To illustrate
this, we will go back to our early sample GOTO subroutine.
Sub GOTO
If (G = 0) Then
If (Z < Z.Previous) Then
Out "<N><G><X><Y>"
Out "<N><G><Z>"
Else
Out "<N><G><Z>"
Out "<N><G><X><Y>"
End If
Else
Out "<N><G><X><Y><Z><F>"
End If
End Sub
With the following APT input;
RAPID
GOTO/1,2,6
RAPID
GOTO/1,2,2

37

The generated G-Code would be;


N21G00X1.Y2.
N22Z6.
N23Z2.
Note that there is only one output line corresponding to the second GOTO, when both X
and Y are unchanged.

38

Post-Processor Debugging
While developing a VcPost file for a machine/control combination, it can be helpful to
step through a test toolpath with the post-processor and watch the effect that each input
line has on the numbers, strings and registers. To see a dialog like the one below, you
need to insert a simple post-processor language statement into your code.
Debug title_string
The title_string is optional, and if present will be used in the title bar of the window.

You could have just one "Debug" statement outside all the subroutines in the VcPost.
Then the window would appear as soon you start processing the input toolpath. As you
step through the toolpath, you can refresh the content of the Debug window at any time,
just by clicking on its
icon.
Alternatively you can place "Debug" statements in several places, with different titles,
and a window will be added to the display each time the post-processor reaches such a
statement. Putting a "Debug" statement inside a loop would not be a good idea. You can
icon.
close any of the Debug windows by clicking on its
A

icon within the register table indicates that a property has no defined value.

39

Probe Cycle Programming


Introduction

VERICUT can be used to generate G-Code files that drive an NC machine through the
steps required to inspect a workpiece with one or more probes. You will find this
capability in the menus at Analysis > Inspection Sequence. Once you have picked the
features that are to inspected, you can use the
(Use probe for all features) icon to
(Program probe cycles) icon will
specify that each of them will be probed. Then the
present the Inspection Programming window, and prompt you to select a post-processor
language file. By convention such a file should have the extension ".VcPost".
Probe cycle programming uses the post-processor language file to determine how to
format the output G-Code files. In addition, comments within the file are used to define
the names of the probe cycles available on the target machine, and the names of each
cycle's parameters. Both types of names get displayed in the programming dialog's table,
and the user is expected to pick a cycle which is appropriate for measuring each feature,
and to provide numeric values for at least some of its parameters. This document is
primarily concerned with defining the syntax of the comments.
There are eight keywords used in the probe cycle comments, each of which starts with the
character "#". The keywords are;
#Save
#Init
#End
#Rapid
#Move
#Approac #Retract #Cycle
h
A subroutine or "Sub" within the post-processor language file can employ at most just
one of these keywords. It may have more than one comment line with the same keyword.
Such comment lines must be between the "Sub" and "End Sub" statements.
In addition to the keyword, any of the comment lines can also contain parameter names,
which should be separated by spaces. Each parameter name will be used as the name of a
register in the post-processor, so the name must conform to the rules for variable names.
They must start with a letter and can only contain letters, numerals and the underscore
character, "_". Note that there are language words that cannot be used as parameter
names. Parameters can be essential to the interpretation of a probe cycle, or optional. An
exclamation mark, "!", preceding a parameter's name in the comment line declares it as
mandatory. The syntax should become much clearer in the following examples.
#Init

There should only be one subroutine containing a comment line with the #Init keyword,
and it will be invoked once, before any other subroutines, when the post-processor is run.
For example, if the following is defined in the post-processor language file,
Sub Initialize()
' #Init Offset Clearance FeedRate
Out "<N> G17"
End Sub

40

then the first row in the inspection programming table will initially look like this.

Note that it is the name of the subroutine, "Initialize", that appears in the "Cycle" column
of the table. So you can alter the prompt in the table to match the user's language and
preferences. The parameter names that follow the #Init keyword on the comment line will
appear in the numbered columns, in the order they are listed. If you need more
parameters than can comfortably fit on one comment line, simply add more lines, each
with the #Init keyword. There is a maximum of 16 parameters per subroutine. As with the
subroutine name, the parameter names can be localized for language and user taste.
In this example the three parameters are optional, so none of their names are preceded by
an exclamation mark. Note too that none of the parameters are used in the subroutine. If
the user provides a value for one of them in the table, that value will be established as the
current value of the register of the same name, before the subroutine is invoked.
#End

There should only be one subroutine containing a comment line with the #End keyword,
and it will be invoked once, after all other subroutines. For example,
Sub Terminate()
' #End
End Sub
This subroutine has no parameters, and more unusually, no executable statements, but its
name will appear in the last row of the table.

#Rapid

One or more rows for rapid motion can be inserted in the programming table before the
approach to any feature that is to be measured. There should only be one subroutine
containing a comment line with the #Rapid keyword, and it will be invoked for each of
the corresponding rows in the table. This example will "square" the rapid motion. Note
that all three parameters are mandatory, so their names are preceded by exclamation
marks.

41

Sub Rapid()
' #Rapid !X !Y !Z
If (Z < Z.Previous) Then
Out "<N> G0<X><Y>"
Out "<N><Z>"
Else
Out "<N> G0<Z>"
Out "<N><X><Y>"
End If
End Sub
A corresponding row in the table will initially look like,

The background of table cells for mandatory parameters is pink. As the user replaces the
parameter names with numeric values, the pink will be removed. He or she should aim to
eliminate all the pink before running the post-processor.

#Move

Like rapid motions, one or more feedrate motions can be inserted in the programming
table before the approach to a feature that is to be measured. There should only be one
subroutine containing a comment line with the #Move keyword, and it will be invoked
for each of the corresponding rows in the table. This example has a mix of mandatory and
optional parameters.
Sub Move()
' #Move !X !Y !Z FeedRate
Out "<N> G1<X><Y><Z><FeedRate>"
End Sub

42

If the user leaves the word "FeedRate" in the last parameter's cell, the register with the
same name will not be altered from its prior state.
#Approach

There should only be one subroutine containing a comment line with the #Approach
keyword, and it will be invoked immediately before each of the cycle routines that
measure a feature. For example,
Sub Approach()
' #Approach !X !Y !Z Clearance FeedRate
Z = Z + Clearance
If (Z < Z.Previous) Then
Out "<N> G1<X><Y><FeedRate>"
Out "<N><Z>"
Else
Out "<N> G1<Z><FeedRate>"
Out "<N><X><Y>"
End If
Z = Z - Clearance
GoFeel
End Sub
If you find that there are several parameters that are common to almost all of your cycle
subroutines, you may wish to move them to the approach subroutine. Since this is always
called before the cycle, you can reduce the number of columns used in the table and
provide a more consistent user interface across different cycle types.
#Retract

There should only be one subroutine containing a comment line with the #Retract
keyword, and it will be invoked after each of the cycle routines that measure a feature.
For example,
Sub Retract()
' #Retract Clearance FeedRate
Z = Z + Clearance
Out "<N> G1<Z><FeedRate>"
End Sub

43

#Cycle

There should as many subroutines containing a comment line with the #Cycle keyword as
there are probe cycles available on the target machine. Typically each such subroutine
will have numerous parameters, and we suggest listing the mandatory ones before the
optional ones. In this example the parameter list is spread across two comment lines, both
beginning with the #Cycle keyword.
Sub WallThick()
' #Cycle !X !Y !Width !Depth !Angle
' #Cycle !Correction Offset MaxSafe
MVAR = 4
CPA
=X
CPO
=Y
SETVAL = Width
ID
= Depth
STA1
= Angle
Out "<N><MVAR><CPA><CPO><SETVAL><ID><STA1>"
Out "<N><Correction><Offset><MaxSafe>"
Out "<N> CYCLE979"
End Sub
The alphabetically sorted set of all cycle subroutines is offered in a drop-down list in the
fourth column of each feature row of the table.

44

Once a cycle type has been selected, the parameters of the corresponding subroutine will
be inserted into the table. Not all of them are included in this illustration.

#Save

Some suites of probe cycles have the ability to save the result of one measurement and
compare it with other measurements in a later cycle. For example, if you wanted to check
that the Z dimension of one surface matched that of another, you could save the result of
probing the first surface, then on the second one use a cycle that compared the new
probed Z with the stored value. If your target machine has this capability, you need a
single subroutine containing the #Save keyword. For example,
Sub Store()
' #Save
Out "<N> G65 P9834"
End Sub
The user will then be able to insert a "save" row prior to any retract.

As with any of the keyword identified subroutines, the #Save subroutine can have
parameters if needed.

45

You might also like