by Dr. Ernest Appleton, Engineering Department, University of Cambridge. Anyone who has sufficient interest in the rapidly developing technologies of computing and robotics will probably be aware of languages for programming computers and they may even have already used a small desk-top robot. Although there are some significant differences between these robots and their larger relations used in modern industry the underlying technology is essentially the same and the amateur and professional technologist can both learn much from such systems. Most readers will be aware of the computer language BASIC and have used or know of other languages such as FORTRAN or PASCAL. Those readers who have used a desk-top robot and those who are familiar with industrial robots that use programming languages will already know that the natures of these systems are essentially similar and that their programming languages can be described as BASIC- like. However, the computer language FORTH is quite different from the languages BASIC, PASCAL etc. in its construction and as a consequence the FORTH based robot programming language ROBOFORTH II is quite different to the usual robot programming languages found in other commercial robot systems. By way of introduction to ROBOFORTH II a brief outline of the language FORTH is useful. FORTH was developed by Charles H. Moore in 1969 and was specifically intended as a computer language for the control of equipment. As a high level language which is fast to execute but requires little memory space it is ideally suited to the control of robots and there are several research groups around the world who have recognised this fact. One of the most powerful features of FORTH and its derivative ROBOFORTH II is the fact that it is extensible. The programmer is able to define new instruction words which consist of combinations of existing instructions allowing the system designer to develop a task specific language which is not only appropriate to the particular application but is optimum in terms of the the instruction set required for that task. The fact that the programmer generates his own language means that the words and phrases used within the language are those usually applied to the task and can be understood by the expert and newcomer alike. Thus ROBOFORTH II is a new approach to robot programming and the possibilities have not been fully explored. ROBOFORTH II offers a low cost opportunity for the expert and beginner to be at the very forefront of a new and exciting technology.
by David N. Sands, author of ROBOFORTH IIROBOFORTH II is an extensive robot control language designed to cover every eventuality in programming your robot, whether it be coating, assembly, laboratory handling, testing, or whatever. There are diverse means of acquiring spacial data and using it such as matrices, continuous path, object tracking, collision avoidance, plus numerous input-output features making it easy to interface with and control peripheral equipment at the same time as control the robot arm. Above all ROBOFORTH II is a real language i.e. has an extensive vocabulary of words which, like a natural language, help you express your ideas to the system. As a language ROBOFORTH II is a means of communication between the human user and the robot arm: for the user to tell the robot what to do and how to do it; for the robot to tell the user what it is doing and what it knows.
. IMPORTANT: Press caps lock. All ROBOFORTH commands are in upper case. Within the workspace of RobWin you will see a smaller window. This is for communication with the robot. Any keystrokes in this window go straight to the robot controller. Commands are interpreted by the robot controller and not by the computer. Any command you type goes direct to the controller and any controller response is sent to this window. Some commands have shortcuts in Robwin, for example the row of buttons across the top. Clicking a button simply inserts that command into the communication window. Robwin permits easier teaching and programming of the robot by organizing commands and data and sending them directly to the robot controller.
Press enter in the communication window and you should see OK. If not try the following: 1. turn the key to cold start. 2. Press reset. You should see a simple herald and the words cold start. Type the word ROBOFORTH (in caps) and press enter. you should see OK, a new line and a > prompt. The system is now ready for use.
At the top click project, new, and give your project a name such as 'test'. Three panes appear. One is labelled 'routes' (see later), one 'places' (see later) and one labelled (name).ed2 in this example v7test.ed2. See later for this also.
Click a button or pane to see relevant section:
As stated in the introduction, all the words in FORTH and ROBOFORTH II are organized as a linked list or "dictionary". With each word in the dictionary is kept its definition, as with a conventional dictionary. Each word in the command line is looked up in the dictionary and its "meaning" is executed. If FORTH cannot find the word it tries it as a number and converts it to a
value. If that fails the word is rejected and the rest of the line ignored.
WARNING: All words are stored in the dictionary as a length plus the first 5 characters of the word.
Therefore ambiguities are possible and should be avoided (such as ROBOT1 and ROBOT2 which are the same
length and have the same 5 starting characters).
In particular avoid creating words similar to Roboforth words for example if you create a word RECEIPT this has the same first 5 characters and the same length as RECEIVE. Since RobWin uses this word communication between RobWin and Roboforth is disabled.
Note that sometimes two English words make up one ROBOFORTH word e.g. GOTO or ISAT.
Words may be made up of any characters and any number of characters. It is a convention that many of the more basic words in the FORTH 'kernel' have agreed pronunciations, for example . (dot) is the shortform (there is no long form) for PRINT and is pronounced "print", ! is pronounced "store", @ is pronounced "fetch" and so on. Pronunciations will be given as they arise.
The standard representation of a number in Forth is a 16 bit integer. A single stack entry is a 16-bit value. Arithmetic is done with 16-bit twos complement values in the range -32768 to +32767 unless unsigned integers are specified (0-65535). If necessary 32 bit values may be used. These occupy 2 stack places and are normally only used to assist with scaling i.e. mixed precision arithmetic. Floating point arithmetic is also possible in FORTH but integer arithmetic is preferred. Even trigonometry can be performed using integers (see controller manual) with an implied decimal point.
FORTH, in its basic form, consists of a "kernel" of some 150 or so "words" or commands, most of which are "primitives" i.e. they directly execute machine code whenever they are used. The programmer must define new words in terms of words already in the kernel. He/she can then define higher level words in terms of words he/she has already defined plus words from the kernel as necessary. These new words are added to the existing dictionary.
Hence the programmer begins by defining short concise procedures which can be tested individually. In this way the user builds up a range of fully tested modules which are then used to construct more powerful procedures, and so on until the final application 'program' is complete, which can be just one word. The modular approach imparts a very high degree of confidence to the final application.
New procedures are created using a colon sign, followed by the name of the procedure, then the definition ending with a semi-colon, for example-
: TANKS? LEFT-TANK RIGHT-TANK + . ;
LEFT-TANK is a previously defined word that takes a measurement from the left tank and leaves it on the stack, similarly RIGHT-TANK. The word + adds the two values together and leaves the result on ths stack, then the dot . which means print, prints the result.
Now all you have to do is type TANKS? to yield the total in both tanks, or alternatively TANKS? can be included in the definition of some grander procedure.
The colon : is also called a word as words may be made from any ASCII characters. Moreover it is called a 'defining word'. Examples of other defining words in Forth and Roboforth are CONSTANT VARIABLE ROUTE PLACE OBJECT.
WARNING: All words are stored in the dictionary as a length plus the first 5 characters of the word.
Therefore ambiguities are possible and should be avoided (such as ROBOT1 and ROBOT2 which are the same
length and have the same 5 starting characters).
In particular avoid creating words similar to Roboforth words for example if you create a word RECEIPT this has the same first 5 characters and the same length as RECEIVE. Since RobWin uses this word communication between RobWin and Roboforth is disabled.
For more detailed information on FORTH and this version of FORTH please see:
Understanding FORTH
Structure of FORTH
Keeping track of the stack
To put a new value into the variable TOPSPEED use the syntax e.g.
2000 TOPSPEED !
Which means store the value 2000 into the address TOPSPEED
Remember TOPSPEED is just a location in memory which has a name.
@ means "fetch the contents of the address on the stack and leave it on the stack". In the process it uses up that address. For example
TOPSPEED @
gets the current value of TOPSPEED and leaves it on the stack for another word to use up, for example the period . which means "print".
The current value of TOPSPEED could be found with
TOPSPEED @ . (pronounced "topspeed fetch print")
or the easier form
TOPSPEED ?
Data can be transferred from one variable to another with e.g.
TOPSPEED @ SPEED !
NOTE: all numbers in FORTH are 16 bit twos complement integers i.e. values between 32767 and -32768. There is the option of 32 bit numbers (double precision). In Cartesian mode co-ordinates are
expressed as integers times 0.1mm i.e. 1000 equals 100.0 mm. In this version of FORTH the decimal point may be inserted just for readability i.e. you can enter 100.0 or just 1000 as you wish.
You can also create a variable with the word USER.
When you use VARIABLE (word) the actual value of the variable is stored in the parameter field of the new word as per standard Forth practice. See the structure of a Forth word in the controller manual. However if the text around this word is edited then recompiled (reloaded) then the actual address of the data may change. There is another way of creating a variable with
USER TOPSPEED
This stores an address is the parameter field which points to a location in a reserved memory area called the User memory. The contents of this are unchanged after a reload. If USAVE is used then the contents of user variables are reloaded from FLASH ROM after a reset or power-up. There is a pointer to this memory UVP which is incremented each time a new USER variable is created. If you FORGET a user variable the pointer is restored to the previous user variable. Typing the word ROBOFORTH restores the pointer to the start of the user memory.
High Memory The controller has two banks of memory. All the positional data you teach the robot is stored in high memory, bank 1. All your software, variables etc are in low memory, bank 0. The words @ and ! refer only to low memory. To access high (extended) memory (which is rare) you would use E! and E@. For example MOVES is a pseudo-variable in high memory so to read it you would use MOVES E@ (see controller manual for details on high memory). MOVES automatically sets BANK to 1.
The structure of an IF statement is this:
(condition) IF (action) THEN
If the condition is true (non-zero) then all of (action) is executed
but if false (zero) then the program flow branches immediately to
the words following after THEN. The word THEN closes the IF statement like
ENDIF in Pascal. In BASIC the close of an IF statement is the end of the line.
A condition may be set up with comparing words such as = > and < but the result of any calculation may be used.
Examples of conditions are:
2 4 = leaves zero on stack i.e. false
2 2 = leaves a 1 on stack i.e. true
PRESSURE 100 > leaves true (non-zero) if the word PRESSURE leaves
any value on the stack which is greater than 100.
Example:
: PRELIEF PRESSURE 1000 > IF VALVE ON THEN ;
It is often useful to set up a continuous loop which ends only if a condition is met. Structure:
BEGIN (action) (condition) UNTIL
This executes action in a loop and repeats until the condition is true.
Example:
This repeats a robot motion until the escape key is pressed
: TASK BEGIN P1 GET P2 PUT ?TERMINAL UNTIL ;Other control loops are: IF ELSE THEN, BEGIN WHILE REPEAT, and counting loops DO LOOP.
WARNING: All control loops are implemented using conditional short jump machine instructions. This means there is a maximum distance between IF and THEN or BEGIN and UNTIL etc. of 127 bytes (approximately 63 words). If exceeded the system will crash. It is bad practice in any case to make a definition that long. You should always try to make short definitions which you can then put into the control loop - the building block approach.
For example the word DROP in Forth drops a value from the stack. But you might want it to mean drop an object from the gripper. In this case you might define a word : DROP BIN UNGRIP ; to drop a held object into a bin. Now you no longer have access to the original definition of DROP so if you want to use both versions you can switch contexts with the words FORTH and ROBOT. For example:
: DUMP-OBJECT KEY FORTH DROP ROBOT DROP ;This waits for a key to be pressed, drops the value of the key because we don't care what key it is, then drops the held object.
: START ( this is defining a new word called START
START ( this is the original definition of START followed by..
15000 SPEED ! ( change speed according to application needs
; ( end of definition
Remember to type or execute START after loading the text from the .ed2 window. Normally the next thing to type would be CALIBRATE (section 2.6)
NORMAL
Restores all the variables like speed which affect the robot
motion back to the default values set by START.
To operate the gripper enter:
GRIP
to close gripper
UNGRIP to open gripper
GRIP sets a flag FGRIP to true and UNGRIP sets it to false.
UNGRIP also clears any object from the WHERE display (i.e. from the variable OBJECT-HELD)
Click
These by-pass the timer TGRIP and do nothing with FGRIP or OBJECT-HELD.
There is another variable which may be useful:
FGRIP - a flag set to 1 when the gripper is closed or 0 when open. This variable is used by RobWin.
However to find out whether the gripper is actually open or closed enter
GRIPPER BIT? which leaves true if the gripper is closed or zero if the gripper is open.
The gripper confirmation on a gripper is set to give a different state between gripped on an object and gripped on nothing at all. Ungripped may well give the same state as gripped on nothing but is irrelevant. With a vacuum pick-up a vacuum switch provides confirmation. If the object is not picked there is no vacuum.
The gripper confirmation switch is usually connected to PB 5 but could be any input. If there is a track then the track calibration sensor is connected to PB 5 and the gripper sensor is moved to PB 7. Note that PB 6 is normally used for interrupts. The definition GRIPSENSE may be patched to a different bit.
To check the grip sensor use
GRIPCHECK
You could then use this definition in a new definition of GRIP e.g.
: GRIP ( new definition GRIP ( old definition GRIPCHECK ;However this could leave the robot in a difficult place from which to recover so it is usually best not to make the check until the robot is in a safe place. For example:
: GETPART TOJIG CONTINUOUS RUN JIG GRIP WITHDRAW TOJIG RETRACE GRIPCHECK ;Note: the grip sensor on a motorized electric gripper is the inversion of the sensor on a pneumatic gripper, i.e. on a motor gripper PB 5 goes to 0 to fail and on a pneumatic gripper it goes to 1 to fail. This is taken care of in the software.
As mentioned earlier all spatial positions around the robot arm
are expressed (in most circumstances) as co-ordinates relative to
the HOME position of the arm where the co-ordinates are all zero.
On an R12 or R17 this is bolt upright. On an R19 it is with the lift axis near to lowest travel and the extend axis almost fully retracted. In both cases the waist is at mid-point of available travel.
Wherever the robot happens to be after typing START is set to
be the HOME position but the true home position must be
established with CALIBRATE -- See calibration
HOME
click
Note nothing will happen right now because the robot already is at HOME
This is a place name which returns the robot to the home position where all counts are zero. You would not normally type this until you had calibrated the robot (See calibration.).
In some applications the HOME position is not a safe one, for example where there is a ceiling too low for an R17 to be bolt upright. In this event you might want to add some programming to conditionally bar the HOME position, e.g.:
: HOME CR ." Are you sure? " KEY DUP EMIT 89 = IF ( looking for capital Y ) HOME THEN ;(for programming such things see later, section 9.1)
SETHOME
Wherever the robot happens to be can be made into a home position
with this word i.e. all co-ordinates are set to zero. Not to be used without good reason.
If the system is in RELATIVE mode then you can use SET-LOCAL-HOME to zero only the LOCAL counts (see later).
The home position can be accurately set up by making use of proximity detectors fitted to each axis.
CALIBRATE
click
This drives all the axes to their proximity detectors , reports the errors then corrects them to the values in LIMITS.
A single axis can be sent to the detector position with the
command (e.g.)
TELL TRACK DATUM
More than one axis could be datumed with the line
TELL (axis1) (axis2) (axis3) DATUM
Suppose that axes 2 and 3 have to move backwards to their datum positions, the correct line would be:-
TELL (axis2) (axis3) REVERSE (axis1) DATUM
DATUM has two major components: ONLIM and OFFLIM. During ONLIM the axis moves onto the sensor. When it detects the sensor, i.e. the sensor input goes low, it decelerates. OFFLIM then reverses the axis at slow speed until it just clears the sensor (sensor input goes high).
CALIBRATE
The robot seeks out the sensors on each axis using DATUM on all axes. When the sensors are reached the joint counts are corrected to the joint counts in the array LIMITS (see below). Each value in LIMITS is the number of counts difference between the sensor and the HOME position for each axis. In addition the number of counts error between this and the previous calibration are shown on screen. Normally the difference would be about 2 or 3 steps and no more than 10 steps.
You can change the values of LIMITS by entering new values into individual elements of the array, e.g. 8000 LIMITS 6 + ! changes the value for the hand to 8000 etc. If the values in LIMITS must be revised because of a change in mechanical characteristics, for example if a sensor is replaced, then the way to do it is as follows:
1. Set a good home position using instruments. See the robot manual for precise instructions.
2. Reset the controller (writes a fresh copy of ROBOFORTH to RAM)
3. Enter
START
4. drive the robot to the sensors using
CHECK
5. Enter
SETLIMITS
6. Enter
PSAVE
which writes the memory image back to flash ROM
Always be careful when using the command PSAVE. If you have damaged ROBOFORTH in any way you will be saving the damaged image back to flash ROM. If you need to you can reload ROBOFORTH from disk - see section 9.2
Other words are:-
ONSPD is a constant determining the speed the axes move onto the
sensors in ONLIM. It can be altered with (n) ' ONSPD !
OFFSPD is a constant determining the speed the axes clear the
sensor in OFFLIM. It can be altered with (n) ' OFFSPD !.
MAXON - maximum number of counts allowed to find a sensor. It can be altered with (n) ' MAXON !
MAXOFF - maximum number of counts allowed to clear the sensor again. It can be altered with (n) ' MAXOFF !
Note these have different ideal values depending on the robot type and RoboForth version.
MCP (Motor Calibrate Pattern) is a motor flag byte determining which motors are to run in ONLIM and OFFLIM.
Version 12 up only: SIP (Sensor Inversion Pattern). Some sensors give a high instead of a low when the axis calibrates, and are low at all other times. The value in SIP is exclusive-or'd with the sensor input to re-invert active high sensors.
In some circumstances it may be desirable to re-calibrate a
single joint individually for example where the working area is restricted. This can be done by driving that joint
to datum then storing the correct value into the current position
list (WHERE), e.g. for a HAND:-
: HCAL TELL HAND REVERSE DATUM LIMITS 6 + @ 3 GLOBALS !;
This forces the WHERE display to the correct value in LIMITS. You also need to fcrce the encoders to show this new value with
ENCSET
The accuracy of the robot after calibration depends on the repeatability of each axis and its sensor. This can be improved upon using a NEST
The first byte contains the MEP value for the first
axis to calibrate, for example if the first byte has value 1 then axis 1 will be the first to calibrate. Usually the lift axis is first so it does not drag on anything as the track moves. So the first byte for an XYZ format robot would be a 4.
The next byte (byte 1) would contain the MDP required. If the axis is required to drive in reverse to find its sensor then byte 1 would be the same as byte 0 i.e. 4 for the lift axis. The next byte is the MEP for the next axis to calibrate and the next byte (byte 3) would be the same value as byte 2 if the axis must seek in reverse. All other bytes would be zero.
Example for a HYPOTHETICAL 3-axis R15:
04 - datum the Z-axis first
04 - move it in reverse to find sensor
02 - next datum the Y-axis
02 - move it reverse
01 - next datum the track/X-axis
00 - move it forward
CALSEQ DUMP would yield:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
A250 04 04 02 02 01 00 00 00 00 00 00 00 00 00 00 00
(to continue a DUMP press space bar; to end press return/enter)
Note: R12/R17s calibrate all axes together and do not have CALSEQ.
The joint names for a Cartesian robot (R14,R15) are TRACK, EXTEND, LIFT and optionally HAND and/or WRIST.
ALL selects all the joints at once.
MOVE is a relative command, example:
>TELL WAIST 500 MOVE OK
or for a Cartesian robot:
>TELL TRACK 500 MOVE OK
The waist or track motor now moves 500 steps and these are
counted by the system.
Since we are still talking to the waist/track it is only
necessary to enter:
500 MOVE
to get the waist/track to move another 500 steps. The waist/track
will now be a total of 1000 steps from the home position.
When the move is complete you can list the current position of
the arm with the command WHERE. This displays the number of steps
each motor has moved since it was at the HOME position.
>WHERE
For an R12/R17 the result is:
WAIST SHOULDER ELBOW L-HAND WRIST OBJECT
1000 0 0 0 0
L-HAND is listed because in the R17 and R12 hand pitch is achieved by running
both motors 4 and 5 together but wrist roll requires only motor 5.
If only motor 4 (L-HAND) runs then the wrist rolls in the opposite direction.
For an R12/R17 six-axis the result is:
WAIST SHOULDER ELBOW L-HAND R-H/YAW WRIST OBJECT
1000 0 0 0 0 0
L-HAND is motor 4, R-H/YAW is motor 5, WRIST (gripper rotate) is motor 6.
For an R19 this results in:
WAIST LIFT EXTEND HAND OBJECT
1000 0 0 0
For an R19T with hand yaw and track this results in:
WAIST LIFT EXTEND HAND TRACK OBJECT
1000 0 0 0 0
For an R15 this results in:
TRACK LIFT EXTEND WRIST OBJECT
1000 0 0 0
and various other combinations.
The particular heading depends on the model and configuration of
the robot. It can be invoked by itself with JOINTHEAD
click Robot, Joint position.
Actually there will be two more lines below the motor position.
The second line shows the actual counts obtained from the
encoders. The third line is the count multiplied by a factor
determined by encoder resolution and gear ratios and is the
computed true position which should be the same as the motor
position within a few bits, for example
WAIST SHOULDER ELBOW L-HAND WRIST OBJECT (R12/R17)
or WAIST LIFT EXTEND HAND TRACK OBJECT (R19T)
or TRACK LIFT EXTEND HAND WRIST OBJECT (R15)
1000 0 0 0 0
642 0 0 0 0
1001 0 0 0 0
There is no encoder on the 6th axis of an R12/R17
WAIST SHOULDER ELBOW L-HAND R-H/YAW WRIST OBJECT
1000 0 0 0 0 0
642 0 0 0 0
1001 0 0 0 0
More than one joint at a time can be moved with e.g.
click Robot, Joint Rel move.
Repeated use of MOVE continues to move the same joints relative
to their previous positions. The joint selection is cancelled
with TELL.
Movement in the reverse direction is achieved with negative
values e.g.
-1000 MOVE
Another way of moving backwards is with e.g.
TELL WAIST REVERSE 1000 MOVE (or TRACK or whatever)
An axis can be made to move to a particular position with e.g.
TELL WAIST 1500 MOVETO
click Robot, Joint Abs move
The waist then moves forward or backward as necessary to finish at 1500 steps from the home position.
Wrist rotate is axis 5 on a 5-axis robot, axis 6 on a 6-axis robot.
The wrist twist may be moved with TELL WRIST (n) MOVE but may
also be moved with
(n) TWIST a relative command.
The wrist may be restored to the zero position with
UNTWIST an absolute command.
The array which contains the counts for each motor is called
GLOBALS and is addressed with (n) GLOBALS where n is 0 for the
first motor, 1 for the next etc. e.g.
0 GLOBALS ? 1500 OK
It could be changed with e.g.
1501 0 GLOBALS !
The simplest motion command is STEPS e.g.
>TELL WAIST 500 STEPS OK (or TRACK or whatever)
The waist or track motor now moves 500 steps, but these are not counted by the system. WHERE will show, in the encoder lines 2 and 3, that the axis has moved but there will be no count in line 1.
-MOVE is a simpler version of MOVE which operates only in JOINT mode and makes less checks.
RELATIVE
This command tells all the axes to start counting a local position starting from where the robot is now. For example suppose you have just moved the waist
TELL WAIST 1000 MOVE
WHERE
shows
WAIST SHOULDER ELBOW L-HAND WRIST OBJECT (R12/R17)
1000 0 0 0 0
xxxx 0 0 0 0
1010 0 0 0 0
Now enter
RELATIVE
WAIST SHOULDER ELBOW L-HAND WRIST OBJECT (R12/R17)
GLOB 2000 0 0 0 0
LOCL 1000 0 0 0 0
xxxx 0 0 0 0
2010 0 0 0 0
If the system is in RELATIVE mode then the local position will be
the second line with the encoder values in lines 3 and 4
A single local position may be read with (axis 0-5) LOCALS @
and changed with (new value) (axis 0-5) LOCALS !
WARNING The robot will not stop when you press the stop button. To stop the robot execute the command
STOP (part of a program or type it quick)
This tells the DSP to stop moving the robot.
When the robot has stopped WHERE will show the robot to be still where it was before you executed DSPMOVE therefore you must, as soon as DSPMOVE has finished, or at worst before you execute the next command, execute
DSPASSUME - this updates the counts from the DSP.
WARNING In some circumstances there may be invalid
values for the DSP parameters SPEED and ACCEL. For example a SPEED value of 1 would result in incredibly slow motion, appearing to be stationary. A negative value will produce undesirable effects. If in doubt enter realistic values e.g.
5000 SPEED ! 1000 ACCEL !
(number) GOTO
Sends the robot to the number of the line in a route.
XGOTO sends the robot to the position stored at an address which can be in high or low memory. If the memory strip is in high memory then first select with BANK C1SET before using XGOTO.
BANK C1SET 64 XGOTO
(address) -GOTO ("dash-goto")
is a faster form of GOTO which assumes that the co-ordinates in
the data strip are joint (motor) and not Cartesian co-ordinates
and performs no checks. The data must be only in low memory (bank 0). This makes it suitable for use with functions which always produce a result in low memory, for example TRANSFORM -GOTO
To see what the data is enter:
VIEW (address of data)
Two positions may be added together and the robot sent to the
result. For example:
(address1) (address2) ADD GOTO
A joint position may not be added to a Cartesian position. Two absolute positions may not be added together. If a relative position is added to an absolute position the result is a new absolute position. If two relative positions are added the result is a new relative position.
You can create positions in the dictionary by use of the word CREATE in your text window, for example
CREATE NEST 1000 , 2000 , 3000 , 4000 , 5000 , 0 , 0 , 0 ,
creates a strip of data in the dictionary itself with the name NEST and with the values as shown for each joint.
NEST GOTO
sends the robot to this position.
The 7th byte of this strip contains flags as follows:
0 Joint mode
1 Joint relative mode
2 Cartesian mode
3 Cartesian relative mode
so
CREATE APR 0 , 0 , 50.0 , 0 , 0 , 0 , 3 , 0 ,
is a relative Cartesian position. If you type
APR GOTO
Then the robot will move up exactly 50mm. Each time you type APR GOTO it will move up another 50mm.
The last byte MUST be zero.
The robot's position can be changed to the data in an address with
(name or address of position) ASSUME
for example LIMITS ASSUME
POSITION is a variable which contains the address of the last position the robot was at.
If, using MOVE or GOTO (but not DSPMOVE or DSPSMOOTH) the stop button is pressed and a task is programmed (i.e. using STOPVEC, See section 6.1) then the DSP will stop but will continue again when the task is complete.
You may use the command (position) DSPSMOOTH where (position) is
the address of a co-ordinate, for example
1 LINE DSPSMOOTH
The DSP will pass control back to the CPU immediately even while
the robot is running so the CPU can do something else. You can determine when the
DSP has finished with ?RUN and other commands, see section 7.2.4
WARNING The robot will not stop when you press the stop button. To stop the robot execute the command
STOP (part of a program or type it quick)
This tells the DSP to stop moving the robot.
In an emergency press the reset button.
?STOP
is a loop which waits for the DSP to finish. If the stop button
is pressed during this time the DSP is sent the STOP command and
the robot stops. As long as the CPU is in command mode or
executing some other command the stop button is ignored.
When the robot has stopped WHERE will show the robot to be still where it was before you executed DSPSMOOTH therefore you must, as soon as DSPSMOOTH has finished, or at worst before you execute the next command, execute
DSPASSUME - this updates the counts from the DSP.
The software works to an internal precision of 0.1 mm and 0.01 degrees of angle.
To select Cartesian positioning mode type:
CARTESIAN
click ![]()
To return to joint mode enter
JOINT
click
click Robot, Cartesian Absolute move.
In the command window the action of MOVE, MOVETO and WHERE are
changed. MOVE and MOVETO now require 3 arguments and no joint
selection.
The arm is positioned by commands of the form X Y Z MOVETO where
X,Y and Z are integers of 0.1 mm, e.g.
1000 2000 3000 MOVETO
though it may look better as:
100.0 200.0 300.0 MOVETO
The software then performs a transformation from Cartesian to
motor co-ordinates and drives the arm to X=100.0 mm, Y=200.0 mm,
Z=300.0 mm. The message "CANNOT REACH" indicates impractical
values entered. Also valid is MOVE e.g.
0 0 -500 MOVE which performs a relative move downwards of 50.0mm.
You will encounter problems with any of the above at first if you start from the HOME position. This is because at HOME position the wrist points straight up i.e. -90.0 degrees. In R12 this is not allowed if the angle between hand and forearm is too negative because of possible contact between the hand and the forearm. It is best to use RobWin to first of all position the robot in a suitable starting position where the hand angle is 0 or 90.0 degrees.
click Robot, Cartesian Relative move.
Alternatively enter the word READY
In 6 axis systems READY positions the gripper pointing down. There is also
READY2
in which the gripper is horizontal.
The current co-ordinates of the end effector are displayed with
the command WHERE which in Cartesian mode displays in an altered
form:
WHERE
X Y Z PITCH W(ROLL) LEN. OBJECT
100.0 200.0 250.0 -90.0 0.0 0.0
PREV 0.0 0.0 0.0 0.0 0.0 0.0
Where the values under X,Y,Z are displacements in mm.
For a 6-axis R12 or R17:
X Y Z PITCH YAW ROLL OBJECT
100.0 200.0 250.0 -90.0 0.0 0.0
PREV 0.0 0.0 0.0 0.0 0.0 0.0
For an R19:
X Y Z W(YAW) LEN. OBJECT
100.0 200.0 250.0 -90.0 0.0
PREV 0.0 0.0 0.0 0.0 0.0
The line PREV is the previous position of the arm, so the
co-ordinates in the first line move down to PREV after each move.
For a 5 axis R12 there are 6 variables in Cartesian mode:
X Y Z PITCH W TOOL-LENGTH
(note: #CARTS=5, #AXES=5)
For a 6 axis R12 there are 6 variables in Cartesian mode:
X Y Z PITCH W ROLL
(note: #CARTS=6, #AXES=6)
For a 4 axis R19 there are 5 variables in Cartesian mode:
X Y Z W TOOL-LENGTH
(note: #CARTS=4, #AXES=4)
These can be manipulated individually if required e.g.
1000 X ! 2000 Y ! 3000 Z ! 900 PITCH ! 45 W ! 0 ROLL ! etc.
To make the robot move to these positions enter:
TRANSFORM -GOTO
At any time TRANSFORM will calculate the joint position (motor step counts from home position) and leave the address of this joint position on the stack. -GOTO drives the motors to that position.
CAN'T REACH If you get this error at any time it is because you told the robot to go to a position it is physically impossible to reach.
COMPUTE
click Robot, Cartesian position
While in Cartesian mode the joint position (motor counts) can be
viewed with JOINTWHERE or just JW. While in joint mode the Cartesian
position can be viewed with COMPUTE CARTWHERE.
NOTES:
(1) WHERE only shows the current values of X,Y,Z,W,PITCH,ROLL
and TOOL-LENGTH. These are not necessarily where the robot
actually is, for example after moving the robot with a PLACE or a
GOTO with an address containing only joint co-ordinates or with
the command -MOVETO then the robot will move but leave the
contents of the Cartesian variables unchanged.
To up-date the Cartesian variables from the motor counts
(Forward Kinematics) use COMPUTE. This computes the Cartesian
position from the motor counts. In most circumstances the system
issues an error message if the user attempts to use MOVE when the
Cartesian positions are not valid.
(2) If you go back to a position created using Cartesian coordinates and then type COMPUTE do not expect the reported co-ordinates to be exactly the same as the ones you first used. There may be a slight difference due to (a) the accuracy with which TRANSFORM conformed to the original Cartesian co-ordinates given and (b) the accuracy with which COMPUTE can convert back to Cartesian co-ordinates.
(3) COMPUTE merely reverses the calculation performed by TRANSFORM. If TRANSFORM or MOVETO would not send the robot to a particular position then COMPUTE can not calculate the Cartesian values for that position. For example if you reach the shoulder and elbow both backwards, then run the waist 180 degrees so the arm looks as if it is in a valid position, COMPUTE will not produce valid results. Another example would be if the arm were at a valid Cartesian position but with the elbow lowermost whereas if sent to that position using a Cartesian command the elbow would be uppermost (to clear the workspace). In that event COMPUTE would not calculate a valid position. Another example would be if the wrist is at 0 degrees and you rotate it through 12000 steps (e.g. 12000 TWIST) it will appear to be at zero degrees again. But COMPUTE will not give a valid Cartesian position for the arm.
Physical Constants
The amount each axis moves for a given number of motor counts is determined by gear ratios which are represented in the software by constants:
B-RATIO - (B for base) - the number of steps for axis 1 to move 90 degrees (or 1000mm if a linear axis)
S-RATIO - (S for shoulder) - the number of steps for the shoulder axis (2) to move 90 degrees
E-RATIO - (E for elbow) - the number of steps for the elbow axis (3) to move 90 degrees
E-RATIO - (E for extend) - the number of steps for the extend axis to move 1000mm
L-RATIO - (L for lift) - the number of steps for the lift axis to move 1000mm
W-RATIO - (W for wrist) - the number of steps for axis 4 to move 90 degrees
T-RATIO - (T for twist) - the number of steps for axis 5 to move 90 degrees
R-RATIO - (R for roll) - the number of steps for axis 6 to move 90 degrees
R15: the limits of travel in X, Y and Z directions are determined by the values in an array WORKSPACE. These values can be checked with:
VIEW WORKSPACE
Bytes 0,1: Max X travel (positive) Bytes 2,3: Max Y travel Bytes 4,5: Max Z travel Bytes 6,7: Min X travel (negative) Bytes 8,9: Min Y travel Bytes 10,11: Min Z travel
To alter any value use this syntax: (new max X) WORKSPACE ! (new max Y)) WORKSPACE 2+ ! (new max Z)) WORKSPACE 4 + ! (new min X)) WORKSPACE 6 + ! (new min Y)) WORKSPACE 8 + ! (new min Z)) WORKSPACE 10 + !
R19: the limits of reach are determined by four constants:
MAXHT - maximum Z value, MINHT - minimum Z value,
MAXLEN - maximum extension of extend axis (i.e. maximum radius),
MINLEN - minimum extension of extend axis (i.e. minimum radius)
The waist is also limited to plus/minus 180 degrees.
R12/R17: the limits of reach are determined by the trigonometry and
by constants for the length of upper arm and fore-arm. These
constants are UPLEN and LOLEN and for R17 both have the value 3750
(375.0mm from shoulder pivot to elbow pivot and 375.0mm from
elbow pivot to wrist/hand pivot.) and the error is also given if
you try to exceed plus/minus 180 degrees of waist rotation. For R12 both these values are 2500 (250.0mm).
Note: because POINT is a defining word, like VARIABLE etc., it cannot itself be compiled into another defining word. However you can include it in your text file by manipulating the Cartesian variables directly then creating a point, for example:
In Cartesian mode all co-ordinates learned into a route are the Cartesian co-ordinates. This also applies to REPLACE.
The joint co-ordinates may be learned instead with JL or a line
can be replaced with joint co-ordinates with (line-number) JR.
When in joint mode the equivalent Cartesian co-ordinates may be
learned into a route by using CL instead of LL . This makes computation slightly quicker, especially for continuous path routes. When a PLACE
name is created the co-ordinates learned are already converted
eliminating computation time.
Another way of using Cartesian commands is to position the robot,
but then to create a PLACE name which will always contain joint
co-ordinates even though the system is in Cartesian mode. You
could then enter, say, 0 0 500 MOVE to lift the arm vertically,
or use PLUNGE with a negative value then set the approach
position with APPROACH (place-name).
R12/R17 only:
ALIGN
If the hand is vertical (i.e. PITCH = 90 degrees or -90 degrees)
then the wrist will adjust so that angle W is relative to the
home position rather that the hand position. Therefore each time
the waist is moved the wrist will rotate so as to leave no change
in angle of the grippers relative to the X-Y axes. This mode
remains until
When WHERE is typed 3 lines are displayed. Line 1 is the regular
motor count, line 2 is the actual encoder count, line 3 is what
the motor count should be, calculated from the encoder count e.g.
After each move the encoders are checked against the motor counts (bottom line against top line) by the CPU. If the difference exceeds the value in ENCTOLS then the message
ENCON - re-enables the encoders by transferring EFP to EEP.
ENCRATIOS - this is an 8 element (16-byte) array containing the
number of encoder steps for each 10000 counts (or rather the value
in S/REV) of the stepping motor.
ENCSET - this presets the encoder counters to correspond with the
stepper count e.g. after calibration.
ENCASSUME - this adjusts the motor counts to the values indicated
by the encoders. Main uses are: (1) if an axis is moved while de-energized
ENCASSUME will correct the motor counts so the system can
continue without error or (2) after a stall detect or collision
(encoder-stepper mismatch) the system can continue by using
ENCASSUME first. See also ASSUME (3.1.1, 7.2)
ENCCHECK - this checks the encoder count against the stepper
count, using the conversion factors in ENCRATIOS. If the error in
the encoder count is more than the corresponding value in the
array ENCTOLS then the system quits with a message.
ENCCHECK only operates on motors which are selected with the
variable EEP (encoder enable pattern) which has bit 0 set to
enable motor 1, bit 1 for motor 2 etc. To enable the first two
motors only enter 3 EEP !. The word START enables all encoders
which are fitted, and this is the result of a constant EFP
(encoder fitted pattern). To change EFP enter n EFP !
ENCVEC - is an execution vector for ENCCHECK. START initialises
this to ENCABORT which issues an error message and aborts. To
force some other action instead of ENCABORT then define a new
word and put its code field address into ENCVEC. You do this with
the syntax SET ENCVEC (word), for example:-
Note: Instead of SET ENCVEC (word) you may also enter ['] (word) 2- ENCVEC !
ENCTOLS - is an array containing limits of error referred to the encoder.
Only when an error exceeds the limit is any action taken by ENCCHECK.
If you get ENCODER-STEPPER MISMATCH too often it may be because the values in
ENCTOLS are too small. To change them proceed as follows:
Use 4 + for axis 3, 6 + for axes 4 and 5. Use 1+ for axis 6.
To check current value enter ENCTOLS ? for axis 1, ENCTOLS 2 + ?
for axis 2 etc. Or enter
ENCERR? - puts the bit value of the channel which is in error
onto the stack.
ENC1, ENC2, ENC3, ENC4, ENC5, ENC6 - reads the count for channel
1,2,3,4,5 or 6 onto the stack.
ENCTEST - continually prints on the screen the output of the four
encoders.
ENCLEARN - same as LEARN but learns joint co-ordinates from the
encoder counts instead of motor counts.
Warning: the encoder counts may differ slightly from the motor counts so ENCLEARN will introduce small errors which may accumulate until the next CALIBRATE. In the case of R12 the errors can be unacceptably high so ENCLEARN should not be used with the R12.
EFP - Encoder Fitted Pattern - This is a value in which each
bit corresponds to an axis. A bit set means that axis has an
encoder fitted. START transfers this value to the variable EEP
(encoder enabled pattern).
The DSP is used for all motion control and values are passed to it from the CPU.
The speed of the robot is determined by SPEED.
The effect of changing SPEED is to change the height of the
plateau in diagram 3. To see what speed is currently set enter:-
Regardless of the value in SPEED the speed of the track may be limited
by the variable TRACKSPEED. Put a bigger value in TRACKSPEED to
make the track go faster. The speed of the track is the lowest of
the two values in SPEED and TRACKSPEED. In compound moves as in
GOTO and PLACE names the speed of the whole robot is limited to
TRACKSPEED if the track is one of the axes which is moving. As
soon as the track finishes moving the speed increases to SPEED.
In v14 this variable is ROLLSPEED
SETTINGS permits simultaneous display and editing of all the above variables and also SEGTIME (see later)
All default values will be restored by START or NORMAL
Speed may be changed during the progress of a route with 'LEARN
e.g.
To change the micro-step scaling factor to 2 for, say axis 1 you would enter
Gecko drives are always set to a micro-step rate of 10 and the value of MICRO is usually 4 for R17 and various values for R12.
With this method pressing a key on the teach box moves the arm.
Since you might let go of the key at any time and expect the
robot to stop it is not possible to accelerate to high speed.
Moreover a slow speed may be more desirable to achieve precision,
and the teach speed is determined by the value of CREEP-FACTOR,
which is requested after you enter TEACH. If you just hit the
return key then the value entered last time TEACH was used will
be retained. CREEP-FACTOR defaults to 16 after typing START.
After entering TEACH you are now in "TEACH mode". To move the arm first select the joint to move J1 to J6. When a joint is selected the terminal will beep. Next press either + or - for motion in a positive or negative direction. On an R12/R17 the hand is driven by two motors, 4 and 5, selected with J4 and the wrist twist is motor 5 only selected by J5.
While the robot is moving it can be stopped with the large red soft stop
key. This button is the same as the stop mushroom on the front panel and is always active even when TEACH has not been invoked.
The gripper is selected with the key marked 'GRIP', then to close the gripper press the + key and to open the gripper press the - key.
To see where you are press the key marked 'WH?'.
The home key (top right) returns the arm to the HOME position.
If you are learning a route then when you are ready to learn press the tick key. This simultaneously learns/adds line to the selected route in RobWin and to the route in the controller. To delete the last step learned press the FN key, then while still holding the FN key press the cross key.
You can change the speed up or down by pressing SPEED then + (to increase) or - (to decrease). A message appears on screen to confirm this.
If the system is in Cartesian mode when the TEACH box is used then the new Cartesian co-ordinates are COMPUTEd after each move of an axis. The tick key learns these Cartesian co-ordinates.
If the robot is de-energized and moved by hand then when the tick key is pressed JOINT co-ordinates are taken from the encoders and learned. This is the same as ENCLEARN. Again this only works when teach mode has been invoked with the
The FN key can be programmed to execute some other word if pressed - chosen with SET. Suppose the word you wanted was TEST:-
Now whenever the FN key is pressed the word TEST will execute. This happens just as you release the key.
Typing START restores the action of the FN key to NUSPEED.
By default (after START) if pressed FN invokes NUSPEED which requests you to enter a new value for CREEP-SPEED through the computer keyboard. You can also change speed on the RobWin screen by clicking New Speed
This is similar to the normal mode of the teach pad except that
the end effector moves in increments in X, Y or Z directions.
When Jog is entered (or when the Jog icon is first clicked) the increment size is announced - this is the amount the robot will move as a multiple of 0.1mm i.e. 10 means 1.0 mm. You can change it by clicking New Increment on the RobWin box or by pressing the space bar.
To move the robot in this mode press J1/X to select the X-axis or J2/Y for the Y-axis or J3/Z for the Z-axis. Then press '+' or '-' as appropriate. The robot will move by the increment size in the direction selected, for example after pressing J3 then each time the '-' key is pressed the robot moves up a fixed amount determined by the increment size.
The J4 key selects the hand (variable PITCH) and the J5 key selects wrist roll or yaw (variable W).
On the style 2 keypad you can change the increment size by pressing the SPD key followed by the + key to increase the increment or the - key to decrease the increment.
All other keys behave the same as in the normal TEACH mode.
To exit JOG mode click escape on the RobWin box or press the esc key.
(TEACH)
This word is the same as TEACH but does not ask for CREEP-FACTOR
first. Thus it can be used without the terminal.
The teach pad may also be used for other purposes, using the
following words:
INKEYPAD
KEYPAD
This is the same as INKEYPAD except that the system stops and
waits for a key to be pressed (similar to KEY). When a key is
pressed it returns a value from the table above.
The stop button on the front panel (and teach pad) causes immediate deceleration of all moving motors. This also happens if you break the stop circuit connected to the rear jack (normally just linked). See controller manual
If a place or a route is executing at the time the stop button is pressed it will continue after (word) finishes. The word itself may include some robot movement but not another place or route. For example:
Another option is to re-enter the outer interpreter so you can type in any command you need to clear the error (see 9.4.1)
Note: Instead of SET STOPVEC (word) you may also enter ['] (word) 2- STOPVEC !
For more examples of how to re-program the stop button see end of manual.
IMPORTANT - the DSP does not check the stop button, only the CPU does.
Normally the CPU polls the stop button and if pressed it sends a
STOP command to the DSP. If the CPU is doing something else the
robot will not stop when the button is pressed. To stop the robot your CPU software must execute the command STOP.
In case of panic press the reset button.
On the menu bar click settings, open file. If you have an R17 click on R17.CFG; if an R19 click on R19.CFG, if an R15 click on R15.CFG. Values may be manually set using settings, configuration – make sure DSP, bank memory and hide mode are checked.
caps lock – All ROBOFORTH commands are in upper case, ensure CAPS LOCK is on.
Type ROBOFORTH into the console. The response should be OK and a new line with a chevron prompt >
Note: When you type anything in the console all buttons are greyed out. If you back off what you typed they will still be greyed. Press esc if in doubt.
Nothing can be learned until the data area is initialized with:
You can learn co-ordinates by creating various named data entities. Teaching the robot is normally achieved by first deciding which type of named entity to use. There are two kinds of named entities for robot positions: ROUTEs are lists of co-ordinates which are learned one at a time and which may be executed one at a time with the command RUN. PLACEs are single named positions which are automatically learned when the PLACE is created. Just by entering the name of the place the robot automatically goes there. A ROUTE is an array of positions which may be executed
sequentially or used as list of co-ordinates for reference, for example for a matrix. When a ROUTE or PLACE is created it occupies space in the dictionary (called the dictionary entry) and space in the data area (RUN-LIST) for the co-ordinates.
A route is created with the form:
RobWin should always be used to learn new positions. It then keeps track of the changes in computer memory. To save computer memory to disk click project, save. If you create new data in the command window you must upload it to RobWin by clicking
Remember also that the data area may be used to learn co-ordinates
as a simple list or by creating named data entities, but not
both.
Using either the TEACH or TELL-MOVE method or 'robot' menu drive the arm to the
desired position.
This creates the name in the dictionary with a pointer to the next available space in the data area. Even if the system is in Cartesian mode it is the joint co-ordinates which are learned.
When the place name is typed the robot goes immediately to these co-ordinates i.e.
A place name occupies 3 x 16 bytes. The first 16 byte strip is
the header and the second 16 bytes are the positional data.
Optionally there can be an approach position which the robot will
move to first before moving to the 'target' position.
NOTES: (1) If you created the place while in Cartesian mode do
not expect the co-ordinates to be the same after executing the
place name. There will always be a slight difference due to (a)
the accuracy with which the robot can conform to the original
Cartesian co-ordinates given and (b) the accuracy with which the
conversion back to Cartesian co-ordinates can be made. (2)
execution time is increased.
WITHDRAW only works if you have first entered the place name. It
will always send the robot to the approach position of the last
place name entered, so beware. To go directly to the APPROACH
position of a new place highlight the place approach position in the list, written as APPR-(name) and click 'goto'.
The approach co-ordinates are stored in the third 16 bytes in the
form of co-ordinates relative to the target position. Thus if the
target position is altered the approach position moves with it.
To confirm the co-ordinates of CAMBRIDGE you may enter:-
If there is an approach position this will show as a second line.
Comms command: To see all the places you have defined you can enter:-
To remove a place highlight the place and click delete.
NOTES: (1) when you forget a place-name, or any other word in the
dictionary, this also forgets any places, words, or other
dictionary entries created SINCE that place-name was created. (2)
If you FORGET a word created prior to the place name then the
place name will also be removed from the dictionary but its data
area will not be recovered. (Avoid this) Therefore RobWin will reload all the other entities as well as any text file after FORGETting the PLACEname.
Using the name of the route changes the context for commands such as LEARN, RUN, GOTO, REPLACE etc. For example if you have two routes R1 and R2 and you enter R1 1 GOTO then the robot will go to line 1 of route R1 or for R2 1 GOTO the robot will go to line 1 of route R2. You only need to type the route name once until you wish to change to a different route which will then be the new context for all those commands.
1. To begin learning positions highlight the new route (click on its name) and click 'Open route'. Then learn the positions as follows:-
Using motion commands
To delete a route highlight it in the routes window and click Delete. RobWin sends the word FORGET followed by the route name which recovers the space allocated to it in the data area but also removes the entry from the dictionary together all the other dictionary entries that come after it. Therefore all these other words are automatically reloaded by RobWin.
A route may be executed simply by typing
When there is more than one route first select the route you wish to run by typing its name e.g. TEST1 RUN
A route can also be run in reverse order with the command
Typing the name of the route makes it the currently active route.
All commands thereafter such as LISTROUTE, RUN, LINE, GOTO, LEARN, REPLACE, DELETE, RETRACE etc.
will apply to the currently active route and no other route.
The routes window lists all the routes created so far or in the command window enter:-
Editing in the comms window alone
LEARN - adds one line to the route.
You would not normally use any of the above commands while using RobWin as RobWin sends these commands when you click the various buttons.
ERASE erases the entire list.
UNLEARN deletes the last line learned.
STARTOVER would do the same but would also restore the NEXT
pointer to initial value which would be disastrous for any
entities which had been created. If no entities have been created
then it is OK to use STARTOVER. Normally STARTOVER and ROBOFORTH
are used together. ROBOFORTH clears out all the user's words from
the dictionary requiring a fresh load from the text file.
A list of co-ordinates is not necessarily to be RUN in sequence. It can also be used as an array or matrix of positions for example a grid of test tubes. See Matrices. To access the data in individual lines:
For ASSUME the syntax is (n) LINE ASSUME
To RUN a limited amount of the route enter:
In segmented mode as a route is being executed it is listed out line by line. This actually takes a significant time and can slow down the robot, especially for small movements. The listing can be turned off with the command LISTFLAG C0SET (pronounced "list-flag see-nought-set").
To abort the route while it is running press the escape key - the robot will stop
after executing the current line. The stop button stops the robot
immediately. The line at which the route aborted is contained in
the variable LINE#. Inspect with LINE# ?
FIRST# and LAST# are variables containing the first and last
lines to be RUN (set by SEQUENCE).
MOVES is a pseudo-variable i.e. a routine which behaves like a variable and contains
the total number of lines in the list or route. e.g.:
To have the gripper operate during progress of the program first enter GRIP or UNGRIP as appropriate to immediately operate the gripper then 'insert func' GRIP or UNGRIP. Leave the value at 0.
In Cartesian mode LEARN learns the Cartesian co-ordinates instead
of the joint co-ordinates. The same applies to REPLACE and INSERT.
However, you can force the system to learn the joint co-ordinates
instead with:
It is possible during the progress of a route to have the controller execute a FORTH program or "word" for example GRIP and UNGRIP, GET and PUT, PLACE names, other routes, changes in SPEED or other variables, or user defined words.
However it is not a good idea to 'LEARN (insert func) words which you have created because your word is looked up in the dictionary and it's code field address (CFA) is compiled into the route. This is then executed when that line is reached (using the word EXECUTE). In FORTH this is known as "vectored execution ". This address could change if you edit the text file rendering the address in the route invalid and the system will crash (and probably the robot as well). You would have to edit all occurrences of your word using edit line. Therefore stick to words in ROBOFORTH. Any ROBOFORTH words can be inserted as functions, leaving the argument (value) at zero. Words which can have values are: MSECS GRIPPER SPEED SETPA
Example FORTH word to make the robot wait until an object is
present to be picked up, indicated by bit 7 of port PB going to a
logical '1':-
WARNING: If you remove or FORGET a word which you have 'LEARNed or 'insert func' into a route then you must also DELETE the line in the route which holds it. Otherwise you will leave an invalid address in the route to be executed and the system will crash.
In the majority of cases we want the arm to do a similar movement in many different positions, that is to say that the movement should be relative to its starting position and not to its home position. To make this happen first put the robot into RELATIVE mode BEFORE creating the route. Enter:
Let's call the relative route WAVE.
WAVE is now a sub-route.
WHERE now has an additional line labelled LOCL and with initial starting values of zero. (example values, typical headers):
By inserting another route name into a route using 'insert func' (or in comms window by using 'LEARN or 'INSERT or 'REPLACE ) a robot route can be made to execute the other route then return to complete the first (calling) route.
If the sub-route WAVE is tick-learned into an absolute route using 'insert func' and
the absolute route is run then when the line containing the sub-route is executed the sub-route will run relative to the robot's position at the previous line.
If RELATIVE is typed AFTER THE ROUTE IS CREATED then the route
will be absolute but LEARN will learn the LOCAL positions. These
positions are given RELATIVE type flags indicated by an 'R' e.g.
If a route is already created and you want to change it into a
sub-route then type:-
ALL 0 MOVETO makes the arm go back to the LOCAL home position
ABSOLUTE cancels RELATIVE mode.
NOTES
(2) When a RELATIVE route is executed it saves the current
position (i.e. the position last at before the route is executed)
on the stack. If the current position is itself relative (e.g.
when sub-routes are nested) it is the local position which is
saved. When the route finishes the position values are 'popped'
off the stack again. If the sub-route does not actually finish at
the same position it started then the difference between starting
and finishing positions is added to the saved position values as
they are restored from the stack.
(3) If the escape key is pressed any route will abort after the
current line is complete. In the case of nested sub-routes each
level will abort leaving a true GLOBAL position.
(4) For information in nested sub-routes, each route announces
itself as it begins (unless LISTFLAG is zero). When a sub-route
finishes it announces the name of the route which called it.
The number of positions in the row is held in the variable POSNS
Dialog box showing creation of a new matrix TRAY1 in Cartesian mode, 10 columns by 5 rows.
The number of positions in each row of the GRID is held in the variable POSNS. The number of rows is in ROWS.
A number of words are provided to work with ROWs and GRIDs. They all require an extra line added to the list which contains a relative (type R) co-ordinate which is added to any line to make an approach position for every line. This line is always the last line and the address of the data is data is MOVES E@ LINE
You can create this approach position as follows:
Cartesian mode
In joint mode the co-ordinates learned are those shown against LOCL in the WHERE display and in Cartesian mode the co-ordinates learned are the difference between the current position and the PREVious position shown in the WHERE display.
Once the relative position, line n+1 has been learned a number of other words may be used:
(n) NEAR
(n) NEARAD
(n) INTO
DOWN
UP
Before using any of the above words the route to which they refer must be selected. If in doubt enter the name of the route again; Remember to use the route name in any definitions.
An example of how to use these commands.
To cancel CONTINUOUS mode enter
The speed in continuous path mode is determined by the variable SPEED. A value of 1000 is a low speed, 10,000 is a high speed. Highest possible is 32767 but of course the robot may not be able to do that. Acceleration is determined by the variable ACCEL 100 is very low acceleration, 5000 would be a high acceleration.
The route may contain contain joint or Cartesian values.
To change speed within the route go to the route box and highlight the required line before which the speed must change. Click 'insert func' then enter SPEED in the dialog box and the required speed below it.
To turn the gripper on or off within the route go to the route box and highlight the required line at which the gripper should operate. Click 'insert func' then enter GRIPPER in the dialog box and the value 1 below it to turn it on, or 0 to turn it off. You cannot use the word GRIP which only works in segmented mode.
STOP BUTTON:
This programmed path comprises 2 right-angle turns. The DSP rounds off the corners according to the acceleration programmed. A high value for ACCEL means a tighter turn (smaller radius). In the above the robot is able to change direction by 90 degrees and back again in the space between lines 2 and 3.
In the above lines 2 and 3 are too close together. The DSP obviously cannot round off both corners so the CPU issues the message "too tight, line 3". Only if ACCEL is increased i.e. reduce the radius of the two curves can the robot make it round both corners. If SPEED is reduced this has the same effect i.e. smaller radius.
For similar mathematical reasons if the distance between lines 1 and 2 is too short then the DSP can not get the robot up to set speed before the first change of direction so would issue the message "too tight line 2". Similarly if lines 3 and 4 are too close the message would be "too tight line 4".
The cure is to reduce the value of SPEED or increase the
acceleration ACCEL. The route is tested first so that the error
does not occur while the robot is in motion and if there is no
such error in the route then the route is run. You can test the
route yourself with the command
There are 2 modes of RUN for the R19, DRY (2) and CONTINUOUS (1). After a DRY RUN, CONTINUOUS is re-asserted. Whenever RUN is executed a dry run is automatically run first to make sure settings are valid.
There exists the possibility to reduce the speed of a route automatically and temporarily with the command
Note that this command will not work if there is a SPEED command
embedded in the route. The system will hang and you will
have to press the escape key to get the system
back. In this case ERR value will be 23 (See section 11.2).
When ADJUST is used the value of SPEED is reduced
until a workable value is found. You will need to restore the
original value yourself with (value) SPEED !.
2. ?RUN
This leaves a value on the stack as follows:
WARNING If you use this command the robot will not stop when you press the stop button. To stop the robot execute the command STOP.
CRUN passes the route data to the DSP but does not wait for it to finish. If the route is short enough control passes straight back to the CPU i.e. you will get OK or the next word will be executed while the DSP is still running the robot. If the route is a long one then the CPU will be held up for a while. CRUN ought not be used with routes that contain SETPA or GRIPPER commands because the CPU must remain monitoring the DSP to get these commands as they arise. When the robot has stopped WHERE will show the robot to be still where it was before you executed CRUN therefore you must, as soon as robot motion finished, or at worst before you execute the
next command, execute
To determine if the DSP has finished use EITHER:
During the first phase (loading buffer) no other activity takes place. During the second and third phases ?GRIP is executed which transfers SETPA or GRIPPER flags to the PA output port. Therefore if you use CRUN, when control is returned to the CPU, no further SETPA commands will be executed. The DSP continues to issue flags but the CPU is not reading them. You must therefore include ?GRIP or ?RUN in the code following CRUN if you want to use SETPA. ?GRIP is a self contained word that operates the output register directly. ?RUN polls the DSP and leaves a flag on the stack as listed above.
STOP
ESTOP?
If ?RUN ever returns a true value when it should not be, for example due to a programming error confusing the DSP you can send the command:
In the example above it is assumed that CRUN has completed as far as the CPU is concerned and the DSP is busy running motors, and issuing flags as programmed. However in the case of a long route the software might be in the second phase of running, and therefore the robot will be moving without MONITOR being executed.
Vectored execution is a way of making sure that a given word is executed all the time the robot is running regardless of which phase the CPU/DSP communication is in. A variable DSPVEC is provided which if non zero will be executed at every opportunity during 2nd and 3rd phases. Remember that this will be executed repeatedly, maybe thousands of times so you need to write appropriate logic for a single operation of something.
Insert function into a straight line
You can also use the straight line function in the curve generator commands of RobWin7. See RobWin7.pdf
From any position in the workspace you can run the route as if it was starting from that position. Use
The basic code for this is below.
The principle of operation is as follows:
The DSP can compute a trajectory for a multi-axis move. It works only with motor counts and only with the change in motor counts, not the actual values.
Normally DSP moves (such as DSPMOVE and CONTINUOUS RUN) subtract the current joint coordinates from the target coordinates and send the difference to the DSP. In a route RUN situation the differences from line to line are computed by the CPU in FORTH and sent to the DSP as fast as possible. The DSP stores them in a buffer. If the buffer is full then the CPU program waits for space to be available. If Cartesian coordinates are used (which they usually are) these are converted to joint coordinates on the fly using TRANSFORM
The DSP uses the whole list of values to compute speeds and ramps for each joint. If this can not be computed (see manual) then a “too tight” error is raised.
As in the previous section the second mode of operation in RUN is TIMED. In this each segment (distance from one line to the next) is executed in a fixed time, the value in SEGTIME in mS. The speed is adjusted by the DSP so that the move is completed in that exact time. A long move requires a higher speed. CHASE is related to that.
A mode in the DSP allows us to check if the buffer is empty. When we send a move to the DSP it immediately starts on it and empties the buffer. We can then send the next move while the DSP is working on the last one. The buffer is now not empty and we must wait for it to be empty before we can send the next. Sequence is therefore:
send move n – DSP starts on them, buffer is empty
send move n+1 – DSP buffers them, buffer not empty
DSP completes move n and starts on n+1, buffer is empty
now we can send move n+2 and so on.
So we can never have more than one move in hand. If you are using a PC program to send these coordinates then it will need to know when the controller is ready for the next coordinates.
In the program CHASE below, to start with we initialize the DSP and set a starting condition. Then we enter a loop: BUFZ is a trap that waits for the buffer to be empty. While in this trap nothing else can be done.
As soon as the buffer is empty BUFZ drops through to
GETCART – this is where you can send the new coordinates to the robot. You have some time because in theory the DSP is still working on the last segment and the robot is still moving. If you are using a PC supervisor then you need to send a message or a character from GETCART to the PC it to indicate GETCART is ready for the coordinates. The PC then sends the coordinates in some form. GETCART needs to parse the string and get the values in to X Y Z PITCH and W (roll) (5-axes) or X Y Z PITCH YAW and ROLL (6-axes). Or just send X Y and Z if the hand parameters do not change.
As soon as the new coordinates are received NEXTSEG computes the changes in motor counts and sends them to the DSP. The DSP attempts to do this move within the time in SEGTIME. For a short move the speed will be low and for a long move it will be high.
NEXTSEG returns a status which should be zero. If you sent impossible coordinates such that the speed required to do that move within SEGTIME is too great then NEXTSEG returns false and we need to stop everything. The procedure prints the “segment too long” message and aborts with error 31. (that value goes into ERR.) If using a supervisor you can change this to some other string or single character or even an output on the PA port.
A project is provided, CHASE. It may be downloaded from the ST Robotics downloads page as CHASE.ZIP. In this project is a route called LIST1 which is just a list of Cartesian coordinates.
INIT sets workable values for ACCEL and SEGTIME. Change them as necessary.
To test the algorithm a program RJ is provided (random jump). A number is picked from the sequence
CREATE SEQUENCE
1 , 5 , 3 , 9 , 10 , 4 , 2 , 8 , 7 , 3 , 1 , 0 , ( 0 means stop
so that 1 means get the coordinates from line 1, 5 means get coords from line 5 etc. The numbers are picked at random although a jump from 10 to 1 could result in the too long error.
The result is as on the youtube video at
http://www.youtube.com/watch?v=1j_o_vwruGI (chase.avi)
The object can be introduced into the system in a number of ways:
This tells the system that the robot is holding PART.
Alternatively the object may be placed at a known position e.g.
To make the robot pick up the object first send the robot to the
position with the place name or with GOTO e.g.
In the case of a single position the arm moves to the position
then the grippers close on the object. In the case of a place
name with an approach position the arm moves via the approach
position to the target position, the grippers close on the object
then the arm moves back to the approach position. Confirm with
WHERE, VIEW (position) and WHEREIS (object)
The object can be put at a known position by first sending the
robot to the position with a place name or with GOTO then
entering PUT e.g.
When an object is logically transferred to a position with PUT or
ISAT the position is also recorded in the object's data field.
This information is used by WHEREIS and also facilitates GOGET
e.g.
IMPORTANT: GOGET (object) cannot be compiled into a definition.
Another form which can be compiled is (object) COLLECT e.g.
A list of all the objects so far created can be had with:-
Notes:
UNGRIP removes the object from the known workspace (sets OBJECT-HELD to zero).
WHEREIS PART NOWHERE
To clear an object from a place or a line use
OBAD is a word which converts a route line address to the memory location address which contains the object. Thus you can manipulate the object field directly with e.g.:
To clear all the objects from a route use:
WARNING: All words are stored in the dictionary as a length plus the first 5 characters of the word.
Example. Suppose you have created some PLACES called BELT and LATHE, you might write the definition of a word to use these places in your .ed2 text file:
The standard I/O has three ports which are called PA PB PC and PD. Each
of these is based on the communications register principle, and can
be controlled on an individual bit basis and outputs can be read as well
as written. PC and PD are only used by the teach pad. The addresses of these ports have constants in
ROBOFORTH; the constants are: PA PB PC and PD
TO OUTPUT connect to PA as indicated on connector pinout in the controller manual.
The most basic form of output is:
Any output port can be read back e.g. PA IN . 55
Individual bits may be manipulated:
(port) (bit) OFF turns off a single bit of the output.
Suppose there were an air solenoid connected to PA 4. You could
turn it on with PA 4 ON and off with PA 4 OFF
Now you can type (or include in a higher level definition):-
If a second Peripheral Interface Adaptor (PIA) is fitted the other output ports are QA and the upper 4 bits of QC.
In case of accidental un-programming of either PIA enter:
You may wish to have an output activity synchronized with robot motion. The way to do this is to embed an I/O word into a route using Insert Function. If you will run the route in segmented mode then you can insert any word either already in ROBOFORTH such as GRIP/UNGRIP or any new word you define though the latter is not recommended. You may used the word SETPA with a value in which case an output will turn on or off depending on the value. Remember that the robot will stop and wait for any word which takes time. If you wish to run the route in continuous mode then only certain words may be used, notably GRIPPER and SETPA. SETPA will turn an output on or off depending on the value of the argument. Remember that the robot will not wait for the output activity to complete but will continue moving. A typical use of this function is controlling a spray gun for e.g. overspray.
The most basic form of input is:
Note that this is an 8-bit twos-complement integer.
(port) (bit) BIT? leaves a true if that bit of input is true and false if that bit is a false.
For the purposes of words like IF and UNTIL zero is FALSE but any value is TRUE. Using the FORTH syntax definitions could be built up as follows:-
WARNING: because BIT? leaves any value for a true, not
necessarily a '1', you may not be able to use AND, for example
after defining : SW1 PB 5 ; : SW2 PB 6 ;
Another word is WAIT which waits for the specified input to change to a specified state. Example:
Note that any PB bit can be used to generate an interrupt. Normally PB 6 is chosen.
If a second PIA is fitted the input ports are QB and the lower 4 bits of QC.
In case of accidental un-programming of the PIA enter:
To set up a slow search you must first determine the criterion
for the search. Define a word which leaves a true when the
search is to end, for example if the light beam device is
connected to, say, bit 5 of port PB, normally a '0' going to '1'
when the beam is interrupted:-
Note: In some versions before Jan 1993 you cannot use SET in a definition.
Instead of SET CRITERION (word) you must enter ['] (word) 2- CRITERION !
Test the slow search with ?TERMINAL which leaves a true if the
escape key is pressed:-
TELL WAIST SLOWSEARCH
If the beam is interrupted in the first example or if the escape
key is pressed in the second example while the robot is in motion
then the robot will stop immediately.
WHERE
The fast search accelerates the selected motors to the full SPEED value. The CPU then checks the criterion and if true sends a STOP command to the DSP and reads back from the DSP where it had got to (DSPASSUME).
To search in the opposite direction use the form:-
A straight line search may be achieved by creating a route which is a straight line.
You can make a ROW and just learn the start and finish then click interpolate. See section 7.3.3
Learn the route such that it is long enough to start in front of the object you are searching for and ends after it.
For example if searching for a surface make sure the route passes through the surface. The route can be moved later using
START-HERE (see section 7.3.9).
Suppose you wish to search vertically (Z axis only) and the route is called ZLINE and your sensor is connected to PB 7.
(see section 8.2).
Put a valid word in INTVEC. See vectored execution, 7.3.8. The word must have the word RETURN as it's last line before the semi-colon for it to work with interrupts e.g.
It is possible, within the definition of a word that has been invoked by an interrupt, to change the contents of INTVEC to a new word so that the next interrupt executes the new word.
There are two kinds of interrupts available:
RETURN returns the word to machine code that ends this interrupt and re-enables the interrupts for next time.
Rules
See section 12 for programming example.
RobWin treats all this as a project. Work is saved to disk by creating or opening a project then saving it back to disk. A project comprises 3 files with the same name and 3 different file types:
WARNING: All words are stored in the dictionary as a length plus the first 5 characters of the word.
UPLOADING
DOWNLOADING
The commands can then be PRINTed to the controller e.g.
PRINT#1,"PURGE". The response from the controller will always be
a reflection of each character sent, except the final return
character which is echoed as a space character. After executing
the command the response should always end in 5 characters:
This response may come (a) immediately, (b) after some unknown
time, (c) not at all (in the case of some task which never ends).
The host software should look for the >. The preceding string
should therefore be OK, if not then there was some error message.
NOTES: (1) All characters which come back from the controller
must be used up or "buffer overflow" will occur. (2) Always CLOSE
the channel before SHELLing another program then open it again on
return.
You can now replace WHERE KEY DROP with OUTER e.g.
short OpenComm(short Port, long BaudRate);
Changing baud rate on port 0
The Baud rate factor is in a location BAUD. The value of this factor is 2,000,000 divided by the required baud rate. So the default value is 2,000,000 / 19,200 = 104 (round to nearest integer) or 68 hex. So if you type:
To send a character out of the serial port use EMIT e.g.
HEX 41 EMIT sends a capital A to the screen
To get a character (byte) from the serial port use KEY - when a character arrives KEY leaves its ASCII value on the stack e.g.
You can read the incoming byte without waiting with INKEY
Second serial port (channel 1)
To access the second serial port change the value of IOFLAG from 0 to 1 with
To get a byte from the second serial port use KEY (as described above) but set the IOFLAG to 1 first, then back to 0 to return control to the computer (channel 0). Note that the system will be stuck in KEY until a byte arrives so if none arrives you'll have to press reset. However you can check to see if a character has arrived by reading port D5 bit 0 e.g. within a definition :
Note that all serial communication words such as . (print), ASK, EXPECT etc will be via the second serial port if IOFLAG is set to 1.
Before ever DEMO is forgotten, or words below it are re-compiled
the controller must be put back to warm start position until AUTO is
used again.
When using a text file define the (word) to be executed on power-up and at the end of the file put AUTO (word) (see section 7.5).
WHICH
MODE
VIEW (position)
WHEREIS (object)
LISTROUTE or L.
VLIST
'VLIST (word)
ROUTES
PLACES
OBJECTS
POINTS
P
PP
XX WATCH
HERALD
WRU
SETTINGS
XX WATCH
ENCTEST
Further tests are available as projects.
If the computer or terminal is not connected when the error occurs then
the error can be found by inspecting the value in the variable ERR
e.g. ERR ? or you can write WWW (what went wrong?)
You also can arrange your own error traps with
(n) ABORT
FORTH errors
Look out for possible stack errors including stack overflows. For
example you might confuse the syntax of WAIT with BIT?
Disaster - there is no BEGIN.
During compilation (downloading to the controller) the controller uses the stack to calculate nesting loops. So unequal nesting could result in a stack underflow error. If not then try the command .S
A nest is a known location in the work space to which all the
other locations are related.
The nest should, ideally, be a separate location to any of the
positions which have been learned. For example make and mount a
dummy fixture that the robot's end effector can fit onto/into
with some accuracy. Type WHERE and note the (motor count)
positions. Suppose this resulted in:
The values are entered value space comma space value etc. There
should be 8 values in all so make the last three (or more) values zero.
Note: most learned positions are created in bank 1 of memory but a CREATEd position is in bank 0.
The system needs to be reminded which bank the CREATEd position is in, especially after using most motion commands which automatically switch to bank 1. Use the phrase:
Note that both PB bits 6 and 7 must be low for the robot to put
a part into the jig. Thus if the test rig is switched off or if
either line breaks the jig cannot be loaded (fail-safe).
PROGRAMMING:
3.2.1 POINTS
Cartesian co-ordinates can be recorded in different ways: one is
by using the defining word POINT e.g.
POINT P1
The current co-ordinates are recorded in the parameter field of P1
and may be viewed with:
VIEW P1
The robot will go to that position with:
P1 GOTO
which drives the arm to the co-ordinates of P1.
To list all points created so far enter:
POINTS
100.0 X ! 200.0 Y ! 300.0 Z ! 90.0 W ! 0 PITCH !
POINT P1
3.2.2 TOOL TRANSFORMATIONS:-
Initially it is the wrist pivot which actually occupies the
specified co-ordinates. To make specified co-ordinates apply to the
tip of the end effector enter the length of the end effector or
tool into the variable TOOL-LENGTH. e.g.
1000 TOOL-LENGTH !
Alternatively use the command:
TOOL
This asks for the pitch of the wrist, the attitude of the wrist
and the tool length, all of which can be different for the same
x-y-z location in space. At the end of this sequence is the
question EXECUTE? If you press Y the tool is immediately re-
positioned but if you press N the TOOL parameters are not acted
upon until the next time MOVE or MOVETO are used.
PLUNGE
is similar to the VAL word APPRO. Whichever direction the end
effector is pointing PLUNGE will move the end effector in that
direction. For example suppose the end effector is at a PITCH of
45.0 degrees. then
1000 PLUNGE
will move the end effector 100.0 mm in the direction 45 degrees
to Z-plane. This is a Cartesian word but works whether the system
is in Cartesian or JOINT mode.
NONALIGN is typed. This cancels align mode.
4
The encoder system comprises additional hardware and software in the DSP card for up to six incremental encoders, one encoder per axis.
ENCODERS
WAIST SHOULDER ELBOW L-HAND WRIST OBJECT (R12/R17)
2000 0 0 0 0
xxxx 0 0 0 0
2010 0 0 0 0
WAIST SHOULDER ELBOW L-HAND R-H/YAW WRIST OBJECT (R12/R17 - six axis)
2000 0 0 0 0 0
xxxx 0 0 0 0
2010 0 0 0 0
TRACK LIFT EXTEND HAND WRIST OBJECT (R19/R15)
1000 2000 3000 0 0
642 2406 3604 0
1001 2005 3003 0
In this example there is a slight error in each axis according to the encoders, but these errors are within the encoder tolerances, ENCTOLS. They represent very small angles or displacements indeed when you consider, for example in R17 that there are about 18000 counts for 90 degrees of shoulder movement.
ENCODER-STEPPER MISMATCH AXIS (and the axis number) is displayed.
The words which may be used are:-
ENCOFF - disables all encoders but leaves their values displayed
by WHERE and ENCWHERE.
It may be viewed with
VIEW ENCRATIOS
The value of each element is the number of counts per encoder divided by the number of counts per rev of the corresponding motor, times 10000
Encoders generally have 128 lines per rev. Because of the quadrature algorithm this produces counts of 512 per rev. So, for example, if there were an encoder coupled 1:1 to a motor that needs 500 microsteps per rev then the value in ENCRATIOS would be 10240 for a 128 line encoder or 8000 for a 100 line encoder.
The array can be addressed as follows:
ENCRATIOS @ or ! - 1st element (waist), ENCRATIOS 2+ @ or ! - 2nd element, ENCRATIOS 4 + -3rd, ENCRATIOS 6 + -4th.
START loads EFP into EEP, but EEP may be manipulated during program flow,
for example to deliberately disable an encoder to permit a stall
situation, then re-enable it to correct the error on the next move.
: ALARM PA 6 ;
: STALLED ALARM ON KEY DROP ALARM OFF ENCASSUME ;
SET ENCVEC STALLED
This last line replaces the "ENCODER-STEPPER MISMATCH" error message with the action taken by STALLED. Then in case of a serious encoder mismatch the robot will stop and wait for the user to press any key. Then the error will be corrected and the robot will carry on.
If a place or a route is executing at the time the error occurs
it will continue after the word finishes (IF it finishes - if the word contains ABORT the system will not continue). The word itself may include some robot movement but not another place or route unless this is the last motion before an ABORT for example:
: STALLED ALARM ON KEY DROP ALARM OFF ENCASSUME HOME ENCABORT ;
To change the value for the first axis (waist or track) enter:
(value) ENCTOLS C!
To change the value for the second axis enter:
(value) ENCTOLS 2 + C!
Note: these values are 7 bit integers, maximum value 127.
ENCTOLS DUMP to see all the values.
In V12 EFP is a variable - to read its value enter:
EFP ?
The value of this variable can be changed by
typing (val) EFP !
In V11 EFP is a constant - to read its value enter:
EFP .
The value of this constant can only be changed by
typing (val) ' EFP !
5
You will have noticed that every time the arm moves it
accelerates and decelerates. At low speeds the stepping motors
move in pulses, stopping between each step ("Pull-in" speed).
The software accelerates ("ramps") the motors to a speed where
motion is more continuous and does not stop between steps ("pull-
out" speed). The controller creates a rotating magnetic field
which the motor armature follows. The armature and the robot have
inertia so the controller must accelerate the motors then
decelerate to the pull-in speed before stopping. Diagram 3 shows
a typical speed profile.
SPEED
SPEED ? 10000 OK (example)
The maximum speed achieved can be changed by entering a new value
for the variable SPEED as follows e.g.
(n) SPEED ! OK
A value of 1000 is a low speed, 10000 is a moderate speed, 30000 is a high speed. Maximum is 65535.
For short moves maximum speed (i.e. the value of SPEED) may not be reached before deceleration must begin.
Click Settings, Variables.
'LEARN SPEED 7500 (or other value or other variable)
Associated commands are:
(line number) 'REPLACE SPEED (new value)
(line number) 'INSERT SPEED (new value)
See section 7.2.1
5.1
Changing the value of SPEED does not affect acceleration, just as in diagram 3. Acceleration is determined by the variable ACCEL e.g.
ACCELERATION
ACCEL ?
change with (val) ACCEL !
100 is very low acceleration, 5000 would be a high acceleration.
If the robot cannot reach SPEED within the distance programmed (depending on ACCEL) then a lower speed is reached as in the short move in diagram 3.
5.2. Micro-stepping
Generally a stepping motor has 200 steps per rev or in half step mode 400 counts per rev. In micro-stepping mode at 10 micro-steps per full step and a scaling factor of 4 in the software then there are 500 counts per rev. That scaling factor is in the array MICROS.
MICROS is an array with a different value for each motor. In this way the software is better matched to different axes which have substantially different loadings and gear ratios. The micro-step scaling factor for the waist is in MICROS, for the shoulder/lift MICROS 2 +, for the elbow/extend MICROS 4 + and so on e.g. to find the value for axis 3:
MICROS 4 + ? 4 OK
2 MICROS !
To change, say axis 2 to a value of 1
1 MICROS 2+!
6
To start moving the arm enter:-
TEACH PAD
TEACH
click ![]()
To exit TEACH mode click escape on the RobWin box or press the ESC key.
Teach pad
LED lamps are self explanatory

Key designations:
Joint R15 R12/R17 R12/R17 six R19 Cartesian
J1 track waist waist waist X
J2 extend/lift shoulder shoulder lift Y
J3 lift/extend elbow elbow extend Z
J4 hand/axis4 L-hand L-hand hand Pitch
J5 wrist/axis5 wrist R-hand/yaw wrist W/Roll/Yaw
J6 axis6 track wrist track plunge
Note that the tick and cross only work when teach mode has been invoked with the
button.
button.
Warning: the encoder counts may differ slightly from the motor counts so ENCLEARN will introduce small errors which may accumulate until the next CALIBRATE. In the case of R12 the errors can be unacceptably high so this feature should not be used with the R12.
SET FN TEST OK
JOG mode
If in Cartesian mode you may enter:-
JOG
click
For these two axes the increment is a multiple of 0.1 degrees, i.e. to rotate hand by 90 degrees change the increment to 90.0
The WH? key displays the current Cartesian position of the robot.
The tick or LRN key learns the current Cartesian position.
To delete a line on style 2 pad press FN then while still holding FN press the cross.
If you let go of the FN without pressing the cross then FN will be executed.
The default for FN in JOG mode is ALIGN however it can be reporgrammed as with TEACH.
KEYPRESSED? returns a true if a key is being pressed, 0 of not.
this returns a zero if no key is being pressed, but if a key is being pressed it returns (puts onto the stack) a value
corresponding to the key being pressed (similar to INKEY). The
value returned is according to the following table:
Key:
J1
J2
J3
J4
J5
J6
home
WH?
hex
11
12
14
18
48
44
41
42
decimal
17
18
20
24
72
68
65
66
Key:
GRIP
FN
tick
X
+
-
SPEED
STOP
hex
21
81
22
82
24
84
28
88
decimal
33
129
34
130
36
132
40
136
Note that 88hex/136dec is always the stop key and is polled
continuously by the system while motors are running.
(except where control has been passed to the DSP)
6.1
STOP BUTTON
WARNING: when the DSP is controlling motion by itself e.g. with the commands DSPMOVE, DSPSMOOTH or CRUN then you must send the command STOP by typing it yourself or have it in your defined words.
Normally STOPABORT is then executed which issues a message and sets ERR to 3. But the response to the stop button may be re-programmed to another word using vectored execution e.g.
SET STOPVEC (word)
For example (27 or 1Bhex is the ASCII value of the escape key)
: ESTOP
CR ." Stop button pressed - hit esc to abort or any other key to continue"
KEY 27 = IF STOPABORT THEN
;
SET STOPVEC ESTOP
: ESTOP
CR ." Stop button pressed - hit esc to abort, spacebar to withdraw and continue or any other key to ignore"
KEY DUP 27 = IF STOPABORT THEN
ASPACE = IF TELL EXTEND 0 MOVETO THEN
;
SET STOPVEC ESTOP
: ESTOP
CR ." Stop button pressed - hit esc to abort, spacebar for new command or any other key to ignore"
KEY DUP 27 = IF STOPABORT THEN
ASPACE = IF OUTER THEN
;
SET STOPVEC ESTOP
Once you have typed in your commands to recover from the problem you can press escape to abort everything or you can type EXIT which continues the program which was stopped. Note the program will assume the stopped motion was completed and continue from there.
Other words
STOP? Checks stop button and leaves true if pressed.
STOPCHECK Checks stop button and aborts if pressed.
- if it's pressed executes STOPABORT
?STOP
is a loop which waits until the DSP has finished. In addition it
checks the stop button. If the stop button is pressed it sends
the STOP command to the DSP, sets a flag FSTOP to '1' then waits
for the DSP to finish.
As long as the CPU is in command mode or executing some other
command the stop button is ignored.
7
TEACHING
Before you can teach the robot anything you have to start a new project (or load an existing one) as follows:
Starting a new projectRun RobWin
Double-click on the RobWin icon. Along the top are the menu buttons, below that is the robot tool bar and below that is the macro bar.
Switch the key switch to cold start and switch on the robot controller.
In the communications window (the console) you should see a herald which includes the words ‘cold start’ (see next page) and a chevron prompt >.
In the tool bar press the start button or type START into the communications window. This energizes motors, zeros all position counts, sets default values for SPEED etc.
Press the Calibrate button or type CALIBRATE Robot moves to the calibrate position and calibrates all axes.
Press the Home button or type HOME Robot moves to the HOME position in which all motor counts are zero.
Open a project
Click project, new and choose a name for your project for example myprog.
When the project is open you will see three more windows: routes, places and a window labeled myprog.ed2
We advise (from experience) to move the communications window to the bottom and to re-arrange the other three so all are visible.
The system sends commands ROBOFORTH and STARTOVER to the controller which you can see in the communications window. This clears out the controller ready for the new session.
7.1
All data is stored in a data area in memory bank 1 which begins at the location
given by the constant RUN-LIST e.g. RUN-LIST X. Each co-ordinate
learned occupies 16 bytes. The first 16 bytes at RUN-LIST is a
block header. The next 16 bytes will be the first co-ordinate or
the header of a named entity (see later) also 16 bytes. The
address of the next available 16 byte strip is maintained in a
variable NEXT (enter NEXT @ X.).
LEARNING POSITIONS
STARTOVER
Among other things this sets NEXT to RUN-LIST plus 16.
Starting a new project executes STARTOVER so there is no need to type the word.
ROUTE (name)
using a (name) of your own choosing, then learn some co-ordinates.
A place is created with the form:
PLACE (name)
using a (name) of your own choosing.
However, you should NEVER use these commands. Always allow RobWin to create the controller entries for you.
When you have created the ROUTE or PLACE, then RobWin immediately enters the same form into a text file, extension .ED1 and in the same order they were created. At the start of this file RobWin places the words ROBOFORTH and STARTOVER. When this file is re-loaded the controller is put in OLD mode and the routes and places are re-created using old (existing) data i.e. the co-ordinates you learned in the first place. The same thing happens if this text file is loaded using Z380.BAT but type the word OLD first. Normally routes and places are created in NEW mode.
. This button will only update any routes or places which have already been created using RobWin.
7.2
Any position in the workspace of the arm can be named, and its
co-ordinates recorded so it can be returned to at will later by
giving it a PLACE name. When a PLACE name is used it executes
itself automatically - that is the robot drives immediately to
the co-ordinates learned unlike a ROUTE which requires RUN.
Furthermore all PLACES are ABSOLUTE and leave the system in
GLOBAL mode after use.
PLACES
Find the Places window and click 'new'. Enter a name for the new place e.g. CAMBRIDGE
comms command PLACE CAMBRIDGE
CAMBRIDGE and the robot goes to the co-ordinates of CAMBRIDGE.
The place name can of course be used in the definition of a higher level word.
click 'GoTo'
Note that HOME is a place name but its co-ordinates are in the ROBOFORTH dictionary, not in the data area.
To learn an approach position move the robot to the desired position and click 'set approach' on the places window.
Comms command APPROACH followed by the place-name.
Now whenever the place name is typed the robot will move via the
approach position to the target position.
WITHDRAW moves the robot back to the approach position.
Comms command 'NEAR (place-name) GOTO
VIEW CAMBRIDGE
Click 'show data' in the places window to display co-ordinates of all the PLACEs.
To change the approach position simply drive the robot to the new approach position, click APPR-(name) and click 'set-to-here'.
Comms command APPROACH (name)
To change the target position drive the robot to the new position, click the place name line then 'set-to-here'.
Comms command PLEARN CAMBRIDGE
PLACES (see VLIST)
nnnn 7 TRENT.. nnnn 9 CAMBR.... nnnn 4 HOME
3 words
OK
The "nnnn n" in the above are the RAM address and lengths of each
word in the dictionary. See VLIST under INFORMATION.
Comms command sent is FORGET (place-name)
This recovers both memory used in the data area and memory in the
dictionary.
7.3
A ROUTE is a named list of positions which can be RUN. When the
route is run the arm moves from one arm position to the next.
Each position is a list of motor co-ordinates, one for each motor
in the same form as shown after entering WHERE. The method of
teaching the robot is as follows:
ROUTES
First choose a name for the route e.g. TEST1
Click the Routes window and click New. Enter the name TEST1 in the dialog box. Check the box to choose a Cartesian or Joint route. RobWin sends the string CARTESIAN or JOINT ROUTE TEST1 to the controller.
By default ROBOFORTH creates a Cartesian route if in Cartesian mode but in RobWin you need to choose whether a route will have JOINT or Cartesian learned positions. When the name of a route is used the system changes to whichever mode the route was specified, Cartesian or Joint.
When a route is created space must be reserved for the expected number of learned lines. This may be increased later if necessary. The route create dialog box asks how many lines to reserve. By default it is 20. RobWin sends the string (n) RESERVE to the controller which moves up the NEXT pointer (inspect with NEXT @ X.) to reserve space for this route before another named entity is added.
If you need to change the reserved space later (either increase for more lines or decrease to save memory) then first close the route, highlight its name in the route list box and click 'change size'.
2. Click 'robot' then absolute or relative Cartesian or joint move and enter the desired target position or relative move.
OR enter motion commands e.g. TELL WAIST 1000 MOVE (Joint) or 100.0 200.0 300.0 MOVETO (Cartesian)
Generally it is best to use the robot drop down menus for Cartesian positioning but may be more convenient to use commands for joint positioning.
3. On the open route box click the next available space then click 'insert position'. RobWin sends the command LEARN to the controller.
To change a position once learned move the robot to the correct position, highlight the line and click 'set to here'. RobWin sends the command (n) REPLACE to the controller (where n is the line number to replace).
To undo the last line learned highlight the line and click 'delete'. RobWin sends UNLEARN
To delete a line within the route highlight the line and click 'delete'. RobWin sends (n) DELETE where n is the line number to delete. These commands are for information only, you don't need them.
Repeat from 2.
Using the teach pad
2. Click on the
or
button
3. Move the arm to the desired position using the teach pad
4. Press the escape key or click 'esc' on the teach dialog box to exit teach mode.
5. On the open route box click the next available space then click 'insert position'.
To change a position once learned move the robot to the correct position, highlight the line and click 'set to here'.
To undo the last line learned highlight the line and click 'delete'.
Repeat from 2.
Using the teach pad
2. Click on the
or
button
3. Move the arm to the desired position using the teach pad
4. Press the tick key on the teach pad.
5. To undo the last line learned press and hold the FN key then press the cross key; release both.
Repeat from 3.
To make changes press the escape key or click 'esc' on the teach dialog box to exit teach mode, highlight the line then choose 'set-to-here' to edit the values or 'delete' to delete the line.
RUN
The robot follows the learned list from point to point. The default mode is SEGMENTED in which the robot stops at each line. In CONTINUOUS mode the robot moves continuously through each line without stopping.
Click the route you wish to run in the routes window; click open route. In the window for the selected route click 'run'.
RETRACE
EDITING
If you wish to list or edit another route type the name of the route first.
To edit a route click the route name in the routes list window then click 'open route'. You can then do various things:
Typical editing dialog:
To see which route is currently active enter:-
WHICH TEST1 ABSOLUTE OK
ROUTES
nnnn 6 TEST2 nnnn 9 TEST1
2 words
OK
The "nnnn n" in the above are the RAM address and lengths of each
word in the dictionary. See VLIST under INFORMATION.
The route window provides all necessary editing buttons. However if you use any of the following commands they will change data in the controller but not in RobWin. To update RobWin click on
(n) DELETE deletes the line number (n) and moves all the following lines down one.
(n) INSERT moves all lines from (n) up one and inserts a new line (n) with the current co-ordinates of the robot.
INSERT may produce a FULL error even when no recent entities have
been added, in which case reserve more space with (n) RESERVE.
(n) REPLACE
replaces the co-ordinates of line n with the current co-ordinates of the robot. This command can also be used in user's software (new definitions).
![]()
However (n) REPLACE is often used within a program to self-learn a particular position, for example by computation or to synchronize the end of one route with the start of another. See below and example in section 12.
(n) LINE returns the memory address of the data in line (n).
This address is suitable for words like GOTO and ASSUME. e.g.
(n) LINE GOTO
GOTO requires the address of some positional data. If you leave
out LINE then GOTO assumes the argument is a line number and finds the data e.g.
(n) GOTO
Click 'goto' on the route window.
For VIEW the syntax is VIEW LINE (n)
To run the route type RUN
Click 'run' on the route window. The robot will progress from line to line, stopping at each point in the route. This is the default SEGMENTED mode. To run through the route without stopping see CONTINUOUS mode.
(n1) (n2) SEQUENCE RUN
which runs the route only from line n1 to line n2 (inclusive).
Note that n1 can be bigger than n2 in which case the route runs
in reverse order.
To turn listing back on enter LISTFLAG C1SET ("list-flag see-one-set").
NOTE: in C0SET the 0 is a zero not letter O.
Segmented mode only: To introduce a delay into the program highlight the line before which you wish to insert the delay and click 'insert func'. In the dialog box enter the word MSECS and in the lower space enter the number of milliseconds to pause. Click the space after the last line to 'insert' the delay onto the end of the route.
MOVES ?
The address left by MOVES is in high memory so must be accessed with E@ and E!.
Example use to self learn the last position in a route:
MOVES E@ REPLACE
See example in section 12.
JL
Likewise a line containing any kind of data may be replaced with joint co-ordinates with
JR
Then upload the data to the computer with
7.3.1
( "TICK" COMMANDS )
PUTTING FORTH WORDS INTO ROBOT PROGRAMS
Use insert func
If you must use new definitions and subsequently re-compile a number of words from the editor so that the address of the word changes then a better practice is to put the line 'REPLACE (word) in your text file to re-install the correct CFA each time the text file is reloaded. Don't forget to precede it with the name of your route or it will be put in the wrong route e.g. if the route is called PATH1 and you have your function in line 2 then enter
PATH1 2 'REPLACE PRESENT
If you wish to update the listing in RobWin then click the red up-arrow
: PRESENT BEGIN PB 7 BIT? UNTIL ;
Then click insert func and enter PRESENT
In the comms window or hyperterminal you can type 'LEARN PRESENT
7.3.2
The following procedures apply only to JOINT mode operation. To do something similar in Cartesian mode go to Relative Cartesian routes.
SUB-ROUTES
RELATIVE
Click 'new' in routes window, then in the route create dialog box click 'relative' and enter the name WAVE.
( The command sent to RoboForth would be SUB ROUTE WAVE )
WAIST SHOULDER ELBOW HAND WRIST OBJECT
TRACK LIFT EXTEND HAND WRIST OBJECT
GLOB 1000 2000 3000 0 0
LOCL 0 0 0 0 0
642 2406 3604 0
1001 2005 3003 0
WAIST SHOULDER ELBOW L-HAND R-H/YAW WRIST OBJECT (R12/R17 - six axis)
2000 0 0 0 0 0
LOCL 0 0 0 0 0 0
642 2406 3604 0 0
2010 0 0 0 0
(encoder values shown are examples only)
If a joint is moved now, say the shoulder or lift by 1000, the result is:-
WAIST SHOULDER ELBOW HAND WRIST OBJECT
TRACK LIFT EXTEND HAND WRIST OBJECT
GLOB 1000 3000 3000 0 0
LOCL 0 1000 0 0 0
xxxx xxxx xxxx 0
1001 3000 3003 0
When co-ordinates are LEARNed into the new sub-route, WAVE, the LOCL (local) position rather than the GLOBal position are learned. These are given ABSOLUTE type flags and will list as absolute positions but when WAVE is RUN it will run the co-ordinates in the list relative to
the initial position of the robot before RUN was typed, rather than relative to the HOME position.
WAIST SHOULDER ELBOW HAND WRIST OBJECT
TRACK LIFT EXTEND HAND WRIST OBJECT
01 1000 3000 3000 0 0 R
RELATIVE RTYPE then upload to the computer with
(1) RELATIVE or SUB designates the next ROUTE created to be a
sub-route, designates all joints to be local and zeros all the
local position counts. Thereafter LEARN will learn the LOCAL
positions but with absolute type flags.
7.3.3
MATRICES ROW
![]()
Click new in routes window; in route create box click row. Then enter the number of points in the row in the columns box. Make sure the number of lines reserved is at least 1 greater than the number in the columns box. Move robot to first position, click the first line in the route window and click set-to-here. Then move robot to last position in the row, click the last line in the route window and click set-to-here. Finally press interpolate.
GRID
This sets up a 2-dimensional array.
![]()
1. Click new in routes window; in route create box click grid. Select whether the numbers should be JOINT or Cartesian co-ordinates. Then enter the number of rows and columns. Make sure the number of lines reserved is at least 1 greater than rows times columns.
2. Guide robot to the first position in the matrix, that will be row 1 column 1. Highlight line 1 (which has an asterisk next to it) and press set-to-here
3. Guide robot to the end of the last column, row 1 i.e. the next corner of the matrix. Highlight the next line with an asterisk and click set-to-here
4. Guide robot to the last position i.e. last row last column. Highlight the last line (which has an asterisk) and click set-to-here
5. Click interpolate.
Joint mode
1. Guide the robot to one of the target positions (one of the lines). The robot might already be there after learning the third corner.
2. Enter RELATIVE
3. Guide the robot to an approach position using commands or the teach pad - for example a vertical movement on lift alone might suffice for a position over a test tube rack.
4. Press set aproach
5. Enter ABSOLUTE
1. Guide the robot to one of the target positions (one of the lines). The robot might already be there after learning the third corner.
3. Command the robot to an approach position using a Cartesian MOVE or use JOG. For example a vertical movement on Z alone might suffice for a position over a test tube rack.
4. Press set aproach
Method A is best suited to joint mode and method B is best suited to Cartesian mode.
This sends the robot to the approach position for line (n) obtained by ADDing the co-ordinates in the last (type R) line to the co-ordinates of line (n).
This looks up the memory address of the near position and leaves it on the stack. It does nothing otherwise. NOTE in v10.0 and below this command actually sent the robot to the near position. The new form of this command is useful for tail-ending other routes. For example suppose you have a matrix route TRAY with an approach position and another route PATH to get you to the general area of the tray from somewhere else. You can amend the last line of PATH so the robot finishes up at the required near position of the tray. The command string would be:
TRAY (n) NEARAD AXES PATH LASTLINE REPLACE
where TRAY is the name of the matrix route, (n) is the position within that matrix you want to go to. NEARAD produces the address of the approach position of line (n) and AXES extracts the Cartesian co-ordinates of that approach position into the variables X Y Z W etc. Next PATH invokes the route which gets the robot there. LASTLINE leaves the line number of the last line of that route on the stack and REPLACE replaces that (last) line with the co-ordinates in the variables X Y Z W etc. extracted from the NEAR position of TRAY. So to get smoothly from the starting position of PATH to, say position 5 of TRAY you could use this sequence of commands.
TRAY 5 NEARAD AXES
PATH LASTLINE REPLACE RUN
TRAY 5 GOTO
or a generic word to take the line number off the stack:
: GOTRAY
DUP ( needed by NEARAD and GOTO
TRAY NEARAD AXES
PATH LASTLINE REPLACE
RUN
TRAY GOTO
;
usage
(n) GOTRAY
NOTE in version 10 the command NEAR was GONEAR and NEARAD was just NEAR
This sends the robot to line (n) of the row or grid via the approach position.
Moves the robot from the approach position to the target position - use only after (n) NEAR.
Moves the robot up from the target position to the approach position. (Actually moves the robot up from any position!)
Suppose you were taking parts from a TRAY and putting them on a BELT
: EMPTY-TRAY
TRAY
MOVES E@ 1 DO
I INTO
GRIP
UP
BELT
UNGRIP
LOOP
;
Note the use of MOVES E@ above. In the first place MOVES is one more than we need, being the number of the line with the RELATIVE position. In the second place, due to a FORTH idiosyncracy DO LOOPs require one more than the actual number of loops, e.g. 9 1 DO LOOP will do 8 loops not 9. Remember also that MOVES is in high memory so must be read with E@ not just @
7.3.4 Continuous Path
A route may be used to generate an almost continuous path. For this the CPU passes all the route data to the DSP line by line and the DSP executes the motion without the CPU being involved (see later, three phases of operation). Learn a route as normal but to RUN it first enter
CONTINUOUS
to put the system into continuous path mode.
SMOOTH is an identical command that includes ADJUST (v11 up) (see 7.3.5)
click
Then when you type RUN
the robot will run through all the points without stopping. Even if the route is small enough to be loaded into the DSP in one go the CPU waits for the DSP to finish driving the robot before control comes back to the user or the software moves to the next word.
To run the route backwards enter
RETRACE
SEGMENTED
which returns motion to line by line mode.
If the stop button is pressed while a continuous path is running then the entire route is abandoned even if the stop button does not itself cause an abort (i.e. re-programmed with STOPVEC). The task programmed into STOPVEC will be executed but the run will not resume and the next word will be executed.
7.3.5 Speed and Acceleration considerations
When a route is run in continuous path mode the DSP computes the
required speed for each motor to get from present count to the
counts in the next line. The path between one line and the next
is called a segment. The speed for a given motor will be
different in one segment from the next. To change speed from one
segment to the next the DSP computes a ramp using the value of
ACCEL. If the motor cannot reach the required speed before the
next segment comes up then an error message
"Too tight, line (n)" is issued and the system aborts with error 22. This means one
motor cannot get from current speed to the computed speed within
the segment.
DRY RUN
There are 3 modes of RUN for the R12/R17, DRY (2), CONTINUOUS (1) and NOCHECK (3). After a DRY RUN, CONTINUOUS is re-asserted. In CONTINUOUS mode a dry run is automatically run first to make sure settings are valid. In NOCHECK mode a dry run check is not performed. The reason for this is that for a very long route a CONTINUOUS RUN takes a significant time resulting in a delay before the robot moves whereas a NOCHECK RUN moves the robot immediately. It is up to the user to ensure that settings are still valid before a NOCHECK RUN. If not the results can be catastrophic.
ADJUST (then RUN)
or
SMOOTH which includes ADJUST so should only be used if a route is selected e.g.
(route-name) SMOOTH RUN
7.3.6 Controlling outputs in continuous path
Besides the gripper other output bits may also be operated by inserting the function SETPA with other values:
SETPA 3 - turns on PA 0 (gripper)
SETPA 2 - turns off PA 0
SETPA 5 - turns on PA 1
SETPA 4 - turns off PA 1
SETPA 7 - turns on PA 2
SETPA 6 - turns off PA 2
SETPA 9 - turns on PA 3
SETPA 8 - turns off PA 3
SETPA 11 - turns on PA 4
SETPA 10 - turns off PA 4
SETPA 13 - turns on PA 5
SETPA 12 - turns off PA 5
Note these functions only work with RUN not with CRUN - see three phase operation below.
0 - DSP is not running anything
1 - DSP is running a route
2 - DSP has read a line GRIPPER 0 which normally means turn off gripper
3 - DSP has read a line GRIPPER 1 which normally means turn on gripper
4 - DSP has read a line SETPA 4 which normally means turn off PA 1
5 - DSP has read a line SETPA 5 which normally means turn on PA 1
6 - DSP has read a line SETPA 6 which normally means turn off PA 2
7 - DSP has read a line SETPA 7 which normally means turn on PA 2
8 - DSP has read a line SETPA 8 which normally means turn off PA 3
9 - DSP has read a line SETPA 9 which normally means turn on PA 3
10 - DSP has read a line SETPA 10 which normally means turn off PA 4
11 - DSP has read a line SETPA 11 which normally means turn on PA 4
12 - DSP has read a line SETPA 12 which normally means turn off PA 5
13 - DSP has read a line SETPA 13 which normally means turn on PA 5
All values for SETPA and ?RUN from 14 to 255 are available to operate other functions.
7.3.7 Advanced commands
CRUN
WARNING If the value of SPEED is invalid the robot will go out of control. Always test the route first with RUN or DRY RUN and reduce speed, increase acceleration or use ADJUST (7.3.5) if necessary.
DSPASSUME - this reads back from the DSP the position the robot got to when it was stopped and changes the counts to the correct values.
1. ?STOP - this traps until the DSP has stopped.
It also checks the stop button and stops the DSP prematurely if pressed. As long as the CPU is in command mode or executing some other command the stop button is ignored.
If the stop button is pressed while executing ?STOP then a flag FSTOP is set to a '1', see below.
OR
2. ?RUN
This leaves a value on the stack as follows: 0 - DSP not running, 1 - DSP running a route, 2 or more - controlling an output (see later)
Three phases of operation
A DSP controlled move may proceed in three phases. In the first phase the CPU is downloading positions (route lines) to the DSP. The DSP fills up a buffer with a capacity of about 50 lines. If there are not enough lines to fill the buffer then once all the lines are downloaded then the robot begins to move. If there are more lines than the buffer can hold then when the buffer is full the robot begins to move and while the DSP is moving the robot it gradually empties the buffer. After each line is executed space is freed and the next line is downloaded into the DSP. When there are no more lines to download the second phase ends. If RUN is being executed the CPU enters phase 3, a loop monitoring the DSP, polling for a motion complete flag. RUN finishes only when all motion is finished. If CRUN is being executed it (CRUN) finishes after phase 2 when there are no lines left to download. At this point there could be up to 50 lines in the DSP buffer so the robot will carry on moving, but the CPU will either be waiting for a command or executing the next word in the definition.
This tells the DSP to stop moving the robot.
If the flag FSTOP is set then ESTOP? executes the stop procedure,
normally STOPABORT i.e. aborts with "stop button pressed"
message, or else whatever word is SET into STOPVEC (See section 6.1).
For example the above definition could be expanded to test the
stop button and stop the robot if pressed:
: TASK
CRUN
BEGIN
?STOP ( Waits for DSP to finish
ESTOP? ( Executes new definition
?RUN ( Gets status of DSP
0= UNTIL
;
Words of the above type are only necessary if you intend to send
a command to the DSP and do something else while the DSP controls
motion. The definition above could be expanded further to do all
kinds of things, for example take analog measurements, while the
robot is running a route in continuous path mode.
CLRDSP
7.3.8 Vectored Execution
The code field (CFA) of a word is executable and can be found using FIND (or using ' (tick) minus two), e.g. FIND GRIP EXECUTE is the same as GRIP. So you can put this value in a variable and have it executed by some other routine which has already been defined. e.g.
VARIABLE GVEC
FIND GRIP GVEC ! ( FINDs the CFA (code field address) of GRIP and stores it in GVEC
GVEC @ EXECUTE ( fetch the value from the variable GVEC and execute that
An easier way to set the CFA into a variable is using the word SET e.g.
SET GVEC GRIP
Example: This will 'chase' lamps connected to the PA output port as the robot moves. Each lamp will stay on for 100mS.
USER CYCLES
USER LAMP
: SCAN
LAMP @ 5 > IF 0 LAMP ! THEN
LAMP @ BIT PA OUT
LAMP INC
100 MSECS
;
: TEST
SET DSPVEC SCAN
TR ( NAME OF A ROUTE
10000 SPEED !
SMOOTH
RUN
;
Although stated that you can only include SETPA I/O control when using RUN, it is possible to set up a loop that monitors the DSP responses to SETPA and operates an output depending on what comes back from the DSP.
: TASK
CRUN
BEGIN
?STOP ( Waits for DSP to finish
ESTOP? ( Executes new definition
?RUN ( Gets status of DSP
DUP 15 = PB 7 BIT? 0 > AND IF CYLINDER ON THEN ( SETPA 15 learned
DUP 14 = PB 7 BIT? 0= AND IF CYLINDER OFF THEN ( SETPA 14 learned
0= UNTIL
;
For example the following definition will call another routine to
turn on or off a device depending on the state of another input:
: CYLINDER PA 5 ;
: TASK
CRUN
BEGIN
?RUN
DUP 15 = PB 7 BIT? 0 > AND IF CYLINDER ON THEN ( SETPA 15 learned
DUP 14 = PB 7 BIT? 0= AND IF CYLINDER OFF THEN ( SETPA 14 learned
0= UNTIL
;
7.3.9 Straight lines
A straight line in any robot is merely a succession of points in a line. The robot passes from point to point. The robot does not move in a straight line between points so to make the path straighter you need more points. However more points will slow down the robot.
Create a ROUTE e.g. SLINE, click Cartesian and Row. Choose number of Columns depending on how straight you want your line. If this is greater than Reserved then increase Reserved. Remember that 50 segments is 51 lines.
Method 1
Using commands or JOG
1. move the robot to one end of the straight line, highlight line 1 of the route and click 'set to here'.
2. Then move the robot to the other end of the straight line, highlight the last line and click 'set to here'.
3. Then click 'interpolate'.
Method 2
1. Determine the exact co-ordinates of each end of the line.
2. Highlight the first line and click 'edit line'. Enter the co-ordinates.
3. Highlight the last line and click 'edit line'. Enter the co-ordinates.
4. Click 'interpolate'.
Enter CONTINUOUS RUN
If you get "too tight" message try
ADJUST to reduce the speed, or else increase value of ACCEL
You can't easily do this because of the limitations of RobWin. Here are two work-arounds:
1. In the communications window do a ROBOFORTH insert, for example to insert GRIP before line 5 enter
5 'INSERT GRIP
2. Type L. to confirm
3. Click the red up-arrow in Robwin to upload the changed data to Robwin. Close and re-open the route to confirm.
You can no longer use interpolate.
or
1. Create a second route with a different name, for example SPATH. Make sure you reserve enough lines for the co-ordinates and the functions.
2. Enter this definition to copy the straight line to the new route: (you can copy and paste this text)
: COPY
SLINE MOVES E@ SPATH MOVES E! ( MAKE #MOVES THE SAME IN EACH
SLINE 1 LINE ( SOURCE ADDR
SPATH 1 LINE ( DEST ADDR
MOVES E@ 16 * ( BYTES TO MOVE IN MEMORY
ECMOVE ( MOVES BYTES IN EXTENDED MEMORY
;
3. Type COPY then Click the red up-arrow to upload the data to the new route. Open SPATH to confirm.
4. Use insert function in the new route SPATH.
7.3.10 RELATIVE Cartesian routes
Version 10.1 up only.
Sometimes it is desirable to program a motion in Cartesian co-ordinates and have it repeated starting from various positions. For example to pull out a shelf might require a move towards the shelf, then down onto the handle then pull out the shelf. Having programmed this for one shelf you can use the same route for the other shelves.
START-HERE
This adjusts all the positions in the route relative to where the robot is now. Note that although the data in the controller will change the data on screen in RobWin will not change. The name of the route must be declared before you use START-HERE
Example usage:
P1 GOTO PATH1 START-HERE CONTINUOUS RUN
The robot will go to point P1 then run the route PATH1 starting at the position P1.
A similar word is
END-THERE
In this case you need to supply the position where the route is to end without the robot being at that position, for example:
P1 PATH1 END-THERE CONTINUOUS RUN
The robot will run PATH1 from whatever position is necessary to finish at P1.
TRAY 1 LINE PATH1 END-THERE CONTINUOUS RUN
The robot will run PATH1 from whatever position is necessary to finish at line 1 of TRAY.
7.3.11 Timed segments
Version v13.5 up only.
Consider a route created as a ROW in which the points are equally spaced. This could be a straight line, or perhaps a circle comprising 36 points as in the following example. There would be 37 lines, line 37 being the same as line 1, so the robot could draw a circle comprising 36 segments of 10 degrees each.

A problem arises because as various axes become dominant in different parts of the circle, or as reach changes, the speed of the arm in real terms changes. This can be corrected by specifiying a time for each segment. This is a completely different mode. To invoke this mode enter
CONTINUOUS TIMED
To cancel this mode and return to the usual mode enter
CONTINUOUS
Having specified the mode you now need to specify the time for each segment - i.e. the time between one line and the next. Enter a value in milliseconds for SEGTIME e.g.
1000 SEGTIME !
Will make each segment 1 second long. This results in the circle being drawn at 10 degrees per second and takes 36 seconds all the way round.
Obviously this can be applied to any path where exact linear speed is critical. The DSP adjusts the speed so that the time between points (lines) is as specified. Clearly if the distance between one pair of points is very large then the DSP will speed up the robot to cross that distance in the specified time.
finally
RUN
Pitfalls
As with normal continuous mode if the move is too long or the time is too short then the DSP can not compute a viable speed and you will get the "too tight" error. ADJUST will not work. The solution is to increase the time, or bring the points closer together, or increase the value of ACCEL.
Unlike the normal mode you can never have two points too close together. In fact you can have two lines with identical coordinates (not possible in the normal mode). The robot would simply pause at that position for the specified time before moving on.
7.3.12 Chasing coordinates
Version v13.61 and V14 up only.
This shows two clips:
The first is with ACCEL set to 3000 and SEGTIME set to 500mS
As you can see the robot speeds up to complete the longer moves.
Next we changed the SEGTIME to 300mS
As you can see the robot stops part way through because the segment can not be achieved in 300mS, with the appropriate error message:
In other words the robot could not make it from line 10 to line 4 in 300mS.
What happens if the move is very small?
The robot moves the short distance in SEGTIME time, so it will move very slowly. Remember also it has to complete each move before it can start on the next. However if the next move is a large one the robot will start accelerating before it finishes the current slow move ready for the faster move.
What happens if the coordinates do not change?
The robot then continues to do zero movement in SEGTIME time. And the segment stored for next move may also be zero so as the next move will not begin until the current one is finished if, for example SEGTIME is 1000, then you may wait up to a second before motion starts again.
( CHASE COORDINATES )
: BUFZ ( wait for buffer empty
BEGIN
24 SPSB SPRB
78 < UNTIL
;
: NEXTSEG
TRANSFORM DROP ( convert to motor values
DSPCHANS @ 0 DO
TARGET I IND @ DUP ( IND is just 2* +
OLDP I IND @
- SWAP ( leave rel pos on stack, axis 6 on top
OLDP I IND ! ( store rel pos in OLDP
LOOP
1 ( flag for DSP ) TSEG
?STAT
;
: GETCART
( GET THE NEXT COORDINATES TO AIM FOR
;
: CHASE
VSET ( send ACCEL to DSP
CFLAG C1SET ( enable DSPASSUME
( set starting position
DSPCHANS @ 0 DO
I GLOBALS @ OLDP I IND !
LOOP
( send initial zero move to DSP
MVST ( start new move
0 0 0 0 0 0 1 TSEG ( first segment zero move
MVRN ( start a run sequence
( now enter loop to collect coordinates and send to DSP
BEGIN ( loop that collects next coordinates
BUFZ ( wait for buffer empty before sending next coords
GETCART ( get the next coordinates
NEXTSEG ( send motor values to DSP
( status from NEXTSEG ) 0 > IF ( fail if non zero
STOP
BEGIN ?RUN 0= UNTIL ( wait for DSP to stop
DSPASSUME
." Segment too long" 31 ABORT
THEN
?TERMINAL UNTIL
MVND ( end move sequence
BEGIN ?RUN 0= UNTIL ( wait for DSP to stop
DSPASSUME ( update counts from DSP
;
7.4
There is also a third entity, the OBJECT. This is only a dictionary entry and has no data in the data area; its data is in the USER variable area. Any item to be handled by the robot can be named. For example:
OBJECTS
OBJECT PART
creates an object called PART in the dictionary.
Note that although you can type this directly into the communications window OBJECTs are best declared near the start of your text.
After simply closing the grippers on the object enter:
HOLDING PART
WHERE
WAIST SHOULDER ELBOW HAND WRIST OBJECT
TRACK LIFT EXTEND HAND WRIST OBJECT
1000 0 0 0 0 PART
642 0 0 0
1001 0 0 0
The address of the object being held is stored in a variable OBJECT-HELD.
PART ISAT CAMBRIDGE
or
PART ISAT LINE 5
This tells the computer where the object is.
It can be confirmed with:
VIEW CAMBRIDGE or VIEW LINE 5
WAIST SHOULDER ELBOW HAND WRIST OBJECT
WAIST LIFT EXTEND HAND TRACK OBJECT
nnn nnn nnn nnn nnn PART
You can also enter:-
WHEREIS PART CAMBRIDGE OK
CAMBRIDGE or 5 GOTO
then enter:-
GET
CAMBRIDGE PUT
GOGET PART
Drives the robot to the position where the object is, via
the approach position if there is one and GETs the object,
withdrawing to the approach position if there is one.
PART COLLECT
OBJECTS
(1) An object cannot be at HOME because HOME is in the ROBOFORTH dictionary
(2) The same object can be at two or more positions at once. The
name of the object is recorded in all the positions. However,
only one place can be recorded in each object.
0 ISAT (place-name) or 0 ISAT LINE n
(object-name) (n) LINE OBAD E! note E! because all routes are in upper memory.
This puts the object in at line (n).
To fill a route with the same object use:
MOVES E@ 1+ 1 DO (name) I LINE OBAD E! LOOP
Note DO-LOOPs can only be used inside a definition.
EMPTY
Remember that if you have more than one route you may need to invoke the name of the route you wish to empty unless you are already working with it, for example:
TRAY EMPTY
If you wanted to preset all the positions with a part so you could remove them one by one the words are:
PART TRAY FILLUP
7.5
Once you have created some routes or places you can now define how they are used, that is when or why the robot goes to which places or routes and in what order.
USING THE TEXT WINDOW
Therefore ambiguities are possible and should be avoided (such as ROBOT1 and ROBOT2 which are the same
length and have the same 5 starting characters).
In particular avoid creating words similar to Roboforth words for example if you create a word RECEIPT this has the same first 5 characters and the same length as RECEIVE. Since RobWin uses this word communication between RobWin and Roboforth is disabled.
click the (project name).ED2 window and enter your text there.
When you have finished editing the text file you can download it with the
button. The communications window will show a line of chevrons
>>>>>>>>>>>>>>>>>>>>>>>>
while the file is loaded and compiled by the controller. At any time you can edit the file and press
again.
( TEST.ED2 )
DECIMAL
OBJECT WIDGET
: FEED
WIDGET ISAT BELT
WIDGET COLLECT
LATHE PUT
;
Test the new word FEED. Once tried and tested the word can be used in higher level definitions and so on until the entire task is defined as one word (or a number of high level words to be sent by the computer).
INPUT-OUTPUT
8.1
This will obviously depend on which input/output cards are fitted
to the system, but the following examples apply to the standard unexpanded outputs.
OUTPUTS
(val) (port) OUT - outputs 8-bit (val) on (port) e.g. 55 PA OUT
(port) (bit) ON turns on a single bit of the output.
A better idea would be to define AIR as follows:-
: AIR PA 4 ;
AIR ON and AIR OFF
Not only is it more readable you can change the connections and bit address without having to go right through your text looking for occurrences of PA 4.
PROGPIA
You will need to know how to insert words into a route, explained in Putting FORTH words into Robot Programs, section 7.3.1.
How to use SETPA including a table of SETPA values is explained in DSP hardware, continuous path, section 7.3.6
8.2
The standard input port allocated is PB. TO INPUT connect to PB as indicated on connector pin-out.
INPUTS
The address of PB is the constant PB
(port) IN - inputs a value from (port) leaving it on the stack.
Suppose there were a switch on PB bit 4 which made PB 4 a logic zero when closed, but logic '1' when open (see connector pin-outs) You could define a word:-
: SWITCH PB 4 ;
then
SWITCH BIT? leaves a number on the stack if switch is open, or zero if switch closed.
: HI BEGIN SWITCH BIT? UNTIL ;
: PROC2 SWITCH BIT? IF TRAY2 RUN THEN ;
etc.
BEGIN ... UNTIL is a loop which executes all the words between BEGIN and UNTIL.
A condition (true or false) must be on the stack before UNTIL. If the condition is false (zero) then the program loops back to BEGIN but if it is true (non-zero) it drops through to the next word.
the following will not work: : RDY SW1 BIT? SW2 BIT? AND IF ....
Instead use the form : RDY SW1 BIT? 0 > SW2 BIT? 0 > AND IF ....
PB 4 0 WAIT waits for bit 4 of port PB to go to zero, or
SWITCH 1 WAIT waits for bit 4 of port PB to go high.
PROGPIA
8.3
One feature of ROBOFORTH II is the ability to move the arm until
an event takes place. For example, a light-beam device on the
arm could be interrupted when the arm reaches the object. You can
initiate a slow or fast search, after first selecting the
joint(s) to move using TELL.... etc. The slow search moves at
"pull-in" speed and stops as soon as a logical criterion is met.
The fast search has to decelerate as soon as the criterion is met and therefore overshoots the position.
However the point at which the criterion was met can be calculated from the deceleration ramp.
SEARCHING
: FOUND PB 5 BIT? ;
You now set the criterion by entering:-
SET CRITERION FOUND
SET CRITERION ?TERMINAL
WAIST SHOULDER ELBOW HAND WRIST OBJECT
WAIST LIFT EXTEND HAND TRACK OBJECT
n - - - -
Where n is the count reached when beam breaks/escape pressed.
The fast search syntax is:-
TELL WAIST (limit) FASTSEARCH
where (limit) is the max movement the axis will make if the criterion is not met.
TELL WAIST REVERSE SLOWSEARCH
or TELL WAIST REVERSE (limit) FASTSEARCH
: ZFIND
ZLINE ( invoke the route )
START-HERE ( move the start of ZLINE to where the robot is now )
SLOW ( predefined to put a low value in SPEED )
CRUN ( tell the DSP to run the robot )
BEGIN ( begin a loop )
?RUN 0= ( checking to see if the DSP has finished )
PB 7 BIT? 0= OR ( or if the object is sensed )
STOP? OR ( or if the stop button is pressed )
UNTIL
STOP ( stop the DSP )
BEGIN ?RUN 0= UNTIL ( wait for the DSP to finish deceleration )
DSPASSUME ( ask the DSP where it got to in counts when it was stopped )
COMPUTE ( change the counts to Cartesian coordinates )
900 PITCH ! 0 W ! ( make sure the hand is still vertical )
;
Run ZLINE until the robot stops. Type WHERE to see where it stopped.
The Z coordinate will be in the variable Z.
8.4
Simple delays can be introduced into any word with (n) MSECS or (n) USECS, e.g.
TIMERS
500 USECS (500 microseconds)
or for e.g. a 5 second delay enter
5000 MSECS
There is also an event timer.
RESETMS resets (zeros) the timer.
MSECS? gives the time since the last reset. Use it or print it e.g. MSECS? .
Maximum time is 32767 mS.
8.5
(Forth v8 and Roboforth v11/12 only)
INTERRUPTS
: NEWWORD
action
RETURN
;
However RETURN must be bracketed out for testing in immediate mode e.g.
: NEWWORD
action
( RETURN )
;
Then remove the brackets when you are ready to use NEWORD as an interrupt word.
Next put the CFA of the new word in the variable INTVEC e.g.
SET INTVEC NEWWORD
INTVEC is a reserved variable that the interrupt code looks in to see what to execute.
Alternatively make two words, one for testing and one simple definition with the tested word followed by RETURN.
For example if you want the interrupt to just beep the terminal do
: BEEPER BEEP RETURN ;
SET INTVEC BEEPER
Then when the interrupt occurs the terminal will beep and the current word being executed continues.
As soon as the interrupt happens further interrupts are disabled. The word RETURN returns the new word back to the BIOS that initiated the interrupt which re-enables interrupts for the next time. An alternative word XRETURN ends the interrupting word and leaves interrupts disabled.
It can of course be any word, but remember that while this word is executing the current (interrupted) word is delayed. If the current word was a motion word then the DSP controls the motion so the motion may not be affected but motion controlled by the CPU e.g. CALIBRATE may be affected. For long routes the CPU is busy "feeding" the DSP with data because its buffer is full. If this process is delayed it can result in erratic motion.
Interrupt from external signal.
Any PB input can create an interrupt. It requires a link on the CPU card from the chosen input (usually PB 6). See controller manual section 8 for hardware details.
If input interrupts are enabled then if PB 6 goes low the interrupt will occur. This is not edge triggered so as long as PB 6 is low the interrupt will keep occurring. However interrupts are disabled for as long as your interrupting word runs and will stay disabled if XRETURN is used. Therefore you must either (a) make sure the input is a pulse which lasts for less time than your interrupt word (minimum duration 10 microseconds) or (b) make the word wait for the input to go high again with PB 6 1 WAIT. But be careful because as long as the system is stuck in the WAIT because PB 6 has not yet gone high, the top level word that was interrupted will be halted. So a pulse is preferable.
Enable interrupts with ENABLE and disable with DISABLE
Note: the first use of ENABLE after a controller reset executes the interrupt one time.
Here is an example. Scenario: we want to count products going past a light beam.
The light beam connects to a relay that joins PB 6 to zero each time the product is detected.
PB 6 has been connected to the interrupt TP1 (see
DECIMAL
USER COUNTER
-1 COUNTER ! ( set a starting value of -1 )
: INT ( this is the word that will run each time there is an interrupt )
50 MSECS ( this 50 milliseconds delay allows for some bounce in the relay contact )
PB 6 1 WAIT ( wait for the relay to open. Warning as long as PB 6 is low the top level program can not )
( continue. Of course if the DSP is running the motors that is not held up. )
COUNTER INC ( increment the counter )
RETURN ( return from interrupts - and in the process re-enable interrupts for the next count )
;
SET INTVEC INT ( set the CFA of the word INT into INTVEC.
: Q ( this word will run in the top level to show you what is happening in the interrupts )
CR ( start a new line )
BEGIN ( start a loop )
13 EMIT ( return the cursor to start of line )
COUNTER ? ( print value of COUNTER over the top of the last one )
1000 MSECS ( wait 1 second then )
?TERMINAL UNTIL ( do it again unless escape is pressed )
;
To test the above first entere ENABLE to enable the interrupts. Then type Q [enter] and the count will continuously display on the screen. You should see the starting value is 0 because ENABLE for some reason gives one interrupt, changing from -1 to 0.
Timer interrupt.
A CPU timer can be set to interrupt every n milliseconds. This value must be put in the variable INT-TIME before you start the timer. The maximum time is 500 msecs. Then use SET-TIME e.g.
250 INT-TIME ! (sets to 250 msecs)
Start the timer with
START-TIMER
Stop the timer with STOP-TIMER
Your interrupting word must end with RETURN
As with the PB 6 interrupt the new word may delay the current word that was interrupted. Also the new word must not take longer to execute than the setting of the timer. For example if you set 100 msecs then in your word you had included 200 MSECS then clearly the word will not complete before the next interrupt.
XRETURN ends this interrupt and disables any future interrupts i.e. a one-off event.
1. Always disable interrupts before reloading a project. As a precaution put DISABLE STOP-TIMER at the head of your ED2 text screen.
2. The interrupting word must not access the DSP while the robot is in motion.
3. In the case of a timer interrupt the interrupting word must not last longer than the timer.
4. The interrupt word must be stack neutral - not leave anything on the stack or take anything off.
5. Because of possible CPU conflicts do not use USECS or MSECS in the interrupt definition.
SAVING ON DISK
9.1
Programming the robot results in two distinct segments of
information:
DISK FILES
(1) The positional data. This is saved as a binary file by uploading from the controller to the disk. These files have the extension .RUN e.g. TEST.RUN
(2) The dictionary. As you create PLACEs, ROUTEs and other
definitions these are compiled directly into the dictionary.
.RUN - binary positional data.
.ED1 - a list of headers of all the routes and places created.
.ED2 - your text file defining higher level words and the final program.
9.1.1
Suppose you type two definitions into the system thus:
Text Files
: HI ." HELLO" ;
: BYE ." GOODBYE" ;
When you execute HI you will see the following:
>HI HELLOOK
The HELLO and the OK merge and a better definition of HI would be
: HI ." HELLO" CR ; i.e. add a new line with CR.
If you just type in the new definition of HI you will see two definitions of HI when you type VLIST - the new and the old. The old one can never be accessed because Forth searches the dictionary from the top down, so it is a waste of space. You need to type FORGET HI then re-enter it. Unfortunately FORGET HI also forgets BYE and every other definition added since. Clearly some sort of editing would be useful. The only way of editing the dictionary is to edit text which is then compiled each time you edit:
click the (project name).ED2 window and enter your text there. There is no need to worry about the other files as these are created and maintained by RobWin. When you have finished editing the text file you can download it with the
button. The communications window will show a line of chevrons >>>>>>>>> while the file is loaded and compiled by the controller. At any time you can edit the file and press
again.
Each time the text is reloaded the words ROBOFORTH and STARTOVER are sent to the controller and the PLACE and ROUTE headers are re-created at the start of the dictionary. RobWin maintains both the ED1 and ED2 files and always downloads the ED1 file first.
Therefore ambiguities are possible and should be avoided (such as ROBOT1 and ROBOT2 which are the same
length and have the same 5 starting characters).
In particular avoid creating words, routes or places with names the same as or similar to Roboforth words for example if you create a word RECEIPT this has the same first 5 characters and the same length as RECEIVE. Since RobWin uses this word communication between RobWin and Roboforth is disrupted.
9.1.2
DISK Periodically save your work back to disk by clicking project, save. When you download the text file with the
Saving your work
button the text file is automatically saved to disk (but not the data).
FLASH ROM Although you have saved the work to disk you also need to save it to the flash ROM so that next time the controller is powered up (or the reset button is pressed) your work is restored to RAM. Otherwise if you power down/up or press reset it will be your previous work that is reloaded to RAM. Save to flash ROM with the command:
USAVE (note this takes a few seconds)
You can, if you wish, make this the last line in your text file so that it happens every time you download with the
button.
9.1.3
Click project, open, select the project you wish to reload. A blue progress bar indicates downloading of the data from the .RUN file. After it reloads 3 windows are opened (if not already open) - the routes window, the places window and the text window (ED2 file). The ED1 and ED2 text files are compiled by the controller CPU and you will see a > for each line the controller compiles so the communications window fills up with >>>>>>>>>>>>>>>>>. Then the routes and places windows open.
Reloading your work
Note that in settings, configuration bank memory must be checked.
Things that can go wrong:
As soon as the blue progress bar appears the system halts. Probably bank memory is not checked. Press reset on the controller, cancel the download then go to settings, configuration and check bank memory.
RUN-LIST NOT DEFINED Your controller has been cold started. Type ROBOFORTH, turn the switch to warm start and try again.
9.2
CONTROLLER SOFTWARE SAVING A COPY OF ROBOFORTH ON DISK
1. Do a cold start (press reset button with selector switch in cold start position). This reloads the RAM from flash ROM but leaves the pointer at the top of FORTH and the start of ROBOFORTH
2. Enter ROBOFORTH and press enter key.
3.
Go to settings, configuration and make sure bank memory is checked.
3. Use 'file', save binary.
4. V11,V12: Check that bank is 0 and enter start 4000 and length 5E00
4. V13: Check that bank is 0 and enter start 4000 and length 6000
5. Enter a file name other than that supplied with the CD, e.g. myrobot.RAM
SAVING THE CALIBRATION PARAMETERS
A copy of the RAM image saved as above will contain all the calibration parameters for your robot, however you may save the calibration parameters (known as a signature) to a small file of its own, as follows:
1. V11,V12: Use file, save binary. Check that bank is 0 and enter start 9C00 and length 100
1. V13: Use file, save binary. Check that bank is 0 and enter start A200 and length 400
2. Choose a file name with .SIG in it e.g. myrobot.sig
It will be saved as myrobot.sig.RAM
RELOADING ROBOFORTH or LOADING UPDATED ROBOFORTH
When the controller is switched on the RAM is reloaded from flash ROM. Just about the only way of corrupting the flash ROM is to corrupt the RAM then save the corrupted RAM to flash ROM with PSAVE. If you think you have done that proceed as follows:
1. Do a cold start (press reset button with selector switch in cold start position). This reloads the RAM from flash ROM but leaves the pointer at the top of FORTH and the start of ROBOFORTH
2.
Go to settings, configuration and make sure bank memory is checked.
3. V11,12: Use 'file', load binary. Check that bank is 0 and enter start 4000 and length 5E00
3. V13: Use 'file', load binary. Check that bank is 0 and enter start 4000 and length 6000
4. Enter the file name supplied with the CD: ______.RAM (e.g. R17V117.RAM, R12V13.RAM etc)
5. After software has loaded (about 30 secs) enter:
ROBOFORTH
6. Enter PSAVE which re-writes the flash ROM.
RELOADING PARAMETERS
A copy of the RAM image saved as above will contain all the calibration parameters for your robot, however if a new version of ROBOFORTH II has been loaded you will need to install your robots signature in the controller by overlaying the calibration parameters for your robot from a disk file. A calibration filename usually takes the form of the robot serial number followed by .SIG e.g. R17A123.SIG. To do this
1. click file, load binary
2. V11,V12: use values bank 0, start 9C00 and length 100
2. V13: use values bank 0, start A200 and length 400
3. load the file Rxxnnn.SIG.RAM
4. Enter USAVE to write the ROBOFORTH with reloaded parameters back to flash ROM.
LOADING A NEW VERSION OF ROBOFORTH
1. Save the calibration parameters (robot signature) as above.
2. Load the new ROBOFORTH as above.
3. For version 11,12 load back your signature as above. This is not ncessary for version 13.
9.3
DATA TRANSFER PROTOCOL
The host must be connected via its serial port set up for 19200
baud, no parity, 8 bits, and 2 stop bits. (to change this see section 9.6
An extremely simple protocol is employed:
To initiate uploading from the controller first send the string
(start-address) (number of bytes) TRANSMIT followed by the return 0Dhex character. The start address and number of bytes may be specified in hex or decimal but hex is usually more useful, for example you may have stored some measurements in the memory from F000 to FFFF. In this case you would upload them with HEX F000 1000 TRANSMIT
The controller will then be waiting for an ENQ (5) character from the computer.
The controller then sends an STX (2) to the host followed
immediately by one block of 256 (100hex) bytes of data. Your host computer software which accepts the data and writes it to a disk file should be buffered.
The controller then waits for the host to send another ENQ and
sends another STX(2) and the next block of 256 bytes. This
repeats until all blocks are sent. When all data is transferred
the controller's answer to ENQ is not STX but ETX (3). When the
host receives ETX instead of STX it finishes the routine and
closes the file.
To upload data from memory bank 1 use
BANK C1SET (start-address) (number of bytes) TRANSMIT
To initiate downloading from host to controller the host sends an
ENQ and waits for STX from the controller. The controller must
first have been given the command
(start-address) (number of bytes) RECEIVE
and the host must also be in some routine to read
data from disk and download it.
The host then sends one block (256 bytes) to the controller.
The host then sends another ENQ and waits for another STX then
sends the next block. This repeats until all the blocks have been
downloaded.
The host then sends sends ETX instead of ENQ meaning no more data
and the host then stops.
Be careful where you load the data. The memory below A000 is ROBOFORTH and your own software is above that. Type HERE X. to see where you have reached in memory.
In memory bank 1 you can load from zero if you wish. Learned positions grow up from 0 and the highest memory location used is found with NEXT @ X.
To load into bank 1 use:
BANK C1SET (start-address) (number of bytes) RECEIVE
9.3.1
Initiated by the controller. To use EMU8 You will need a DOS window open. You can call the batch
file EZ80.BAT as required which in turn runs EMU8.EXE.
AUTOMATIC DATA TRANSFER in DOS or a command window using EMU87
If you are running EMU8 (or your own software with the same protocol as described above)
then data can be transferred to/from disk
under control of a Forth definition. Such a definition should use
the command SEND to save to the file or FETCH to get data from
the file, then type the file name followed with a CR. For example
transfer RAM from C000 to C7FF to or from a disk file called TEST.RAM :-
To write to file: To read from file:
: RECORD : PLAYBACK
SEND ." TEST.RAM" CR FETCH ." TEST.RAM" CR
C000 800 TRANSMIT C000 800 RECEIVE
; ;
To do the same in bank 1 from, say 0 to 7FF
To write to file: To read from file:
: RECORD : PLAYBACK
BANK C1SET BANK C1SET
SEND ." TEST.RAM" CR FETCH ." TEST.RAM" CR
0 800 TRANSMIT 0 800 RECEIVE
; ;
9.4
The host computer can control the controller by sending commands
down the RS232 serial link. The host software should start by
opening the serial channel e.g.
SUPERVISORY SOFTWARE
OPEN "COM1:19200,N,8,1,CS,DS,CD" AS #1
O K cr lf >
In case (c) the host can continue some other task without
waiting. The program ROBOT.BAS contains a routine
which can be implemented in any language.
9.4.1
If a robot program is currently running it is possible to insert a new command (such as WHERE) and upon completion of this command have the robot continue with its original task. In order to do that you need to poll for some specific character from the supervisor, for example a space. For example
RE-ENTRANT OUTER INTERPRETER (v11.4 up)
: TASK
BEGIN
SAFE
HOME
INKEY ASPACE = IF WHERE KEY DROP THEN
?TERMINAL UNTIL
;
This program will run the robot back and forth between SAFE and HOME until you press the escape key at which time the loop quits after doing the last HOME. If you press the space bar then after the robot has completed HOME the space is noticed and the system prints the results for WHERE. It then waits for the use to press another key (KEY DROP) and continues with indefinite SAFE HOME.
: TASK
BEGIN
SAFE
HOME
INKEY ASPACE = IF OUTER THEN
?TERMINAL UNTIL
;
Now when you press the space bar you will see the OK prompt after the robot goes HOME. You can then enter (or the supervisor can send) any command at all as usual. Finally send the command EXIT and the original TASK will continue as before. Or send the required command and EXIT all on one line, for example WHERE EXIT.
9.5
ActiveX Control Robx.ocx
ACTIVEX CONTROLInstallation
The installation disk contains the control, the dynamic-link libraries it needs and the installer program setup.exe. Run setup to install and register the components. The program xdem can be used to test the control.
Methods
The following methods are provided. C-Style declarations are used here. If you are using another language then the appropriate declarations should be automatically generated when you add the control to your application.
Opens the communications port.
Port is 1 for COM1 etc.
BaudRate should normally be 19200 (to change this see section 9.6
The return value is 1 if successful, 0 for failure. Use the method GetCommErrorString() to get a description of the problem.
void CloseComm();
Call this before quitting the application.
short SendString(LPCTSTR String);
Sends the string to the controller. The string should end with a "Carriage Return" character (ASCII 0D hex).
The return value is 1 if the string was successfully sent, 0 if a communication error occurred. Use the method GetCommErrorString() to get a description of the problem.
The controller must be in the "ready" state (as reported by GetStatus) before invoking this method. After sending the string invoke GetStatus() until the "ready" state is received.
short GetStatus();
Gets the controller status as follows:
0: Waiting
2: Ready, received OK
1: Ready but not OK
-1: Communication error
After receiving status 1 or 2, GetResponse gets the last line sent by the controller.
If status is -1, use GetCommErrorString() to get a description of the problem.
CString GetResponse();
This gets the controller response. If status was 1 the response string indicates what went wrong.
CString GetCommErrorString();
Gets a description of communication problems.
void AboutBox();
Displays the AboutBox();
9.6
The main serial port is 'channel 0' and the second is 'channel 1'. The second port is optionally connected to a 25w D connector - see controller manual. Otherwise it is only available on the CPU card.
SERIAL PORTS
The Baud rate always defaults to 19200 on a cold start. But you can change the baud rate for a warm start. If you mis-enter the baud rate and get lost simply do a cold start.
BAUD ?
you should see 104
To change the baud rate enter a new value into Baud, USAVE, do a warm start then change RobWin.
For example to change to 56,000 (factor 2000/56):
36 BAUD !
USAVE
Then press reset. You will lose communication with the computer. Click Comm, configuration and select 56,000 in the drop-down menu.
KEY . (press a key) - system waits for the key to be pressed then prints its ASCII value on the screen.
You will first need to initialize the port using a value calculated as above to set the baud rate. Put the value on the stack then jump to location 001F, e.g.
HEX 68 1F JUMP
will initialize the port to 19200 baud.
HEX D0 1F JUMP
will initialize the port to 9600 baud.
IOFLAG C1SET
From this point on you can only communicate with the controller through the second serial port. Therefore make sure you issue all commands to end with
IOFLAG C0SET
e.g.
IOFLAG C1SET ASPACE EMIT IOFLAG C0SET
will send a space character out of serial port 1 then return control to port 0.
[ HEX ] D5 IN 1 AND IF IOFLAG C1SET KEY IOFLAG C0SET THEN
10.
In many cases it is desirable to have a program run as soon as
power is switched on rather than have to type something every
time. In these cases the program to run is a single word, or you
might have to generate a new word e.g.:-
TURNKEY OPERATION
: DEMO START CALIBRATE HOME RUN ;
Then enter:-
AUTO DEMO
USAVE
and set the front panel switch to auto position (see system manual and robot manual section A). Now the word DEMO will execute immediately on power-up and the computer can be removed.
11
WHERE
INFORMATION
In joint mode yields current position of robot motors and
encoders, in Cartesian mode yields Cartesian position of robot.
Tells which route is currently active, and what mode the route is
i.e. relative (a sub-route) or absolute.
Lists out various modes: local or global, joint or Cartesian,
simple or smooth (joint interpolated motion).
Lists out the co-ordinates of a single position. In the case of a
PLACE name lists out target and approach positions. Also shows
any objects present.
Shows name of place where object is.
Lists the co-ordinates contained in the currently active route.
Lists all the words in the dictionary in the form xxxx y zzzzz...
where xxxx is the memory address of the entry, y is the length of
the name, zzzzz... is the name. Each word is stored in the
dictionary as a length plus the first 5 letters of the word.
Therefore when listed back the unknown letters beyond number 5
are replaced with dots.
Lists all the words in the dictionary of the same type as the
example following 'VLIST, in same form as VLIST.
Lists all route names in the dictionary in same form as VLIST.
Lists all place names in the dictionary in same form as VLIST.
Lists all object names in the dictionary in same form as VLIST.
Lists all Cartesian points in the dictionary in same form as VLIST.
Prints the input on the PB port in binary. A '0' shows a sensor
is covered, a '1' shows axis is clear of sensor.
Continually prints the input on the PB port in binary. A '0' shows a sensor
is covered, a '1' shows axis is clear of sensor.
(e.g. QB WATCH) will display 8 bits from the specified port as 1s and 0s like PP.
Shows current version of ROBOFORTH II.
(who are you) reveals the serial number of the robot.
Shows settings of speed and acceleration, just press escape if you don't want to change them.
11.1
PP
TESTING
Continually displays the current state of the PB input (see P
above). If an input goes to zero (sensor is covered) there is a
beep.
(e.g. QB WATCH) will display 8 bits from the specified port as 1s and 0s like PP.
Continually displays the four encoder counts. As the axis is
moved by hand the counts change.
11.2
If the robot stops due to an error the error is reported. Each
error has a value which is put into the variable ERR.
ERRORS
The errors are:
ERR value Error/Probable cause
1 Bad value
e.g. impractical value entered for SETRAMP or SETTINGS
2 Encoder mismatch
Robot stalled by obstruction or too high speed/acceleration
3 Stop button pressed
4 Interrupted
Interrupt connected and ENABLEd but INTVEC not SET
5 Can't Reach (co-ordinates out of bounds)
Position further than maximum reach of robot (e.g. 550mm for an
R19, 750mm for an R17, 500mm for an R12)
6 Cartesian position not valid
Some move in joint mode was made since the last Cartesian
move so that the Cartesian variables are out of date.
7 Non positional data in ADD
8 Invalid position in ADD, GOTO or LISTROUTE
9 ADDing joint and Cartesian positions together
10 ADDing two absolute positions
11 Invalid line number
12 Incorrect header using OLD (word doesn't match data)
13 Route full
14 RUN aborted
15 Object lost
UNGRIP used while holding object
16 Can't find sensor (sensor target not reached)
Usual reason is the distance to the sensor is too great and
the system has timed out. Alternatively a fault such as
motor or sensor cable disconnected;
perhaps sensor reflector damaged.
17 Can't clear sensor (behaving as if still on the sensor target)
Perhaps faulty sensor, or robot stalled or excess backlash.
18 Stalled in TEACH mode.
19 No room for any more data.
20 Tried to move with brake engaged.
21 Position already occupied (error in PUT).
22 Continuous path algorithm error.
23 ADJUST was hung (See section 7.3.5)
24 Invalid code in continuous path.
25 Didn't type START
or: PC port was reprogrammed or rewritten in such a way
as to disable the soft stop.
26 No object there (error in GET).
27 Can't use RELATIVE and Cartesian modes together.
28 START-HERE and END-THERE only work in Cartesian mode.
29 Invalid command in curve construction.
30 CHECK (CALIBRATE) error exceeds tolerance. V12 up.
Errors 12, 13, 19 would only occur in command mode, not while
robot is running.
Errors 14, 15, 18 do not abort robot program i.e. only warnings
Errors 2, 3, 4 may be re-programmed.
For example to reprogram what happens when there is an encoder error enter in your text:
SET ENCVEC (word) where (word) is the definition of what happens when there is an encoder-stepper mismatch. For example:
: ALARM BEEP PA 5 ON ENCABORT ;
SET ENCVEC ALARM
Or to reprogram what happens when you press the stop button:
SET STOPVEC (word) (See section 6.1)
which quits to the outer interpreter leaving (n) in ERR.
The FORTH interpreter itself can also issue errors. These do not
have error numbers. They are as follows:
If you use up a stack value when there is none the message is
"STACK UNDERFLOW". This check is not made until your word has
fully executed and command mode is re-entered, so too much stack
underflow in your word can crash the system.
"NUMERIC OVERFLOW" - result of signed multiply exceeding 32767 or
7FFF hex, or unsigned multiply exceeding FFFF hex or the result
of M* exceeding 7FFF FFFF hex.
"DIVIDE BY ZERO" - also fatal error i.e. program cannot continue
through such an error.
"ILLEGAL" means you used a compile-only word e.g. a control word
or semicolon (;) when not in compile mode.
PA 4 0 WAIT is legal
PA 4 BIT? is legal
PA 4 0 BIT? will not only NOT test PA 4 but will leave a value
(address of PA) on the stack each time it is invoked. Eventually
the system will crash, for example after some hours running the
system will do a cold or warm start for no apparent reason.
FORTH is a wide open system. Like an assembler you can access any
part of memory or input-output in any way you like. That also
makes it vulnerable.
Another crashing error is unequal nesting for example:
: TEST
PA 4 BIT? IF
TELL TRACK 4000 MOVE
THEN
;
If you leave out the word THEN, TEST will seem to work OK as long
as PB 4 BIT? is true. As soon as it is false the system fails.
: TEST2
100 0 DO
?TERMINAL UNTIL
LOOP
;
This prints the contents of the stack which should be empty. If it is not empty then don't use the program until you have looked for the nesting problem.
11.3 USING A NEST
In theory all the locations are
related to the calibrate position i.e. the counts in the array
LIMITS. However if the robot is serviced (or even replaced with
another robot having a different "signature") or in case of
severe "trauma" (nasty collision) the calibrate position may
alter. Suppose, for example, the waist sensor were moved. All the
learned positions would move also. Therefore it is necessary to
drive the robot to a known location, count back to the calibrate
position and over-write the values in LIMITS to these new counts.
WAIST SHOULDER ELBOW L-HAND WRIST OBJECT (R12/R17)
or WAIST LIFT EXTEND HAND TRACK OBJECT (R19)
or TRACK LIFT EXTEND HAND WRIST OBJECT (R15)
1000 2000 3000 4000 5000
1280 2560 3480 5120 6402
1001 2002 2999 4000 5001
Then enter:
CREATE NEST 1000 , 2000 , 3000 , 4000 , 5000 , 0 , 0 , 0 ,
Make sure this line goes into your text window for reloading.
BANK C0SET
Later you can correct errors with this procedure:
1. Press reset and enter START
2. Move to the NEST using commands and/or TEACH
3. Adjust the position of the robot to fit exactly using TEACH
4. enter BANK C0SET NEST ASSUME
5. enter ENCOFF to turn off the encoders (because they will try to undo what you have just changed)
6. TEACH robot clear of NEST
Use of CALIBRATE would restore previous positioning so you should
change future calibration as follows:
7. enter CHECK - this seeks out the sensors in the same way as
CALIBRATE but does not correct errors.
8. enter SETLIMITS
9. Enter PSAVE (only when you have final values)
You have now changed LIMITS to new values to which all your
learned positions are related.
10. Save the new calibration figures by saving a copy of memory to disk using file, save binary, and a filename.RAM
12
PROGRAMMING TECHNIQUESExample 1
Programming a simple pick-and place cycle.
DEFINE ROBOT TASK:
1. If a part has arrived at the pickup point on the belt a signal
on bit 5 of port PB goes low.
2. Robot takes item from feeder belt and takes to the test jig.
3. Providing the test jig is ready the robot puts the item in the
jig. Jig ready is indicated by bit 6 of port PB being low.
4. Robot signals to test jig that a part is loaded by asserting
PA 1 low.
5. Robot waits for jig to complete. There is a signal from the jig
into bit 6 of port PB which goes logic low if the test
is complete. Bit 7 is high if the part is in the jig. So bit
6 must be low and 7 must be high is the jig is ready to be
unloaded.
6. When test is complete the robot picks the part from the jig.
7. Robot signals jig when it has taken the part by changing bit 1
of port PA back to high. Jig then restores bit 7 of port PB
back to logic low.
8. Robot puts the part into bin.
(ROBOFORTH strings are shown in brackets if you do not use Windows)
First the co-ordinates have to be programmed:
1. With the robot holding the part and using the teach pad put
the part into the gate on the feeder. 'Practice' removing
and replacing the part.
Create a PLACE called BELT (PLACE BELT)
2. Raise above the belt.
Click 'set apprch' (APPROACH BELT)
3. With the robot holding the part (put part into gripper and enter
GRIP) seek out the jig with the teach pad.
Create a place called JIG (PLACE JIG)
4. Using teach pad withdraw part from jig.
Click 'set apprch' (APPROACH JIG)
5. With the robot holding the part seek out the bin with the teach
pad. Create a place BIN (PLACE BIN)
6. Raise gripper above and clear of bin.
Click 'set apprch' (APPROACH BIN)
7. Drive robot to a new position between the bin and the jig
which is higher than both as a safe intermediate position.
Create a new place SAFE (PLACE SAFE)
8. Save all the co-ordinates learned so far with project save
9. Add the program flow to the second text file using the ED2 window as follows.
( TASK.ED2 ) ( 4 JULY 1776 )
OBJECT PART
: JIGLOAD
PB 5 0 WAIT ( WAIT FOR PART TO BE PRESENT AT GATE )
PART ISAT BELT
BELT GET
PB 6 0 WAIT ( WAIT FOR JIG TO BE READY FOR PART )
( WE ASSUME THIS LINE IS ONLY ZERO IF THE JIG IS NOT BUSY )
PB 7 0 WAIT ( DOUBLE-CHECK THAT THE JIG IS EMPTY )
JIG PUT
PA 1 ON ( TELL JIG THAT PART IS LOADED )
( JIG THEN PROCEEDS, AND CHANGES PB 6 TO '1' AND PB 7 TO '1'
SAFE
;
: UNLOAD
PB 6 0 WAIT ( SIGNAL FROM JIG THAT TEST IS COMPLETE )
JIG GET
PA 1 OFF ( TELL JIG ROBOT HAS THE PART )
SAFE
BIN PUT
SAFE
;
: TASK
BEGIN ( BEGIN A CONTINUOUS LOOP )
JIGLOAD
UNLOAD
?TERMINAL UNTIL ( STOP AFTER COMPLETE CYCLE IF THE ESC KEY IS PRESSED )
;
( NOTE ROBOT WILL STOP IMMEDIATELY IF THE STOP BUTTON IS PRESSED )
: FULLTASK
START
CALIBRATE
TASK
;
AUTO FULLTASK ( FULLTASK WILL EXECUTE ON POWER UP )
Example 2
The following is an example of a complex definition of an action
to be taken by the CPU while the DSP is running a route.
The required features are:
1. Throughout the route the stop button must be checked and if
pressed the CPU must tell the DSP to stop.
2. Part way through the route we wish to operate an air cylinder
defined as PUSH-CYL. So the line SETPA 5 is inserted at the
appropriate line. When the DSP gets to this it sends the value 5
back when polled by ?RUN and the CPU then operates PUSH-CYL.
3. After PUSH-CYL is operated we then wish to look out for a
signal from sensor PUSHED. When this sensor goes low we open the
gripper. But as a safety measure we insert the line GRIPPER 0
somewhere further along the route. When the DSP reads this line it
issues 2 from ?RUN to the CPU which turns the gripper off anyway.
: DSP? ( to follow CRUN - monitors state of DSP
FGRIP C1SET
BEGIN
STOP? IF ( if stop button pressed
STOP ( stop DSP ) FSTOP C1SET ( set flag
DSPRDY ( wait for DSP to finish
THEN
?RUN ( what is DSP doing?
DUP 5 = IF ( use SETPA 5 to turn on PUSH-CYL not gripper
PUSH-CYL OFF
THEN
DUP 2 = IF GRIPPER OFF THEN ( ANYWAY
PUSH-CYL BIT? 0= ( is PUSH-CYL off?
PUSHED BIT? 0 > ( is the sensor confirming?
AND ( both ) IF
GRIPPER OFF ( ungrip immediately
STOP ( stop the DSP
FGRIP C0SET ( set a flag
THEN
0= ( result from ?RUN is zero i.e. DSP has finished
FGRIP C@ 0= ( or the flag was set 3 lines back
OR UNTIL ( if either is true leave the loop
ESTOP? ( if stop flag was set by ?STOP then execute STOPVEC procedure
DSPASSUME ( correct counts to the values read back from DSP
GRIPPER OFF ( ungrip anyway in case the above fails
;
Example 3
Self learning
Suppose you have a matrix TRAY (with approach level), a place WASHER and route between the two, TOTRAY.
A typical definition might be:
: WASHPART
TRAY INTO GRIP UP ( get part
TOTRAY RUN ( go to the washer
WASHER UNGRIP WITHDRAW ( put part in washer
RETRACE ( go back to tray
;
Usage is (n) WASHPART
Notice that INTO has no number in front of it. It needs to know what number to go into and it gets that from stack. In (n) WASHPART, n is placed on the stack but is used by INTO which is part of the definition of WASHPART
You might also notice a small physical gap between the end of TOTRAY and the approach position of WASHER. You could try to make them the same but then every time you adjusted WASHER there would be a small gap again and an annoying jerk. So you can automatically adjust the last line of TOTRAY the first time round so that thereafter there is no jerk:
: WASHPART
TRAY INTO GRIP UP ( get part
TOTRAY RUN ( go to the washer
WASHER UNGRIP WITHDRAW ( put part in washer
MOVES E@ REPLACE
RETRACE ( go back to tray
;
You can go further. After retracing TOTRAY the robot's next move will be to a different position on the TRAY each time. You could make the first line of TOTRAY always the same as the approach position of the TRAY as follows:
: WASHPART
TRAY INTO GRIP UP ( get part
TOTRAY 1 REPLACE
RUN ( go to the washer
WASHER UNGRIP WITHDRAW ( put part in washer
MOVES E@ REPLACE
RETRACE ( go back to tray
;
This next example is more complex. Consider a reverse situation:
: GETPART
WASHER GRIP WITHDRAW
TOTRAY RUN
TRAY INTO
UNGRIP
UP
TOTRAY RETRACE
;
Usage:
n GETPART
where n is the required position on the tray and is taken up by INTO
Example 4 - interrupts
This example shuws how to set up a timer interrupt to control a heater. It is assumed there is a temperature sensor which gives 1 volt per 10 degrees:
The code checks the sensor every 500 mSecs and turns on or off the heater to regulate temperature to 60 deg. +/- 0.5 deg.
DECIMAL
: HEATER PA 6 ;
: TEMP
0 ADC
2048 -
1000 M* 2048 M/
;
: TEMP-CONTROL
TEMP
DUP 605 > IF HEATER OFF THEN
597 < IF HEATER ON THEN
RETURN
;
: HEAT
500 INT-TIME !
SET INTVEC TEMP-CONTROL
START-TIMER
;
Once you type HEAT the control will continue in the background and you can carry on your robot program.
©1989-2010 D Sands, ST Robotics