last revision 2021.12.31

ROBOFORTH II v17

© David N Sands, Cambridge, England

A license is granted to the user of an ST Robot for RoboForth II, RobWin7, RobX ActiveX modules, Robpad Teach console (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.

    PROGRAMMERS REFERENCE MANUAL

    CONTENTS

    ----+----+----
  • 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
  • Initialising.................................2.1
  • Motor drive controls.........................2.2
  • Motor flag bytes.............................2.3
  • Gripper......................................2.4
  • Home Position................................2.5
  • Calibration..................................2.6
  • Calibration axis sequence....................2.7
  • MOVEMENT 3
  • 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
  • Motion limits and constants .................3.2.3
  • Encoders.....................................4
  • Speed .......................................5
  • Acceleration ................................5.1
  • Micro stepping ..............................5.2
  • Teach Pad....................................6
  • Stop button..................................6.1
  • TEACHING 7
  • Starting a new project.......................7
  • Learning positions...........................7.1
  • Places.......................................7.2
  • Routes.......................................7.3
  • Editing Routes...............................7.3.1
  • Putting FORTH words into Routes..............7.3.2
  • 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
  • Objects......................................7.4
  • Programming the procedure....................7.5
  • INTERACTION WITH THE ENVIRONMENT 8
  • Outputs......................................8.1
  • Inputs.......................................8.2
  • Searching....................................8.3
  • Timers ......................................8.4
  • Interrupts ..................................8.5
  • COMMUNICATION AND SAVING ON COMPUTER 9
  • 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
  • ADVANCED 10
  • Vectored execution...........................10.1
  • Turnkey operation............................10.2
  • Re-entrant outer interpreter.................10.3
  • INFORMATION 11
  • Queries......................................11
  • Testing......................................11.1
  • Errors.......................................11.2
  • Using a nest.................................11.3
  • Programming Techniques ......................12

  • 1.1
    FOREWORD

    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.


    1.2
    INTRODUCTION

    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

    1.3
    GETTING STARTED

    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:

    Without RobWin

    All RoboForth commands are available. This manual focuses on the RoboForth words and where there are RobWin shortcuts or features these are indicated with the RobWin icon: .


    1.4
    FORTH AND ROBOFORTH RUDIMENTS


    ROBOFORTH may be used without any knowledge of FORTH but some ground rules are helpful. A glossary of the Forth words used in the 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.:-
    TELL OK
    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 )
    TELL TRACK OK

    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-

    : TANKS? LEFT-TANK RIGHT-TANK + . ;

    LEFT-TANK is a previously defined word that takes a measurement from the left tank and leaves it on the stack, similarly RIGHT-TANK. The word + adds the two values together and leaves the result on ths stack, then the dot . which means print, prints the result.
    Now all you have to do is type TANKS? to yield the total in both tanks, or alternatively TANKS? can be included in the definition of some grander procedure.

    The colon : is also called a word as words may be made from any ASCII characters. Moreover it is called a 'defining word'. Examples of other defining words in Forth and Roboforth are CONSTANT VARIABLE ROUTE PLACE OBJECT.

    WARNING: All words are stored in the dictionary as a length plus the first 5 characters of the word.
    Therefore ambiguities are possible and should be avoided (such as ROBOT1 and ROBOT2 which are the same
    length and have the same 5 starting characters).
    In particular avoid creating words similar to Roboforth words for example if you create a word RECEIPT this has the same first 5 characters and the same length as RECEIVE. Since RobWin uses this word communication between RobWin and Roboforth is disabled.

    FORGET (word) removes this word from the dictionary. It unfortunately also removes all words added since that one, i.e. editing the dictionary by tearing out all the following pages. Hence the need for an editor (see later).

    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

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

    1.5.1

    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.
    VARIABLE TOPSPEED
    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
    TOPSPEED @
    gets the current value of TOPSPEED and leaves it on the stack for another word to use up, for example the period . which means "print".

    The current value of TOPSPEED could be found with
    TOPSPEED @ . (pronounced "topspeed fetch print")

    or the easier form
    TOPSPEED ?

    Data can be transferred from one variable to another with e.g.
    TOPSPEED @ SPEED !

    NOTE: all numbers in Forth are 16 bit twos complement integers i.e. values between 32767 and -32768. There is the option of 32 bit numbers (double precision). In Cartesian mode co-ordinates are expressed as integers times 0.1mm i.e. 1000 equals 100.0 mm. In this version of Forth the decimal point may be inserted just for readability i.e. you can enter 100.0 or just 1000 as you wish.

    You can also create a variable with the word USER.
    When you use VARIABLE (word) the actual value of the variable is stored in the parameter field of the new word as per standard Forth practice. See the structure of a Forth word in the controller manual. However if the text around this word is edited then recompiled (reloaded) then the actual address of the data may change. There is another way of creating a variable with
    USER TOPSPEED
    This stores an address is the parameter field which points to a location in a reserved memory area called the User memory. The contents of this are unchanged after a reload. If USAVE is used then the contents of user variables are reloaded from FLASH ROM after a reset or power-up. There is a pointer to this memory UVP which is incremented each time a new USER variable is created. If you FORGET a user variable the pointer is restored to the previous user variable. Typing the word ROBOFORTH restores the pointer to the start of the user memory.

    High Memory The controller has two banks of memory. All the positional data you teach the robot is stored in high memory, bank 1. All your software, variables etc are in low memory, bank 0. The words @ and ! refer only to low memory. To access high (extended) memory (which is rare) you would use E! and E@. For example MOVES is a pseudo-variable in high memory so to read it you would use MOVES E@ (see controller manual for details on high memory). MOVES automatically sets BANK to 1.

    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 THEN. The word THEN closes the IF statement like ENDIF in other languages. In BASIC the close of an IF statement is the end of the line.
    A condition may be set up with comparing words such as = > and < but the result of any calculation may be used.
    Examples of conditions are:
    2 4 = leaves zero on stack i.e. false
    2 2 = leaves a 1 on stack i.e. true
    PRESSURE 100 > leaves true (non-zero) if the word PRESSURE leaves any value on the stack which is greater than 100.
    Example:

    : PRELIEF PRESSURE 1000 > IF VALVE ON THEN ;

    It is often useful to set up a continuous loop which ends only if a condition is met. Structure:
    BEGIN (action) (condition) UNTIL
    This executes action in a loop and repeats until the condition is true.
    Example:
    This repeats a robot motion until the escape key is pressed

    : TASK
    BEGIN
      P1 GET
      P2 PUT
    ?TERMINAL UNTIL
    ;
    This repeats a robot motion until ctrl-C is pressed
    : TASK
    BEGIN
      P1 GET
      P2 PUT
    CTRL-C UNTIL
    ;
    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

    1.6
    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

    : DROP BIN UNGRIP ;
    to drop a held object into a bin. Now you no longer have access to the original definition of DROP so if you want to use both versions you can switch contexts with the words FORTH and ROBOT. For example:
    : DUMP-OBJECT
    KEY FORTH DROP
    ROBOT DROP
    ;
    
    This waits for a key to be pressed, drops the value of the key because we don't care what key it is, then drops the held object.
    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.
    VARIABLE GVEC
    FIND GRIP GVEC ! ( FINDs the CFA (code field address) of GRIP and stores it in GVEC
    GVEC @ EXECUTE ( fetch the value from the variable GVEC and execute that
    An easier way to set the CFA into a variable is using the word SET e.g.
    SET GVEC GRIP
    See section 10.1. Possible uses for this are described in sections 6.1 and 7.3.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 that 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

    2.1
    INITIALISING

    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:

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

    STARTOVER
    Resets the data pointer NEXT to the start of data mamory (bank 1)

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

    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.

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

    You can also do a software reset with
    RESET
    If you don't have reset you can use
    HEX 420 JUMP or define a word
    HEX : RESET 420 JUMP ;

    You can also quit a word from any level and restart it from scratch by using the TURNKEY feature (see section 10)
    RESTART
    If you don't have RESTART you can define it:
    HEX : RESTART 423 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.

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

    2.2
    MOTOR CONTROL

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

    2.3 MOTOR/SENSOR/ENCODER FLAG BYTES


    There are several motor flag bytes in which bit 0 controls or corresponds to axis/motor 1 (waist), bit 1 controls axis 2 etc.
    They are like variables but only the bottom 8 bits have any significance.
    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.
    EFP - Encoder Fitted Pattern - bit set means motor has an encoder fitted.
    SIP - Sensor Inversion Pattern - for sensors which send a 1 when calibrating as opposed to the normal 0.
    The above flag bytes are like variables but only 8 bits. To read a value enter: EEP C@ .

  • Back to contents page

    2.4
    GRIPPER

    To operate the gripper enter:
    GRIP
    to close gripper

    UNGRIP to open gripper

    GRIP sets a flag FGRIP to true and UNGRIP sets it to false.
    UNGRIP also clears any object from the WHERE display (i.e. from the variable OBJECT-HELD)

    Click

    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
    GRIPPER ON
    or
    GRIPPER OFF

    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.

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

    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
    1 - electric gripper
    2 or greater - intended for a vacuum pickup. The value of GTYPE matches the PA bit number connected to the valve. For example if GTYPE is 4 then GRIP and UNGRIP will operate PA 4 followed by the delay in TGRIP
    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 !
    To change to a vacuum pickup or other on/off device: If the valve is connected to e.g. PA 5 then enter 5 GTYPE !

    2.4.1 GRIPPER CONFIRMATION

    The gripper confirmation on a gripper is set to give a different state between gripped on an object and gripped on nothing at all. Ungripped may well give the same state as gripped on nothing but is irrelevant. With a vacuum pick-up a vacuum switch provides confirmation. If the object is not picked there is no vacuum.
    The gripper confirmation switch is usually connected to PB 5 but could be any input. If there is a track then the track calibration sensor is connected to PB 5 and the gripper sensor is moved to PB 7. Note that PB 6 is normally used for interrupts. The definition GRIPSENSE may be patched to a different bit.

    To check the grip sensor use
    GRIPCHECK You could then use this definition in a new definition of GRIP e.g.

    : GRIP      ( new definition
    GRIP        ( old definition
    GRIPCHECK
    ;
    
    However this could leave the robot in a difficult place from which to recover so it is usually best not to make the check until the robot is in a safe place. For example:
    : GETPART
    TOJIG CONTINUOUS RUN
    JIG
    GRIP
    WITHDRAW
    TOJIG RETRACE
    GRIPCHECK
    ;
    
    Note: the grip sensor on a motorized electric gripper is the inversion of the sensor on a pneumatic gripper, i.e. on a motor gripper PB 5 goes to 0 to fail and on a pneumatic gripper it goes to 1 to fail. This is taken care of in the software.

  • Back to contents page

    2.5 HOME POSITION

    WARNING
    Before trying any of the following commands be sure to
    KEEP OUT OF THE ROBOT ENVELOPE

    As mentioned earlier all spatial positions around the robot arm are expressed (in most circumstances) as co-ordinates relative to the HOME position of the arm where the co-ordinates are all zero. On an R12 or R17 this is bolt upright. On an R19 it is with the lift axis near to lowest travel and the extend axis almost fully retracted. In both cases the waist is at mid-point of available travel.
    Wherever the robot happens to be after typing START is set to be the HOME position but the true home position must be established with CALIBRATE -- See calibration

    HOME

    click
    Note nothing will happen right now because the robot already is at HOME

    This is a place name which returns the robot to the home position where all counts are zero. You would not normally type this until you had calibrated the robot (See calibration.).

    In some applications the HOME position is not a safe one, for example where there is a ceiling too low for an R17 to be bolt upright. In this event you might want to add some programming to conditionally bar the HOME position, e.g.:

    : HOME
    CR ." Are you sure? "
    KEY DUP EMIT 89 = IF ( looking for capital Y )
       HOME
    THEN
    ;
    
    (for programming such things see later, section 9.1)

    SETHOME
    Wherever the robot happens to be can be made into a home position with this word i.e. all co-ordinates are set to zero. Not to be used without good reason.

  • Back to contents page

    2.6 CALIBRATION

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

    CALIBRATE

    click

    This drives all the axes to their proximity detectors, reports the errors then corrects them to the values in LIMITS.

    A single axis can be sent to the detector position with the command (e.g.)
    TELL TRACK DATUM
    More than one axis could be datumed with the line
    TELL (axis1) (axis2) (axis3) DATUM
    Suppose that axes 2 and 3 have to move backwards to their datum positions, the correct line would be:-
    TELL (axis2) (axis3) REVERSE (axis1) DATUM

    DATUM has two major components: ONLIM and OFFLIM. During ONLIM the axis moves onto the sensor. When it detects the sensor, i.e. the sensor input goes low, it decelerates. OFFLIM then reverses the axis at slow speed until it just clears the sensor (sensor input goes high).

    CALIBRATE
    The robot seeks out the sensors on each axis using DATUM on all axes. When the sensors are reached the joint counts are corrected to the joint counts in the array LIMITS (see below). Each value in LIMITS is the number of counts difference between the sensor and the HOME position for each axis. In addition the number of counts error between this and the previous calibration are shown on screen. Normally the difference would be about 2 or 3 steps and no more than 10 steps.

    Possible errors

    CANNOT FIND SENSOR
    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

    CHECK
    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.
    LIMITS
    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
    START
    4. drive the robot to the sensors using
    CHECK
    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 + !

    R12 only

    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.
    SET CALVEC OUTER
    Then if there is a calcheck error 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:-
    : HCAL TELL HAND REVERSE DATUM LIMITS 6 + @ 3 GLOBALS !;
    This forces the WHERE display to the correct value in LIMITS. You also need to fcrce the encoders to show this new value with
    ENCSET

    The accuracy of the robot after calibration depends on the repeatability of each axis and its sensor. This can be improved upon using a NEST

  • 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
    The 6-axis version calibrates in this order: 1,2,3,5,4,6
    The axis number calibrating is shown on screen.

    R12-6 and R17-6

    CALSEQ is an array of 6 bytes used to determine the order in which the robot axes calibrate. The default sequence is 1,2,3,5,4,6
    You can see it with:
    CALSEQ DUMP If you want, for example, to swap the shoulder and waist you could enter:
    2 CALSEQ C! 1 CALSEQ 1+ C!
    Or to calibrate axis 6 first and move the others up (example only):
    6 CALSEQ C! 1 CALSEQ 1+ C! 2 CALSEQ 2+ C! 3 CALSEQ 3 + C! 5 CALSEQ 4 + C! 4 CALSEQ 5 + C!

    R15 only

    CALSEQ is an array of 8 bytes used to determine the order in which the robot axes calibrate but it works with motor selection patterns so groups of axes can calibrate together as for the R17.
    To help understand this facility please see the words MEP (Motor Enable Pattern) and MDP (Motor Direction Pattern) in section 2.3.
    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. MOVEMENT COMMANDS

    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
    WAIST, SHOULDER, ELBOW, HAND, WRIST.
    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
    WAIST, SHOULDER, ELBOW, HAND (2 motors), L-HAND, R-HAND (yaw), WRIST

    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:
    >TELL WAIST 500 MOVE OK
    or for a Cartesian robot:
    >TELL TRACK 500 MOVE OK
    The waist or track motor now moves 500 steps and these are counted by the system.

    Since we are still talking to the waist/track it is only necessary to enter:
    500 MOVE
    to get the waist/track to move another 500 steps. The waist/track will now be a total of 1000 steps from the home position.

    When the move is complete you can list the current position of the arm with the command WHERE. This displays the number of steps each motor has moved since it was at the HOME position.
    >WHERE

    For an R12/R17 the result is:

          WAIST  SHOULDER  ELBOW  L-HAND  WRIST    OBJECT  
           1000       0       0       0       0 
    L-HAND is listed because in the R17 and R12 hand pitch is achieved by running both motors 4 and 5 together but wrist roll requires only motor 5. If only motor 4 (L-HAND) runs then the wrist rolls in the opposite direction.

    For an R12/R17 six-axis the result is:

          WAIST  SHOULDER  ELBOW  L-HAND  R-H/YAW  WRIST    OBJECT  
           1000       0       0       0       0       0
    L-HAND is motor 4, R-H/YAW is motor 5, WRIST (gripper rotate) is motor 6.

    For an R19 this results in:

          WAIST    LIFT   EXTEND   HAND   OBJECT  
           1000       0       0       0  
    For an R19T with hand yaw and track this results in:
     
          WAIST    LIFT   EXTEND   HAND   TRACK    OBJECT  
           1000       0       0       0       0  
    For an R15 this results in:
     
          TRACK    LIFT   EXTEND  WRIST  OBJECT  
           1000       0       0       0  
    and various other combinations. The particular heading depends on the model and configuration of the robot. It can be invoked by itself with JOINTHEAD

    click Robot, Joint position.

    Actually there will be two more lines below the motor position. The second line shows the actual counts obtained from the encoders. The third line is the count multiplied by a factor determined by encoder resolution and gear ratios and is the computed true position which should be the same as the motor position within a few bits, for example

          WAIST  SHOULDER  ELBOW  L-HAND  WRIST   OBJECT        (R12/R17)  
    or    WAIST     LIFT  EXTEND   HAND   TRACK   OBJECT        (R19T) 
    or    TRACK     LIFT  EXTEND   HAND   WRIST   OBJECT        (R15)  
           1000       0       0       0       0  
            642       0       0       0       0  
           1001       0       0       0       0  
    There is no encoder on the 6th axis of an R12/R17
          WAIST  SHOULDER  ELBOW  L-HAND  R-H/YAW  WRIST    OBJECT  
           1000       0       0       0       0       0
            642       0       0       0       0
           1001       0       0       0       0
    More than one joint at a time can be moved with e.g.
    TELL SHOULDER ELBOW 1000 MOVE
    or
    TELL LIFT EXTEND 1000 MOVE

    click Robot, Joint Rel move.

    Repeated use of MOVE continues to move the same joints relative to their previous positions. The joint selection is cancelled with TELL.
    Movement in the reverse direction is achieved with negative values e.g.
    -1000 MOVE

    Another way of moving backwards is with e.g.
    TELL WAIST REVERSE 1000 MOVE (or TRACK or whatever)

    An axis can be made to move to a particular position with e.g.
    TELL WAIST 1500 MOVETO
    click Robot, Joint Abs move

    The waist then moves forward or backward as necessary to finish at 1500 steps from the home position.

    Wrist rotate is axis 5 on a 5-axis robot, axis 6 on a 6-axis robot.
    The wrist twist may be moved with TELL WRIST (n) MOVE but may also be moved with (n) TWIST a relative command.
    The wrist may be restored to the zero position with
    UNTWIST an absolute command.

    The array which contains the counts for each motor is called GLOBALS and is addressed with (n) GLOBALS where n is 0 for the first motor, 1 for the next etc. e.g.
    0 GLOBALS ? 1500 OK
    It could be changed with e.g.
    1501 0 GLOBALS !

    The simplest motion command is STEPS e.g.
    >TELL WAIST 500 STEPS OK (or TRACK or whatever)

    The waist or track motor now moves 500 steps, but these are not counted by the system. WHERE will show, in the encoder lines 2 and 3, that the axis has moved but there will be no count in line 1.

    -MOVE is a simpler version of MOVE which operates only in JOINT mode and makes less checks.

    TELL WAIST 1000 MOVE
    WHERE shows

          WAIST  SHOULDER  ELBOW  L-HAND  WRIST   OBJECT        (R12/R17)  
           1000       0       0       0       0  
           xxxx       0       0       0       0  
           1010       0       0       0       0  

  • 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:
    TELL WAIST 5000 DSPMOVE
    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.3.7

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


    3.1.1 POSITIONAL DATA

    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 Cartesian mode for a 5-axis robot the data is X, Y, Z, PITCH, W, then TOOL-LENGTH, two bytes each. For a 6-axis robot the data is X, Y, Z, PITCH, YAW, ROLL. The 7th value (bytes 12,13) 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.
    BANK C1SET 64 XGOTO

    (address) -GOTO ("dash-goto")
    is a faster form of GOTO which assumes that the co-ordinates in the data strip are joint (motor) and not Cartesian co-ordinates and performs no checks. The data must be only in low memory (bank 0). This makes it suitable for use with functions which always produce a result in low memory, for example TRANSFORM -GOTO

    To see what the data is enter:
    VIEW (address of data)

    Two positions may be added together and the robot sent to the result. For example:
    (address1) (address2) ADD GOTO

    A joint position may not be added to a Cartesian position. Two absolute positions may not be added together. If a relative position is added to an absolute position the result is a new absolute position. If two relative positions are added the result is a new relative position.

    You can create positions in the dictionary by use of the word CREATE in your text window, for example
    CREATE NEST 1000 , 2000 , 3000 , 4000 , 5000 , 0 , 0 , 0 , (8 numbers separated by commas and spaces)
    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 2-byte value of this strip contains flags as follows:
    0 Joint mode
    1 Joint relative mode
    2 Cartesian mode
    3 Cartesian relative mode
    so
    CREATE APR 0 , 0 , 50.0 , 0 , 0 , 0 , 3 , 0 ,
    is a relative Cartesian position. If you type APR GOTO
    Then the robot will move up exactly 50mm. Each time you type APR GOTO it will move up another 50mm. (see next section)
    The last 2 bytes 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
    1 LINE DSPSMOOTH
    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.3.7

    WARNING The robot will not stop when you press the stop button. To stop the robot execute the command STOP (part of a program or type it quick)
    This tells the DSP to stop moving the robot.

    In an emergency press the reset button.

    ?STOP
    is a loop which waits for the DSP to finish. If the stop button is pressed during this time the DSP is sent the STOP command and the robot stops. As long as the CPU is in command mode or executing some other command the stop button is ignored.

    When the robot has stopped WHERE will show the robot to be still where it was before you executed DSPSMOOTH therefore you must, as soon as DSPSMOOTH has finished, or at worst before you execute the next command, execute
    DSPASSUME - this updates the counts from the DSP.

  • 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:
    CARTESIAN
    click

    To return to joint mode enter
    JOINT
    click

    click Robot, Cartesian Absolute move.
    In the command window the action of MOVE, MOVETO and WHERE are changed. MOVE and MOVETO now require 3 arguments and no joint selection.
    The arm is positioned by commands of the form X Y Z MOVETO where X,Y and Z are integers of 0.1 mm, e.g.
    1000 2000 3000 MOVETO
    though it may look better as:
    100.0 200.0 300.0 MOVETO

    The software then performs a transformation from Cartesian to motor co-ordinates and drives the arm to X=100.0 mm, Y=200.0 mm, Z=300.0 mm. The message "CANNOT REACH" indicates impractical values entered. Also valid is MOVE e.g.
    0 0 -500 MOVE which performs a relative move downwards of 50.0mm.
    You will encounter problems with any of the above at first if you start from the HOME position. This is because at HOME position the wrist points straight up i.e. -90.0 degrees. In R12 this is not allowed if the angle between hand and forearm is too negative because of possible contact between the hand and the forearm. It is best to use RobWin to first of all position the robot in a suitable starting position where the hand angle is 0 or 90.0 degrees.
    click Robot, Cartesian Relative move.
    Alternatively enter the word READY
    In 6 axis systems READY positions the gripper pointing down. There is also
    READY2
    in which the gripper is horizontal.

    The current co-ordinates of the end effector are displayed with the command WHERE which in Cartesian mode displays in an altered form:
    WHERE

             X       Y       Z     PITCH    W(ROLL)  LEN.  OBJECT  
          100.0   200.0   250.0    -90.0     0.0     0.0  
    PREV    0.0     0.0     0.0      0.0     0.0     0.0  
    Where the values under X,Y,Z are displacements in mm.

    For a 6-axis R12 or R17:

             X       Y       Z     PITCH     YAW    ROLL  OBJECT  
          100.0   200.0   250.0    -90.0     0.0     0.0  
    PREV    0.0     0.0     0.0      0.0     0.0     0.0  
    For an R19:
             X       Y       Z     W(YAW)    LEN.  OBJECT  
          100.0   200.0   250.0    -90.0     0.0  
    PREV    0.0     0.0     0.0      0.0     0.0
    The line PREV is the previous position of the arm, so the co-ordinates in the first line move down to PREV after each move.
    To return to the PREVious position enter PREVIOUS RESUME
    or PREVIOUS TRANSFORM -GOTO

    For a 5 axis R12 there are 6 variables in Cartesian mode:
    X Y Z PITCH W
    (note: #CARTS ? 5, #AXES ? 5)
    For a 6 axis R12 there are 6 variables in Cartesian mode:
    X Y Z PITCH YAW ROLL
    (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:
    RESUME or just GO
    or TRANSFORM -GOTO
    You can change any single variable e.g. 450 PITCH ! and GO will make the changes happen.

    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.

    COMPUTE
    click Robot, Cartesian position
    While in Cartesian mode the joint position (motor counts) can be viewed with JOINTWHERE or just JW. While in joint mode the Cartesian position can be viewed with COMPUTE CARTWHERE.

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

    3.2.1 POINTS

    Cartesian co-ordinates can be recorded in different ways: one is by using the defining word POINT e.g.
    POINT P1
    The current co-ordinates are recorded in the parameter field of P1 and may be viewed with:
    VIEW P1
    The robot will go to that position with:
    P1 GOTO

    which drives the arm to the co-ordinates of P1.
    To list all points created so far enter:
    POINTS

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

    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

    3.2.2 TOOL TRANSFORMATIONS:-

    By default it is the wrist pivot which actually occupies the specified co-ordinates. This is known as the TCP (Tool Center Point) 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 !
    This is the distance between the old TCP and the new one as a multiple of 0.1mm.
    From here on it will be the end of the tool which is the TCP occupying the specified coordinates.
    Alternatively use the command:
    TOOLSET (Tool Settings)
    5-axis
    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 enter a value for TOOL-LENGTH then 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 or TCP.
    NOTE: if you use a value for TOOL-LENGTH then the coordinates learned into PLACEs and ROUTEs will be the coordinates of the new TCP and not the default center of wrist and roll. 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"

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

    PLUNGE
    is similar to the VAL word APPRO. Whichever direction the end effector is pointing PLUNGE will move the end effector in that direction.
    For example suppose the end effector is at a PITCH of 45.0 degrees then
    1000 PLUNGE
    will move the end effector 100.0 mm in the direction 45 degrees to Z-plane. 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.
    ALIGN
    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

    3.2.3 CONSTANTS AND LIMITS

    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

    Limits of Travel
    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, i.e. a total of 750.0mm.) and for R12 twice 250.0mm, max reach 500.0mm.
    There are 2 constants, MAXLEN and MINLEN. MAXLEN is 5000 or 7500 for R12 or R17. MINLEN prevents the robot hitting itself.
    Enter
    MAXLEN .
    Exceeding this gets "CAN'T REACH OUT"
    MINLEN .
    Going less than this gets "CAN'T REACH IN"

    To prevent the R12 or R17 robot hitting a back wall there is a limit to negative Y, MINY
    MINY ? to show present limit. If you try to go further back you get CAN'T REACH ON Y
    To change it to, say -6000 enter
    -6000 MINY !
    To prevent the R12 or R17 robot hitting the bench there is a limit to negative Z, MINZ MINZ ? to show present limit. If you try to go further down you get CAN'T REACH ON Z
    To change it to, say -3000 enter
    -3000 MINZ !

    R15: the limits of travel in X, Y and Z directions are determined by the values in an array WORKSPACE. These values can be checked with:
    VIEW WORKSPACE
    Bytes 0,1: Max X travel (positive) 
    Bytes 2,3: Max Y travel 
    Bytes 4,5: Max Z travel 
    Bytes 6,7: Min X travel (negative) 
    Bytes 8,9: Min Y travel 
    Bytes 10,11: Min Z travel 

    To alter any value use this syntax: 
    (new max X) WORKSPACE ! 
    (new max Y)) WORKSPACE 2+ ! 
    (new max Z)) WORKSPACE 4 + ! 
    (new min X)) WORKSPACE 6 + ! 
    (new min Y)) WORKSPACE 8 + ! 
    (new min Z)) WORKSPACE 10 + ! 
    

    R19: the limits of reach are determined by four constants:
    MAXHT - maximum Z value, MINHT - minimum Z value,
    MAXLEN - maximum extension of extend axis (i.e. maximum radius),
    MINLEN - minimum extension of extend axis (i.e. minimum radius)
    The waist is also limited to plus/minus 180 degrees.


    4 ENCODERS

    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
    VIEW ENCRATIOS
    The value of each element is the number of counts per encoder divided by the number of counts per rev of the corresponding motor, times 10000
    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 ;
    : STALLED ALARM ON KEY DROP ALARM OFF ENCASSUME ;
    SET ENCVEC STALLED
    This last line replaces the "ENCODER-STEPPER MISMATCH" error message with the action taken by STALLED. Then in case of a serious encoder mismatch the robot will stop and wait for the user to press any key. Then the error will be corrected and the robot will carry on.
    If a place or a route is executing at the time the error occurs it will continue after the word finishes (IF it finishes - if the word contains ABORT the system will not continue). The word itself may include some robot movement but not another place or route unless this is the last motion before an ABORT for example:
    : STALLED ALARM ON KEY DROP ALARM OFF ENCASSUME HOME ENCABORT ;

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

    ENCLEARN - same as LEARN but learns joint co-ordinates from the encoder counts instead of motor counts. (see LEARN)
    Warning: the encoder counts may differ slightly from the motor counts so ENCLEARN will introduce small errors which may accumulate until the next CALIBRATE. In the case of R12 the errors can be unacceptably high so ENCLEARN should not be used with the R12.

    EFP - Encoder Fitted Pattern - This is a value in which each bit corresponds to an axis. A bit set means that axis has an encoder fitted. START transfers this value to the variable EEP (encoder enabled pattern).
    The value of this variable can be changed by typing (val) EFP !

  • Back to contents page

    5 SPEED

    You will have noticed that every time the arm moves it accelerates and decelerates. 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 and the entire robot then decelerate before stopping.
    The diagram below 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 the above diagram. 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. The track is the 6th axis. In a 6 axis robot wrist roll is the 6th axis and the speed limit is ROLLSPEED. Put a bigger value in TRACKSPEED or ROLLSPEED to make the track or wrist go faster. The speed of the 6th axis is the lowest of the two values in SPEED and TRACKSPEED or ROLLSPEED. In compound moves as in GOTO and PLACE names the speed of the whole robot is limited to TRACKSPEED or ROLLSPEED if the 6th axis is one of the axes which is moving. As soon as the track finishes moving the speed increases to SPEED.

    Speed may be changed during the progress of a route with 'LEARN (see 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.3.2

    5.1 ACCELERATION

    Changing the value of SPEED does not affect acceleration, just as in the above diagram. The slope of the speed profile is the acceleration.
    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.

    Moreover the rate of change of acceleration is also programmable and the variable is called JERK. This reduces shock in the robot resulting in less or no overshoot of position.
    Change with (val) JERK !
    The below diagram is a typical speed profile based on a theoretical speed of 16m/s (which the robot obviously can not do):

    A high value for JERK means that programmed ACCEL is reached sooner. A low value of JERK means that ACCEL will be reached later.
    If JERK is a very low value then the programmed ACCEL may not be reached at all before the set SPEED is reached so no time will be spent in the ACCEL segment. For any series of very short moves it may be wise to keep JERK at a high value so that ACCEL and SPEED are reached and cycle time is optimum.

    Similarly if speed is too low there may not be time to reach the programmed ACCEL before deceleration must begin.

    SETTINGS permits simultaneous display and editing of all the above variables and also SEGTIME (see later)
    To restore default values use NORMAL

    The time to reach set speed is SPEED / ACCEL * 41 mSecs
    The time to reach set accel is ACCEL / JERK * 82 mSecs

    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.
    You can VIEW 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+ !

    There would rarely be any reason to change these values. But if you do the values for RATIOS and ENCRATIOS would also need to change.
    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

    6 TEACH PAD

    To start moving the arm enter:-
    TEACH
    click

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

    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
    J6axis6trackwristtrackplungeroll

    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:-
    SET FN TEST OK

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

    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.

    (TEACH)

    This word is the same as TEACH but does not ask for CREEP-FACTOR first. Thus it can be used without the terminal.

    The teach pad may also be used for other purposes, using the following words:
    KEYPRESSED? returns a true if a key is being pressed, 0 of not.

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

    KEYPAD

    This is the same as INKEYPAD except that the system stops and waits for a key to be pressed (similar to KEY). When a key is pressed it returns a value from the table above.

    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

    6.1 STOP BUTTON

    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"
    KEY 27 = IF STOPABORT THEN
    ;

    SET STOPVEC ESTOP
    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
    START
    SET STOPVEC ESTOP
    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 press 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"
    KEY 27 = IF STOPABORT THEN
    RESUME
    ;

    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"
    KEY 27 = IF STOPABORT THEN
    TRANSFORM -GOTO
    ;

    Emergency stop
    When you press the stop button (or interrupt the stop circuit) the robot immediately decelerates. The rate of deceleration is the same as programmed i.e. ACCEL. However in some circumstances you may wish to decelerate faster. A variable STOPACC contains the value for emergency deceleration. Normally it is the same value as ACCEL however if you set it very high, for example 8000 then the robot will stop much sooner. During emergency stop the same value is also used for jerk to ensure the most rapid stop.
    Possible programming:
    : TASK
    START
    8000 STOPACC !
    SET STOPVEC ESTOP
    rest of definition
    ;


    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 temporarily so that 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"
    KEY DUP 27 = IF STOPABORT THEN
    ASPACE = IF OUTER THEN
    ;

    SET STOPVEC ESTOP
    Once you have typed in your commands to recover from the problem you can press escape to abort everything or you can type EXIT which continues the program that was stopped. Note the program will assume the stopped word was completed and continue from there. See RESUME

    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.

    ?STOP
    is a loop which waits until the DSP has finished. In addition it checks the stop button. If the stop button is pressed it sends the STOP command to the DSP, sets a flag FSTOP to '1' then waits for the DSP to finish.
    As long as the CPU is in command mode or executing some other command the stop button is ignored.

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

  • Back to contents page

    7 TEACHING

    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.

    7.1 LEARNING POSITIONS

    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:
    STARTOVER
    Among other things this sets NEXT to RUN-LIST plus 16.
    Starting a new project executes STARTOVER so there is no need to type the word.

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

    7.2 PLACES

    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 (note "NEAR can not be compiled into another word.)

    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:-
    VIEW CAMBRIDGE
    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  
    OK  
    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

    7.3 ROUTES

    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 are not sure how many you willl need reserve too much e.g. 100 or more. There is space for 4000 positions for all routes and places.
    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 'append 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 'append 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
    RUN
    The robot follows the learned list from point to point.
    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.

    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
    RETRACE

    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.

    Looping a route: A route in CONTINUOUS mode can be made to repeat from the beginning without stopping using the user variable REPEATS. (v17.3 up only).
    The default value of REPEATS is 0.
    1 REPEATS ! gives you 1 repeat or two complete runs. n REPEATS ! gives you n+1 complete runs.
    IMPORTANT As explained below REPEATS doesn't work if the coordinates in two successive lines are too close together.
    REPEATS can not be used with SEQUENCE or RETRACE.

    7.3.1 EDITING

    If you wish to list or edit another route type the name of the route first.
    To edit a route click the route name in the routes list window then click 'open route'. You can then do various things:
  • 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:-
    WHICH TEST1 ABSOLUTE OK

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

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

    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 with the current position of the robot.
    RLEARN adds one line to the route with the last relative move of the robot.
    (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 restores the NEXT pointer to the start of the memory block. This 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.

    RTYPE changes the type of route (e.g. JOINT or CARTESIAN) to the current mode (e.g. CARTESIAN or JOINT).

    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

    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 E@ .
    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
    or just LASTLINE 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:
    JL
    Likewise a line containing any kind of data may be replaced with joint co-ordinates with
    JR
    Then upload the data to the computer with

    7.3.2 PUTTING FORTH WORDS INTO ROUTES

    ( "TICK" COMMANDS )

    It is possible during the progress of a route to have the controller execute a FORTH program or "word" for example GRIP and UNGRIP, MSECS, changes in SPEED or other variables, or user defined words.
    Use insert func

    For example, to insert a 5 second delay:

    or a speed change

    You can also insert words you have defined.
    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':-
    : PRESENT BEGIN PB 7 BIT? UNTIL ;

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

    However it is not a good idea to 'INSERT (insert func) or 'LEARN (append function) 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
    PATH1 2 'REPLACE PRESENT
    If you wish to update the listing in RobWin then click the red up-arrow

    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.

    Note that most words can not be inserted into a route that is intended to run in CONTINUOUS (or SMOOTH) mode. For example you can't use MSECS because a continous path route is meant to be continuous and not held up part way through. So you can only insert words (functions) that take no time and are recognized by the DSP for example GRIPPER or SETPA.

    AGAIN
    In the comms window or hyperterminal you can type 'LEARN AGAIN
    or click insert func and enter AGAIN
    To repeat a route in CONTINUOUS mode use REPEATS.
    This simply repeats the route from the beginning again. It only works in SEGMENTED mode. It never ends until you stop it with control-C
    The default value of REPEATS is 0.
    1 REPEATS ! gives you 1 repeat or two complete runs. n REPEATS ! gives you n+1 complete runs.
    There are restrictions in using this feature, see 7.3.5

    7.3.3 MATRICES

    ROW


    Click new in routes window; in route create box click row. Then enter the number of points in the row in the columns box. Make sure the number of lines reserved is at least 1 greater than the number in the columns box. Move robot to first position, click the first line in the route window and click set-to-here. Then move robot to last position in the row, click the last line in the route window and click set-to-here. Finally press interpolate.

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

    GRID

    This sets up a 2-dimensional array.


    1. Click new in routes window; in route create box click grid. Select whether the numbers should be JOINT or Cartesian co-ordinates. Almost certainly joint mode will be meaningless unless you are using a Cartesian robot so select Cartesian mode. Then enter the number of rows and columns. Make sure the number of lines reserved is at least 1 greater than rows times columns. There's plenty of space so just reserve plenty. It is possible to increase this later if necessary.
    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.
    Image: dialog box showing creation of a new matrix TRAY in Cartesian mode, 3 columns by 9 rows.

    Using the 4-point feature: in some cases the 4th corner (and related points distant from the 3 corners) may be slightly out due to errors in the tray or the robot. Guide the robot to the 4th corner, position carefully and click the line marked i4 and set-to-here. Then click interp. 4pt.

    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

    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:
    TRAY (n) NEARAD AXES
    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.

    TRAY 5 NEARAD AXES
    PATH LASTLINE REPLACE RUN
    TRAY 5 GOTO
    
    or a generic word to take the line number off the stack:
    : GOTRAY
    DUP ( needed by NEARAD and GOTO
    TRAY NEARAD AXES
    PATH LASTLINE REPLACE
    RUN
    TRAY GOTO
    ;
    usage
    (n) GOTRAY
    
    NOTE in version 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.
    DOWN
    Moves the robot from the approach position to the target position - use only after (n) NEAR.
    UP
    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

    : EMPTY-TRAY
    TRAY
    MOVES E@ 1 DO
      I INTO
      GRIP
      UP
      BELT
      UNGRIP
    LOOP
    ;
    
    Note the use of MOVES E@ above. In the first place MOVES is one more than we need, being the number of the line with the RELATIVE position. In the second place, due to a Forth idiosyncracy DO LOOPs require one more than the actual number of loops, e.g. 9 1 DO LOOP will do 8 loops not 9. Remember also that MOVES is in high memory so must be read with E@ not just @

    7.3.4 Continuous Path

    A route may be used to generate an almost continuous path. For this the CPU passes all the route data to the DSP line by line and the DSP executes the motion without the CPU being involved (see later, three phases of operation). Learn a route as normal but to RUN it first enter
    CONTINUOUS
    to put the system into continuous path mode.
    SMOOTH is an identical command that includes ADJUST (v11 up) (see 7.3.5)click
    Then when you type RUN
    the robot will run through all the points without stopping. The CPU waits for the DSP to finish driving the robot before control comes back to the user or the software moves to the next word.
    To run the route backwards enter
    RETRACE

    To cancel CONTINUOUS mode enter
    SEGMENTED
    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. Acceleration may not be reached if the value of JERK is too low. For highest throughput increase both ACCEL and JERK.

    The route may contain contain joint or Cartesian values.

    To change speed within the route go to the route box and highlight the required line before which the speed must change. Click 'insert func' then enter SPEED in the dialog box and the required speed below it.

    To turn the gripper on or off within the route go to the route box and highlight the required line at which the gripper should operate. Click 'insert func' then enter GRIPPER in the dialog box and the value 1 below it to turn it on, or 0 to turn it off. You cannot use the word GRIP which only works in segmented mode.

    STOP BUTTON:
    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 values of ACCEL and JERK. 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 (and JERK if that is the limitation) 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
    DRY RUN

    There are 3 modes of RUN. After a DRY RUN, CONTINUOUS is re-asserted. In CONTINUOUS mode RUN automatically does a dry run first to make sure settings are valid. In NOCHECK mode (not R19) 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. Lines in a very long route queue up. It is up to the user to ensure that SPEED, ACCEL and JERK settings are valid before a NOCHECK RUN. If not the results can be catastrophic.

    There exists the possibility to reduce the speed of a route automatically and temporarily with the command
    ADJUST (then RUN)
    or
    SMOOTH selects continous mode then does ADJUST 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
    RESTORE

    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 up. If your system does not have it you can add it to your project ed2 window (section 7) as follows:

    : CONVERT
    LASTLINE 1+ 1 DO
       I LINE EXAD E@ 2 = IF
         I LINE AXES
         TRANSFORM I LINE 16 MOVUP
       THEN
    LOOP
    ;
    

    Looping a route: A route can be made to repeat from the beginning without stopping using the user variable REPEATS. (v17.3 up only)
    The default value of REPEATS is 0.
    1 REPEATS ! gives you 1 repeat or two complete runs. n REPEATS ! gives you n+1 complete runs.
    IMPORTANT As explained above the system doesn't work well if the coordinates in two successive lines are too close together. It doesn't work at all if two successive lines are identical. In the case of REPEAT make sure the last line is not the same as the first line or they are effectively successive and identical and the robot will stop with error 33. It is a good idea to add a line that is identical with the first line, then use SMOOTH or ADJUST to find an ideal speed, then delete the last line again then run with REPEATS using the value for SPEED that was recommended by SMOOTH or ADJUST.
    REPEATS can not be used with SEQUENCE or RETRACE.

    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: Words that you embed must be complete before the next embedded word or the end of the route. For this reason RoboForth permits quickly passing the embedded value to the output port.
    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
    SETPA 15 - turns on PA 6
    SETPA 14 - turns off PA 6
    SETPA 17 - turns on PA 7
    SETPA 16 - turns off PA 7
    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.

    ?RUN
    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
      14 - DSP has read a line SETPA 12 which means turn off PA 6
      15 - DSP has read a line SETPA 13 which means turn on PA 6
      16 - DSP has read a line SETPA 12 which means turn off PA 7
      17 - DSP has read a line SETPA 13 which means turn on PA 7
    All values for SETPA and ?RUN from 18 to 255 are available to operate other functions in advanced programming.
    For example if you absolutely must operate a word that takes time to operate (for example GRIP for an electric gripper) you can use the higher values. The embedded word is still SETPA but you can write a word to read back the value and operate your time-using word. Put that word in the vector DSPVEC. The executable value in DSPVEC is execute repeatedly during RUN.
    For example to do GRIP and UNGRIP on the fly you could use values 18 and 19:
    : XGRIP
    ?RUN 18 = IF
      PA 0 BIT? 0= IF GRIP THEN
    THEN
    ?RUN 19 = IF
      PA 0 BIT? IF UNGRIP THEN
    THEN
    ;
    : START
    START
    SET DSPVEC XGRIP
    ;
    Since the value from SETPA remains until the next line of the route we need the PA 0 test so we only operate the gripper once.

    7.3.7 Advanced commands

    CRUN

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

    Three phases of operation

    A DSP controlled RUN 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. Then the CPU enters phase 3, a loop simply monitoring the DSP waiting for it to finish by 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 with CRUN. ?GRIP is a self contained word that operates the output register directly. ?RUN polls the DSP and leaves a flag on the stack as listed above.

    STOP
    This tells the DSP to stop moving the robot.

    Example program

    This example uses a vertical straight line. The robot moves down the line, all in Z axis.


    We want the robot to stop moving when a sensor is reached. So this is in a BEGIN-UNTIL loop. When the sesnor activates the loop ends.
    It must also end if the stop button is pressed or if the route finishes without the sensor being reached.
    : TASK
    R1
    SMOOTH       ( FIND SAFE SPEED
    CRUN         ( RUN WITHOUT WAITING
    BEGIN
      PB 7 BIT?  ( SENSOR TRUE
      ?RUN 0= OR ( DSP FINISHED ALREADY
      STOP? OR   ( IS STOP BUTTON PRESSED?
    UNTIL
    STOP         ( STOP DSP RUN IF NOT ALREADY STOPPED
    ?STOP        ( WAIT FOR IT TO STOP
    DSPASSUME    ( GET BACK COUNTS OF WHERE IT GOT TO
    COMPUTE      ( CONVERT TO CARTESIAN
    ;
    

    ESTOP?
    If the flag FSTOP is set then ESTOP? executes the emergency stop procedure.
    The stop button normally executes 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 emergency stop the robot if pressed:
    replace the line
    STOP? OR ( IS STOP BUTTON PRESSED?
    with
    ESTOP?
    The OR is not needed because we want to stop unconditionally.
    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:
    CLRDSP

    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.
    USER CYCLES
    USER LAMP
    : SCAN
    LAMP @ 5 > IF 0 LAMP ! THEN
    LAMP @ BIT PA OUT
    LAMP INC
    100 MSECS
    ;
    : TEST
    SET DSPVEC SCAN
    TR ( NAME OF A ROUTE
    10000 SPEED !
    SMOOTH
    RUN
    ;
    
    Although stated that you can only include SETPA I/O control when using RUN, it is possible to set up a loop that monitors the DSP responses to SETPA and operates an output depending on what comes back from the DSP.
    For example the following definition will call another routine to turn on or off a device depending on the state of another input:

    : CYLINDER PA 5 ; 
    : TASK
    CRUN 
    BEGIN 
      ?RUN 
      DUP 15 = PB 7 BIT? 0 > AND IF CYLINDER ON THEN ( SETPA 15 learned 
      DUP 14 = PB 7 BIT? 0= AND IF CYLINDER OFF THEN ( SETPA 14 learned 
    0= UNTIL
    ;

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


    Enter CONTINUOUS RUN
    If you get "too tight" message try
    ADJUST to reduce the speed, or else increase value of ACCEL
    SMOOTH sets continuous mode and calculates maximum speed.

    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
    5 'INSERT GRIP
    2. Type L. to confirm
    3. Click the red up-arrow in Robwin to upload the changed data to Robwin. Close and re-open the route to confirm.
    You can no longer use interpolate.

    or
    1. Create a second route with a different name, for example SPATH. Make sure you reserve enough lines for the co-ordinates and the functions.
    2. Enter this definition to copy the straight line to the new route: (you can copy and paste this text)

    : COPY
    SLINE MOVES E@ SPATH MOVES E! ( MAKE #MOVES THE SAME IN EACH
    SLINE 1 LINE                  ( SOURCE ADDR
    SPATH 1 LINE                  ( DEST ADDR
    MOVES E@ 16 *                 ( BYTES TO MOVE IN MEMORY
    ECMOVE                        ( MOVES BYTES IN EXTENDED MEMORY
    ;
    
    3. Type COPY then Click the red up-arrow to upload the data to the new route. Open SPATH to confirm.
    4. Use insert function in the new route SPATH.

    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
    START-HERE
    This adjusts all the positions in the route relative to where the robot is now. Note that although the data in the controller will change the data on screen in RobWin will not change. The name of the route must be declared before you use START-HERE
    Example usage:
    P1 GOTO PATH1 START-HERE CONTINUOUS RUN
    The robot will go to point P1 then run the route PATH1 starting at the position P1.
    Note that P1 is a POINT not a PLACE.

    A similar word is
    END-THERE
    In this case you need to supply the position where the route is to end without the robot being at that position, for example:
    P1 PATH1 END-THERE CONTINUOUS RUN
    The robot will run PATH1 from whatever position is necessary to finish at P1.
    Again note that P1 is a POINT not a PLACE.

    You can also use another route for the reference positions, for example:
    TRAY 1 LINE PATH1 END-THERE CONTINUOUS RUN
    The robot will run PATH1 from whatever position is necessary to finish at line 1 of TRAY.

    7.3.11 Timed segments

    Version v13.5 up.
    Consider a route created as a ROW in which the points are equally spaced. This could be a straight line, or perhaps a circle comprising 36 points as in the following example. There would be 37 lines, line 37 being the same as line 1, so the robot could draw a circle comprising 36 segments of 10 degrees each.

    A problem arises because as various axes become dominant in different parts of the circle, or as reach changes, the speed of the arm in real terms changes. This can be corrected by specifiying a time for each segment. This is a completely different mode. To invoke this mode enter
    CONTINUOUS TIMED
    To cancel this mode and return to the usual mode enter
    CONTINUOUS
    Having specified the mode you now need to specify the time for each segment - i.e. the time between one line and the next. Enter a value in milliseconds for SEGTIME e.g.
    1000 SEGTIME !
    Will make each segment 1 second long. This results in the circle being drawn at 10 degrees per second and takes 36 seconds all the way round.
    Obviously this can be applied to any path where exact linear speed is critical. The DSP adjusts the speed so that the time between points (lines) is as specified. Clearly if the distance between one pair of points is very large then the DSP will speed up the robot to cross that distance in the specified time.
    finally
    RUN
    The complete line being CONTINUOUS TIMED RUN
    Pitfalls
    As with normal continuous mode if the move is too long or the time is too short then the DSP can not compute a viable speed and you will get the "too tight" error. ADJUST will not work. The solution is to increase the time, or bring the points closer together, or increase the value of ACCEL. You may also need to increase JERK to achieve that acceleration.
    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.

  • Back to contents page

    7.4 OBJECTS

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

    This tells the system that the robot is holding PART.
    WHERE

          WAIST  SHOULDER  ELBOW   HAND   WRIST    OBJECT  
          TRACK     LIFT  EXTEND   HAND   WRIST    OBJECT  
           1000       0       0       0       0     PART
            642       0       0       0  
           1001       0       0       0  
    
    The address of the object being held is stored in a variable OBJECT-HELD.

    Alternatively the object may be placed at a known position e.g.
    PART ISAT CAMBRIDGE
    or
    PART ISAT LINE 5
    This tells the computer where the object is. It can be confirmed with:
    VIEW CAMBRIDGE or VIEW LINE 5

     
          WAIST  SHOULDER  ELBOW   HAND   WRIST    OBJECT  
          WAIST    LIFT   EXTEND   HAND   TRACK    OBJECT  
            nnn     nnn     nnn     nnn     nnn   PART
    You can also enter:-
    WHEREIS PART CAMBRIDGE OK

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

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

    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.
    GOGET PART
    Drives the robot to the position where the object is, via the approach position if there is one and GETs the object, withdrawing to the approach position if there is one.

    IMPORTANT: GOGET (object) cannot be compiled into a definition. Another form which can be compiled is (object) COLLECT e.g.
    PART COLLECT

    A list of all the objects so far created can be had with:-
    OBJECTS

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

    WHEREIS PART NOWHERE

    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:
    EMPTY
    Remember that if you have more than one route you may need to invoke the name of the route you wish to empty unless you are already working with it, for example:
    TRAY EMPTY
    If you wanted to preset all the positions with a part so you could remove them one by one the words are: PART TRAY FILLUP

  • Back to contents page

    7.5 USING THE TEXT WINDOW

    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 )
    DECIMAL
    OBJECT WIDGET
    : FEED
    WIDGET ISAT BELT
    WIDGET COLLECT
    LATHE PUT
    ;
    
    Test the new word FEED. Once tried and tested the word can be used in higher level definitions and so on until the entire task is defined as one word (or a number of high level words to be sent by the computer).

  • Back to contents page

    INPUT-OUTPUT

    8.1 OUTPUTS

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

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

    8.2 INPUTS

    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:-
    : HI BEGIN SWITCH BIT? UNTIL ;
    : PROC2 SWITCH BIT? IF TRAY2 RUN THEN ;
    etc.
    BEGIN ... UNTIL is a loop which executes all the words between BEGIN and UNTIL.
    A condition (true or false) must be on the stack before UNTIL. If the condition is false (zero) then the program loops back to BEGIN but if it is true (non-zero) it drops through to the next word.

    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.

    You can monitor the PB input while setting up hardware (or testing robot sensors) with
    PP
    You will see a row of 8 1's
    11111111
    if any input goes to zero the 1 changes to zero, for example
    11011111

    Note that any PB bit can be used to generate an interrupt. Normally PB 6 is chosen. See hardware manual

    If a second PIA is fitted the input ports are QB and the lower 4 bits of QC.
    The QB equivalent of PP is>br> QB WATCH
    or SB WATCH QC WATCH etc.

    In case of accidental un-programming of the PIA enter:
    PROGPIA

  • Back to contents page

    8.3 SEARCHING

    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.
    Single axis search
    You can initiate a slow or fast search, after first selecting the joint(s) to move using TELL.... etc. These searches are for a single axis only and may only be suitable for R15 and R19.
    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:-
    SET CRITERION FOUND

    Test the slow search with ?TERMINAL which leaves a true if the escape key is pressed:-
    SET CRITERION ?TERMINAL
    TELL WAIST SLOWSEARCH
    If the beam is interrupted in the first example or if the escape key is pressed in the second example while the robot is in motion then the robot will stop immediately.
    WHERE

          WAIST  SHOULDER  ELBOW   HAND   WRIST    OBJECT
          WAIST     LIFT  EXTEND   HAND   TRACK    OBJECT  
              n       -       -       -       -  
    Where n is the count reached when beam breaks/escape pressed.
    The fast search 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:-
    TELL WAIST (limit) FASTSEARCH
    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:-
    TELL WAIST REVERSE SLOWSEARCH
    or TELL WAIST REVERSE (limit) FASTSEARCH

    Straight line search
    A straight line search may be achieved by creating a route which is a straight line. You can make a CARTESIAN 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.10).

    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 )
    UNTIL
    STOP ( stop the DSP )
    BEGIN ?RUN 0= UNTIL ( wait for the DSP to finish deceleration )
    DSPASSUME ( ask the DSP where it got to in counts when it was stopped )
    COMPUTE ( change the counts to Cartesian coordinates )
    900 PITCH ! 0 W ! ( make sure the hand is still vertical ) 
    ;
    
    Run ZFIND until the robot stops. Type WHERE to see where it stopped. The Z coordinate will be in the variable Z.

    8.4 TIMERS

    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.


    8.5 INTERRUPTS

    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.
    : NEWWORD
    action
    RETURN
    ;
    However RETURN must be bracketed out for testing in immediate mode e.g.
    : NEWWORD
    action
    ( RETURN )
    ;
    Then remove the brackets when you are ready to use NEWORD as an interrupt word.
    Next put the CFA of the new word in the variable INTVEC e.g.
    SET INTVEC NEWWORD
    INTVEC is a reserved variable that the interrupt code looks in to see what to execute.
    Alternatively make two words, one for testing and one simple definition with the tested word followed by RETURN.
    For example if you want the interrupt to just beep the terminal do
    : BEEPER BEEP RETURN ;
    SET INTVEC BEEPER
    Then when the interrupt occurs the terminal will beep and the current word being executed continues.
    As soon as the interrupt happens further interrupts are disabled. The word RETURN returns the new word back to the BIOS that initiated the interrupt which re-enables interrupts for the next time. An alternative word XRETURN ends the interrupting word and leaves interrupts disabled.
    It can of course be any word, but remember that while this word is executing the current (interrupted) word is delayed. If the current word was a motion word then the DSP controls the motion so the motion may not be affected but motion controlled by the CPU e.g. CALIBRATE may be affected. For long routes the CPU is busy "feeding" the DSP with data because its buffer is full. If this process is delayed it can result in erratic motion.

    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.

    DECIMAL
    USER COUNTER
    
    : 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.
    DISABLE
    ;
    
    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
    START-TIMER
    Stop the timer with STOP-TIMER
    Your interrupting word must end with RETURN

    As with the PB 6 interrupt the new word may delay the current word that was interrupted. Also the new word must not take longer to execute than the setting of the timer. For example if you set 100 msecs then in your word you had included 200 MSECS then clearly the word will not complete before the next interrupt.

    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.

    Rules
    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

    SAVING ON DISK

    9.1 DISK FILES

    Note that the flash disk drive in Forth is no longer available. All files are in the PC
    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.

    9.1.1 Text Files

    Suppose you type two definitions into the system thus:
    : HI ." HELLO" ;
    : BYE ." GOODBYE" ;
    When you execute HI you will see the following:
    >HI HELLOOK
    The HELLO and the OK merge and a better definition of HI would be
    : HI ." HELLO" CR ; i.e. add a new line with CR.
    If you just type in the new definition of HI you will see two definitions of HI when you type VLIST - the new and the old. The old one can never be accessed because Forth searches the dictionary from the top down, so it is a waste of space. You need to type FORGET HI then re-enter it. Unfortunately FORGET HI also forgets BYE and every other definition added since. Clearly some sort of editing would be useful. The only way of editing the dictionary is to edit text which is then compiled each time you edit:

    click the (project name).ED2 window and enter your text there. There is no need to worry about the other files as these are created and maintained by RobWin. When you have finished editing the text file you can download it with the button. The communications window will show a line of chevrons >>>>>>>>> while the file is loaded and compiled by the controller. At any time you can edit the file and press again. Each time the text is reloaded the words ROBOFORTH and STARTOVER are sent to the controller and the PLACE and ROUTE headers are re-created at the start of the dictionary. RobWin maintains both the ED1 and ED2 files and always downloads the ED1 file first.

    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.

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

    9.1.3 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

    9.2
    CONTROLLER SOFTWARE

    SAVING A COPY OF ROBOFORTH ON DISK

    1. Do a cold start (press reset button with selector switch in cold start position). This reloads the RAM from flash ROM but leaves the pointer at the top of Forth and the start of ROBOFORTH
    2. Enter ROBOFORTH and press enter key.
    3. Use 'file', save binary.
    4. Enter start 4000 and length 6000
    5. Enter a file name other than that supplied with the CD, e.g. myrobot.RAM

    SAVING THE CALIBRATION PARAMETERS

    A copy of the RAM image saved as above will contain all the calibration parameters for your robot, however you may save the calibration parameters (known as a signature) to a small file of its own, as follows:
    1. V13 up: Use file, save binary. Check that bank is 0 and enter start A200 and length 200
    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

    RELOADING ROBOFORTH or LOADING UPDATED ROBOFORTH

    When the controller is switched on the RAM is reloaded from flash ROM. Just about the only way of corrupting the flash ROM is to corrupt the RAM then save the corrupted RAM to flash ROM with PSAVE. If you think you have done that proceed as follows:
    1. Do a cold start (press reset button with selector switch in cold start position). This reloads the RAM from flash ROM but leaves the pointer at the top of Forth and the start of ROBOFORTH
    2. Go to settings, configuration and make sure bank memory is checked.
    3. V13 up: 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:
    ROBOFORTH
    6. Enter PSAVE which re-writes the flash ROM.

    RELOADING PARAMETERS

    A copy of the RAM image saved as above will contain all the calibration parameters for your robot, however if a new version of ROBOFORTH 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. 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.

    LOADING A NEW VERSION OF ROBOFORTH

    1. Save the calibration parameters (robot signature) as above.
    2. Load the new ROBOFORTH as above.

  • Back to contents page

    9.3 DATA TRANSFER PROTOCOL

    The host must be connected via its serial port set up for 19200 baud, no parity, 8 bits, and 2 stop bits. (to change this see section 9.6
    An extremely simple protocol is employed:

    UPLOADING
    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

    DOWNLOADING
    To initiate downloading from host to controller the host sends an ENQ and waits for STX from the controller. The controller must first have been given the command
    (start-address) (number of bytes) RECEIVE and the host must also be in some routine to read data from disk and download it.
    The host then sends one block (256 bytes) to the controller. The host then sends another ENQ and waits for another STX then sends the next block. This repeats until all the blocks have been downloaded.
    The host then sends sends ETX instead of ENQ meaning no more data and the host then stops.
    Be careful where you load the data. The memory below A000 is ROBOFORTH and your own software is above that. Type HERE X. to see where you have reached in memory.
    In memory bank 1 you can load from zero if you wish. Learned positions grow up from 0 and the highest memory location used is found with NEXT @ X.
    To load into bank 1 use:
    BANK C1SET (start-address) (number of bytes) RECEIVE


    9.4 SUPERVISORY SOFTWARE

    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:
    flow chart
    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: (6 values for 6-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.

    9.5 ACTIVEX CONTROL

    ActiveX Control Robx.ocx

    Installation

    The installation disk contains the control, the dynamic-link libraries it needs and the installer program setup.exe. Run setup to install and register the components. The program xdem can be used to test the control.

    Methods

    The following methods are provided. C-Style declarations are used here. If you are using another language then the appropriate declarations should be automatically generated when you add the control to your application.

    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

    9.6 SERIAL PORTS

    The main serial port is 'channel 0' and the second is 'channel 1'. The second port is optionally connected to a 9w 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
    IOFLAG C1SET
    From this point on you can only communicate with the controller through the second serial port. Therefore make sure you issue all commands to end with
    IOFLAG C0SET
    e.g. IOFLAG C1SET SPACE IOFLAG C0SET
    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 :
    [ HEX ] D5 IN 1 AND IF IOFLAG C1SET KEY IOFLAG C0SET THEN

    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.

    ADVANCED FEATURES

    10.1
    VECTORED EXECUTION

    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.
    VARIABLE GVEC
    FIND GRIP GVEC ! ( FINDs the CFA (code field address) of GRIP and stores it in GVEC
    GVEC @ EXECUTE ( fetch the value from the variable GVEC and execute that
    An easier way to set the CFA into a variable is using the word SET e.g.
    SET GVEC GRIP
    Possible uses for this are described in sections 6.1, 7.3.1 7.3.8 8.5.

    10.2 TURNKEY OPERATION

    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.:-
    : DEMO START CALIBRATE HOME RUN ;
    Then enter:-
    AUTO DEMO
    USAVE
    and set the front panel switch to auto position (see system manual and robot manual section A). Now the word DEMO will execute immediately on power-up and the computer can be removed.

    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
    BEGIN
      STUFF
    ?TERMINAL UNTIL
    ;
    
    : TASK
    START
    CALIBRATE
    MAIN
    ;
    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
    RESTART
    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
    BEGIN STOP? 0= UNTIL ( WAIT FOR STOP BUTTON RELEASE
    READY
    PB 6 0 WAIT ( WAIT FOR CONTINUE BUTTON
    RESTART
    ;
    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
    SET STOPVEC ESTOP
    ['] MAIN 2- TURNKEY !
    START
    CALIBRATE
    MAIN
    ;
    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.

    10.3 RE-ENTRANT OUTER INTERPRETER

    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
    BEGIN
      SAFE
      HOME
      INKEY ASPACE = IF WHERE KEY DROP THEN
    ?TERMINAL UNTIL
    ;
    
    This program will run the robot back and forth between SAFE and HOME until you press 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
    BEGIN
      SAFE
      HOME
      INKEY ASPACE = IF OUTER THEN
    ?TERMINAL UNTIL
    ;
    
    Now when you press the space bar you will see the OK prompt after the robot goes HOME. You can then enter (or the supervisor can send) any command at all as usual. Finally send the command EXIT and the original TASK will continue as before. Or send the required command and EXIT all on one line, for example WHERE EXIT.

  • Back to contents page

    11 INFORMATION

    WHERE
    In joint mode yields current position of robot motors and encoders, in Cartesian mode yields Cartesian position of robot.

    WHICH
    Tells which route is currently active, and what mode the route is i.e. relative (a sub-route) or absolute.

    MODE
    Lists out various modes: local or global, joint or Cartesian, simple or smooth (joint interpolated motion).

    VIEW (position)
    e.g. VIEW (place-name), VIEW LINE n
    You can also VIEW RATIOS VIEW ENCRATIOS VIEW ENCTOLS

    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.

    LISTROUTE or L.
    Lists the co-ordinates contained in the currently active route.

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

    ROUTES
    Lists all route names in the dictionary in same form as VLIST.

    PLACES
    Lists all place names in the dictionary in same form as VLIST.

    OBJECTS
    Lists all object names in the dictionary in same form as VLIST.

    POINTS
    Lists all Cartesian points in the dictionary in same form as VLIST.

    P
    Prints the input on the PB port in binary. A '0' shows a sensor is covered, a '1' shows axis is clear of sensor.

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

    XX WATCH
    (e.g. QB WATCH) will display 8 bits from the specified port as 1s and 0s like PP.

    HERALD
    Shows current version of ROBOFORTH.

    WRU
    (who are you) reveals the serial number of the robot.

    WWW
    (what went wrong) brief explanation or error code of what happened to stop the robot.

    SETTINGS
    Shows settings of speed, acceleration, jerk and also emergency stop deceleration figure and the segment time for timed routes.
    Just press escape if you don't want to change them. Press enter for any parameter to retain the existing value.

  • Back to contents page

    11.1
    TESTING

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

    XX WATCH
    (e.g. QB WATCH) will display 8 bits from the specified port as 1s and 0s like PP.

    ENCTEST
    Continually displays the six encoder counts. As the axis is moved by hand the counts change.

    Further tests are available as projects.

  • Back to contents page

    11.2 ERRORS

    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:
    : ALARM BEEP PA 5 ON ENCABORT ;
    SET ENCVEC ALARM
    Or to reprogram what happens when you press the stop button: SET STOPVEC (word) (See section 6.1)

    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  
    THEN  
    ;
    If you leave out the word THEN, TEST will seem to work OK as long as PB 4 BIT? is true. As soon as it is false the system fails.
    : TEST2  
    100 0 DO  
    ?TERMINAL UNTIL  
    LOOP  
    ;

    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:

          WAIST  SHOULDER  ELBOW  L-HAND  WRIST   OBJECT (R12/R17) 
    or    WAIST     LIFT  EXTEND   HAND   TRACK   OBJECT (R19)
    or    TRACK     LIFT  EXTEND   HAND   WRIST   OBJECT (R15) 
           1000     2000    3000   4000    5000  
           1280     2560    3480   5120    6402  
           1001     2002    2999   4000    5001  

    Then enter:
    CREATE NEST 1000 , 2000 , 3000 , 4000 , 5000 , 0 , 0 , 0 ,

    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
    4. enter BANK C0SET NEST ASSUME
    5. enter ENCOFF to turn off the encoders (because they will try to undo what you have just changed)
    6. TEACH robot clear of NEST
    7. HOME 8. enter CHECK - this seeks out the sensors in the same way as CALIBRATE but does not correct errors.
    9. enter SETLIMITS
    10. Enter USAVE (only when you have final values)
    You have now changed LIMITS to new values to which all your learned positions are related.
    11. 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

    12 PROGRAMMING TECHNIQUES

    The best way to start is to sketch the workspace and write a "story board" of sequence of events. At some points in the workspace write possible place names for where the robot will stop. Or a route name if the robot needs to move from one place to another in a defined path.

    Example 1

    Programming a simple pick-and place cycle.
    DEFINE ROBOT TASK:
    1. If a part has arrived at the pickup point on the belt a signal on bit 5 of port PB goes low.
    2. Robot takes item from feeder belt and takes to the test jig.
    3. Providing the test jig is ready the robot puts the item in the jig. Jig ready is indicated by bit 6 of port PB being low.
    4. Robot signals to test jig that a part is loaded by asserting PA 1 low.
    5. Robot waits for jig to complete. There is a signal from the jig into bit 6 of port PB which goes logic low if the test is complete. Bit 7 is high if the part is in the jig. So bit 6 must be low and 7 must be high is the jig is ready to be unloaded.
    6. When test is complete the robot picks the part from the jig.
    7. Robot signals jig when it has taken the part by changing bit 1 of port PA back to high. Jig then restores bit 7 of port PB back to logic low.
    8. Robot puts the part into bin.

    Note that both PB bits 6 and 7 must be low for the robot to put a part into the jig. Thus if the test rig is switched off or if either line breaks the jig cannot be loaded (fail-safe).

    PROGRAMMING:
    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
    2. Raise above the belt. Click 'set apprch'
    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
    4. Using teach pad withdraw part from jig. Click 'set apprch'
    5. With the robot holding the part seek out the bin with the teach pad. Create a place BIN
    6. Raise gripper above and clear of bin. Click 'set apprch'
    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
    8. Save all the co-ordinates learned so far with project save 9. Add the program flow to the second text file using the ED2 window as follows.

    ( TASK.ED2 ) ( 4 JULY 1776 )
    
    OBJECT PART
    
    : JIGLOAD
    PB 5 0 WAIT ( WAIT FOR PART TO BE PRESENT AT GATE )
    PART ISAT BELT
    BELT GET
    PB 6 0 WAIT ( WAIT FOR JIG TO BE READY FOR PART )
    ( WE ASSUME THIS LINE IS ONLY ZERO IF THE JIG IS NOT BUSY )
    PB 7 0 WAIT ( DOUBLE-CHECK THAT THE JIG IS EMPTY )
    JIG PUT
    PA 1 ON ( TELL JIG THAT PART IS LOADED )
    ( JIG THEN PROCEEDS, AND CHANGES PB 6 TO '1' AND PB 7 TO '1' 
    SAFE 
    ;
    : UNLOAD 
    PB 6 0 WAIT ( SIGNAL FROM JIG THAT TEST IS COMPLETE )
    JIG GET
    PA 1 OFF ( TELL JIG ROBOT HAS THE PART )
    SAFE 
    BIN PUT
    SAFE
    ;
    : TASK
    BEGIN ( BEGIN A CONTINUOUS LOOP )
      JIGLOAD 
      UNLOAD
    ?TERMINAL UNTIL ( STOP AFTER COMPLETE CYCLE IF THE ESC KEY IS PRESSED )  
    ;  
    ( NOTE ROBOT WILL STOP IMMEDIATELY IF THE STOP BUTTON IS PRESSED ) 
    : FULLTASK  
    START
    CALIBRATE
    TASK
    ; 
    AUTO FULLTASK ( FULLTASK WILL EXECUTE ON POWER UP )
    

    Example 2

    Multiple inputs.
    Suppose the following:
    : PLC PB 6 ; ( this is a signal from a PLC to pick up a part
    : BUTTON PB 7 ; ( this is a button the user can press to end the program
    : TASK
    some action
    this next BEGIN UNTIL loop checkes to see if either input goes too zero
         BEGIN
             PLC BIT? 0=
             BUTTON BIT? 0=
         OR UNTIL
    if either PLC or BUTTON goes to zero the loop ends and continues here
         PLC BIT? 0= IF ( yes it was PLC
    but we only do the next bit if it was PLC signal
             WHEEL GRIP ( going to wheel & grips disk
             WAITING ( move up from wheel
             OVERTABL ( move to place over table
             TABLE UNGRIP ( move down to drop disk
            OVERTABL ( move back up over table
             WAITING ( move back to place over star wheel
         THEN
    if it wasnt the PLC but was the button then program jumps to here
    ;
    
    The problem with the BEGIN - UNTIL loop above is that if neither signal goes to zero then there is no way out.
    A good way to check things without actually aborting the loop would be to add
    ?TERMINAL IF OUTER THEN
    
    Now if you press escape you get OUTER INTERPRETER and a command line. You can check inputs and anything else such as SPEED ? and so on.
    : TASK
    some action
         BEGIN
    ?TERMINAL IF OUTER THEN
             PLC BIT? 0=
             BUTTON BIT? 0=
         OR UNTIL
         PLC BIT? 0= IF ( yes it was PLC
             WHEEL GRIP ( going to wheel & grips disk
             WAITING ( move up from wheel
             OVERTABL ( move to place over table
             TABLE UNGRIP ( move down to drop disk
            OVERTABL ( move back up over table
             WAITING ( move back to place over star wheel
         THEN
    ;
    
    So it's a useful thing to put in any program. As soon as you press esc you get a command line.
    Enter EXIT to continue the program.

    Example 3

    The following is an example of words to search for an event. In this case the search is in the Z axis only. The search runs by running a route ZLINE using CRUN. Create ZLINE as a Cartesian Row, suggested 101 lines. Do set-to-here on the first and last lines then edit the last line say 100.0mm more than line 1 in Z.
    Of course it can be in any axis or even at an angle.
    The word START-HERE shifts the route to the current robot position.
    In this case the event is a change of state on PB 7 from 1 to 0

    : SLOW 1000 SPEED ! ;
    : FAST 10000 SPEED ! ;
    : 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 your criterion here )
      STOP? OR          ( or if the stop button is pressed )
    UNTIL
    STOP                ( stop the DSP )
    BEGIN ?RUN 0= UNTIL ( wait for the DSP to finish deceleration )
    DSPASSUME           ( ask the DSP where it got to in counts when it was stopped )
    COMPUTE             ( change the counts to Cartesian coordinates )
    900 PITCH ! 0 W !   ( make sure the hand is still vertical )
    FAST
    ;
    

    Example 4

    The following is an example of a complex definition of an action to be taken by the CPU while the DSP is running a route.
    The required features are:
    1. Throughout the route the stop button must be checked and if pressed the CPU must tell the DSP to stop.
    2. Part way through the route we wish to operate an air cylinder defined as PUSH-CYL. So the line SETPA 5 is inserted at the appropriate line. When the DSP gets to this it sends the value 5 back when polled by ?RUN and the CPU then operates PUSH-CYL.
    3. After PUSH-CYL is operated we then wish to look out for a signal from sensor PUSHED. When this sensor goes low we open the gripper. But as a safety measure we insert the line GRIPPER 0 somewhere further along the route. When the DSP reads this line it issues 2 from ?RUN to the CPU which turns the gripper off anyway.

    : DSP?       ( to follow CRUN - monitors state of DSP
    FGRIP C1SET
    BEGIN
      STOP? IF   ( if stop button pressed
         STOP    ( stop DSP ) FSTOP C1SET ( set flag
         DSPRDY  ( wait for DSP to finish
      THEN
      ?RUN       ( what is DSP doing?
      DUP 5 = IF ( use SETPA 5 to turn on PUSH-CYL not gripper
         PUSH-CYL OFF
      THEN
      DUP 2 = IF GRIPPER OFF THEN ( ANYWAY
      PUSH-CYL BIT? 0= ( is PUSH-CYL off?
      PUSHED BIT? 0 >  ( is the sensor confirming?
      AND ( both ) IF
         GRIPPER OFF ( ungrip immediately
         STOP        ( stop the DSP
         FGRIP C0SET ( set a flag
      THEN
    0=           ( result from ?RUN is zero i.e. DSP has finished
    FGRIP C@ 0=  ( or the flag was set 3 lines back
    OR UNTIL     ( if either is true leave the loop
    ESTOP?       ( if stop flag was set by ?STOP then execute STOPVEC procedure
    DSPASSUME    ( correct counts to the values read back from DSP
    GRIPPER OFF  ( ungrip anyway in case the above fails
    ;
    
    

    Example 5

    Self learning
    Suppose you have a matrix TRAY (with approach level), a place WASHER and route between the two, TOTRAY.
    A typical definition might be:
    : WASHPART
    TRAY INTO GRIP UP ( get part
    TOTRAY RUN ( go to the washer
    WASHER UNGRIP WITHDRAW ( put part in washer
    RETRACE ( go back to tray
    ;
    
    Usage is (n) WASHPART
    Notice that INTO has no number in front of it. It needs to know what number to go into and it gets that from stack. In (n) WASHPART, n is placed on the stack but is used by INTO which is part of the definition of WASHPART
    You might also notice a small physical gap between the end of TOTRAY and the approach position of WASHER. You could try to make them the same but then every time you adjusted WASHER there would be a small gap again and an annoying jerk. So you can automatically adjust the last line of TOTRAY the first time round so that thereafter there is no jerk:
    : WASHPART
    TRAY INTO GRIP UP ( get part
    TOTRAY RUN ( go to the washer
    WASHER UNGRIP WITHDRAW ( put part in washer
    MOVES E@ REPLACE
    RETRACE ( go back to tray
    ;
    
    You can go further. After retracing TOTRAY the robot's next move will be to a different position on the TRAY each time. You could make the first line of TOTRAY always the same as the approach position of the TRAY as follows:
    : WASHPART
    TRAY INTO GRIP UP ( get part
    TOTRAY 1 REPLACE
    RUN ( go to the washer
    WASHER UNGRIP WITHDRAW ( put part in washer
    MOVES E@ REPLACE
    RETRACE ( go back to tray
    ;
    
    This next example is more complex. Consider a reverse situation:
    : GETPART
    WASHER GRIP WITHDRAW
    TOTRAY RUN
    TRAY INTO
    UNGRIP
    UP
    TOTRAY RETRACE
    ;
    Usage:
    n GETPART
    where n is the required position on the tray and is taken up by INTO
    

    Example 5 - interrupts

    This example shuws how to set up a timer interrupt to control a heater. It is assumed there is a temperature sensor which gives 1 volt per 10 degrees:
    The code checks the sensor every 500 mSecs and turns on or off the heater to regulate temperature to 60 deg. +/- 0.5 deg.
    DECIMAL
    : HEATER PA 6 ;
    : TEMP
    0 ADC
    2048 -
    1000 M* 2048 M/
    ;
    
    : TEMP-CONTROL
    TEMP
      DUP 605 > IF HEATER OFF THEN
      597 < IF HEATER ON THEN
    RETURN
    ;
    
    : HEAT
    500 INT-TIME !
    SET INTVEC TEMP-CONTROL
    START-TIMER
    ;
    
    Once you type HEAT the control will continue in the background and you can carry on your robot program.


    ©1989-2018 David N. Sands