last revision 2015.12.28


© David N Sands, Cambridge, England

A license is granted to the user of an ST Robot for RoboForth II, RobWin7, RobX ActiveX modules, (hereinafter referred to as the Software) under the following conditions:

  • The Licensee will not have any proprietary rights to the Software.
  • The Licensee acknowledges and agrees that the Licensor retains all copyrights and other proprietary rights in and to the Software.
  • The Licensee must reproduce all copyright notices and any other proprietary legends on any copy of the Software.
  • The Licensee may not disassemble, reverse-engineer, modify or alter in any way the Software without the Licensor’s specific approval.



  • Foreword.....................................1.1
  • Introduction.................................1.2
  • Getting Started..............................1.3
  • FORTH and ROBOFORTH rudiments................1.4
  • FORTH words you need to know.................1.5
  • FORTH extras and 'tricks' ...................1.6
  • Initialising.................................2.1
  • Motor drive controls.........................2.2
  • Gripper......................................2.4
  • Home Position................................2.5
  • Calibration..................................2.6
  • Calibration axis sequence....................2.7
  • Joint co-ordinates...........................3.1
  • DSP moves....................................3.1
  • Positional data..............................3.1.1
  • Cartesian co-ordinates.......................3.2
  • Cartesian Points.............................3.2.1
  • Tool transformations.........................3.2.2
  • Encoders.....................................4
  • Speed .......................................5
  • Acceleration ................................5.1
  • Micro stepping ..............................5.2
  • Teach Pad....................................6
  • Stop button..................................6.1
  • Starting a new project.......................7
  • Learning positions...........................7.1
  • Places.......................................7.2
  • Routes.......................................7.3
  • Putting FORTH words into Robot Programs......7.3.1
  • Matrices.....................................7.3.3
  • DSP commands, continuous path................7.3.4
  • Speed and acceleration with continuous path..7.3.5
  • Controlling outputs in continuous path.......7.3.6
  • Advanced commands............................7.3.7
  • Vectored execution in continuous path........7.3.8
  • Straight Lines...............................7.3.9
  • Relative Cartesian routes....................7.3.10
  • Timed segments ..............................7.3.11
  • Chasing coordinates..........................7.3.12
  • Objects......................................7.4
  • Programming the procedure....................7.5
  • Outputs......................................8.1
  • Inputs.......................................8.2
  • Searching....................................8.3
  • Timers ......................................8.4
  • Interrupts ..................................8.5
  • Disk files ..................................9.1
  • Text files...................................9.1.1
  • Saving your work ............................9.1.2
  • Reloading your work .........................9.1.3
  • Saving/Reloading ROBOFORTH ..................9.2
  • Data transfer protocol.......................9.3
  • Supervisory software.........................9.4
  • ActiveX controls ............................9.5
  • Serial ports ................................9.6
  • Vectored execution...........................10.1
  • Turnkey operation............................10.2
  • Re-entrant outer interpreter.................10.3
  • Queries......................................11
  • Testing......................................11.1
  • Errors.......................................11.2
  • Using a nest.................................11.3
  • Programming Techniques ......................12

  • 1.1

    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 is quite different to the usual robot programming languages found in other commercial robot systems.

    By way of introduction to ROBOFORTH 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 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 is a new approach to robot programming and the possibilities have not been fully explored. ROBOFORTH 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 II

    ROBOFORTH 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 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 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.

    Forth and ROBOFORTH are organized as a linked list of words known as the dictionary. Together with each word in the dictionary is its definition which is usually in terms of words lower down in the dictionary except for 'primitives' at the bottom which are coded in machine language. Programming in Forth and ROBOFORTH consists of entering new words into the dictionary whose definitions are in terms of words already defined. New words may include data e.g. positional information about the robot. Data (or arguments) are passed between words on a stack.

    Any given position of the arm may be specified as co-ordinates relative to a central position for the arm known as the HOME position. In ROBOFORTH these co-ordinates are in terms of the movement required by the motors of the arm to reach that position i.e. number of stepping motor pulses counted from the HOME position. Alternatively they may be expressed in millimetres in Cartesian X,Y,Z co-ordinates. To teach the robot you first move the arm to the required position using any of the means provided and secondly record the co-ordinates of that position. When replayed the arm moves from one position to the next in turn (point-to-point programming). Each position is a list of 16 bytes containing flags to indicate what kind of data it is e.g. Cartesian co-ordinates etc.

    In ROBOFORTH there are various means of moving the robot and various ways of teaching the robot. These are distinctly separate. In practice the procedure is to first move the robot to the desired position then learn it. Similarly the gripper must be operated and learned as two separate operations. All positions and motions have names which are then used to create the 'program' or words which define the global function of the robot. Error conditions can be re-programmed so, for example, you can determine what the robot does and what happens to the associated equipment in the event of the stop button being pressed or a stall because of jammed product. These and other features make ROBOFORTH the most powerful robot control system in existence.
  • Back to contents page


    RobWin (Visual Project Management System)

    Assuming all robot software is loaded into a directory ROBOT then communication is established by running RobWin. The latest version is robwin7.exe. RobWin7 does not need to be installed. Simply create a desktop icon for it (right click, send to, desktop). However there is an install version, Robwin7x.msi that will install RobWin and the resulting program is robwin.exe
    Double click on robwin7.exe or the blue robot icon. . 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:


    ROBOFORTH may be used without any knowledge of FORTH but some ground rules are helpful. A glossary of the Forth words used in the ST robot systems is given in the system manual. I recommend you read one of the books listed in section 12.

    Throughout this manual the user's entry will be written in UPPER CASE, GREEN UNDERLINED but not the computer's response e.g.:-
    You press the return key after typing TELL and the computer answers OK. I won't keep repeating that you need the return key after the command or after a line of commands.

    Where commands have RobWin shortcuts the RobWin key, button or mouse sequences are indicated with the RobWin icon:

    1.4.1 Command Line

    Commands are words which you type in followed by the return key. All commands in FORTH and ROBOFORTH are in upper case. Commands may have lower case but they are different commands. It is easier just to press caps lock and stay in upper case. Sometimes a string of commands are required; these are typed on one line separated by spaces e.g.
    ( don't type this )

    You press the return key after the last word and the computer answers OK when it successfully completes the whole line - provided there has been no mistake as in the following:-
    TELL TRUCK TRUCK NOT DEFINED - the word 'TRUCK' was not understood.

    As stated in the introduction, all the words in FORTH and ROBOFORTH 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.

    1.4.2 Arguments

    Arguments are values used by any function or command e.g. in
    100 MOVE
    the argument is 100 and is typed in before the command which needs it.

    The BASIC expression 5 + 6 uses INFIX notation. In Forth we write 5 6 + which is POSTFIX notation. This is because the values 5 and 6 are placed on a STACK for use by +. A stack is an area in memory into which values are temporarily stored on a last-in first-out basis. The answer is left on the stack for use by following words for example a period which means print the value on the stack. For example:-
    DECIMAL (return key) OK

    5 6 + . (return key) 11 OK

    What happened above was that the 5 went onto the stack followed by the 6, like playing cards. At this point the 6 is now on top of the stack with the 5 underneath it. + is a Forth word (words can be spelled from any characters on your keyboard) which takes the 6 and 5 off the stack, adds them together and leaves the answer (11) on the stack. The next word '.' (dot) meaning print, takes the 11 off the stack and prints it on the screen. The stack is now empty again.
    This postfix (or reverse Polish notation, RPN) is different from usual mathematical notation, but can be more human. You would not go to a fruit stand and ask them please to make oranges = 6, you'd ask for 6 oranges. 100 MOVE is just a level higher than 100 STEPS.

    1.4.3 - Integers

    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.

    1.4.4 - Definitions

    This principle is fundamental to Forth. It is the building-block approach to programming.

    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-


    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

  • Back to contents page

    Forth words you need to know

    The FORTH words are not part of ROBOFORTH but exist at the bottom of the dictionary. They support the higher level ROBOFORTH words. While many of these words are esoteric there are some that are really useful or even essential for writing any kind of software that goes beyond the basics, for example changing speed, I/O etc. The following Forth words are worth knowing. For details of all the Forth words see the system manual. It is possible to do really complex tasks using both FORTH and ROBOFORTH.


    Although the stack is used extensively to pass arguments, variables also exist and are handled with the words ! (pronounced "store") and @ (pronounced "fetch"). A variable is just a word which leaves its address on the stack. The actual address is unimportant.

    A new variable is created with the word VARIABLE e.g.
    creates a new variable with the name TOPSPEED. VARIABLE is a defining word. The word ! (exclamation mark) means "store the second value down on the stack into the address which is the top item on the stack", for example 12 1000 ! means "store the value 12 into address 1000". In the process both numbers are used up leaving the stack empty.

    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
    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

    Data can be transferred from one variable to another with e.g.

    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
    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.

    1.5.2 Conditional Branching

    Conditional branching words are IF...THEN, BEGIN...UNTIL and DO...LOOP. These words cannot be used in command mode but must be incorporated into new words (new definitions).

    As already stated arguments are passed on a stack. A condition is a numerical argument for such words as IF, WHILE and UNTIL. Any non zero value (positive or negative) is treated as true, and zero is false.

    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.


    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.
    This repeats a robot motion until the escape key is pressed

    : TASK
      P1 GET
      P2 PUT
    This repeats a robot motion until ctrl-C is pressed
    : TASK
      P1 GET
      P2 PUT
    Other control loops are: IF ELSE THEN, BEGIN WHILE REPEAT, and counting loops DO LOOP.
    For a full explanation of all the various control words and how to use them please see the system manual section 10.6

    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.

  • Back to contents page

    Forth extras and tricks

    1.6.1 Re-entrant outer interpreter

    When you enter a word or a new word definition as in section 1.4.1 these are handled in Forth by an internal function called the Outer Interpreter which parses what you've typed and sends each word to the Inner Interpreter to be actioned. This is also a word called OUTER. It is possible to have OUTER as part of a definition (program) so that when you execute your newly defined word there is an opportunity to enter new words or commands during the running of this word. Then the command EXIT exits the outer interpreter and continues with your program. Possible uses are described in sections 6.1. See section 10.3.

    1.6.2 Vocabularies (context switching)

    It's part of the Forth standard to be able to have more than one vocabulary in the dictionary. This means that the same word can be entered in the dictionary more than once with different meanings depending on the context. Roboforth has two vocabularies, FORTH and ROBOT. Dictionary searches start at an address determined by a variable CONTEXT and this can have one of two values.

    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

    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:
    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.
    Having the same word with different meanings can be confusing.

    1.6.3 Vectored execution

    As Forth works through your words it passes an address in each word to the Inner Interpreter. This address is called the code field address or CFA. The CFA of a word is therefore executable. You can find the CFA of a word 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.
    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.
    See section 10.1. Possible uses for this are described in sections 6.1 and 7.2.8.

    1.6.4 Interrupts

    Interrupts are like vectored execution. The CFA of a word is placed in a particular variable, INTVEC. Then when the interrupt occurs the system looks in INTVEC to see what to do. Therefore a word may be defined which you want executed on interrupt and the CFA of this word is placed in INTVEC. Instructions on how to use interrupts are at section 8.5

  • Back to contents page


    When power is switched on or if the reset button is pressed then ROBOFORTH is transferred from flash memory to high speed static RAM. If this is done while the front panel switch is in the cold start position then the FORTH dictionary will be initialized and pointers set to the start of the user's dictionary. (This has to be done at least once with a virgin system.)
    The dictionary can then be extended by the user but this extension will be lost if another cold start is performed or if the word ROBOFORTH is typed.
    After a cold start press return once and enter the word ROBOFORTH.
    Relevant initializing words are:

    Strips off any user's words from the dictionary and restores the ROBOFORTH vocabulary.

    Initialises the robot controls, energising the motors and setting default values to things like speed etc. These variables may be manipulated after START has been used.

    START should always be followed by CALIBRATE (see later)
    Often it is desirable to redefine START inside your text window (test.ed2). See section 9. for example:

    : 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)

    Software resets

    QUIT If used in a definition it just quits everything and returns you to the command line.

    This is the address of the cold start entry point for the Forth kernel. Hence a cold start may be performed with:

    You can also do a software reset with
    If you don't have reset you can define use
    HEX 420 JUMP or as a definition in DECIMAL
    : RESET ORG 32 + JUMP ;

    You can also quit a word from any level and restart it from scratch by using the TURNKEY feature (see section 10)
    If you don't have RESTART you can define it:
    : RESTART ORG 35 + JUMP ;
    You must put a valid CFA in TURNKEY, see section 10
    Note: when you press the reset button on the controller all the contents of RAM are refreshed from Flash memory. It follows that the current contents of RAM are lost. However with a software reset the contents of RAM are preserved and this includes the current position of the robot. Pressing the reset button resets everything and you must follow with START and CALIBRATE but these are not necessary with a software reset.
    You can do the same as pressing the reset button with
    0 JUMP which restores everything from flash memory.

    Restores all the variables like speed which affect the robot motion back to the default values set by START.


    De-energizes all motors. Joints may then be moved by hand.
    Energizes (or energises) the motors. (see ENCASSUME)


    There are several motor flag bytes in which bit 0 controls or corresponds to axis/motor 1 (waist), bit 1 controls axis 2 etc.
    MEP - Motor Enable Pattern - bit is set by typing the joint name.
    MDP - Motor Direction Pattern - bit is set by system depending on direction motor is to move. Set to a 1 for reverse direction e.g. a negative argument or the word REVERSE.
    MSP - Motor Sense Pattern - to set a sub-count or local motor step count separate from the main counts.
    MCP - Motor Calibrate Pattern - determines which motors are to run in ONLIM and OFFLIM.
    EEP - Encoder Enable Pattern - enables encoder check on motor if bit is set.
    The above flag bytes are like variables. To read a value enter: EEP ?
    EFP - Encoder Fitted Pattern - bit set means motor has an encoder fitted.
    In V12 EFP is a variable - to read its value enter: EFP ?
    In V11 EFP is a constant - to read its value enter: EFP .
    SIP - Sensor Inversion Pattern (v12 only) (also a variable).

  • Back to contents page


    To operate the gripper enter:
    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)


    Pneumatic and solenoid grippers

    Time is allowed for the gripper to operate so that the robot arm does not move on before the gripper has finished opening/closing. This time, in milliseconds, is in the variable TGRIP. To change use the syntax: (new value in milliseconds) TGRIP ! e.g.
    1000 TGRIP !
    allows 1000 milliseconds before the robot moves on.
    For pneumatic grippers this delay is short e.g. 300 mS and TGRIP is normally set to 500 as default.
    The gripper (not electric) can also be operated with

    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.

    Electric motor gripper

    The motorized electric gripper is operated in a more complex manner. The motor is given a chopped signal to close the gripper gently. Once closed the power is changed to full on to give maximum grip. When it opens a similar procedure is followed but the motor is left de-energized.

    How the electric gripper is controlled.

    Power is applied in a pulse width modulated fashion. The time for power on is determined by a variable TON and time off is 1000 micro-seconds. TON defaults to 1000 so the mark-space ratio is 1:1
    After TGRIP expires power is then applied at full current for full gripping force.
    Power is then applied in a pulse modulated fashion. The time for power on is determined by TON and time off is 1000 micro-seconds.
    After TGRIP expires power is then removed altogether.
    To increase the speed of open or close increase the value of TON as follows e.g.
    4000 TON ! (changes to a 4:1 mark-space ratio)
    In versions prior to 13.6 TON is a constant; change with e.g. 4000 ' TON !

    By default TGRIP is given a value sufficient for the gripper to fully close from fully open and vice versa. However this may not be necessary. If you expect to grip an object then the gripper need not fully close. Equally you don't need to fully open to release the object. If you reduce the value of TGRIP then the stroke will reduce. For example
    500 TGRIP !

    Gripper types
    A variable GTYPE has the value
    0 - single acting pneumatic gripper or vacuum pickup
    1 - electric gripper
    2 - double acting pneumatic gripper
    This variable is part of the parameter file for the robot.
    To change from pneumatic to electric (for example when using a tool changer) enter:
    1 GTYPE !
    or vice versa 0 GTYPE !


    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
    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:
    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.

  • Back to contents page


    Before trying any of the following commands be sure to

    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


    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 )
    (for programming such things see later, section 9.1)

    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).

  • Back to contents page


    The home position can be accurately set up by making use of proximity detectors fitted to each axis.



    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.)
    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).

    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.

    Possible errors

    The axis must find its sensor (ONLIM) within MAXON counts (MAXON is dynamic). If this error occurs it means the axis had too far to go, or was already past the sensor and just keeps on going, or the sensor is faulty or out of adjustment. For adjustment ask for the service manual.
    CANNOT CLEAR SENSOR (may be followed by axis number)
    The axis has found the sensor or may already have been on the sensor and is backing off again (OFFLIM). It must get clear of the sensor again within MAXOFF counts. If it does not then either the axis was already on the sensor but too far on, or the sensor needs adjustment. For adjustment ask for the service manual.

    Related words

    This is similar to CALIBRATE because it will drive the arm to the proximity detectors and show the errors in positions obtained but not actually correct them.
    is a simple array of 8 2-byte values. Try VIEW LIMITS
    The address of the value for the first axis or joint (waist or track) is LIMITS
    (try LIMITS ?) the value for the second axis (shoulder or extend) is at LIMITS 2 + (try LIMITS 2 + ?), 4 + for the next axis and so on.

    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
    4. drive the robot to the sensors using
    5. Enter SETLIMITS
    6. Enter USAVE
    which writes the memory image back to flash ROM

    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 !.
    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.

    R19 only

    The standard R19 has only 4 axes. The value of #AXES is 4 (#AXES ?). The DSP is normally fitted with an EPROM for 6 axes. The value of DSPCHANS is 6 (DSPCHANS ?). Therefore it is possible to add a 5th or 6th channel. If the 5th channel is a track then this will be calibrated along with the robot. However in some circumstances, for example if the 5th axis is a rotating table or other stepping motor driven device then it can be excluded from the calibration by setting it's LIMITS value to zero. e.g.
    0 LIMITS 8 + !


    A new command CALCHECK checks the calibration and if the error on any axis exceeds the value of constant CALMAX then the robot stops and reports CALIBRATE ERROR and the size of the error.
    It is possible to put some other action in the vector CALVEC (see vectored execution)
    For example you could put OUTER in it e.g.
    Then the system re-enters the outer command interpreter and waits for a command. See section 1.6. Enter EXIT to ignore the error and continue the program. Or you can enter some commands for example CALIBRATE to calibrate the robot then EXIT to continue the program. Or you can press escape and abort the program.

    6th channel

    A controller may be fitted with a 6th channel, for the 6th axis (roll) or for a track in the case of R12/R17. The track is calibrated along with the rest of the robot. Both #AXES and DSPCHANS have the value 6 and the DSP is fitted with 6 channel EPROM. For R19 the 6th channel is for a peripheral and may be excluded from the calibration with 0 LIMITS 10 + !. For any robot it is not necessary for #AXES to be 6, it can be 5 or 4, but DSPCHANS must be 6 for a 6 channel DSP. Whatever the values are for #AXES and #CARTS the corresponding values must be set in RobWin7 configuration or communication will fail.

    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:-
    This forces the WHERE display to the correct value in LIMITS. You also need to fcrce the encoders to show this new value with

    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

  • Back to contents page

    2.7 Calibration axis sequence

    R17 and R19

    All axes are started together. When a sensor is reached all axes stop, then the remaining axes restart and so on recursively until all axes have reached their sensors. Then each axes creeps back off the sensor one axis at a time starting with axis 1.

    R12 only

    Unlike R17 the R12 axes calibrate one at a time in this order: 1,2,3,5,4,6
    The axis number calibrating is shown on screen.

    R15 only

    CALSEQ is an array of 8 bytes used to determine the order in which the robot axes calibrate. To help understand this facility please see the words MEP (Motor Enable Pattern) and MDP (Motor Direction Pattern).
    In these patterns bit 0 (value 1) represents motor/axis 1; bit 1 (value 2) represents motor/axis 2; bit 2 (value 4) represents motor/axis 3; bit 3 (value 8) represents motor/axis 4 and so on.

    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.

  • Back to contents page


    3.1 JOINT MODE

    Each joint can be moved by entering commands from the keyboard. Commands are of the form
    TELL [joint-name(s)] [amount] MOVE or MOVETO or STEPS. or

    5-axis versions

    The joint names for a revolute robot (R12/R17) are
    The R12/R17 hand is driven by two motors, the WRIST motor and another motor which may be selected individually with the name L-HAND. If only L-hand is driven the wrist will roll while it pitches. Optionally the robot may be mounted on a track (R19T,R17T/R12T) and the track is called TRACK.

    6-axis versions

    The joint names are

    Cylindrical format

    The joint names for a cylindrical robot (R19) are WAIST, EXTEND, LIFT and optionally HAND and/or WRIST. Optionally the robot may be mounted on a track and the track is called TRACK.

    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:
    or for a Cartesian robot:
    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.

    For an R12/R17 the result is:

           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:

           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:
           1000       0       0       0       0  
    For an R15 this results in:
           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
           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.
    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.

    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
    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
    Again move the waist WAIST 1000 MOVE
    WHERE shows
          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
    You can zero out the local position with:

    A single local position may be read with (axis 0-5) LOCALS @
    and changed with (new value) (axis 0-5) LOCALS !

  • Back to contents page

    DSP Moves

    All moves are controlled by the DSP however the DSP may told to do the move without monitoring by the CPU, freeing the CPU for other action. To move a joint with the DSP alone use the form:
    You will notice the system comes back immediately with OK while the robot is still moving. Do not issue another movement command until the robot has stopped moving. 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.
    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 !

    Back to contents page


    A robot arm position is stored in memory as a strip of 16 bytes, 2 bytes per joint followed by other data. The first two bytes are the count for the waist, the next two are for shoulder etc. In In Cartesian mode for a 5-axis robot the data is X, Y, Z, PITCH, W, then either a blank or TOOL-LENGTH, two bytes each. For a 6-axis robot the data is X, Y, Z, PITCH, YAW, ROLL. The 7th byte contains flags indicating whether the position is joint or Cartesian, relative or absolute.
    A JOINT position contains motor counts. This position GOTO sends the robot to where it's counts are the absolute values in this memory strip.
    A Cartesian position contains real engineering units. GOTO sends the robot to this absolute position.
    If this position is marked as RELATIVE then the joints move BY the amounts in the memory strip i.e. the values in the position are added to the current position.

    There are 3 forms of GOTO: GOTO, -GOTO and XGOTO.
    (address) GOTO
    sends the robot to the coordinates stored at the address given. The robot arm moves to the position determined by the argument. All GOTOs expect the address of a 16-byte data strip on the stack. For example
    40000 GOTO
    assuming that address 40000 actually contains valid data. If not then the message "INVALID DATA" is issued.
    P1 GOTO
    where P1 is a point created with POINT (see section 3.2.1)

    (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.

    (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
    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 joint co-ordinates, for example
    NOTE the line must contain joint coordinates.
    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.

    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.

  • Back to contents page

    3.2 Cartesian MODE

    Positioning the arm by telling each joint how much to to move is accomplished in JOINT mode. Instead the arm may be positioned by specifying a point in space by distances in 3 axes (x,y,z) from the origin. This is located at the center or rotation of the waist axis on an R19, or on an R12/R17 it is intersection of the axis of waist rotation and the axis of shoulder rotation. The z-axis is positive for all positions above this point and negative for all positions below this point. The x and y axes are as seen by the robot: x is left-right, positive x is right as seen by the robot or left to the user viewing from the front; y is fore-aft, positive y is in front of the robot. The part of the robot which occupies the set position on an R19 is the center of rotation of the hand or on an R12/R17 it is inside the hand drive at the intersection of the axis of rotation of pitch and axis of rotation of roll or on a 6-axis robot it is the intersection of yaw and roll axes.

    The software works to an internal precision of 0.1 mm and 0.01 degrees of angle.

    To select Cartesian positioning mode type:

    To return to joint mode enter

    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
    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:

             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.
    To return to the PREVious position enter PREVIOUS RESUME

    For a 5 axis R12 there are 6 variables in Cartesian mode:
    (note: #CARTS=5, #AXES=5)
    For a 6 axis R12 there are 6 variables in Cartesian mode:
    (note: #CARTS=6, #AXES=6)
    For a 4 axis R19 there are 5 variables in Cartesian mode:
    X Y Z W
    (note: #CARTS=4, #AXES=4)
    These can be manipulated individually if required e.g.
    1000 X ! 2000 Y ! 3000 Z ! 900 PITCH ! 45 YAW ! 0 ROLL ! etc.
    To make the robot move to these positions enter:

    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.

    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.

    (1) WHERE only shows the current values of X,Y,Z,W,YAW,PITCH,ROLL. 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:

    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).

    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:

    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:
    100.0 X ! 200.0 Y ! 300.0 Z ! 0 PITCH ! 90.0 W !
    100.0 X ! 200.0 Y ! 300.0 Z ! 0 PITCH ! 90.0 YAW ! 0 ROLL !
    POINT P1

    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).

  • Back to contents page


    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:
    TOOLSET (Tool Settings)
    This asks for the pitch of the wrist, the angle of the wrist and the tool length, all of which can be different for the same x-y-z location in space.
    WRIST PITCH (followed by the current value) - answer in degrees times 10. This is an integer and the entry must be a multiple of 0.1 degrees, so for example enter 900 or 90.0 for 90 degrees and not just 90 which would be taken as 9.0 degrees. Or just press enter to keep the current value.
    WRIST ROLL (W) (followed by the current value) - answer in degrees times 10 as above.
    TOOL LENGTH (followed by the current value) - answer in mm times 10. So for example for 120mm enter 1200 or 120.0 and not just 120. Press enter to keep the current value.
    ALIGN ROLL? Press Y to invoke ALIGN mode (see below), or N to cancel it or just press enter for no change.
    EXECUTE? If you press Y the tool is immediately re-positioned but if you press N the changes in the TOOL parameters are delayed until the next time MOVE or MOVETO are used.
    NOTE: if you use a value for TOOL-LENGTH then the coordinates learned into PLACEs and ROUTEs will be the coordinates of the tool end not the usual center of wrist and roll. As soon as you answer Y to EXECUTE the robot arm will immediately pull back so that it is the tool position that now occupies the specified Cartesian position. Therefore if you change the value of TOOL-LENGTH you will need to edit any learned positions or you may get the error message "CAN'T REACH"

    This asks for the pitch of the wrist, the yaw angle and the roll angle plus the tool length, all of which can be different for the same x-y-z location in space.
    WRIST PITCH (followed by the current value) - answer in degrees times 10. This is an integer and the entry must be a multiple of 0.1 degrees, so for example enter 900 or 90.0 for 90 degrees and not just 90 which would be taken as 9.0 degrees. Or just press enter to keep the current value.
    WRIST YAW (followed by the current value) - answer in degrees times 10 as above.
    WRIST ROLL (followed by the current value) - answer in degrees times 10 as above.
    ALIGN? Press Y to invoke ALIGN mode (see below), or N to cancel it or just press enter for no change.
    EXECUTE? If you press Y the tool is immediately re-positioned but if you press N the changes in the TOOL parameters are delayed until the next time MOVE or MOVETO are used.

    R19 4-axis
    This asks for the the yaw angle and the roll angle plus the tool length, all of which can be different for the same x-y-z location in space.
    WRIST YAW (followed by the current value) - answer in degrees times 10 as above.
    ALIGN? Press Y to invoke ALIGN mode (see below), or N to cancel it or just press enter for no change.
    EXECUTE? If you press Y the tool is immediately re-positioned but if you press N the changes in the TOOL parameters are delayed until the next time MOVE or MOVETO are used.

    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. System must be in CARTESIAN mode.
    6-axis: You will need ALIGN mode first. Also there may be some angles which are out of range.
    R19 you must use ALIGN first.
    For a 5-axis robot if the hand is vertical (i.e. PITCH = 90 degrees or -90 degrees or for a 6-axis robot if PITCH is 0 deg) then the wrist will adjust so that angle W (5-axis) or ROLL (6-axis) is relative to the original position rather than 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.
    For a 6-axis robot if the hand is horizontal (PITCH is 90 or -90) then the YAW is adjusted to the same angle as the waist moves.
    This mode remains until
    NONALIGN is typed. This cancels align mode.
    If you are in ALIGN mode and you take the pitch away from vertical then you get a message "WRIST NOT VERTICAL" (5-axis version) or "BAD PITCH" (6-axis version). This non-fatal error cancels ALIGN mode.

  • Back to contents page


    The encoder system comprises additional hardware and software in the DSP card for up to six incremental encoders, one encoder per axis. The 6th axis of an R12 or R17 does not have an encoder due to it's physical size but the channel is available for other uses, for example a track encoder.

    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. Typical WHERE results depending on model:

          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  
           1995       0       0       0       0
          WAIST  SHOULDER  ELBOW  L-HAND  WRIST    TRACK   OBJECT    (R12/R17 with track)  
           2000       0       0       0       0       0
           xxxx       0       0       0       0       0
           2010       0       0       0       0       0
          WAIST     LIFT  EXTEND   HAND   OBJECT            		 (R19)
           1000    2000    3000       0   
            642    2406    3604       0  
           1001    2005    3003       0  
          WAIST     LIFT  EXTEND   HAND   TRACK    OBJECT            (R19 with track)
           1000    2000    3000       0       0  
            642    2406    3604       0       0
           1001    2005    3003       0       0
          TRACK     LIFT  EXTEND   HAND   OBJECT            		 (R15)
           1000    2000    3000       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.

    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
    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.

    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.
    It may be viewed with
    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
    The array can be addressed as follows: ENCRATIOS @ or ! - 1st element (waist), ENCRATIOS 2+ @ or ! - 2nd element, ENCRATIOS 4 + -3rd, ENCRATIOS 6 + -4th.

    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 !
    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.

    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:-
    : ALARM PA 6 ;
    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:

    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:
    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.

    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
    ENCTOLS DUMP to see all the values.

    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).
    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 !

  • Back to contents page


    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.

    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:-
    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.

    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. '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


    Changing the value of SPEED does not affect acceleration, just as in diagram 3. Acceleration is determined by the variable ACCEL e.g.
    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

    To change the micro-step scaling factor to 2 for, say axis 1 you would enter
    2 MICROS !
    To change, say axis 2 to a value of 1
    1 MICROS 2+ !

    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.

  • Back to contents page


    To start moving the arm enter:-

    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.
    To exit TEACH mode click escape on the RobWin box or press the ESC key.

    Teach pad

    LED lamps are self explanatory

    R17 joints
    Key designations:
    JointR15R12/R17R12/R17 sixR19Cartesian 5-axisCartesian 6-axis
    J1trackwaistwaistwaist X X
    J2extend/liftshouldershoulderlift Y Y
    J3lift/extendelbowelbowextend Z Z
    J4hand/axis4hand (L+R)hand (L+R)handpitchpitch
    J5wrist/axis5wristR-hand (yaw)wristW (roll)yaw

    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.
    Note that the tick and cross only work when teach mode has been invoked with the button or button.

    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. You can also change speed on the RobWin screen by clicking New Speed.

    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 or 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.

    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.

    JOG mode

    If in Cartesian mode you may enter:-

    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).
    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

    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.

    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 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 reprogrammed as with TEACH.

    To exit JOG mode click escape on the RobWin box or press the esc key.


    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:
    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)


    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.

    Android teach console
    An Android based teach console may be used in place of the standard teach pad. This requires extra hardware and an overlay is added to RoboForth, either NEXUS5 for 5-axis or NEXUS6 for 6-axis. This teach console only works in Jog (Cartesian) mode.
    To invoke the Android teach pad first enter BLUETOOTH then click the button. To exit Android mode first press escape (or click the escape button) then press the stop key on the Android teach console.
    To use the standard teachpad again first enter TEACHPAD
    See the separate pdf manual for this option.

  • Back to contents page


    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
    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"

    The SET STOPVEC ESTOP line can be executed in the command line but is best put as part of the main task, for example:
    : TASK
    rest of definition

    Problem: take a sequence of moves like this:
    P1 P2 P3
    As the robot goes to P1, if you press the stop button the robot will stop. The CPU tells the DSP to stop and current joint position is read back from the DSP and that is the end of that move. When you pess any key as defined in ESTOP above the robot goes immediately to the next word P2 without completing P1.
    If the move was a Cartesian one (i.e. P1 is a place with Cartesian coordinates) then the target X-Y-Z-Pitch-W values remain in their variables so you can try again after an E-STOP with RESUME.
    TRANSFORM converts those Cartesian variables to joint counts. The definition of E-STOP is then
    : ESTOP
    CR ." Stop button pressed - hit esc to abort or any other key to continue"

    For an earlier version of RoboForth that does not have RESUME use TRANSFORM -GOTO
    : ESTOP
    CR ." Stop button pressed - hit esc to abort or any other key to continue"

    Using re-entrant outer interpreter
    When you power up the outer interpreter gets your commands. The commands are looked up in the dictionary and their CFAs (code field addresses) are sent to the inner interpreter to be executed. The outer interpreter is itself a word that can be included in definitions.
    You can re-enter the outer interpreter so you can type in any command you need to clear the error (see 10.1)
    : ESTOP
    CR ." Stop button pressed - hit esc to abort, spacebar for new command or any other key to ignore"

    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

    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.

    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.

    Another option is to re-use the turnkey feature to restart the entire word from the beginning (see 10)

  • Back to contents page


    Starting a new project

    Before you can teach the robot anything you have to start a new project (or load an existing one) as follows:

    Run 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.

    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.
    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 >.

    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.
    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.


    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.).

    Nothing can be learned until the data area is initialized with:
    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.

    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:
    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.

    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 . This button will only update any routes or places which have already been created using RobWin.

  • Back to contents page


    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.

    Using either the TEACH or TELL-MOVE method or 'robot' menu or using the JOG drive the arm to the desired position.

    Find the Places window and click 'new'. Enter a name for the new place e.g. CAMBRIDGE
    comms command PLACE CAMBRIDGE

    This creates the name in the dictionary with a pointer to the next available space in the data area. If the system is in Cartesian mode it is the Cartesian co-ordinates which are learned (v1365 up).

    Subsequently when the place name is typed the robot goes immediately to these co-ordinates i.e.
    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.

    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 the third 16 bytes can be an approach position to which the robot will move first before moving to the 'target' position.

    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.

    WITHDRAW only works if you have first entered the place name. It will always send the robot back 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'.
    Comms command 'NEAR (place-name) 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:-
    Click 'show data' in the places window to display co-ordinates of all the PLACEs.

    If there is an approach position this will show as a second line.

    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'. The approach position moves with it.
    Comms command PLEARN CAMBRIDGE

    Comms command: To see all the places you have defined you can enter:-
    PLACES (see VLIST)

    nnnn 7 TRENT..      nnnn 9 CAMBR....    nnnn 4 HOME  
    3 words  
    The "nnnn n" in the above are the RAM address and lengths of each word in the dictionary. See VLIST under INFORMATION.

    To remove a place highlight the place and click delete.
    Comms command sent is FORGET (place-name)
    This recovers both memory used in the data area and memory in the dictionary.

    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.

  • Back to contents page


    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:
    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'.

    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
    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.

    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
    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.

    When there is more than one route first select the route you wish to run by typing its name e.g. TEST1 RUN
    Click the route you wish to run in the routes window; click open route. In the window for the selected route click 'run'.

    A route can also be run in reverse order with the command


    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:
  • edit a line
  • delete a line insert a line
  • add to all - this will add the same value to all the lines at once, useful for shifting an entire route up or down.
    Typical editing dialog:

    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.
    To see which route is currently active enter:-

    The routes window lists all the routes created so far or in the command window enter:-

    nnnn 6 TEST2        nnnn 9 TEST1  
    2 words  
    The "nnnn n" in the above are the RAM address and lengths of each word in the dictionary. See VLIST under INFORMATION.

    Editing in the comms window alone
    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

    LEARN - adds one line to the route.
    (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).

    You would not normally use any of the above commands while using RobWin as RobWin sends these commands when you click the various buttons.
    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.

    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:
    (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 ASSUME the syntax is (n) LINE ASSUME
    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.

    To RUN a limited amount of the route enter:
    (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.
    RNORM restores the start and finish to the first and last lines.

    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 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.

    To abort the route while it is running press ctrl-C - 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.:
    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.

    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:
    Likewise a line containing any kind of data may be replaced with joint co-ordinates with
    Then upload the data to the computer 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.
    Use insert func

    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
    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
    If you wish to update the listing in RobWin then click the red up-arrow

    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':-

    Then click insert func and enter PRESENT
    In the comms window or hyperterminal you can type 'LEARN PRESENT

    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 comms window or hyperterminal you can type 'LEARN AGAIN
    Then click insert func and enter AGAIN
    This simply repeats the route from the beginning again. It only works in SEGMENTED mode.



    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.

    The number of positions in the row is held in the variable POSNS


    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.
    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:

    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

    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.
    Method A is best suited to joint mode and method B is best suited to Cartesian mode.

    Once the relative position, line n+1 has been learned a number of other words may be used:

    (n) NEAR
    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).

    (n) NEARAD
    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:
    extracts the coordinates of the near position to WHERE
    It may be 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 or
    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.

    or a generic word to take the line number off the stack:
    : GOTRAY
    DUP ( needed by NEARAD and GOTO
    (n) GOTRAY
    NOTE in version 13.65 up the command CARTASSUME may be used in place of AXES as it is semantically similar to ASSUME

    (n) INTO
    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!)

    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.
    Suppose you were taking parts from a TRAY and putting them on a BELT

    MOVES E@ 1 DO
      I INTO
    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
    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

    To cancel CONTINUOUS mode enter
    which returns motion to line by line mode.

    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 65535 but of course the robot may not physically 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.

    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.

    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 fix 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 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. However see CONVERT below.

    There exists the possibility to reduce the speed of a route automatically and temporarily with the command
    ADJUST (then RUN)
    SMOOTH which includes ADJUST so should only be used if a route is selected e.g.
    (route-name) SMOOTH RUN

    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. However the original SPEED is saved. You can restore the original speed with

    Note that the DSP only uses joint counts. If the route is a Cartesian route and all the lines are Cartesian. The system converts each line to joint counts before sending to the DSP. If the route is very long then this can take some time and there will be a short pause before motion. If ADJUST or SMOOTH are used then the delay can be significant because the entire route must be converted and sent to the DSP several times to get a working speed. This delay can be dramatically reduced by converting the whole route to joint coordinates first with the command
    CONVERT After this command all the lines in the route will be joint coordinates however the display in RobWin will still be in the original Cartesian coordinates and can still be edited as Cartesian coordinates.

    CONVERT is part of V16. If your system does not have it you can add it to your project ed2 window (section 7) as follows:

    LASTLINE 1+ 1 DO
       I LINE EXAD E@ 2 = IF
         I LINE AXES

    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) (note you can not control an electric gripper with this.)
    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.
    To incorporate these functions into a route using RobWin click append function (or insert function), enter SETPA then in the box below enter the number from the above list. Never make the function as line 1; line 1 must always be a position.
    Suppose you have a glue gun on PA 0 (the gripper line), a route with 10 lines and wish to turn on the gun at line 2 and off at line 8:
    Click line 2 then insert function. Enter 3 as a value. Click line 9 (was line 8 before line 2 was inserted) and insert function, use 2 as a value.

    This leaves a value on the stack as follows:

       0 - DSP is idle
       1 - DSP is running a route
       2 - DSP has read a line GRIPPER 0 which means turn off gripper
       3 - DSP has read a line GRIPPER 1 which means turn on gripper
       4 - DSP has read a line SETPA 4 which means turn off PA 1
       5 - DSP has read a line SETPA 5 which means turn on PA 1
       6 - DSP has read a line SETPA 6 which means turn off PA 2
       7 - DSP has read a line SETPA 7 which means turn on PA 2 
       8 - DSP has read a line SETPA 8 which means turn off PA 3
       9 - DSP has read a line SETPA 9 which means turn on PA 3 
      10 - DSP has read a line SETPA 10 which means turn off PA 4
      11 - DSP has read a line SETPA 11 which means turn on PA 4 
      12 - DSP has read a line SETPA 12 which means turn off PA 5
      13 - DSP has read a line SETPA 13 which means turn on PA 5
    All values for SETPA and ?RUN from 14 to 255 are available to operate other functions in advanced programming.

    7.3.7 Advanced commands


    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.
    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.

    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
    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.

    To determine if the DSP has finished use EITHER:
    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 SETPA,

    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.

    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.

    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
      ?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.

    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:

    7.3.8 Vectored execution in a DSP controlled route

    Using vectored execution (see section 10.1 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.
    Example: This will 'chase' lamps connected to the PA output port as the robot moves. Each lamp will stay on for 100mS.
    : SCAN
    LAMP @ 5 > IF 0 LAMP ! THEN
    100 MSECS
    : TEST
    10000 SPEED !
    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.
    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
      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

    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 TASK being executed.

    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'.

    If you get "too tight" message try
    ADJUST to reduce the speed, or else increase value of ACCEL

    Insert function into a straight line
    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
    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.

    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 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.

    You can also use the straight line function in the curve generator commands of RobWin7. See RobWin7.pdf

    7.3.10 RELATIVE Cartesian routes

    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.

    From any position in the workspace you can run the route as if it was starting from that position. Use
    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:
    The robot will go to point P1 then run the route PATH1 starting at the position P1.

    A similar word is
    In this case you need to supply the position where the route is to end without the robot being at that position, for example:
    The robot will run PATH1 from whatever position is necessary to finish at P1.
    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
    To cancel this mode and return to the usual mode enter
    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.
    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.

    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
    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 (chase.avi)
    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.

    : BUFZ ( wait for buffer empty
     24 SPSB SPRB
    78 < UNTIL
    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
      1 ( flag for DSP ) TSEG
    : CHASE
    VSET ( send ACCEL to DSP
    ( set starting position
         I GLOBALS @ OLDP I IND !
    ( 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
            BEGIN ?RUN 0= UNTIL ( wait for DSP to stop
            ." Segment too long" 31 ABORT
    ?TERMINAL UNTIL ( repeats until escape key is pressed.
    MVND ( end move sequence
    BEGIN ?RUN 0= UNTIL ( wait for DSP to stop
    DSPASSUME ( update counts from DSP

  • Back to contents page


    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:
    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.

    The object can be introduced into the system in a number of ways:
    After simply closing the grippers on the object enter:

    This tells the system that the robot is holding PART.

           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.

    Alternatively the object may be placed at a known position e.g.
    This tells the computer where the object is. It can be confirmed with:

            nnn     nnn     nnn     nnn     nnn   PART
    You can also enter:-

    To make the robot pick up the object first send the robot to the position with the place name or with GOTO e.g.
    then enter:-

    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.
    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.

    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:-

    (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.

    UNGRIP removes the object from the known workspace (sets OBJECT-HELD to zero).


    To clear an object from a place or a line use
    0 ISAT (place-name) or 0 ISAT LINE n

    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.:
    (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.

    To clear all the objects from a route use:
    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:
    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

  • Back to contents page


    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.

    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.

    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.

    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:

    ( TEST.ED2 )
    : FEED
    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).

  • Back to contents page



    This will obviously depend on which input/output cards are fitted to the system, but the following examples apply to the standard unexpanded outputs.

    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:
    (val) (port) OUT - outputs 8-bit (val) on (port) e.g. 55 PA OUT

    Any output port can be read back e.g. PA IN . 55

    Individual bits may be manipulated:
    (port) (bit) ON turns on a single bit of the output.

    (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
    A better idea would be to define AIR as follows:-
    : AIR PA 4 ;

    Now you can type (or include in a higher level definition):-
    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.

    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.
    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

  • Back to contents page


    The standard input port allocated is PB. TO INPUT connect to PB as indicated on connector pin-out.
    The address of PB is the constant PB

    The most basic form of input is:
    (port) IN - inputs a value from (port) leaving it on the stack.

    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.
    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.

    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:-
    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.

    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 ;
    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 ....

    Another word is WAIT which waits for the specified input to change to a specified state. Example:
    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.

    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:

  • Back to contents page


    One feature of ROBOFORTH 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.

    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:-
    : FOUND PB 5 BIT? ;
    You now set the criterion by entering:-

    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:-


    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.


              n       -       -       -       -  

    Where n is the count reached when beam breaks/escape pressed.

    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).
    The fast search syntax is:-
    where (limit) is the max movement the axis will make if the criterion is not met.

    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).

    : 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 )
    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.


    Simple delays can be introduced into any word with (n) MSECS or (n) USECS, e.g.
    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.


    Put a valid word in INTVEC. See vectored execution. The word must have the word RETURN as it's last line before the semi-colon for it to work with interrupts e.g.
    However RETURN must be bracketed out for testing in immediate mode e.g.
    ( 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.
    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
    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.

    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:

    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 circuit that puts PB 6 to zero each time the product is detected.

    : INT          ( this is the word that will run each time there is an interrupt )
    PB 6 1 WAIT    ( wait for the beam to clear. 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 )
    -1 COUNTER !   ( set a starting value of -1 )
    ENABLE         ( enable interrupts and also runs INT once.
    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 )
      100 MSECS    ( wait 0.1 second then )
    ?TERMINAL UNTIL ( go round again unless escape is pressed )
    ( or CTRL-C UNTIL ( or do it until ctrl-c is pressed.
    To test the above 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
    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.

    RETURN returns the word to machine code that ends this interrupt and re-enables the interrupts for next time.
    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.

    See section 12 for programming example.

  • Back to contents page



    Programming the robot results in two distinct segments of information:
    (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.

    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:
    .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.

    Text Files

    Suppose you type two definitions into the system thus:
    : HI ." HELLO" ;
    : BYE ." GOODBYE" ;
    When you execute HI you will see the following:
    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.

    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, 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.

    Saving your work

    DISK Periodically save your work back to disk by clicking project, save. When you download the text file with the 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.

    Reloading your work

    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. 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.

  • Back to contents page



    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. V13,V14 with RobWin 6: 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


    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,V14: Use file, save binary. Check that bank is 0 and enter start A200 and length 400
    The files may not be 100% compatible.
    2. Choose a file name with .SIG in it e.g. myrobot.sig
    It will be saved as myrobot.sig.RAM


    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 (it is not asked in RobWin 7) and enter start 4000 and length 6000
    4. Enter the file name supplied with the CD: ______.RAM (e.g. R17V16.RAM, R12V16.RAM etc)
    5. After software has loaded (about 30 secs) enter:
    6. Enter PSAVE which re-writes the flash ROM.


    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 has been loaded you may 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 up: use values bank 0, start A200 and length 200
    3. load the file Rxxnnn.SIG.RAM
    4. Enter USAVE to write the ROBOFORTH with reloaded parameters back to flash ROM.


    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 up.

  • Back to contents page


    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

    AUTOMATIC DATA TRANSFER in DOS or a command window using EMU87

    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.
    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  
    ;                                         ; 

  • Back to contents page


    The host computer can control the robot by sending commands down the RS232 serial link to the controller. The host software should start by opening the serial channel e.g.
    OPEN "COM1:19200,N,8,1,CS,DS,CD" AS #1

    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:
    O K cr lf >

    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. In case (c) the host can continue some other task without waiting.

    Suggested flowchart:

    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.

    Useful words for a supervisor:
    GF - (Globals Fetch) controller returns 5 or 6 values of the joint counts.
    CF - (Cartesian Fetch) controller returns 5 or 6 Cartesian coordinates.
    Send 5 values (or 6 for 6-axis) followed by CM - (Cartesian Move) robot moves to that position. The 5 or 6 values are in reverse order with X on top (sent last)
    for example
    900 0 1000 2000 3000 CM - sends robot to X=300mm Y=200mm, Z=100mm, pitch 0, roll 90 deg.
    or for 6-axis robot
    450 0 900 1000 2000 3000 CM - sends robot to X=300mm Y=200mm, Z=100mm, pitch 90deg, yaw 0, roll 45deg.
    The following examples are for 5 axis robots: 0 900 1000 2000 3000 CG - (Cartesian Get) just sets the variables but does not move the robot.
    0 900 1000 2000 3000 CL - (Cartesian Learn) sets the variables and learns them into the current active route but does not move the robot.
    100 200 300 400 500 JMA - (Joint Move Absolute) moves each joint to the absolute positions listed on the stack. They all start and stop at the same time. Waist is the last value onto the stack (500 in this example)
    100 200 300 400 500 JMR - (Joint Move Relative) moves each joint by the amounts on the stack. They all start and stop at the same time. Waist is the last value onto the stack (500 in this example)
    0 900 1000 2000 3000 AL - (Add to All) adds the 5 values (or 6) to all the lines in the currently selected route. It works the same for joint or Cartesian routes. For example in joint mode 3000 would be added to all waist positions.


    ActiveX Control Robx.ocx


    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.


    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.

    short OpenComm(short Port, long BaudRate);
    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();

  • Back to contents page


    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.

    Changing baud rate on port 0
    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.

    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:
    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.

    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.
    KEY . (press a key) - system waits for the key to be pressed then prints its ASCII value on the screen.

    You can read the incoming byte without waiting with INKEY

    Second serial port (channel 1)
    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.

    To access the second serial port change the value of IOFLAG from 0 to 1 with
    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
    will send a space character out of serial port 1 then return control to port 0.

    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. Control will simply switch to port 1. You can then send or type commands into port 1 as you did with port 0. To return to port 0 enter IOFLAG C0SET into port 1.
    BUG: for EPROMS version 10 (VA) and below the > character still appears on port 0 even though OK is on port 1. To correct this (if you wish) then perform the following patch:

    3A 1FE2 C! 06 1FE3 C! A0 1FE4 C! C3 1FE5 C! C7 1FE6 C! 05 1FE6 C!
    This should be typed all on one line at one time. Hit enter at the end. Or put the whole line in your project file.



    The code field (CFA) of a word is executable and can be found using FIND (or using ' (tick) minus 2), 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.
    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.
    Possible uses for this are described in sections 6.1, 7.3.1 7.3.8 8.5.


    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.:-
    Then enter:-
    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.

    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 you use AUTO (word) you are putting the CFA (code field address) in the (pseudo) variable TURNKEY.

    You can also use this feature to restart a word. Because all Forth loops are structured you can not easily get out of a loop and just go back to the beginning. There is no GOTO as in BASIC for example. What you can do is put a word in TURNKEY. For example suppose you want it so that when the stop button is pressed, the robot does not abort, neither can it continue, but must instead start the whole program from the beginning. Consider a main word

    : MAIN
    : TASK
    Now in the middle of STUFF somewhere, someone presses the stop button. You want the robot to go back to READY, wait for a signal (say a button connected to PB 6) and start again from the beginning. You can use
    This jumps to the auto-start entry point of the Forth, see section 2, Initialising.
    You can now set a temporary value in TURNKEY that will execute when you use RESTART. The original value for AUTO will be restored from flash after a hard reset.
    In immediate mode use
    FIND YOURWORD TURNKEY ! (where YOURWORD is an example word)
    You can't compile FIND. You also can not use SET with TURNKEY because it is an address not a variable.
    Within a definition use ['] YOURWORD 2- TURNKEY !

    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).

    : ESTOP
    There's no need to recalibrate because there was no hardware reset. This is called a software reset. There is no need to turn the key to auto. A software reset leaves all RAM contents, values in variables unchanged. Even the current position of the robot is unchanged so providing there has not been a crash the positional information is valid.
    : TASK
    ['] MAIN 2- TURNKEY !
    What if you have already set TURNKEY to TASK and have the key set to Auto? Use USAVE to save that to flash. Now if you press the reset button TASK will execute, including START and CALIBRATE.
    But as soon as TASK executes TURNKEY changes to MAIN but don't USAVE that.


    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
    : TASK
    This program will run the robot back and forth between SAFE and HOME until you press escape 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.

    You can now replace WHERE KEY DROP with OUTER e.g.

    : TASK
    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.

  • Back to contents page


    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).

    VIEW (position)
    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.

    WHEREIS (object)
    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.

    'VLIST (word)
    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.

    (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.

  • Back to contents page


    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.

    Further tests are available as projects.

  • Back to contents page


    If the robot stops due to an error the error is reported. Each error has a value which is put into the variable ERR.

    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?)
    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        RELATIVE and SUB ROUTES discontinued.
    28        START-HERE and END-THERE only work in Cartesian mode.
    29        Invalid command in curve construction.
    30        CHECK (CALIBRATE) error exceeds tolerance.
    31        CHASE segment too large.
    32        Bad angle value for TOOL motion. (non fatal)
    33    	  ADJUST error – route has 2 or more identical adjacent lines resulting in negative speed.
    Errors 12, 13, 19 would only occur in command mode, not while robot is running.
    Errors 14, 15, 18, 32 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:
    Or to reprogram what happens when you press the stop button: SET STOPVEC (word) (See section 6.1)

    You also can arrange your own error traps with (n) ABORT
    which quits to the outer interpreter leaving (n) in ERR.

    FORTH errors
    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.

    Look out for possible stack errors including stack overflows. For example you might confuse the syntax of WAIT with BIT?
    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  
    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  

    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
    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.

  • Back to contents page

    11.3 USING A NEST

    A nest is a known location in the work space to which all the other locations are related.
    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.

    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:

    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 ,

    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.
    Make sure this line goes into your text window for reloading.

    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:
    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
    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 USAVE (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

  • Back to contents page


    Example 1

    Programming a simple pick-and place cycle.
    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.

    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).

    (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 )
    : UNLOAD 
    : TASK
    : FULLTASK  

    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
      STOP? IF   ( if stop button pressed
         STOP    ( stop DSP ) FSTOP C1SET ( set flag
         DSPRDY  ( wait for DSP to finish
      ?RUN       ( what is DSP doing?
      DUP 5 = IF ( use SETPA 5 to turn on PUSH-CYL not gripper
         PUSH-CYL OFF
      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
    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:
    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:
    TRAY INTO GRIP UP ( get part
    TOTRAY RUN ( go to the washer
    WASHER UNGRIP WITHDRAW ( put part in washer
    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:
    TRAY INTO GRIP UP ( get part
    RUN ( go to the washer
    WASHER UNGRIP WITHDRAW ( put part in washer
    RETRACE ( go back to tray
    This next example is more complex. Consider a reverse situation:
    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.
    : HEATER PA 6 ;
    : TEMP
    0 ADC
    2048 -
    1000 M* 2048 M/
      597 < IF HEATER ON THEN
    : HEAT
    500 INT-TIME !
    Once you type HEAT the control will continue in the background and you can carry on your robot program.

    ©1989-2014 David N. Sands