RCCL/RCI Startup and Installation Guide

John Lloyd
July 1992

McGill Research Centre for Intelligent Machines
McGill University
Montr ?eal, Qu ?ebec, Canada

Postal Address: 3480 University Street, Montr?eal, Qu?ebec, Canada H3A 2A7
Telephone: (514) 398-6319 Telex: 05 268510 FAX: (514) 283-7897
RCCL/RCI Bug Reports: lloyd@curly.mcrcim.mcgill.edu
General Network Address: mcrcim@larry.mcrcim.mcgill.edu

RCCL/RCI Release 4.2, July 30,1992

RCCL/RCI Startup and Installation Guide

John Lloyd

Abstract

This document describes the set up procedures for RCCL/RCI. The first section explains how to run RCCL/RCI application programs. Subsequent sections describe how to install the system itself, add the necessary support to the UNIX kernel, and configure the system to support different types of robots or interface devices.

Copyright cfl1988, 1991 by John E. Lloyd and Vincent Hayward.

Permission to use, copy, modify, and distribute this document, and the RCCL/RCI software, is granted for non-commercial and research purposes only, and providing that (1) no fee is charged except the minimum necessary to cover copying and shipping expenses, and (2) all copyright notices are preserved and the authors are fully acknowledged. All other rights are reserved. The commercial sale of RCCL/RCI, its supporting documentation, or a system which contains RCCL/RCI as a component, is prohibited unless permission is obtained from the authors.

Since RCCL/RCI is licensed free of charge, it is provided "as is", without any warranty, including any implied warranty of merchantability or fitness for a particular use. The authors assume no responsibility for, and shall not be liable for, any special, indirect, or consequential damages, or any damages whatsoever, arising out of or in connection with the use of the software.

RCCL/RCI Release 4.2, July 30,1992

i

Contents

1 Introduction 1 1.1 Documentation Conventions : : : : : : : : : : : : : : : : : : : : : : : : : : : : 1 1.1.1 Path name descriptions : : : : : : : : : : : : : : : : : : : : : : : : : : 1 1.1.2 Manual page references : : : : : : : : : : : : : : : : : : : : : : : : : : 1

2 Getting Started 1 2.1 Environment Variables and the Path : : : : : : : : : : : : : : : : : : : : : : : : 1 2.1.1 Sample .cshrc entries : : : : : : : : : : : : : : : : : : : : : : : : : : 2 2.2 Program Compilation : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 2 2.2.1 Using non-ansi compilers : : : : : : : : : : : : : : : : : : : : : : : : : 2 2.2.2 The rcc command : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 3 2.2.3 rcc examples : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 3 2.3 Turning on the Robot : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 4 2.3.1 Loading the moper program into the controller : : : : : : : : : : : : : : 4 2.3.2 Calibrating the robot : : : : : : : : : : : : : : : : : : : : : : : : : : : : 7 2.3.3 Summary of the controller startup procedure : : : : : : : : : : : : : : : 7 2.3.4 When you need to reload or recalibrate : : : : : : : : : : : : : : : : : : 8 2.4 Running Programs : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 8 2.4.1 Robot arm power : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 8 2.5 For the MicroVAX-II: Booting Auxiliary CPUs : : : : : : : : : : : : : : : : : : 9 2.6 Using the Robot Simulator : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 10 2.7 The .rciparams File : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 10

3 RCCL/RCI Installation 11 3.1 Installing the GNU make Command : : : : : : : : : : : : : : : : : : : : : : : : 11 3.2 Setting up Your Environment : : : : : : : : : : : : : : : : : : : : : : : : : : : 12 3.3 Editing the Configuration File : : : : : : : : : : : : : : : : : : : : : : : : : : : 12 3.3.1 The imake utility : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 12 3.4 Building the System : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 13 3.4.1 Commands defined in the main system Makefile : : : : : : : : : : : : : 13 3.5 Installing the Simulator Service : : : : : : : : : : : : : : : : : : : : : : : : : : 14

RCCL/RCI Release 4.2, July 30,1992

ii CONTENTS

4 Adding Real-time Support to the System Kernel 14 4.1 Introduction : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 14 4.1.1 Real-time support for MicroVAX and Sun4 systems : : : : : : : : : : : : 15 4.1.2 Support for auxiliary CPUs : : : : : : : : : : : : : : : : : : : : : : : : 15 4.2 MicroVAX-II Kernel Configuration : : : : : : : : : : : : : : : : : : : : : : : : 15 4.2.1 Doing it the easy way : : : : : : : : : : : : : : : : : : : : : : : : : : : 16 4.2.2 Doing it yourself : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 16 4.2.3 Support for RCI tasks running on the main UNIX CPU : : : : : : : : : : 16 4.2.4 Support for RCI tasks running on auxiliary CPUS : : : : : : : : : : : : : 18 4.2.5 Summary of the system configuration at McGill : : : : : : : : : : : : : : 18 4.3 Sun4 Kernel Configuration : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 19 4.3.1 What the reader should know : : : : : : : : : : : : : : : : : : : : : : : 20 4.3.2 Unpacking the modules : : : : : : : : : : : : : : : : : : : : : : : : : : 20 4.3.3 Installing the modules : : : : : : : : : : : : : : : : : : : : : : : : : : : 20 4.3.4 Editing the configuration files : : : : : : : : : : : : : : : : : : : : : : : 21 4.3.5 Building the kernel : : : : : : : : : : : : : : : : : : : : : : : : : : : : 22 4.3.6 Creating device entries : : : : : : : : : : : : : : : : : : : : : : : : : : 22 4.3.7 If you have an S-bus machine : : : : : : : : : : : : : : : : : : : : : : : 23 4.4 SGI IRIX Kernel Configuration : : : : : : : : : : : : : : : : : : : : : : : : : : 25 4.4.1 What the reader should know : : : : : : : : : : : : : : : : : : : : : : : 26 4.4.2 Unpacking the modules : : : : : : : : : : : : : : : : : : : : : : : : : : 26 4.4.3 Editing the system config file : : : : : : : : : : : : : : : : : : : : : : : 26 4.4.4 Major device numbers : : : : : : : : : : : : : : : : : : : : : : : : : : : 27 4.4.5 Editing the mem file : : : : : : : : : : : : : : : : : : : : : : : : : : : : 27 4.4.6 Building the kernel : : : : : : : : : : : : : : : : : : : : : : : : : : : : 28 4.4.7 Creating device entries : : : : : : : : : : : : : : : : : : : : : : : : : : 28 4.5 The rciCheck Program : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 29

5 Configuring the RCCL/RCI Software 29 5.1 Review of Basic Concepts : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 30 5.1.1 Robot classification : : : : : : : : : : : : : : : : : : : : : : : : : : : : 30 5.1.2 Robot parameter structures : : : : : : : : : : : : : : : : : : : : : : : : 30 5.1.3 Computation Functions : : : : : : : : : : : : : : : : : : : : : : : : : : 31 5.1.4 Robot communication functions : : : : : : : : : : : : : : : : : : : : : : 32 5.1.5 RCI I/O driver : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 32 5.1.6 RCI UNIX devices to provide polling interrupts : : : : : : : : : : : : : : 33 5.1.7 Communication software in the robot controller : : : : : : : : : : : : : : 34 5.2 Adding a Robot to the System : : : : : : : : : : : : : : : : : : : : : : : : : : : 34 5.2.1 Updating the robot data table : : : : : : : : : : : : : : : : : : : : : : : 34 5.2.2 Updating the robots file : : : : : : : : : : : : : : : : : : : : : : : : : 35

RCCL/RCI Release 4.2, July 30,1992

CONTENTS iii

5.2.3 Creating a .jls file : : : : : : : : : : : : : : : : : : : : : : : : : : : : 37 5.2.4 Creating a .kyn file : : : : : : : : : : : : : : : : : : : : : : : : : : : : 41 5.2.5 Creating a .pos file : : : : : : : : : : : : : : : : : : : : : : : : : : : : 42 5.3 Other Configuration Files : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 42 5.4 Configuring moper for a Unimation Mark X Controller : : : : : : : : : : : : : : 43 5.4.1 Creating a moper for a new robot : : : : : : : : : : : : : : : : : : : : : 43 5.4.2 General description of the moper config file : : : : : : : : : : : : : : : : 46 5.4.3 Determining servo control parameters : : : : : : : : : : : : : : : : : : : 50 5.5 Testing the Robot Connection : : : : : : : : : : : : : : : : : : : : : : : : : : : 51 5.6 Robot Calibration Programs : : : : : : : : : : : : : : : : : : : : : : : : : : : : 53 5.6.1 The primecal program : : : : : : : : : : : : : : : : : : : : : : : : : : 53 5.6.2 The potcal program : : : : : : : : : : : : : : : : : : : : : : : : : : : 54 5.6.3 Manually calibrating for current control : : : : : : : : : : : : : : : : : : 55 5.6.4 Manually calibrating gravity and friction terms : : : : : : : : : : : : : : 57 5.7 Adding a New Device to the System : : : : : : : : : : : : : : : : : : : : : : : : 58 5.7.1 The RCI I/O driver : : : : : : : : : : : : : : : : : : : : : : : : : : : : 58 5.7.2 The counterpart driver in moper : : : : : : : : : : : : : : : : : : : : : : 59 5.7.3 The RCI UNIX driver : : : : : : : : : : : : : : : : : : : : : : : : : : : 59 5.7.4 Debugging a driver : : : : : : : : : : : : : : : : : : : : : : : : : : : : 60

6 Installation Summaries 60 6.1 Real-time Installation for VME-based Hosts with PUMA Robots : : : : : : : : : 60 6.2 Hardware : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 60 6.3 Software : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 61 6.4 Installation for Simulator-only Systems : : : : : : : : : : : : : : : : : : : : : : 61

7 Adding New Classes of Robots to the System 61 7.1 Writing JLS and KYN Access Functions : : : : : : : : : : : : : : : : : : : : : : 62 7.2 Writing the JLS Conversion Routines : : : : : : : : : : : : : : : : : : : : : : : 63 7.3 Writing the Kinematic Routines : : : : : : : : : : : : : : : : : : : : : : : : : : 63 7.4 Writing the Robot Communication Functions : : : : : : : : : : : : : : : : : : : 63 7.5 Interface Software in the Target Controller : : : : : : : : : : : : : : : : : : : : 64

RCCL/RCI Release 4.2, July 30,1992

1

1. Introduction

Section 2 of this document describes what an RCCL/RCI user should do in order to compile and run application programs. Sections 3 and 4 explain how to compile the software and install the necessary kernel support. Section 5 talks about configuring the system for a particular site: how to set up the parameter data base for a particular robot, how to run the calibration programs, how to attach a robot to a different device, etc. An installation ?check list? is given in section 6. Section 7 describes how to create a new class of robot for the system.

1.1 Documentation Conventions

1.1.1 Path name descriptions

Most of the file names referred to in this document are generally contained either within the main RCCL distribution tree (normally denoted by the environment variable RCCL), or within the system kernel tree (whose root directory is usually /sys). For brevity, when describing path names, the root directory portion will sometimes be omitted. For example, conf/site.conf refers to $RCCL/conf/site.conf.

1.1.2 Manual page references

A lot of detailed information about RCCL/RCI is found in the ?manual pages?, a documentation set fashioned after the UNIX manual pages. The documentation is available either on-line or in hardcopy. When referring to a particular manual page in this document, the convention ?see someManPage(3)? will frequently be used. This means look for the manual page with the title someManPage. The number in parentheses indicates the manual page section number, which roughly follows the section numbering conventions of the UNIX manual. The hardcopy manual pages (which ignore the section numbers) are found in either the RCCL Reference Manual or the RCI Reference Manual.

2. Getting Started

The first thing an RCCL/RCI user must do is set up an environment. This is best done by making a few entries in the user's .cshrc file.

2.1 Environment Variables and the Path
The following environment variables should be set:

RCCL/RCI Release 4.2, July 30,1992

2 2. GETTING STARTED

RCCL This environment variable should be set to the root directory of the RCCL system.

MANPATH This is a standard UNIX environment variable that defines a list of directories that are searched by the man command. It should be set to contain $RCCL/man, in addition to the usual directory /usr/man. The format of MANPATH is described in the manual page for the man command.

C_LD On MicroVAX-II systems only, this environment variable should be set to $RCCL/bin/ld. It defines the location of a private copy of the loader that is used by the rcc command. Non-MicroVAX systems should not set this variable since $RCCL/bin/ld will not exist.
You should also add the directory $RCCL/bin to your path, ahead of /bin and /usr/bin.

2.1.1 Sample .cshrc entries

The following set of declarations in a .cshrc file should do nicely to set up the environment described above:

setenv RCCL ~/rccl.new
setenv MANPATH $RCCL/man:/usr/man
setenv C_LD $RCCL/bin/ld # for MicroVAX systems only
set path=(. $RCCL/bin /bin /usr/bin ... )

2.2 Program Compilation

You should now be able to compile RCCL or RCI programs.

2.2.1 Using non-ansi compilers

If you are compiling RCCL/RCI applications using a non-ansi C compiler, you may need to define some special preprocessor symbols so that the compiler can handle the RCCL/RCI include files.

#define NO_PROTOTYPES 1
Define this if your compiler does not understand prototypes (which applies to some compilers on SunOS and BSD systems).

#define const
Define this if your compiler does not understand const (which applies to some compilers on SunOS and BSD systems).

#define void int
Define this if your compiler does not understand void (which applies to some compilers on BSD systems).

RCCL/RCI Release 4.2, July 30,1992

2.2. PROGRAM COMPILATION 3

If made inside the application source code, these definitions should precede any RCCL/RCI include files. You may want to put whatever definitions you use in an include file of their own.

Alternatively, the definitions can be made directly on the command line for cc (or rcc, described in the next section). Usually the -D option is used to do this. The arguments to define everything would look like
cc file.c -DNO_PROTOTYPES -Dconst= -Dvoid=int

2.2.2 The rcc command

RCCL/RCI programs should be compiled and loaded with the rcc command, which is like the cc command except it does a few extra things:

1. Delimits the code and data segments used by the control tasks so the system knows what portions must be either locked into memory, or downloaded to an auxiliary process (for RCI tasks running on auxiliary CPUs; see section 4.1.2).

2. Automatically references the RCCL/RCI libraries and the math library.

3. Automatically names its output after the first module in the command line (instead of a.out).

To support item 1, the user must place all modules containing code or data referenced by the control level to the right of the special keyword CTRL in the command line. If compiled separately, these modules must also be compiled by the rcc command with the usual -c option (again, placed in the command line to the right of the CTRL keyword). Modules whose code and data will not be accessed at all by the control level can be compiled separately using cc. There is no restriction per se against referencing control level code or data from the planning level.

rcc supports all the usual options of cc and can be used in place of cc, except that in the load phase, it will reference the RCCL/RCI libraries, which may be inconvenient.

The default compilation command used by rcc is specified by the entry to the right of the keyword cc in the file conf/.rcc. You can change the compilation command by modifying this entry. It is probably best to do this using a private copy of the .rcc file in your home directory (rcc will check for a file there), to avoid disturbing the system configuration.
More information on rcc can be found in the RCCL manual pages.

2.2.3 rcc examples

Suppose the user wishes to compile the program test, which consists of the planning level module test.c and the control module testCtrl.c. This program can be compiled as follows:

% rcc test.c CTRL testCtrl.c

Alternatively, the compilation may be done separately, as in:

% rcc -c test.c
% rcc -c CTRL testCtrl.c
% rcc test.o CTRL testCtrl.o

RCCL/RCI Release 4.2, July 30,1992

4 2. GETTING STARTED

Also, test.c could have been compiled using cc directly.

Suppose there is a library support.a that contains modules to be used by the control level. Then this library must also be placed to the right of the CTRL keyword:
% rcc test2.o CTRL test2Ctrl.o support.a
All the usual C options are available. For example, a regular program foo that does not set up any RCI control tasks can be compiled with the optimizer, according to:
% rcc foo.c -O

2.3 Turning on the Robot

This section describes how to initialize the robot controller so that it can connect to an RCI program.

NOTE: The discussion in this section refers only to Unimate controllers and PUMA robots, since these are the principle systems that the RCCL/RCI distribution currently provides support for. If your system is connected to a different type of robot or controller, then the initialization procedure will probably be different, and you should consult the local ?guru?. Or better yet, get the local ?guru? to write a local version of this document.

2.3.1 Loading the moper program into the controller

An RCCL/RCI program communicates with the robot through a special communication program called moper, which runs inside the Unimate controller in place of the manufacturer supplied VAL software. moper takes care of communicating with all the devices attached to the robot controller, such as the joint controllers, the teach pendant, and the force torque sensor (if attached). A separate version of moper is usually compiled for each robot, and is given the same name as the robot. The moper programs live in the directory $RCCL/lsi11, and are created by a cross-compiler that usually lives in $RCCL/Xcompile. For example, if your robot is given the name RobotX, then its moper program will probably reside in the file lsi11/RobotX.

moper should be downloaded into the robot controller when the controller is powered up. It is downloaded through the controller console line, which should be connected to the host system through a serial port whose getty process has been switched off. The program down, in $RCCL/bin, is used to do the download. For down to work, the controller should be turned on and VAL should be aborted so that the controller's CPU is running ODT (the prom monitor for the CPU). You know you are in ODT when the controller console gives you an @ for a prompt, and when you type <CR>, you get an @? for a response.

2.3.1.1 Putting the controller into ODT

There are several ways to get the robot controller into ODT. On any controller, if you are in VAL, you can get into ODT simply by entering the command DONE.

On Mark II and Mark III controllers, an easier way is to simply toggle the ?run/halt? switch after you power the controller up. On Mark II controllers, this switch is located along the top edge.

RCCL/RCI Release 4.2, July 30,1992

2.3. TURNING ON THE ROBOT 5

On Mark III controllers, it is mounted on a bus card called ?interface board C?, which is visible as soon as you open the front panel door. Remember to toggle the switch, i.e., to turn it off and then back on again. If you don't turn it back on the moper software won't be able to run (in fact, nothing will be able to run).

NOTE: The ?run/halt? switch is not the black-knobbed three position rotary switch
which appears on the front panel of the Mark I and Mark II controllers (and which has
the settings ?run?, ?halt?, and ?restart?).

On Mark I controllers, the run/halt switch is switch S2 on the clock terminator board. Getting to it is a bit of a nuisance because you have to take the lid off the controller. It is possible, however, to remove the switch from the board and mount it on the front panel, as we have done.

On Mark II and Mark III controllers, VAL has to be loaded into the system from a floppy disk, where it then remains in static RAM. Since moper overwrites VAL when it is loaded, you have to reload VAL if you want to use it after moper has been running. When you power up the controller, you usually get a prompt asking if you want to load VAL in from the disk. If moper was previously running when the controller was shut off, then answering no (N) to this question will usually cause the boot program to crash, which will either put you into ODT, or (infrequently) cause the CPU to ?hang?. If the CPU hangs, you can get into ODT by toggling the run/halt switch, as described above.

2.3.1.2 Downloading moper

Once the controller is in ODT, you should download the moper software by running the program down, which lives in $RCCL/bin. It is assumed that the controller console line is connected to a serial port on the host system and that the login process getty on this line has been switched off. If you don't normally leave the console line connected to the host, you will have to connect it before running down.

Assume that we have a robot called RobotX, that is has a moper program that lives in lsi11/RobotX, and that the controller console line is connected to a terminal device corresponding to the special file /dev/RobotX. Then to load moper into the controller, you would generally call down with the following arguments:

% down -d /dev/RobotX -e 10000 -a 10000 \
$RCCL/lsi11/RobotX -t

-d /dev/robotX specifies the serial line used for loading. -e 10000 and -a 10000 specify moper's load and entry points, and $RCCL/lsi11/RobotX identifies the moper program itself. -t tells down to terminate when the load is completed; otherwise, it will go into a termlink mode which directly links your.00 screen and keyboard to the controller's console line. You can break out of termlink mode by typing a tilde (~).
It is usually easiest to define an alias for the down command, such as:

% alias loadRobotX 'down -d /dev/RobotX
-e 10000 -a 10000 $RCCL/lsi11/RobotX -t'
after which you can download moper with the simple command

RCCL/RCI Release 4.2, July 30,1992

6 2. GETTING STARTED

% loadRobotX
More information about down can be found in the manual pages.

2.3.1.3 Talking to moper

After the moper program has been loaded, it is possible to communicate with it over the controller console serial line. While this usually isn't necessary, it is occasionally useful for diagnostic purposes. Also, the same program that lets you communicate with moper can be used at any time to allow communication with whatever happens to be running in the Unimate controller (for instance, VAL or ODT). This means that you generally do not have to disconnect the controller console line from the host system.

To connect to the controller console line, you use the program termlink to create a virtual terminal connection. The necessary arguments to termlink usually look like this:

% termlink -d /dev/RobotX -s 9600 -T

-d /dev/RobotX specifies the name of the serial port attached to the console line, -s 9600 sets the communication speed to 9600 baud, and -T tells termlink to switch off any getty login process that might happen to be running on that line. If termlink does find a login process on the line and shuts it off, it will turn it on again before exiting.
As with down, termlink is most easily used when wrapped in an alias:

% alias talkRobotX 'termlink -d /dev/RobotX -s 9600 -T'

The command talkRobotX will put you into direct communication with the controller console. Whatever you type will be sent to the console, and whatever is printed to the console will go to your terminal (or window). To break out of termlink, you type ~, which will put you into a command menu with the prompt

termlink>

from which you can exit by typing quit<CR>, or any abbreviation thereof. More information about termlink can be found in the manual pages.

What you see when you run talkRobotX (and hit <CR> a few times) depends on what is running on the controller at the time. If the controller is turned off, you will get (predictably) nothing. If the controller is running VAL, you will get the VAL command line interpreter; if it is in ODT, you will get the @ prompt, etc.

If moper is running, you will get a prompt consisting of the character >, although this prompt appears only when you type a command character; it is not repeated if you just hit <CR>. To see if moper is running, type ?; if moper is running, it will print out a command menu for you. This command menu is mainly intended for running diagnostics and the like, although you might occasionally find the h command useful; it halts moper and puts the CPU back into ODT.
To reenter moper from ODT, type the ODT command
10000G
You should then get the response

RCCL/RCI Release 4.2, July 30,1992

2.3. TURNING ON THE ROBOT 7

moper started

listening

which is the same thing moper prints when it is first loaded into the controller.

NOTE: Don't halt and restart moper frivolously. Restarting moper reinitializes the
controller, which means the robot will have to be recalibrated.

2.3.2 Calibrating the robot

After you have powered up the robot controller and loaded in the moper software, you need to calibrate the robot arm.

PUMA robots are generally calibrated by running the RCI utility program pumacal. The basic form of this command is

% pumacal [<robotName>]

where, if <robotName> is not given, a default name is read from the file conf/defaultRobot. A PUMA 260 robot usually needs to be in the nest when it is calibrated. Alternatively, you can calibrate from the park position if you give pumacal the option -atpark:

% pumacal -atpark [<robotName>]

If you do use the -atpark option to calibrate a PUMA 260, make sure it actually is in the park position (or within a couple of degrees of it). The easiest way to ensure this is to move the robot to the park position before you turn off the controller. This can be done with the RCI utility program move:

% move [<robotName>] to park

The actual definition of the park position, in terms of joint values, is contained in the file conf/<robotName>.pos.

PUMA 560 and 760 robots use potentiometers to estimate their position at calibration time, and so there is no need for them to start from a specific location like the nest or park position.

2.3.3 Summary of the controller startup procedure

1. Turn on the robot controller(s).

2. Put the controller CPU into ODT.

3. Download the moper software into the PUMA controller using the down command, or an alias thereof.

If moper has loaded correctly, then the teach pendant (if connected) will beep and the CAL LED will turn on. No message should be displayed?. You can also check that moper is running by connecting to the console line with termlink and typing a ?, which should give you a menu of commands.

RCCL/RCI Release 4.2, July 30,1992

8 2. GETTING STARTED

4. Calibrate the robot using pumacal.

2.3.4 When you need to reload or recalibrate

Generally, you need to reload moper and calibrate the arm only when you power up the controller. The moper software will continue to run until you either power off the controller, or tell it to halt by giving it the h command.

It is occasionally possible that moper will crash, although this is extremely unlikely unless you are configuring new moper software. If moper does crash, it will generally exit to ODT. To restart moper in this case, enter the ODT command

10000G

as was described above. You will then need to recalibrate the arm. In even rarer cases, moper may hang. When this happens, you will get no response. To break the program and get into ODT, you can use the run/halt switch that was described in section 2.3.1.1. moper can then be restarted. In pathological cases, moper's internal data structures may be corrupted so that the only way to get moper to run again is to reload it from the host.

Exclusive of the above conditions, moper will continue to run and the robot will remain calibrated until the controller is switched off. This will remain true even if you are having trouble on your host system. For instance, it is generally unnecessary to reload moper or recalibrate the robot even if you get a UNIX system crash.

2.4 Running Programs

Once compiled, an RCCL or RCI program runs more or less like any other UNIX program, except for the control level ?task? which is executed in the background. If the program needs to communicate with a robot controller, it will establish the necessary connections automatically, assuming that the controller is powered on and properly initialized.

2.4.1 Robot arm power

Usually, when an RCCL or RCI program starts up and begins to control a robot, it will check to see if the robot's arm power is on. If it is not, it will attempt to turn it on automatically.

NOTE: Please understand the difference between the controller power, which is enabled when you turn on the controller, and the robot arm power, which turns on the actuators. The controller will usually have separate controls to turn the arm power on and off.

Normally, on Unimate controllers, the only way to turn on the arm power is to manually press the power-on switch. This means that if an RCCL/RCI program tries to turn on the power automatically, it will be unable to do so. In this case, the program will simply print a message requesting that you turn the power on, and then wait until you do so.
?The teach pendants that work with RCI are the large heavy orange ones and the small black boxy ones.

RCCL/RCI Release 4.2, July 30,1992

2.5. FOR THE MICROVAX-II: BOOTING AUXILIARY CPUS 9

NOTE: If you turn the arm power off while a program is running, it will normally
cause the program to freeze (and perhaps jolt the arm a bit), but RCI will make no
attempt to turn the power back on again.

Because constantly turning the arm power on can be an inconvenience, we suggest wiring the controller so that the arm power can be turned on automatically by the RCI software. On the Unimate controller, this usually entails choosing a bit from one of the controller's output signals and attaching this to an input signal line that turns on the arm power. Details of how this can be done are given in the RCCL/RCI Hardware Installation Notes.

An alternative to arranging for the power to turn on automatically is to simply never turn it off. By default, RCI shuts off arm power whenever control of the robot is released (e.g., when the program exits). However, most of the utility programs (such as pumacal or move) have -on options that cause them to leave the arm power on when they exit. In an RCCL program, you can leave the power on by calling rcclRelease() with an argument of 0, or by using rcclSetOptions() to set RCCL_LEAVE_POWER_ON. (You can also set the parameter leavePowerOn to ?true? in the RCCL and sysprogs parameter sets of the .rciparams file (see section 2.7).) At the RCI level, you can arrange for power to be left on after the control session has ended by using the macro SET_POWER_ON_RELEASE(). If no RCI program is running, the robot arm power can be controlled using the RCI utility program power:

% power [<robotName>] (-off|-on)

The -off option turns the arm power off, and the -on option turns it on.

On some systems, RCI may not even have the ability to turn the robot power on and off, the way it does with Unimation controllers. For such systems, you would most likely control the robot power manually from the robot controller, independently of the execution of RCCL/RCI applications.

2.5 For the MicroVAX-II: Booting Auxiliary CPUs

This section applies only to multi-CPU MicroVAX-II implementations.

If your program uses auxiliary CPUs, then it will attempt to automatically load them with the control portion of the RCI program, booting them first if necessary. However, if an auxiliary CPU is not currently booted and it happens to be in monitor (or console) mode, the RCI program will be unable to do this and will probably exit with an error indicating such. To rectify the situation, you need to put the CPU into a ?boot-wait? by entering the command B on its console serial line.

If an auxiliary CPU is in console mode, it will give you a >>> prompt on its console line when you type <CR>.

Auxiliary CPUs on the MicroVAX generally go into console mode whenever the MicroVAX system is powered up or rebooted, unless the HALT switch on the CPU's configuration module is turned off; see the KA630 or KA620 User's Guide and/or the RCCL/RCI Hardware Installation Notes for details.

RCCL/RCI Release 4.2, July 30,1992

10 2. GETTING STARTED

2.6 Using the Robot Simulator

RCCL and RCI programs can also be run in simulation mode. In this case, the control task actually runs in user mode, driven by a UNIX signal, and instead of connecting to a real robot, the program connects to another UNIX program that simulates the robot and its controller.

The default simulator program provided with RCI, called robotsim, provides 3D graphic and kinematic simulation of one or more robots. Several types of robot are supported (PUMA, Stanford arm, Elbow manipulator). Typically, you start up robotsim with the name of the robot(s) you want to emulate, and then leave it running in the background:

% robotsim <robotName>

This is analogous to ?turning on? a robot controller. An RCI program running in simulator mode connects to robotsim instead of a physical robot. Communication is based on Internet domain sockets, which means that the simulator program can be executed on a different machine.

robotsim does not currently model very much in the way of dynamics (except for gravity loading), and does no collision detection, although it would not be difficult to add these features to the program.

The graphic display provided by robotsim runs under either X11, SunView, or the Silicon Graphics GL library. A wireframe display is provided for X11 and SunView, and solid shaded graphics is provided for GL. The simulator is also capable of running interactively, allowing control cycles to be explicitly single stepped.

To see how to run RCCL programs in simulation mode, consult the RCCL User's Guide. To see how to run RCI programs in simulation mode, consult the RCI User's Guide. Detailed information on robotsim and its features can be found in the manual pages.

2.7 The .rciparams File

This is a file containing parameter values that can be referenced by RCCL/RCI programs. It defines a sort of ?environment? for the RCCL/RCI system, where parameter values can be changed without having to recompile programs. Parameters are grouped into named sets and can be accessed from software with special primitives (see rciParameters(3)).
A few parameter set names are reserved by the system:

} RCCL identifies run time parameters which are used by RCCL programs. These include an option to force the program to run in simulator mode, as well as options which control the robot's speed, the control task timeout tolerance, the CPUs which the program may attempt to use, and the control task sample rate. For details, see RCCL_params(5).

} RCISYS is the name of a set of parameters that defines some basic RCI system parameters. For details, see RCISYS_params(5).

} sysprogs is the name of a parameter set which is used by RCI utility programs such as pumacal, move, and free. For details, see sysprogs_params(5).

RCCL/RCI Release 4.2, July 30,1992

11

An RCCL/RCI program will look for a .rciparams file in three places: the directory $RCCL/conf, the user's home directory, and the current directory, remembering all parameter sets found but allowing files read later to redefine parameter sets defined earlier. The current directory is the most common place for a user to set up a .rciparams file.

3. RCCL/RCI Installation

The following sections describe how to install RCCL/RCI. This generally is a three step process.

1. Building the main software tree. This involves unpacking the tape, installing gnuMake, setting up some configuration files, and running make. Instructions for this are given in this section.

2. Installing the necessary kernel support. Exactly what this involves depends on your system. If you are building a ?simulator only? system, then you do not need to add any kernel support. VxWorks configurations are usually set for ?simulator only? operation on the host system and therefore don't need any kernel support either. On the other hand, if you are building a system for real-time operation on the host system, you will need to configure some special support into the system's UNIX kernel. Instructions for this are given in section 4. Real-time support is currently provided for Sun4 Sparc systems running SunOS 4.1 and 4.2, Silicon Graphics systems running IRIX, and MicroVAX-II systems running 4.3 BSD.

3. Attach the required hardware to your system. Depending on what you intend to do with your system, you will probably need to attach some external hardware. Typically, this will be to provide communication with one or more robot controllers. On some systems, special hardware can also be added to give the RCI system a more accurate real-time clock. Most of the hardware arrangements that are currently ?supported?, at least in terms of being documented, involve connecting Unimation Mark X robot controllers to either MicroVAX-II, Sun4 Sparc, Silicon Graphics IRIS, or VxWorks systems. The MicroVAX-II system can be configured to support multiple CPUs. An overview of the hardware work required for these systems is given in the RCCL/RCI Hardware Installation Notes.

There is no particular order to these steps.

3.1 Installing the GNU make Command

At present, the RCCL/RCI Makefiles assume the use of the GNU make utility. This is because it provides some useful features (and bug-fixes) not found in other versions of make. GNU make has been ported at present to a wider range of platforms than are ever likely to receive RCCL/RCI.

One feature which GNU make provides, and which RCCL/RCI uses, is the ability to include files from within the main Makefile. This allows us to place the include file dependencies, which are generated automatically using make depend, in a separate file called DependFile, which will not be destroyed when the Makefile is rebuilt using imake (imake is described below).

RCCL/RCI Release 4.2, July 30,1992

12 3. RCCL/RCI INSTALLATION

GNU make is provided by the Free Software Foundation. In case you presently do not have GNU make, a copy is provided along with the RCCL/RCI distribution, in the directory gnuMake. You should install this before you do anything else.

To install GNU make, you should first go into the gnuMake directory and read the copyright information in the file COPYING. You should then read the instructions in the file README, which will tell you to make the appropriate configuration adjustments in Makefile. You should then be able to build make with the command

% make

You do not need gcc to compile GNU make (at least, we didn't).

NOTE: There may be some conflicts between the native make on your system and GNU make, mostly involving new features that have been added by the vendor. You may want to call GNU make by a different name. On Sun systems, kernel compilation may not work with GNU make because of the use of Sun-specific features in the kernel Makefile.

3.2 Setting up Your Environment

You should set up an RCCL/RCI UNIX environment as described in section 2.1.

3.3 Editing the Configuration File

Before running make on your system, you should edit the configuration file conf/site.conf. This allows you to set various options describing the sort of system you want and what sort of platform you are running on.

The definitions in site.conf are used by the C preprocessor, which is invoked by the utility program imake (described below). What the available options are and what they do are described by comments in the supplied version site.conf. We do not describe the options here because they are likely to change quickly with time.
Different versions of site.conf, written for various systems, are available in the conf directory under the general name <SysType>.conf.

3.3.1 The imake utility

RCCL/RCI builds its Makefiles automatically using the utility program imake, which was developed by Todd Brunhoff and Jim Fulton for the MIT X Windows Consortium. imake creates a Makefile from a source file named Imakefile by running it through the C preprocessor in conjunction with some pre-declared definition and template files.

Since it is operated on by the C preprocessor, the Imakefile may contain preprocessor compilation directives and macros. This is particularly useful for generating Makefiles whose targets and/or actions depend on the configuration parameters of the system.

RCCL/RCI Release 4.2, July 30,1992

3.4. BUILDING THE SYSTEM 13

The configuration files used by the RCCL flavour of imake are contained in $RCCL/conf. The template file, which is responsible for including all the other files, is called Imake.tmpl. The site-specific definitions are contained in site.conf. Defaults definitions (that get set if not previously defined in site.conf) are declared in defaults.conf. Finally, the macro definitions that are used by most of the system's Imakefiles are contained in Imake.rules.

Most RCCL/RCI directories will contain an Imakefile in addition to a Makefile. The Makefiles are created automatically by the system when it is first built. If you wish to recreate a Makefile within a particular directory, then the best way to do this is to use the command rmkmf, which is a script that lives in $RCCL/bin. Running

% rmkmf

will attempt to turn any Imakefile (or imakefile) that lives in the current directory into a Makefile, using the configuration files in $RCCL/conf. Alternatively, you can give rmkmf (1) the name of the root directory in which to seek the conf directory, and (2) the name of the directory in which to look for the Imakefile and build the Makefile:

% rmkmf <rootDirectory> <currentDirectory>

For example, the command

% rmkmf $RCCL .

should have the same effect as running rmkmf with no arguments.

If you already have imake as part of an X-windows distribution, this should cause no conflict, although you should be careful to specify $RCCL/conf as the directory in which to locate the include files (rmkmf will do this automatically).
More information on imake can be found in the manual pages.

3.4 Building the System

Once the configuration file site.conf has been prepared properly, you can go to the RCCL root directory ($RCCL) and run the command

% make World

The system Makefile will first build imake and then use this to rebuild itself and all the subordinate Makefiles. It will then clean the directories, build all the libraries and utility programs, and install the manual pages. On MicroVAX-II systems, it will also compile the kernel for the auxiliary CPUs. make World will take about four hours or so on an unloaded MicroVAX-II, and about one hour on an unloaded Sun4.

3.4.1 Commands defined in the main system Makefile
The system Makefile contains the following commands which may be of some use:
} make clean removes all executable, object, and garbage files from the source tree.

RCCL/RCI Release 4.2, July 30,1992

14 4. ADDING REAL-TIME SUPPORT TO THE SYSTEM KERNEL

} make depend builds the include file dependencies for all of the Makefiles. These are kept in a separate file, called DependFile, which co-exists alongside the Makefile and is included by it.

} make libs builds all of the system libraries, except for those defined in locallib and libCtree.

} make bins builds all of the utility programs, expect for those defined in localbin. It does not build the demo programs.
} make manpages creates the online manual pages.

3.5 Installing the Simulator Service

In order to be able to run the simulator program robotsim, it is necessary to define a TCP/IP service port for it in the /etc/services file of every machine on which it is to run. If you are running yellow pages, then the service should be defined in the corresponding yellow pages file instead.

The service name is RCISimMux, and the port number which we usually assign is 5347. The corresponding entry in the file looks like this:

RCISimMux 5347/tcp # RCI simulator service

The port number should be unique. If 5347 has already been assigned on your system, then select some other port number which has not been assigned. Be sure to select a port number which is reserved for site-specific usage; the comments in /etc/services should indicate which these are. It may be convenient (or necessary) to consult your local system administrator for help in defining the simulator service.

4. Adding Real-time Support to the System Kernel

4.1 Introduction

Because RCI provides the ability to create real-time tasks, it is necessary that the host system kernel be able to support real-time tasks. Historically, the UNIX kernels available on most workstations did not do this, although the situation is now changing.

Fortunately, the real-time support needed by RCI is rather minimal, and so on some systems (MicroVAXen and Sun4s) it is possible to patch the needed features into the kernel. The MicroVAX patches require kernel source code, whereas the Sun4 patches do not. The SGI IRIX kernel already has sufficient real-time support for RCI, and so it does not need any patching at all, although a special RCI ?driver? is added to provide a convenient interface to certain kernel services.

If you are building a simulator-only version of RCCL/RCI, then the real-time support features described here are not needed, and you can skip to the next section.

The extra kernel support which is required on MicroVAX and Sun4 systems is described in section 4.1.1. Actual kernel configuration procedures are described for the MicroVAX in section

RCCL/RCI Release 4.2, July 30,1992

4.2. MICROVAX-II KERNEL CONFIGURATION 15

4.2, for the Sun4 in section 4.3, and for SGI machines in 4.4. The concepts are similar in most cases, and so it may be useful to scan the documentation for systems other than your own.

4.1.1 Real-time support for MicroVAX and Sun4 systems

RCI control tasks are generally executed upon the occurrence of a particular clock or device interrupt. Giving the task the necessary real-time response requires that it be able to respond quickly to such events. Since neither BSD 4.3 nor SunOS 4.2 (the primary kernels for MicroVAX and Sun4 systems) offer this capability directly, we handle the situation ourselves by arranging for RCI tasks to be run in system kernel mode, at high IPL, off of the interrupt stack.
Doing this immediately presents three technical difficulties:

1. The control level code must be locked into physical memory so that it is not paged out when the clock or device interrupt driving the control task occurs;

2. Some support must be placed into the kernel trap handling code so that exceptions which occur while the control task is running will not produce a UNIX system crash;

3. Executing process code from within an interrupt handler requires that there be a way of quickly switching to and from the process memory context.

The kernel support for MicroVAX and Sun4 systems handles these three things. SunOS provides a memory locking primitive which more or less takes care of item (1).

4.1.2 Support for auxiliary CPUs

In principle, RCI control tasks can be run on either the main UNIX CPU (also known as the arbiter CPU), or on auxiliary CPUs connected to the same backplane. Running tasks on dedicated auxiliary CPUs requires a real-time kernel for those CPUs, plus a special driver to interface this kernel to the UNIX system.

Support for using auxiliary CPUs is presently provided only for MicroVAX-II systems. The auxiliary CPUs consist of KA630 (or KA620) MicroVAX CPU modules plugged into the system Q-bus. They run a small real-time kernel which was written at McGill University by Mike Parker, and are interfaced to UNIX through a special device driver. The real-time kernel is part of the standard RCCL distribution, and is located in the directory $RCCL/auxkernel.

4.2 MicroVAX-II Kernel Configuration

The real-time support for MicroVAXen is more complex than that for other systems, since the operating system provides none of the required features and it was necessary to add them ourselves. This included adding a set of system calls to take care of memory locking, in addition to the support required to quickly switch process memory contexts at interrupt level.

The modifications were made to a stock Berkeley 4.3 system, not a Mt. Xinu system or Ultrix. Adding the changes described to those systems should not be much more difficult, but you will need source code.

RCCL/RCI Release 4.2, July 30,1992

16 4. ADDING REAL-TIME SUPPORT TO THE SYSTEM KERNEL

4.2.1 Doing it the easy way

The easiest way to obtain the kernel support is to acquire a modified 4.3 kernel from McGill. If you can send us your system configuration file and your disk table sizing parameters, we can probably build a bootable kernel that will run on your system.

4.2.2 Doing it yourself

If obtaining a kernel from McGill is not possible, you can go through the modifications we have made and install them yourself. This will require that you have source code for your system.

Making the modifications yourself requires that you have a very good understanding of low level UNIX system concepts, such as device drivers, how to configure a kernel, and how to add system calls. The documentation in this section is more of a guide than a recipe.

The kernel support for MicroVAXen is located in the directory $RCCL/sys.uVAX. This contains, basically, a copy of all the files we either added or changed, located in the same places that they normally occupy in the full source tree. For more details on the modifications and how they are implemented, see the supporting document MicroVAX-II Kernel Support for RCI.

The best approach to installing these changes on your system is probably to do something like run diff on the two source trees:

% cd $RCCL
% diff -r sys.uVAX /sys

Much of the output will talk about files in sys that are not included in sys.uVAX; you can forget about these. Ideally, the rest of the output should be things that we have added and you should simply be able to add yourself. There may be a few places where the indentation format for the two files differs, in which case the diff output will be very verbose and not too interesting. The best thing to do here is probably to run both files through indent and then run diff again.

4.2.3 Support for RCI tasks running on the main UNIX CPU

The changes as currently implemented are compiled into the kernel by setting the following options in the system config file:

options MEMORYMAPPING
options KERNEL_USER_TRAPS
options LOCAL
options RCI

An RCI control task running on the main UNIX (or arbiter) CPU executes at interrupt level, which implies that it needs an interrupt to connect to. This is provided by a UNIX device driver which contains the code necessary to run an RCI task inside its interrupt service routine. That is about all the driver has to do; RCI tasks have direct access to the I/O bus and do their data input and output directly. In fact, the UNIX interrupt routine actually calls the RCI task monitor, which uses polling functions to determine which of its tasks can be run. The UNIX driver simply provides a polling interrupt. Consequently, the code to do this is pretty much the same for all the drivers.

RCCL/RCI Release 4.2, July 30,1992

4.2. MICROVAX-II KERNEL CONFIGURATION 17

The file rci_template.c in the directory sys/rciext contains a template RCI interrupt driver. Support routines are contained in the file sys/rciext/rci.c. An interrupt driver for the DEC DRV11-J parallel port is found in sys/vaxuba/drvj.c, and an interrupt driver for the DRV11 is found in sys/vaxuba/pri.c. The latter driver is much more complicated than it presently needs to be because it contains support code for the old RCCL system.

The interrupt drivers are presently written with an option to access them as exclusive open devices (i.e., openable by only one process at a time), which is usually desirable as a check against multiple processes colliding over the same device (the other way this is done is to maintain lock files in $RCCL/lock). An interrupt driver is opened exclusively if, typically, bit 7 in its minor device number is set.
RCI control tasks running on the arbiter also make use of something called a generic RCI device. This is a pseudo-device configured into the kernel which provides the following services:

} provide the addresses of various kernel objects such as the kernel print routine and the virtual memory locations of the bus interfaces;

} provide a way to execute RCI tasks directly at the request of the planning program;

} connect an RCI task to the system clock interrupt.

These services are used by the RCI system code to implement the RCI interface seen by the programmer. Much of the functionality of the driver is identical to that provided by the polling device drivers. The code for the generic RCI device driver lives in sys/rciext/genrci.c.

A generic RCI device is configured into the kernel by placing it into cdevsw, defining several units for the pseudo-device genrci in the kernel config file, and creating the character device files /dev/genrci<n>, each with the appropriate major device number and minor device number <n>. Every RCI program needs to open a generic RCI device. Since these devices are exclusive open, the number of them provided determines the maximum number of RCI programs that may be run simultaneously.

Lastly, RCI control tasks running on the arbiter may make use of a clock device to provide a time base independent of the system clock. Providing a separate clock device allows (1) the setting of a time interval not provided by the system clock, and (2) a separate count to be kept which allows recovery from clock interrupts missed because of RCI control tasks (RCI control tasks running on the arbiter must run non-interruptibly, which can cause the system clock to miss ticks).

An RCI program looks for a clock device in /dev/rciclk. If this device is present, it is assumed that the clock is available and will remain active for at least as long as some process has it open. The clock device implemented for the MicroVAX-II Q22-bus was built using a DRV11 parallel port and a small amount of timer logic. The hardware aspects of the device are discussed in the document RCCL/RCI Hardware Installation Notes. Its device driver lives in sys/rciext/drvclk.c.

Clock devices are not as necessary if the system contains auxiliary CPUs, mainly because control tasks running on the auxiliaries do not have to run non-interruptibly, and therefore their system clocks will not lose time. A system clock running on one of the auxiliary CPUs can be broadcast to other CPUs, including the arbiter, so that the arbiter system clock does not have to be used.

RCCL/RCI Release 4.2, July 30,1992

18 4. ADDING REAL-TIME SUPPORT TO THE SYSTEM KERNEL

4.2.4 Support for RCI tasks running on auxiliary CPUS

UNIX is interfaced to auxiliary CPUs using a special driver (which is called the ka driver because the MicroVAX processors are named KA630s). The driver is mainly responsible for managing and allocating shared memory space on the Q22-bus which is used to provide inter-CPU communication. It also provides a set of I/O controls that boot an auxiliary CPU and exchanges messages with it.

The code for this driver lives in sys/rciext/ka.c and various other ka*.h files in the directory sys/rciext.

On MicroVAX-II systems, the ka driver should be configured into the system at Q-bus address 0177500 (this is the base address of the processor mailbox registers). At boot time, the driver checks the reserved mailbox locations to see what CPUs are actually present. Up to four MicroVAX CPUS, including the arbiter, can be placed onto the Q-bus (although there are restrictions on where you can place them; see the RCCL/RCI Hardware Installation Notes). Within the driver, each CPU unit corresponds to a different minor device, with minor device 0 being used for CPU 0, minor device 1 being used for CPU 1, etc. To allow the driver to be opened, four character devices named /dev/ka<n> should be created. These are exclusive open devices. Four other character devices, named /dev/kaD<n>, should be created with bit 7 of their minor device number set to provide multiple open capability?.

Information about the hardware aspects of installing auxiliary CPUs can be found in the document RCCL/RCI Hardware Installation Notes. Once an auxiliary CPU is in place and noticed by the ka driver at boot time, the RCI system code will do everything else for you ? a call to rciCreate() requesting a particular CPU will ask the ka driver if the CPU is available, cause that CPU to be booted, if necessary, and then load it with a copy of the RCI program image. The minikernel that runs on the auxiliary CPU is located in the directory $RCCL/auxkernel, and is created as part of the general system ?make?.

4.2.5 Summary of the system configuration at McGill

This section describes the MicroVAX-II system configuration as it is currently implemented at the McGill University site.
The system configuration file contains the following entries related to RCI:

options MEMORYMAPPING
options KERNEL_USER_TRAPS
options LOCAL
options RCI

# driver for auxiliary, microVAX CPUs
device ka0 at uba? csr 0177500
vector kaintr

# driver for the DRV11 port connected to the robot
?Note that this is the opposite of the convention for polling interrupt devices, where setting bit 7 in the minor device number indicates an exclusive open device; this is a historical artifact.

RCCL/RCI Release 4.2, July 30,1992

4.3. SUN4 KERNEL CONFIGURATION 19

device pri0 at uba? csr 0167770 flags 0300
vector priintr

# driver for the DRV11 based real-time clock module
device drvclk0 at uba? csr 0160400 flags 0100
vector drvclkintr

# general RCI interface devices
pseudo-device genrci 4

The device pri0 is the polling interrupt device for the DEC DRV11 parallel port (used to communicate with our robot), and drvclk0 is the RCI clock device, which also happens to be implemented with a DRV11. Because the DRV11 cannot force itself to interrupt, vector information for any DRV11 based device is passed to the driver probe routine using the flags field.

The special files located in /dev are described in table 1. Major device numbers are quoted verbatim, although these will vary from system to system.

file name major device minor device

/dev/ka0 70 0 /dev/ka1 70 1 /dev/ka2 70 2 /dev/ka3 70 3

/dev/kaD0 70 128 /dev/kaD1 70 129 /dev/kaD2 70 130 /dev/kaD3 70 131

/dev/genrci0 71 128 /dev/genrci1 71 129 /dev/genrci2 71 130 /dev/genrci3 71 131

/dev/pri0 67 0 /dev/priRCI0 67 128 /dev/rciclk 74 0

Table 1:Special files in /dev related to RCCL/RCI at the McGill site

/dev/ka<n> are the exclusive open ka devices and /dev/kaD<n> are the multiple open ones. /dev/pri0 is multiple open, and /dev/priRCI0 is exclusive open.

4.3 Sun4 Kernel Configuration

The real-time support that was developed for SunOS 4.1 and 4.2 represented something of a breakthrough because it can be installed on binary-only distributions. Installation is therefore more

RCCL/RCI Release 4.2, July 30,1992

20 4. ADDING REAL-TIME SUPPORT TO THE SYSTEM KERNEL

of a ?drop in?.

At the time of this writing, Sun is preparing to upgrade its operating system to Solaris 2.0. It is unlikely that the RCI kernel patches will work with Solaris 2.0, at least in their current form. Hopefully, Solaris 2.0 may contain enough real-time support so as to make the kernel patches unnecessary.

4.3.1 What the reader should know

The reader is assumed to be familiar with configuring system kernels, and with installing device drivers. Documentation on these subjects is available as part of the Sun documentation kit. The procedures are not really difficult, but they can be time consuming.

4.3.2 Unpacking the modules

In the RCCL distribution tape, there is a directory labeled sys.Sun4, which in turn contains the subdirectories rciext, sun4/conf, and sun.

The rciext directory contains the kernel-level support code for RCI. A copy of this should be placed in the kernel root directory (which is usually called /sys), alongside other directories such as os and net.

The other directories contain template files to help in configuring the kernel. In particular, you should find the template files

sys.Sun4/sun4/conf/CONFIG.RCI
sys.Sun4/sun4/conf/files.RCI
sys.Sun4/sun/conf.c.RCI
The text below will make occasional references to these.

4.3.3 Installing the modules

After the directory rciext has been copied to /sys, you should go there and check the Makefile to make sure that OBJD (which is defined near the top) is set to the correct directory for system object modules. The default setting in the distribution is ../sun4/OBJ. If you are configuring RCI for a Sun4c, you will need to change this to ../sun4c/OBJ.
When OBJD is correctly set in the Makefile, you should do

% make install

This will build some utility programs and insert some static patches into a few of the kernel object modules.

CAUTION: Copies of the original (unpatched) object files will be placed in the kernel object directory (OBJD) with the name extension .orig. You do not want to delete these files, since if you do, make may attempt to replace them with the new (patched) versions. To play it safe, you should probably make a secondary copy of the .orig files.

RCCL/RCI Release 4.2, July 30,1992

4.3. SUN4 KERNEL CONFIGURATION 21

4.3.4 Editing the configuration files

4.3.4.1 The main config file

Options to compile in RCI kernel support must be added to the main system config file, normally found in the directory /sys/sun4/conf (or sun4c/conf). The file usually has the same name as the system being configured; we will assume here that this is <SYSNAME>.
The following option commands should be added to the config file:

options LOCAL
options RCI

The following pseudo-device should also be defined:

pseudo-device genrci 4

The number of genrci devices determines the number of RCI programs that can be running simultaneously; four has always been more than adequate.
If you are going to be using a real-time clock for RCI (i.e., the XYCOM XVME 203 or 293), then you will also need to include the device driver for this:

device xyclk0 at vme16d16 ? csr <address> priority 5 \
vector xyclkintr <vecnum>

<address> gives the device's address in the VME short I/O space. Information on how to set this is given in the RCCL/RCI Hardware Installation Notes. See section 4.3.7 if you have an S-bus machine. The device's VME interrupt level is set in software by the driver and 5 matches the value which the driver uses by default; to change this value, edit the file sys/rciext/xyclkreg.h. The interrupt vector number is also set by software to whatever value is specified by <vecnum>; this selection should be based on what vectors are available.

Finally, you need to configure in the driver for whatever interface devices you will need. At the moment, only one driver is supplied with the distribution; this is for a XYCOM XVME 240 parallel port used to communicate with a Unimation robot controller. The configuration entry for this device looks like this:

device xyd0 at vme16d16 ? csr <address> priority <ipl> \
vector xydintr <vecnum>

Again, <address> gives the physical address of the device in VME short I/O space; see the RCCL/RCI Hardware Installation Notes for more information on how to set it. <ipl> is the VME interrupt priority level, which should match the value set on the board and which is also described in the hardware manual. The interrupt vector will be set by software to <vecnum>.

4.3.4.2 The ?files? file

The config directory should also contain a file called files.<SYSNAME>, which gives the names and locations of source modules which are specific to the system. If this file does not already exist, you should create it. Add to this file all the entries defined in the template file files.RCI. If you have written your own interface drivers, you will need to add the filenames for them as well.

RCCL/RCI Release 4.2, July 30,1992

22 4. ADDING REAL-TIME SUPPORT TO THE SYSTEM KERNEL

4.3.4.3 The ?conf? file

The file conf.c, located in the directory /sys/sun, contains the configuration tables for the system device drivers. You need to add entries to this table for the generic RCI driver, plus any other RCI drivers which your system needs (such as for the xyclk clock timer or the xyd parallel interface described above). All the drivers supplied with the system (at least all the ones so far!) are character devices. Structures describing the entry points and data structures for these devices need to be entered into the table cdevsw, located in conf.c. Entries are usually placed at the end of the existing table, and the table index (which appears in a comment at the right of each entry) denotes the major number for the device.

Take note of the major device numbers you assign; you will need them when creating
special files for the devices in /dev.

For each device structure there is usually a set of preprocessor definitions that appear before the cdevsw array. These definitions first reference an include file to determine if, in fact, the driver should be configured into the current kernel. If not, some #define statements are used to ?null-out? the appropriate table entries. The include file in question has the name <device>.h, and is created by /etc/config when it processes the kernel config file.

Sample table entries for the drivers supplied with the distribution are given in the template file conf.c.RCI.

4.3.5 Building the kernel

Once the configuration files have been set up, you may proceed with building the system in the usual fashion:

% cd /sys/sun4/conf # (or /sys/sun4c/conf)
% /etc/config <SYSNAME>

... this takes a few minutes ...
% cd ../<SYSNAME>
% /bin/make vmunix # do not use GNU make
... this takes a few more minutes ...

Important: As the comment in the above example indicates, GNU make should not
be used because the Makefile generated by /etc/config uses Sun-specific features
not found in GNU make. In particular, it uses a += operator.

You can now move the completed kernel into / and reboot. Saving the previous kernel is highly recommended in case the new kernel will not boot; you might want to use the move command supplied in the rciext directory with the RCI kernel software.

4.3.6 Creating device entries

The last thing you need to do is go to the directory /dev and create a special file for each device which you have configured into the system.

RCCL/RCI Release 4.2, July 30,1992

4.3. SUN4 KERNEL CONFIGURATION 23

All devices provided with the distribution are character devices, and their corresponding special files are created with the following usage of the command mknod:

% /etc/mknod <filename> c <major> <minor>

<filename> is usually the same as the device driver name, plus a number at the end indicating the unit number (which usually starts at 0). <major> is the major device number (i.e., the index into the driver table cdevsw), and <minor> is the minor device number.

The minor device number is usually the unit number, except that other bits may be set as well. Because the number of units for a particular device is limited to a small integer, the higher order bits of the minor number can be used to pass other information to the driver routines. In particular, RCI drivers are written so that if bit 7 (i.e., 0x80) of the minor number is set, then the device behaves as an exclusive open device, which means it may be opened by only one process at a time. This provides a reasonable safety check against having more than one process try to do something like control the same robot simultaneously. To determine the minor number for an exclusive open RCI device, take its unit number and then set bit 7 (or, equivalently, add 128).

A special file genrciX should be created for every RCI generic pseudo-device. These devices should be exclusive open, so bit 7 of the minor number should be set. The commands to create four such devices, if the major number were 104, would be:

% /etc/mknod /dev/genrci0 c 104 128 % /etc/mknod /dev/genrci1 c 104 129 % /etc/mknod /dev/genrci2 c 104 130 % /etc/mknod /dev/genrci3 c 104 131

If the xyclk real-time clock device is present, then a special file must be created for it as well. It is given the generic name rciclk, and since it is not an exclusive open device, the minor number should be 0. The command to set this up may look like:

% /etc/mknod /dev/rciclk c 105 0

Finally, create a special file for each interface device. These devices should be exclusive open, so, again, add 128 to the minor number. The corresponding special file usually takes the name of the device driver, plus RCI, plus the unit number. For example, the special file for unit 0 of the xyd interface can be created with a command which looks like:

% /etc/mknod /dev/xydRCI0 c 106 128

After the special files have been created, make sure that they have world read-write permission; you can use the command chmod for this.

4.3.7 If you have an S-bus machine

4.3.7.1 Bus adaptors

If you have an S-bus machine, and you want to interface it to VME devices, then the approach we recommend is to get an S-bus to VME adaptor. Several manufacturers make S-bus to VME adaptors, and we have had some experience with two: Performance Technologies, Inc, and Bit-3 Corporation.

RCCL/RCI Release 4.2, July 30,1992

24 4. ADDING REAL-TIME SUPPORT TO THE SYSTEM KERNEL

The Performance Technologies interface (called the PT-SBS915) appears to be the more powerful product, although it may also be more expensive. They can supply some configuration software which makes the device completely transparent to kernel configuration. If you do this, you can then follow the Sun4 kernel configuration procedure described above as though the system is a VME-based Sun. The configuration software comes with a private version of /etc/config that takes references to VME devices in the system config file and introduces the necessary interface board software into the kernel.

If you do not wish to buy the configuration software supplied by Performance Technologies, then you may be able to use a driver which was written by John Bradley at the University of Pennsylvania. The driver, contained in the directory sys.Sun4/pti, implements the xyclk and xyd drivers (described in section 4.3.4.1) directly on top of a Performance Technologies interface board.
The current address for Performance Technologies is:

Performance Technologies, Incorporated
315 Science Parkway
Rochester, New York
USA 14620
(716) 256-0200

The Bit-3 interface does not (as far as we know) come with software that makes its completely transparent. Consequently, you may have to write your own S-bus driver for it.

A driver for the Bit-3 interface was also written by John Bradley at the University of Pennsylvania, although this is not supplied with the RCCL distribution. You may be able to contact John Bradley directly and arrange for a copy:

bradley@grasp.cis.upenn.edu

You many also be able to clone John Bradley's PTI driver (in sys.Sun4/pti) into a workable Bit-3 driver.
The address for Bit-3 Corporation is:

Bit-3 Computer Corporation
8120 Penn Avenue South
Minneapolis, MN 55431-1393
(612) 881-6955
FAX: (612)881-9674

In the next couple of sections, information is provided that might be of general use if you are writing your own S-bus to VME interface driver.

4.3.7.2 The VME bus map variables

RCI currently provides application programs with direct access to the VME bus through a couple of variables, rciIOpage and rciBus, which are pointers to regions of virtual address space which map the following subsections of the VME bus:
} IOpage ? all of the VME A16D16 subspace;

RCCL/RCI Release 4.2, July 30,1992

4.4. SGI IRIX KERNEL CONFIGURATION 25

} bus ? a two megabyte (0x200000) subsection of VME a24d16 space, starting at the subspace's midpoint (i.e., VME24_BASE + 0x800000).

The virtual address regions that map these subspaces are set up by the RCI kernel software the first time any RCI device is opened after a system reboot.

There is a routine called createBusMaps(), located in sys/rciext/rci.c, which allocates the necessary amount of kernel virtual space and maps it onto the two subsections of the VME bus. A system which uses a bus adaptor will have to have this routine modified so that the bus maps are still set up correctly.

NOTE: There is nothing particularly special about which parts of the bus space are mapped by RCI. The assignment for rciIOpage makes sense since utility devices often appear in VME A16D16 space. This space is also small (64K bytes), and so there is no reason not to map the whole thing. The assignment for rciBus is a bit more artificial. We chose to map VME A24D16 space, since that is the second likeliest place to find user devices. We mapped only part of it since the whole space is 16M bytes long and it was hard (back when we first did this) to get that much virtual address space from the Sun kernel. 2M bytes seemed more reasonable, and we started the map at the midpoint of the address space because Sun tends to use the lower half for its own devices. But, in short, there's no serious reason why you can't have rciBus map anything that's convenient (or set it to NULL and forget about it).

4.3.7.3 Bus adaptors and interrupts

About the only other thing you need to worry about with a VME bus adaptor is to ensure that interrupts get passed to the system correctly: RCI usually uses device interrupts to help it schedule events. For instance, the clock-timer device (XVME 203) uses interrupts to provide RCI with its own private timing base.

If for some reason a bus adaptor is absolutely incapable of providing interrupts, you can probably still survive if you set the scheduling discipline for all RCI tasks to ON_CLOCK (you'll recognize this term if you've read the RCI/RCCL documentation). Under this scheduling discipline, an RCI task is simply run periodically by the system clock; once woken up, it is then free to access or poll external devices as necessary. The penalty paid is one of efficiency. For instance, if you run RCCL using ON_CLOCK, the control task has to ?wake up? the robot controller and then wait two or three milliseconds for the controller to gather its feedback data and respond. The latter delay can be avoided using the ON_TRIGGER scheduling discipline, which uses interrupts.

4.4 SGI IRIX Kernel Configuration

The real-time support for SGI systems is even easier to install than that for Sun4 systems. There are two reasons for this: (1) the IRIX kernel provides more intrinsic real-time support, and (2) the kernel configuration procedure on the SGI is much more streamlined.

The supplied kernel support should work with IRIX 4.0.X, although it will probably work with releases higher than this.

RCCL/RCI Release 4.2, July 30,1992

26 4. ADDING REAL-TIME SUPPORT TO THE SYSTEM KERNEL

4.4.1 What the reader should know

The reader is assumed to be familiar with configuring system kernels. Some familiarity with writing device drivers would also be an asset. SGI provides documentation on writing device drivers (although you have to ask for it specially), but is somewhat weak on providing documentation on how to reconfigure the kernel. Nevertheless, the procedure is straightforward, and hopefully the instructions here are sufficient.

4.4.2 Unpacking the modules

In the RCCL distribution tape, there is a directory labeled sys.SGI, which in turn contains a subdirectory rciext.

The rciext directory contains the kernel-level support code for RCI, and is also used as the base directory for re-configuring the kernel. A copy of this directory should be made in /usr/sysgen.

The file rciext/README contains a synopsis of the instructions given here. In case of conflict, the README file will usually be more accurate.

4.4.3 Editing the system config file

You need to edit the system configuration file to identify the various device drivers to be loaded into the system. There is a generic device driver for all RCI systems, plus specific device drivers for each type of hardware interface. The standard distribution supplies drivers for the XYCOM XVME 240 parallel port and the BIT3 411 VME to VME bus adaptor. If you have different hardware, then you will need to write your own device driver, and configure it into the kernel in the same way as described below. The easiest way to write an RCI device driver is to clone an existing one.

Information on the system configuration file can be obtained from the system manual page system(4).

Start by creating a private configuration file: copy the file /usr/sysgen/system to /usr/sysgen/rciext. Then add the contents of sys.SGI/master.d/system.RCI to the end of it. system.RCI contains the following entries:

INCLUDE: genrci(4)

VECTOR: module=xyd vector=<vect> ipl=<ipl> unit=0 base=<baddr>
probe=<baddr+0x81> probe_size=1

VECTOR: module=bit vector=0xff ipl=<ipl> unit=0 base=<baddr>

Undesired entries should be commented out using a star (*).

The genrci entry declares the generic RCI device driver; this is the standard kernel-level RCI interface and should always be included.

The xyd entry describes the driver for a XYCOM XVME 240 parallel port. Include this entry if your hardware configuration contains such a device. <vect> should be set to an unused interrupt vector. <ipl> should be set to the desired IPL level (4 is a reasonable value). <baddr> should be set to the memory address at which the system can find the board. This will be the base address in

RCCL/RCI Release 4.2, July 30,1992

4.4. SGI IRIX KERNEL CONFIGURATION 27

the VME A16D16 (short I/O) space, added to the system memory address for the VME A16D16 space itself. The value of the former depends on what you set the board to (0x9000 is a common value), while the value of the latter depends on your SGI system. The SGI device driver manual documents the following values for various system types:

System CPU/type VME A16 base address (supervisor)

R2300 0xbd000000 IP4/6 0xbd000000 IP5/7/9 0xb7c10000

Address information may be contained in the system file itself, as well. The address associated with the probe field gives the address of a location used by the driver's probe routine; this should be set to <baddr> plus 0x81.

The bit entry describes a driver for a BIT3 411 VME to VME shared memory board. Include this entry if your hardware configuration contains such a device. The vector field must be set to 0xff, since this is the only vector the device can generate. <ipl> should be set to the desired IPL level, and <baddr> should be set to the address of the device's I/O registers in VME A16D16 space. The probe and probe_size fields do not need to be set.

4.4.4 Major device numbers

Each of the device drivers configured into the kernel has a synopsis file located in the directory /usr/sysgen/master.d. Each device has a prefix and a major device number defined by the fields PREFIX and SOFT in the synopsis file. These are used by the kernel to keep track of the devices internally, and are also used to generate the special files which provide user level access to the devices (more on this is given below).

The synopsis files for the supplied RCI device drivers are packaged into the directory rciext/master.RCI (and are later copied into master.d by the make command which builds the system). If you have written a device driver yourself, then you will have created your own synopsis file.

It is necessary that the prefix and major number for any devices being introduced into a new kernel do not conflict with existing devices. A conflict is unlikely, but the possibility should be kept in mind.

4.4.5 Editing the mem file

RCI, by default, maps a certain portion of the VME bus space into user space for direct access by RCI applications. A description of the sections that are to be mapped must be placed in the file /usr/sysgen/master.d/mem. Edit this file, and add to the array mmmap_addrs all the entries described in rciext/master.RCI/mem which are appropriate to your system. There is documentation in master.RCI/mem describing what to include.

RCCL/RCI Release 4.2, July 30,1992

28 4. ADDING REAL-TIME SUPPORT TO THE SYSTEM KERNEL

4.4.6 Building the kernel

Now you should be able to execute the following sequence:

% cd /usr/sysgen/rciext
% make unix.new

to build a new UNIX kernel called unix.new.

NOTE: This procedure will install new files in /usr/sysgen/master.d, and create symbolic links to /usr/include/sys and /usr/sysgen/boot in the sysgen/rciext directory.

The new kernel can now be installed by copying it into /unix. Saving a copy of the previous kernel is highly recommended in case the new kernel will not boot.

NOTE: When UNIX reboots, it may ask you if it should reconfigure itself automatically. You should answer no to this request, since the new UNIX has been configured privately in the rciext directory and the auto-configure procedure will not know to look there.

4.4.7 Creating device entries

You now need to go to the directory /dev and create a special file for each device which you have configured into the system.

All devices provided with the distribution are character devices, and their corresponding special files are created with the following usage of the command mknod:

% /etc/mknod <filename> c <major> <minor>

<filename> is usually the same as the device driver name, plus a number at the end indicating the unit number (which usually starts at 0). <major> is the major device number (the SOFT entry in the synopsis file) and <minor> is the unit number.

NOTE: On SGI systems, we do not overload the minor device number the way we do on Sun systems.

A special file genrciX should be created for every RCI generic pseudo-device. The commands to set up four such devices, if the major number were 60, would be:

% /etc/mknod /dev/genrci0 c 60 0 % /etc/mknod /dev/genrci1 c 60 1 % /etc/mknod /dev/genrci2 c 60 2 % /etc/mknod /dev/genrci3 c 60 3

A special file must also be created for each interface device. The corresponding special file usually takes the name of the device driver (check the PREFIX entry in the synopsis file), plus a trailing ?RCI? and the unit number. For example, the special file for unit 0 of the xyd interface can be created with a command which looks like:

RCCL/RCI Release 4.2, July 30,1992

4.5. THE RCICHECK PROGRAM 29

% /etc/mknod /dev/xydRCI0 c 61 0

After the special files have been created, make sure that they have world read-write permission; you can use the command chmod for this.

4.5 The rciCheck Program

After you have built the kernel and installed all the necessary devices, you can verify that things are working correctly by compiling and then running the program rciCheck, located in $RCCL/rci. (You will need to have built the main RCCL directory first.) rciCheck can be built within the rci directory using the command

% make rciCheck

The program will start up an RCI control task and run it through some operations in an attempt to verify that the basic RCI kernel support is operational. It will print some messages while it is doing this, and then terminate (if all goes well) with an OK message. The first time you run rciCheck, you should probably also run the script syncs in the background. syncs, which is also located in $RCCL/rci, make continuous calls to the system disk-sync command, thus reducing the chance of file system problems if the system does in fact crash.

rciCheck should also be run with the -crash option. This will cause the program to go through the same initial checks, but at the end it will terminate by forcing an exception within the control code. The purpose of this is to check out the control level exception handling mechanism. On MicroVAX and Sun4 systems, this should result in a message like

Program Crash on arbiter, generic RCI device

followed by a numeric stack trace. On SGI systems, you should simply get a message like

Program crash in RCI control level. Check core file.

On VxWorks, you should get a VxWorks exception message and the suspension of the VxWorks task rciCtrl, which implements the RCI control level.

5. Configuring the RCCL/RCI Software

This section discusses configuring an RCCL/RCI system. Most of this involves specifying the parameters, operating characteristics, and interfaces for the robots that are attached to the system. The system currently supports robots of the type (or class) PUMA, STAN (the Stanford arm), and ELBOW (the ?elbow? manipulator). Other types may have been added since this writing. Adding a new class of robot to the system is discussed in section 7.

NOTE: If you are setting up a VxWorks system, then you should read the auxiliary
document RCCL/RCI on VxWorks as well.

RCCL/RCI Release 4.2, July 30,1992

30 5. CONFIGURING THE RCCL/RCI SOFTWARE

5.1 Review of Basic Concepts

The robot support facilities used by RCCL/RCI are a component of the RCI subsystem. Most of what is described here is also described in the RCI User's Guide and the RCI Reference Manual.

5.1.1 Robot classification

A robot configured into the RCI system is given a symbolic name and is associated with a particular class of robots (such as PUMA, STAN, or ELBOW). Classes are defined in the file h/robot_class.h. Each class of robots is associated with
1. A set of robot-specific parameter structures (and functions to create them);
2. A set of kinematic and dynamic computation functions.

5.1.2 Robot parameter structures

Parameter information for a robot is defined by three data structures.

1. The JLS structure ? This contains a ?joint level? description of the robot, including such things as the gear ratios, joint and velocity limits, encoder to joint value conversion factors, and joint level calibration information. It also contains pointers to special functions for doing operations such as mapping from actuator (encoder) values to joint values (see section compfunc.sec). The definition of the JLS structure is identical for all classes of robot, and is contained in h/robot_jls.h. For more information on the JLS structure and how to obtain it, see JLS(3) and getJls(3).

2. The KYN structure ? This contains ?kinematic level? information for the robot in question. The KYN structure contains pointers to two data areas: gen and ext. gen references a structure of type GEN_KYN, which defines a fixed set of parameters which are applicable to most robot types. The ?A? matrix parameters, and some dynamic modeling coefficients, fit into this category. A field class contains the class of the robot as defined in h/robotClass.h. The GEN_KYN structure also contains a set of functions, whose implementation is specific to the robot class, for doing various kinematic and dynamic computations (see section 5.1.3). ext references a separate data area whose definition is specific to the robot class. This can include special-case parameters used by the kinematic and dynamic computation functions. The KYN ext structure for a particular robot has the name <class>_KYN, and is defined in h/<class>_kynvar.h. For more information on the KYN structure and how to obtain it, see KYN(3) and getKyn(3).

3. The VAR structure ? The purpose of this structure is to serve as a ?scratch pad? for robot computational routines. It provides a place to store interim computational results, which can then be used by other routines to save time. For instance, for many robots, the VAR structure is used to store the sines and cosines of the joint angles, which are produced as a by-product of forward and inverse kinematic computations. These values can then be used by other routines (usually during the same control cycle), such as those which do Jacobian or

RCCL/RCI Release 4.2, July 30,1992

5.1. REVIEW OF BASIC CONCEPTS 31

dynamic computations. The type of the VAR structure depends on the class of the particular robot. For any given class, the VAR type has the name <class>_VAR, and is defined in h/<class>_kynvar.h. A program must allocate its own VAR structures for a particular robot, using the size returned by the routine getVarSize(). For more information on the VAR structure, see VAR(3) and getVarSize(3).

5.1.3 Computation Functions

5.1.3.1 JLS conversion functions

The JLS structure contains pointers to functions that do conversions between joint and actuator coordinate systems. These functions include:

encoderToAngle (ang, enc, jls) angleToEncoder (enc, ang, jls) encoderToJoint (jnt, enc, jls) jointToEncoder (enc, jnt, jls) mtorqueToJtorque (jtor, mtor, jls)
jtorqueToMtorque (mtor, jtor, jls)

Generic versions of these functions, which will work for all classes of robots, are defined in robots/gen_convert.c and are documented in the RCI Reference Manual. The reason for having class-specific versions as well is that they can be implemented much more efficiently.

5.1.3.2 Kinematic functions

The GEN_KYN substructure of the KYN structure contains pointers to class-specific functions for implementing the following generic routines:

fwdKinematics (t6,cp,j6,kyn,var)
invKinematics (j6,t6,c,refj,kyn,jls,var)
solveConf (cp,j6,kyn)

fwdJacob (dc,dj,j6,kyn)
invJacob (dj,dc,j6,kyn,epsilon)
fwdJacobT (t,f,j6,kyn)
invJacobT (f,t,j6,kyn,epsilon)

gravload (t,j6,kyn)

fwdJacobVar (dc,dj,var,kyn)
invJacobVar (dj,dc,var,kyn,epsilon)
fwdJacobTVar (t,f,var,kyn)
invJacobTVar (f,t,var,kyn,epsilon)
gravloadVar (t,var,kyn)

RCCL/RCI Release 4.2, July 30,1992

32 5. CONFIGURING THE RCCL/RCI SOFTWARE

updateVar (var,ang,kyn)
updateVarXsincos (var,ang,kyn)

The implementation functions take the same arguments as the routines. Note that they all take a pointer to the KYN structure as an argument. Each function has a manual page in the RCI Reference Manual explaining exactly what it does.

These function definitions are adequate for any six degree of freedom robot. Controlling robots with more degrees of freedom will probably require that the function set be generalized to allow the incorporation of strategies for resolving kinematic redundancies.

5.1.4 Robot communication functions

Each robot class defines a set of communication functions which is used to handle the communication between the RCI control task and the robot controller. There are six of these functions:

startup (rbt)
input (rbt)
output (rbt)
release (rbt)

ready (arg)
wakeup (arg)

Their definitions are given in detail in the RCI User's Guide and also in the manual page robotComfxns(7).

The job of the communication functions is to maintain the HOW structure, send commands to the robot, and perform limit checking. How this is done is basically up to the functions themselves. Each of the first four functions takes a pointer argument to a robot descriptor rbt (type RCI_RBT), which contains pointers to all the robot parameter structures as well as the communication functions. The ready and wakeup functions are called with argument values that are stored in the rbt structure and are set by the startup function?.

5.1.5 RCI I/O driver

The robot communication functions usually perform data transfers with the robot controller using an RCI I/O driver, which implements a standard set of communication routines for a particular type of communication hardware. This allows the robot interface functions to be independent of the communication hardware. An RCI I/O driver contains the following nine routines:

read (dev, buf, size)
write (dev, buf, size)
readTest (dev)
writeTest (dev)
?This is done to allow these functions to be specified directly as the trigger or wakeup functions for an RCI task.

RCCL/RCI Release 4.2, July 30,1992

5.1. REVIEW OF BASIC CONCEPTS 33

signal (dev, num)
probe (dev)
attach (dev)
detach (dev)

ioctl (dev, cmd, buf)

These routines are referred to by pointers in the data type IO_DEVICE, which is defined in h/IOdevice.h. Detailed specifications for the routines can be found in the section on device drivers in the RCI User's Guide, and also in the manual page IOdevice(7). A separate IO_DEVICE structure is assigned to each physical device associated with an RCI I/O driver.

RCI device routines do their I/O by accessing the system bus directly; they do not make use of any UNIX system calls. They can't because RCI tasks execute independently of UNIX. Each RCI task executes at high priority (possibly with interrupts disabled) and runs to completion. Tasks are normally executed either periodically or on the occurrence of a specific event interrupt. This implies that RCI device functions must do their work immediately; the device model contains no buffering and no interrupt routines. It is possible to poll the other end using the readTest() or writeTest() routines. One of these polling routines can be given to the RCI scheduling monitor to use as a test to see whether or not an RCI task is ready to run.

Each RCI device is usually given a short alphanumeric name and is defined in a file called drivers/XXXDriver.c, where XXX denotes the driver name. An include file, defining bit codes and structures used by the driver, is usually located at h/XXXDevice.h. A table of all the devices is contained in the file drivers/IOdriverTable.c

5.1.6 RCI UNIX devices to provide polling interrupts

RCI tasks are usually run on the occurrence of either an RCI clock tick or an external interrupt. If the RCI task is running on the UNIX CPU, then external interrupts must first pass through the UNIX interrupt mechanism. This involves catching the interrupt within the handler of a UNIX device driver, which then gives control of the CPU to RCI. In terms of communication, the UNIX driver provides no other functiony.

The hardware associated with an RCI I/O driver is usually capable of providing interrupts to the UNIX CPU. In order to use these interrupts to wake up the RCI control task, an RCI UNIX driver should be installed to catch them. For instance, the XYCOM XVME 240 digital I/O module is commonly used to communicate between Sun4 host systems and the Unimate robot controller. The robot controller can wake up the RCI task by sending an interrupt through the XVME 240; this interrupt is caught by the RCI UNIX driver for the XVME 240, which is called xyd and which lives in sys/rciext/xyd.c. Once the RCI task is running, the actual data communication is handled using the xyd RCI I/O driver, which is defined in drivers/xydDriver.c.

NOTE: It is important to understand the difference between the two types of drivers
just discussed. RCI I/O drivers are used by RCI tasks to read and write data, are

yIn fact, it would probably be possible to have RCI patch the system vector table directly, so that you wouldn't have to go through the UNIX interrupt mechanism at all and no UNIX device drivers would be needed. We may do this in the future.

RCCL/RCI Release 4.2, July 30,1992

34 5. CONFIGURING THE RCCL/RCI SOFTWARE

defined in the RCCL drivers directory, and are part of the RCCL/RCI library. UNIX RCI devices are stripped down UNIX device drivers whose main purpose is to catch external interrupts for waking up RCI control tasks. They are configured into the running UNIX kernel.

5.1.7 Communication software in the robot controller

For RCI to be able to communicate with a particular robot controller, there must be a communication program running in the controller which can talk to the RCI I/O driver and (one level higher) the robot communication functions.

For Unimate Mark I, II, and III robot controllers, this communication program is called moper, and it is loaded into the Unimate controller where it replaces the manufacturer supplied VAL software.

5.2 Adding a Robot to the System

This section outlines, in some detail, the procedures necessary for configuring a new robot into the RCCL/RCI system. It is assumed that the class of the robot is already defined, which means the various interface functions described in section 5.1 already exist.

5.2.1 Updating the robot data table

The first thing one must do is assign the robot a name. The robot should then be given an entry in rciRobotDataTable, located in robots/robotDataTab.c. Each entry in this table contains the following fields:

1. The robot's name.

2. The robot's class, as defined in h/robotClass.h.

3. Two class-specific functions, named <class>_jls and <class>_kyn, which are used internally by the system to help instantiate the robot's JLS and KYN structures. (For details, see getJls(3).)

4. The sizes of the two class-specific data types <class>_KYN and <class>_VAR, which are defined in the file h/<class>_kynvar.h.

5. The startup, input, output, and release robot communication functions. These are often specific to a robot's class, but because they tend to depend as much on the robot's controller as on the robot itself, it is sometimes useful to define separate interface functions. If your robot is only going to be run with the simulator robotsim, or is being controlled by any Unimation Mark I, II, or III controller, then you can use the ?generic? communication functions defined in robots/gen_comfxns.c.

As an example, the rciRobotDataTable entry for a PUMA robot attached to a Unimation Mark X controller typically looks like this:

RCCL/RCI Release 4.2, July 30,1992

5.2. ADDING A ROBOT TO THE SYSTEM 35

"frank", PUMA, puma_jls, puma_kyn,
sizeof(PUMA_KYN), sizeof(PUMA_VAR),
puma_startup, puma_input,
puma_output, puma_release

An entry for a robot of class STAN that uses the generic communication functions would look like

"stan0", STAN, stan_jls, stan_kyn,
sizeof(STAN_KYN), sizeof(STAN_VAR),
gen_startup, gen_input,
gen_output, gen_release

After robotDataTab.c has been updated, you should run the command

% make libs

in the robots directory. This will compile the data table and reinstall it in the RCCL/RCI library. The robot will be given an ID number equal to its table index plus 1; this is the number that is returned by the routine find_robot().

5.2.2 Updating the robots file

A file called robots, in the directory $RCCL/conf, describes the RCI I/O devices and the RCI UNIX devices which are used by the robots to communicate with their controllers. The entry for each robot contains the following fields: the name of the robot, the name of the RCI I/O driver used to exchange information with the robot controller, the address of the device associated with the driver, and the name of an RCI UNIX device that provides a polling interrupt (needed only if RCI is being run on the main UNIX CPU). Some optional arguments may also be included for the RCI I/O driver.
Update this file as follows:

1. Specify the name of the robot with a field of the form

name = <robotName>

NOTE: All of the remaining fields can be omitted if the robot is only to be run in simulation mode.

2. Specify the RCI device driver with a field of the form

device = <driverName>

<driverName> should be one of the RCI I/O devices specified in the file IOdriverTable.c. Commonly used devices include pri, which is for DRV11s on MicroVAX systems, and xyd, which is for XYCOM XVME 240s on Sun4 systems.
3. Specify the device's address with a field of the form
address = <number>

RCCL/RCI Release 4.2, July 30,1992

36 5. CONFIGURING THE RCCL/RCI SOFTWARE

The address is an integer that specifies the physical location of the device. Usually, this will be a bus address. It can be specified in either octal, decimal, or hex (using the conventional C syntax).

4. Specify a UNIX device that provides a polling interrupt which can be used by any RCI task controlling the robot. The field should be of the form

interrupt = <UNIXdevice>

This field can sometimes be omitted; it is necessary only when the robot is controlled by an RCI task running on the main UNIX CPU.

5. Specify any arguments needed by the device driver with fields of the form

arg<n> = <argvalue>

where <n> is in the range 0 to MAX_DEVARGS ? 1 and <argvalue> is an integer (in either decimal, octal, or hex). These fields are necessary only if the device driver requires additional argument information (which is not the case with the pri or xyd drivers). For instance, the driver for a shared memory board with multiple address spaces might need extra information: the address field might describe the location of a control-status register, and additional arguments could give the base addresses of the actual shared memory regions. Argument values appear in the args field of the per-device dev structure (see IOdevice(7)). They are set to UNDEF if not defined in the robots file.

As an example, consider the following robots file entry for the robot ?frank?:

robot=frank device=xyd address=0x9000
interrupt=/dev/xydRCI0

This indicates that frank is interfaced to its robot controller using the driver xyd for a device located at 0x9000, and a polling interrupt delivered by the RCI UNIX device /dev/xydRCI0.
As indicated above, only the robot name needs to be indicated if the robot is to run only in simulation. In that case, the entry

robot=frank

would do quite nicely.

IMPORTANT: For robots run on VxWorks systems, the file conf/robots.vxw is used instead of conf/robots. Also, some additional information fields are required to specify interrupt information for the I/O device. See the manual RCCL/RCI on VxWorks.
More information on the robots file can be found in the manual pages.

RCCL/RCI Release 4.2, July 30,1992

5.2. ADDING A ROBOT TO THE SYSTEM 37

5.2.3 Creating a .jls file

The .jls file for a robot, which lives in conf/<robotName>.jls, describes the information used to build the robot's JLS structure.

On most versions of RCI, the ascii .jls file is first compiled into a binary file (which takes the prefix .JLS), before being read by application software. This compilation is done automatically using the program makejls whenever the .jls file is seen to have been updated. The binary .JLS file is not used for VxWorks systems, because binary data may not be compatible between the VxWorks host and target systems. Use of the binary .JLS file may be phased out altogether in later RCCL/RCI releases.

Basically, the .jls file contains information describing a robot at the ?joint level?: the number of joints, the gear ratios, joint range and velocity limits, etc. It also contains the information necessary for calibrating the robot.

Detailed informationon each particular field can be found in JLS(3) and makejls(3). General information on the format of the file can be found in makejls(3). The amount of information can be daunting, but it should be understood that some fields are not always used, and so the corresponding information can be set to zero.
A template .jls file is contained in conf/template.jls.

5.2.3.1 Making a .jls file for a PUMA robot

Creating a .jls file for a PUMA robot is fairly easy because one can basically clone an existing file.

Assume that your new robot is named ?frank?. Then go to the conf directory and create the file frank.jls by copying either puma260.jls, puma560.jls, or puma760.jls, depending on whether frank is a PUMA 260, 560, or 760.

At this point, frank.jls should be roughly correct, but the calibration information will be wrong. RCCL/RCI applications should run, but the angles may be off by a few degrees. Current control may be a bit off as well; this is used by programs such as free, zerograv, and the free joint mode of teachdemo.

To calibrate the .jls file properly, you need to pay attention to the following fields. Some fields may not apply to your system; in that case, you can either leave the values alone, or set them to zero.

encCalvec These values are used by the robot calibration routine and should be measured using the program primecal (see section 5.6.1).

encHome This field is used only if your robot is a PUMA 260, in which case it should contain the encoder values for the nest position (only PUMA 260s have nests). Once the arm has been initially calibrated (using primecal, for instance), you should put it into the nest, read back the encoder values, and then enter them into this field. You can put the robot into the nest using a program such as free or zerograv. The contents of the field are used by the program pumacal when calibrating the robot from the nest.

RCCL/RCI Release 4.2, July 30,1992

38 5. CONFIGURING THE RCCL/RCI SOFTWARE

potSlope, potIntercept
For robots which have potentiometers (i.e., the PUMA 560 and 760), the contents of these fields should be set to the values measured by the program potcal, which should be run soon after the robot is first calibrated using primecal (see section 5.6.2).

mtorqueToCurrent, currentBias
The values in these fields describe the conversion used to turn a specified actuator torque into an output DAC value. The values given in the generic files puma260.jls, puma560.jls, and puma760.jls are roughly correct for each robot, but you may need to ?tune? the values to get current controlled programs like zerograv to work properly. See section 5.6.3 for information on how to adjust these these values ?by eye?. Most supplied RCCL/RCI programs do not use current control, so you may not want to worry about this for now.

currentToMtorque
This field needs to be set only if your system is instrumented to measure motor currents or torques. This is usually done by having the moper software in the robot controller measure the joint actuator torques using an analogto-digital converter. (For information on setting up the hardware to do this, see the RCCL/RCI Hardware Installation Notes). The contents of this field are used by RCI to convert the ADC values returned by moper into motor torques. See section 5.6.3 for information on how to determine these values.

forGearRatios, encWheelSize
The default information supplied in puma260.jls, puma560.jls, and puma760.jls is almost always correct for these fields. (A detailed description of what they represent is given in section 5.2.3.3.) In pathological cases, however, the information may be wrong for one or more joints. The symptoms of this are that the corresponding joints don't seem to move by the amount requested; for example, a motion request of 90 degrees may in fact produce a motion of around 80 degrees. In these cases the proper values need to be obtained, either from the manufacturer, or by measuring them using some ad-hoc method. The program primecal can be useful here, because it allows joint motions to be specified in either angle or encoder coordinates.

Finally, you may wish to set or change some of the maximum or nominal operating values described in section 5.2.3.4.

5.2.3.2 Making a .jls file for a simulated-only robot

Robots of the class STAN and SCARA are currently supported in simulator mode. To create a .jls file for one of these, you can simply copy one of the generic files scara.jls or stan.jls.

If you are making a .jls file from scratch, and the robot will run only in simulation, then much of the information can often be faked if necessary:

RCCL/RCI Release 4.2, July 30,1992

5.2. ADDING A ROBOT TO THE SYSTEM 39

encCalvec, encHome, potSlope, potIntercept
There is usually no need to worry about setting these fields because simulated robots start up in a known position and are therefore already ?calibrated?.

mtorqueToCurrent, currentBias, currentToMtorque
These fields can usually be set to some reasonable ?fake? values because (a) the simulator program may not do anything interesting with current control commands, and (b) even if it does, it will probably use the information in these fields to do its own internal computations, thereby ensuring that everything is consistent. Setting the values of mtorqueToCurrent to 1000.0 for large joints and 4000.0 for small joints usually works. currentBias values are set to 0, and the currentToMtorque values can be set to the inverse of the mtorqueToCurrent values.

forGearRatios, encWheelSize, encOffset
These fields describe the relationship between joint and encoder coordinates (for more information, see section 5.2.3.3). On a purely simulated robot one can often fake these values, providing the simulator program itself is using the JLS structure to obtain the same information. Setting the encWheelSize values to 1000 and the forGearRatios to 50.0 for rotary joints, or .05 for prismatic joints, is often resonable. The number of gear couplings is usually set to zero. About the only real constraint is to keep the joint values within the encoder range. This means that for each joint, the product of its encWheelSize value, forGearRatios value, and range (in revolutions for a rotary joint or millimeters for a prismatic joint) should not exceed 2N , where N is the number of encoder bits. The encOffset field should also be specified so that the joint range midpoint is close to the encoder range midpoint 2N?1.

5.2.3.3 Making a .jls file for a general robot

For any robot, the easiest way to create a .jls file is to clone an existing .jls file for a robot of the same class.

If you are creating a .jls file for a robot from scratch, then you may have to pay more attention to the fields at the top of the file, which define the number of joints and their type, the number and locations of joint to actuator couplings, the gear ratios, and the encoder wheel sizes. A good knowledge of the robot's mechanics is necessary in order to set these fields correctly.

The forGearRatios, encWheelSize, and encOffset entries in the file describe the relationship between joint and encoder coordinates. (In some cases, the interface from RCI to the robot controller may be based entirely on joint coordinates, and encoder values may not play a role. In this case, these fields can be faked, as described in section 5.2.3.2.)

The forGearRatios field describes the (mostly diagonal) coefficients of the gear ratio matrix that maps joint coordinates to motor shaft coordinates (e.g., joint revolutions to motor revolutions). Let this matrix be called G. encWheelSize describes the number of encoder counts per motor revolution. Let these form the coefficients of a diagonal matrix W. The relationship between

RCCL/RCI Release 4.2, July 30,1992

40 5. CONFIGURING THE RCCL/RCI SOFTWARE

joint coordinates (given by a vector j) and encoder coordinates (given by a vector e) can then be expressed as
e = W G j + e0

where e0 is an offset vector whose values are determined by the entries in the encOffset field. Each entry in this field consists of an encoder value, followed by its corresponding joint value. This specifies one complete set of encoder values e0 and corresponding joint values j0. e0 is then computed from
e0 = e0 ? W G j0

e0 and j0 are usually chosen so as to place the joint range midpoint near the encoder range midpoint (which is 32768 for a 16 bit encoder; note the encoder values are always positive). This helps ensure that all the joint values will remain within the range of the encoders if the gear ratios or wheel size information is changed.

Sometimes, the robot controller interface may not support position calibration. Calibration in these cases is usually done locally by the robot controller without any RCI involvement. In such situations, the calibration information supplied by the encCalvec, encHome, potSlope, and potIntercept fields can be left unspecified.

It is also necessary to furnish a park position and a best position for the robot (in the fields parkAngles and bestAngles, respectively). The park position describes a default location for the robot to move to when it is idle; this location may be used occasionally by RCCL/RCI software. The ?best? position is some location where the manipulator Jacobian is well conditioned; this location is also referenced occasionally by RCCL/RCI software. The park and best positions are frequently defined to be the same.

5.2.3.4 Setting limit values in the .jls file

Several of the fields in the robot's JLS structure are used to specify various limit values. Other fields are used to indicate the nominal operating values. These fields can be tuned as necessary for a particular robot, and the values can be referred to by application software.

jmin, jmax The maximum joint ranges (in degrees or millimeters). These are used by the low-level RCI checking options CHK_REQPOS and CHK_MAXPOS; see SET_CHECKING(3).

maxVel, maxAcc, maxJerk
These fields indicate the maximum allowed values on velocity, acceleration, and jerk for each joint. maxVel is used by the low-level RCI checking options CHK_REQVEL and CHK_MAXVEL; see SET_CHECKING(3). At the time of this writing, no supplied RCCL/RCI software makes use of the maxAcc or maxJerk fields (acceleration information is taken from the nominalAcc field; see below).

maxMtorque, maxJtorque
These fields indicate the maximum allowed torques that may be applied to each joint at the motor shaft and joint levels, respectively (i.e., before and after the gear train). maxMtorque is used by the low-level RCI checking

RCCL/RCI Release 4.2, July 30,1992

5.2. ADDING A ROBOT TO THE SYSTEM 41

options CHK_REQTOR and CHK_MAXTOR (the latter only if current or torque feedback is implemented); see SET_CHECKING(3). No supplied RCCL/RCI software makes use of the maxJtorque field at the time of this writing.

nominalVel, nominalAcc, nominalJerk
These fields represent nominal ?desired? values for the velocity, acceleration, and jerk of the robot joints. Modifying the contents of these fields can cause those programs which refer to them to change behaviour. For instance, lowering the values in nominalVel will cause programs which obtain their velocity setpoints from this field to move the robot more slowly. The nominalVel and nominalAcc fields are used by the RCCL and CHASE trajectory generators to determine reasonable trajectory profiles. No supplied software uses the nominalJerk field at the time of this writing.

5.2.4 Creating a .kyn file

The .kyn file for a robot, which lives in conf/<robotName>.kyn, describes the information used to build the robot's KYN structure.

As currently implemented, the .kyn file contains information pertaining to the kinematic and dynamic aspects of the robot. In principle, the contents of the .kyn file depend on the robot's class (since part of the KYN structure itself is class-specific).

For the PUMA, STAN, and ELBOW classes, this file contains (1) the ?A? matrix parameters, (2) the gravity loading coefficients, and (3) a rough friction model. Only those ?A? matrix parameters which are relevant to a particular class are specified; this is also true of the gravity coefficients. In the next release of RCCL/RCI (most likely), joint inertia information will be included as well.

5.2.4.1 Making a .kyn file for a PUMA robot

Creating a .kyn file for a PUMA robot mostly involves copying a file.

Assume that your new robot is named ?frank?. Then go to the conf directory and create the file frank.kyn by copying either puma260.kyn, puma560.kyn, or puma760.kyn, depending on whether frank is a PUMA 260, 560, or 760.

Occasionally, the ?A? matrix parameters in the file are ?out? by a few millimeters. This occurs because of minor variations in different versions of PUMA robots. If you happen to know a-priori the exact ?A? matrix parameters for your robot, then you should replace the default values in the .kyn file. Note also that there are two versions of the PUMA 760: the 761 and the 762. The parameters in puma760.kyn are actually for a PUMA 762. The PUMA 761 has a longer forearm. With regard to the gravity loading and friction information, see section 5.2.4.3.

5.2.4.2 Making a .kyn file for a general robot

As with the PUMA robot, the easiest way to create a .kyn file for a particular robot is to clone an existing .kyn file for a robot of the same class. It may be necessary to change ?A? matrix parameter values.

RCCL/RCI Release 4.2, July 30,1992

42 5. CONFIGURING THE RCCL/RCI SOFTWARE

Generic .kyn files for the Stanford and ?elbow? manipulators (classes STAN and ELBOW) are contained in the files stan.kyn and elbow.kyn.

5.2.4.3 Gravity loading and friction information

Within .kyn files for the presently implemented robot classes, gravity loading terms are described by parameters of the form CP<XX>, where <XX> indicates joint and index numbers. Static, Coulomb, and viscous friction terms are described by parameters of the form STATF<n>, COULF<n>, and VISCF<n>, where <n> is the associated joint number.

It is sometimes not possible to determine the gravity loading and friction terms for a robot. In this case, one can either use approximate values (often taken by copying the information for an identical robot), or set the values to zero. Static and Coulomb friction terms can often be set equal. Do not worry too much about the gravity or friction information, since very little of the supplied RCCL/RCI software actually uses it. See section 5.6.3.

Unfortunately, no supplied software presently exists for auto-calibrating the gravity loading and friction terms.

5.2.5 Creating a .pos file

The .pos file for a robot, which lives in conf/<robotName>.pos, gives a list of named positions in joints coordinates. These positions are referenced by the routine getRobotPosition(3). The only position which is routinely referenced by application software is ?rcclpark?, which is the starting point for some RCCL demo programs.

A .pos file for a new PUMA can be created by copying either puma260.pos, puma560.pos, or puma760.pos, as appropriate.

5.3 Other Configuration Files

Other files contained in the directory $RCCL/conf that you may want to have a look at include:

defaultRobot
Contains the name returned by the routine getDefaultRobot(). This is used by some utility programs in case no robot name is specified in the argument list. It is particularly useful on systems that have only one robot.

.rcc The control file for the rcc command (q.v.), containing the names of all the libraries and include directories which are automatically referenced by rcc. It should not usually be necessary to change this file, but it is good to know that it exists. The file can be overridden by .rcc files contained in the user's home directory or the current directory. Its format is described in the manual page for rcc.

RCCL/RCI Release 4.2, July 30,1992

5.4. CONFIGURING MOPER FOR A UNIMATION MARK X CONTROLLER 43

5.4 Configuring moper for a Unimation Mark X Controller

The name moper identifies the communication software which is loaded into a Unimation controller, where it replaces VAL and serves as a communication interface between the robot joint servos and RCI on the host computer. Code for the moper software is located in the directory $RCCL/lsi11.

NOTE: moper will run on Unimation Mark I, II, and III controllers. It will not run on
the newer Unival controller.

5.4.1 Creating a moper for a new robot

This is definitely the most difficult aspect of configuring an RCCL/RCI system, because RCI depends on the low level joint servo interface inside the Unimation controller, and some aspects of this interface tend to vary from controller to controller.

The actual joint servo command interface is fairly consistent. What varies is the joint servo control code, and the associated control parameters. Normally, when VAL starts up on a particular controller, it loads some control parameters into the joint servos. Unfortunately, exiting VAL has the effect (on Mark II and Mark III controllers) of resetting the joint servos, and thereby clearing the loaded parameter values. Consequently, it is necessary for moper to load the servo parameters itself, and this requires knowing what they are and where they are located. The servo parameters may change depending on the version of the joint servo control software.

In the instructions immediately below, the parameters are guessed for a particular controller/robot combination, based on commonly occurring values. This frequently works. The alternative is to determine the parameters exactly by methods discussed in section 5.4.3.

5.4.1.1 Necessary system information

Before creating the moper, you need to know

1. What sort of PUMA you have (i.e., 260, 560, or 760). This should be clear.

2. What sort of controller you have. Mark III controllers are set in large upright cabinets. Mark II controllers come in a silver box, with a small row of switches along the top-front edge. Mark I controllers come in a silver box without a row switches along the top.

3. What type of CPU you have. This will be either an LSI11/03 (on Mark I controllers), an LSI11/23 (on early Mark II controllers), or an LSI11/73 (on later Mark II, and all Mark III, controllers). If your CPU is not an LSI11/73, you may want to consider upgrading; see the RCCL/RCI Hardware Installation Notes for details.

5.4.1.2 Creating the moper config file

The moper executable for a particular robot takes the same name as that robot. All mopers are compiled from the same set of source files, except for a robot-specific config file, <robotName>.c, that contains routines and tables specific to the robot in question.

RCCL/RCI Release 4.2, July 30,1992

44 5. CONFIGURING THE RCCL/RCI SOFTWARE

1. Copy a template file ? Go to the directory $RCCL/lsi11, and create the file <robotName>.c by copying either puma260.c, puma560.c, or puma760.c, as appropriate. For example, if your robot's name is ?frank?, and it is a PUMA 560, then you would do

% cp puma560.c frank.c

2. Edit the Imakefile ? Next, create an entry in the Imakefile which will build the moper program. Entries take the form

pdp11Program(<robotName>, $(MOPER) <robotName>.s <hostIO>.s)

where <hostIO> is the name of the driver which will interface to the RCI I/O driver; unless you wish to specify your own driver (as in section 5.7.2), this will almost always be drv11. The entry for the robot frank would look like

pdp11Program(frank, $(MOPER) frank.s drv11.s)

3. Do a test compilation ? After you have edited the Imakefile, rebuild the Makefile by running the command

% rmkmf

and then build the moper program by running

% make <robotName>

You now have a moper program named <robotName>, although it is probably not ready to run; you still need to configure the program as described in the next couple of sections.

5.4.1.3 Adjusting the config file

Now you should make some adjustments to the file <robotName>.c.
Before proceeding, take note that the three standard config files come pre-configured as follows:

robot name robot type controller cpu

puma260.c PUMA 260 Mark 1 LSI-11/73 puma560.c PUMA 560 Mark 2 LSI-11/73 puma760.c PUMA 760 Mark 3 LSI-11/73

1. Set the CPU ? If you are not using an LSI11/73, the include file lsi11_73.h should be changed to either lsi11_23.h or lsi11_03.h, depending on which CPU you have.

2. Set the ?hostIO? address ? This is the address and vector of the Q-bus interface device which connects the controller to the RCI system. As indicated above, this is almost always a DRV11. The address and vector are specified as arguments to the routine hostDevice(). These arguments should be set to whatever values have been set on the interface board. For details on setting the interface board, see the RCCL/RCI Hardware Installation Notes.

RCCL/RCI Release 4.2, July 30,1992

5.4. CONFIGURING MOPER FOR A UNIMATION MARK X CONTROLLER 45

3. Set the controller parameters ? This is the tricky part. Basically, there is no really good way to determine what these parameters are, since there are so many versions of the joint servo code in the various controllers. So an educated guess must be made based on the type of controller and robot you have.

Below the comment ?parameter defs:?, include one of the pre-defined parameter definition files which takes the form

<controller>.<robotType>.c

<robotType> should be either 260, 560, or 760, as appropriate. <controller> should be mk1_std for Mark I controllers or mk2_std for Mark II controllers. For Mark III controllers, use mk3_760 if you have a PUMA 760, or mk3_std otherwise. For example, if you have a PUMA 560 on a Mark II controller, you would specify

#include "mk2_std.560.c"

NOTE: if these control values are incorrect for your robot, it may track poorly, vibrate, or possibly jump. Be careful the first few times you start the robot up. Also, there could be difficulties when changing the control sample rate; change the sample rate and see what happens. If you have problems, refer to section 5.4.3.

4. Rebuild the new moper program.

Your moper program should now be ready to load into the Unimate controller using the down command.

Start by making sure that the controller's console line has been connected to a serial line unit on the host system (see the RCCL/RCI Hardware Installation Notes for information about this). Power on the controller and put its CPU into ODT as described in section 2.3.1. If the moper executable is called RobotX, and the console line is connected to /dev/RobotX, moper can be loaded using the command

% down RobotX -e 10000 -a 10000 -d /dev/RobotX

Notice that we have omitted the -t option described in section 2.3.1, so that down will go into direct communication with the controller console after the load is finished. This will allow us to see whatever messages are printed by moper after it is loaded. (To get out of down at this point, type a tilde (~) character.)
If all goes well, then you should get a message similar to
moper started

listening

If the teach pendant is connected, it should beep once or twice to indicate that moper is communicating with it as well. The moper program is now waiting for an RCCL/RCI program to connect to it.

If things do not go well, one possibility is that moper will crash with a ?panic? message and put the CPU into ODT. This almost always indicates that some Q-bus device specified in the moper

RCCL/RCI Release 4.2, July 30,1992

46 5. CONFIGURING THE RCCL/RCI SOFTWARE

config file does not exist. Test the specified device addresses (using ODT). In particular, test the address specified by hostDevice(). You can test a device address in ODT by entering it, in octal, followed by a slash (/). If there is nothing at that address, ODT will print a ?; otherwise, it will print the word contents of the address. On the LSI11/73 CPU, I/O addresses always have 22 bits, so you need to add another couple of ?sevens? to the leading digits. For example, to test the address 0177560, you would enter

17777560/

Another thing that may happen is that you get an error message about ?joint servo timeout? or ?error initializing memory?. This indicates that the joint servo control parameters may be incorrect, and you should see section 5.4.3

5.4.2 General description of the moper config file

The file moper config file <robotName>.c contains a number of parameters and switches which can be used to control various aspects of moper's operation. It also contains definitions and routines which manage the various sensor I/O features available in moper.

Most of these parameters should have the correct default settings so that the robot will run. However, you may need to make changes to configure certain types of sensor I/O into your moper.

5.4.2.1 Basic operating parameters

The variable robotType is set to the appropriate robot type as defined in armtypes.h. The variables robotID and moperID are not presently used for anything in particular, so you don't need to worry about them.

The variable potsAvail is set to 1 if the robot has calibrating potentiometers (which is true for the PUMA 560 and 760 robots), and 0 otherwise.

The variable pendantAvail should be set to 1 if the controller has a teach pendant, and 0 otherwise.

rbtComDelay is a delay count used when the LSI-11 is talking to the joint micro interface. Increase this value if you find that moper is getting timeouts while talking to the joint servos. This may happen if a CPU upgrade was performed and the new, faster CPU runs quicker than the interface can handle. The value required will probably be in the range 1 to 5. A delay value of 5 was needed in a PUMA 560 Mark II controller when an LSI-11/23 was upgraded to an LSI-11/73.

rbtTimeout is a spin-timeout count used by moper when talking to the joint servo interface. This should not be less than 400.

The next four variables control the automatic arm power-on software, and need to be set properly if you have wired up your controller to allow arm power to be turned on automatically (see the description of this in the RCCL/RCI Hardware Installation Notes). powerChan identifies which of the controller's two standard 16-bit output ports is being used to provide the power-on bit. powerBit is a mask identifying the bit within the port. powerNegative should be set ?true? if the power-on action is active low; i.e., turning the power on is achieved by clearing the bit. powerPulse is used if the power-on bit is to be pulsed instead of simply set; if powerPulse is set

RCCL/RCI Release 4.2, July 30,1992

5.4. CONFIGURING MOPER FOR A UNIMATION MARK X CONTROLLER 47

to a non-zero value, then the power-on bit will be asserted only for the length of time it takes the CPU to count to this value.

traceBit is a mask which specifies a bit to be set high whenever the moper control functions are active; this can be used for tracing on an oscilloscope. The output port used is the same one specified by powerChan. If you don't want a tracing bit, then set traceBit to 0.

intStretch is a parameter that can be used to stretch the position sample rate expected by the joint processors. Normally, you set the value of this variable to 1 (which means non-stretched). Giving it a value of X will tell the joint micros to interpolate the position commands sent to them over an interval that is X times longer than the interval at which commands are really being sent. This may make the robot move more smoothly at the expense of a little bit of lag.

The parameter definition file (included after the comment parameter defs: contains a few variables that describe the controller's clock: varClkRate should be set to 1 if the controller onboard clock needs to be set up by software (which is true for the Mark II and Mark III controllers), and 0 otherwise. If varClkRate is ?true?, then varClockParam describes a magic parameter that is used to set up the clockz. baseClkRate should be set to the base interval of the system clock, which is described in units of .1 msec. Generally, you set this to 28 (i.e., 2.8 msec.) if varClkRate is ?true?, and 70 (7 msec.) otherwise. jntClockRate is the sample interval of the control code running in the joint micro controllers, also in units of .1 milliseconds. From what we have seen, this should be set to 18 (1.8 msec.) for the PUMA 760, and 9 (.9 msec) otherwise.

5.4.2.2 Sensor I/O parameters and routines

The remainder of the config file defines the sensor I/O devices that are available for moper (and are hence available to the RCI interface; see HOW(3)).

The first set of variables indicates specific I/O features that are present. If any of these are set ?true?, then make sure that the feature is actually implemented by the corresponding interface routines at the end of the file.

jstickAvail should be set to 1 if the controller has a joystick interface. forceAvail should be set to 1 if the controller is connected to a force/torque sensor. torqueAvail should be set to 1 if the controller has implemented some way of reading back joint torques or currents (see the description for this in the RCCL/RCI Hardware Installation Notes). numADC is the number of general purpose analog-to-digital converter channels that are connected to the controller. Most controllers don't have any unless you add them explicitly, so this number will probably be zero.

The next set of variables describes the addresses of various I/O interfaces available on the controller.

pioOutAddr and pioInAddr are tables giving the addresses of all the 16-bit parallel input and output ports which can be used for general I/O. The number of each type available is compiled automatically into numPioOut and numPioIn by sizing the table. Most Unimate controllers come with a single high density parallel port board that has 32 bits of input and 32 bits of output; this is the configuration supplied by default. Note that the parallel port board may be present even

zYou should be able to use the supplied parameter value. The controller clock is usually generated by circuitry on the joint micro interface board. Changing the clock rate involves sending a magic command to the joint micro interface; this magic number is part of that magic command.

RCCL/RCI Release 4.2, July 30,1992

48 5. CONFIGURING THE RCCL/RCI SOFTWARE

if you don't have any of the I/O relay modules. DACAddr is a similar table listing the available digital-to-analog converter ports. Most systems don't usually come with any of these.

NOTE: With any of these tables, if there are no entries, then the table definition must
be commented out and an explicitly null entry must be put in its place; this is because
the compiler can't size objects of zero size.

The table serialDevs describes all the serial line units connected to the controller, except for the console line and any line which you provide your own interrupt handler for. The entry for each port gives its base address and vector. The ports are assumed to look like those on a standard DEC DLV, with a receive CSR, receive data buffer, transmit CSR, and a transmit data buffer. Units which are included in this table will be assigned interrupt service routines and an interface control block by the moper micro-kernel. Serial lines which do not need to make use of the micro-kernel interface should not be included in this table. Usually the only thing you need to ask yourself with regard to this table is whether your controller has a second serial board (many do). If so, then you should uncomment the entries for it in the second half of the table.

RCI itself contains a general serial line interface as part of the HOW structure and CHG macros. moper implements these general interfaces using serial lines connected to the micro-kernel serial line interface. These are configured using the table sluDesc. The entries consist of the channel number (a zero-based array index into the table serialDevs, described above), and the number of bytes that should be allocated as buffers for storing read and write data. The only time you will probably need to make changes here is if you take over one of these serial line units for something else (such as a force torque sensor).

The remainder of the file contains routines which implement various sensor and I/O interfaces. The implementation of these interfaces will vary from site to site depending on the hardware used. The functionality of each interface as expected by the rest of moper is fairly simple, however, and can be explained here.
The force/torque sensor interface contains the following routines:

initForce() ?
An initialization routine that is called once when moper is first started up.

startForce() ?
Called in response to an RCI command to start reading force values.

stopForce() ?
Called in response to an RCI command to stop reading force values.

getForce(buf) ?
Called once per control cycle, while force reading is turned on, to collect the force values. These are placed in an array of six shorts whose address is passed in as a parameter. The order of the data expected is the usual x-y-z forces followed by the x-y-z torques. The routine should return 1 if successful and 0 if the force readings are not available for some reason.

The interface routines used by moper for the joystick interface are analogous to the force sensor ones:

RCCL/RCI Release 4.2, July 30,1992

5.4. CONFIGURING MOPER FOR A UNIMATION MARK X CONTROLLER 49

initJstick() ?
An initialization routine that is called once when moper is first started up.

startJstick() ?
Called in response to an RCI command to start reading joystick values.

stopJstick() ?
Called in response to an RCI command to stop reading joystick values.

getJstick(buf) ?
Called once per control cycle, while joystick reading is turned on, to collect the values. These are placed in an array of shorts whose address is passed in as a parameter. The routine should return 1 if successful and 0 if the joystick readings are not available for some reason.

The analog-to-digital conerter interface consists of a single routine:

getAdc(chan,valuep) ?
Called once per control cycle, while ADC input is activated for the channel chan. Reads the corresponding ADC channel and places the result into the address given by valuep.

The routines for the torque sensor interface are analogous to the force sensor and joystick routines:

initTorque() ?
An initialization routine that is called once when moper is first started up.

startTorque() ?
Called in response to an RCI command to start reading torque values.

stopTorque() ?
Called in response to an RCI command to stop reading torque values.

getTorque(buf) ?
Called once per control cycle, while torque reading is turned on, to collect the values. These are placed in an array of shorts whose address is passed in as a parameter. The routine should return 1 if successful and 0 if the torque readings are not available for some reason.

The torque values returned by getTorque() are not assumed to be real torque values (they might be current readings for instance). RCI will convert the values to real motor torques (Newtonmeters) using the conversion constants currentToMtorque contained in the JLS structure.

5.4.2.3 Adding torque and force sensing

By default, moper provides force sensor routines (as described in the previous section) which can read data from a Lord F/T series force torque sensor (made by Lord Corporation).

The RCCL/RCI Hardware Notes has a section describing how to hook this sensor up and configure moper accordingly. There is also a section which describes how to install sensors for reading joint currents, which can be used to provide an estimate of joint torques.

RCCL/RCI Release 4.2, July 30,1992

50 5. CONFIGURING THE RCCL/RCI SOFTWARE

5.4.3 Determining servo control parameters

In some cases, the joint servo parameters specified for a particular controller/robot combination may turn out to be incorrect for your controller.

One thing you might do, before applying the methods described in this section, is try a different parameter set. In particular, if you have a PUMA 560, and the mk3_std.560 seems to cause problems, try mk2_std.560 instead. If you have a Mark I controller, try changing mk1_std to mk1_old.

5.4.3.1 Disassembly of the joint servo EPROMs

The first way to resolve this problem is to dump the contents of the joint servo EPROMs, disassemble the code, and see where the parameters actually are. The EPROMs are identical for all the joint servos, so you only need to dump one.

This is in fact not as difficult as it sounds, since the code is no more than 2K bytes in length. Furthermore, actual variations in the code structure tend to be rather slight. It is, however, a tedious exercise if one has not done it before. Therefore, we recommend that if you decide to do this, you mail the EPROM dump to the author and we will do the disassembly for you.

To dump the EPROMs, select one of the six joint servo cards in the robot controller (which one doesn't matter; they are all identical) and remove it. The card should contain a Rockwell 6503 microprocessor, a 6532 RAM I/O timer chip, a digital-to-analog converter chip, and an EPROM. The EPROM will most likely be 4 Kbyte 2716, or equivalent. Dump the EPROM using a PROM developer, and create an ascii hex dump of its contents. Although the EPROM is 4 Kbytes, the top and bottom 2 Kbytes should be identical (you might want to check this). E-mail the dump to

lloyd@curly.mcrcim.mcgill.edu

If you are interested in doing the disassembly yourself, the disassembler is located in $RCCL/servoCode. Compile the programs disas and reroll. Take the ascii hex dump, strip off any addresses at the beginning of the line, and make sure it is in a single byte format (like one of the .hex files in the directory). Then run it through the command

% disas -1 0x800 < input | reroll > output

A 6502 reference manual will be useful for interpreting the result (the 6503 is a 6502 in a different package). Numerous disassembled listings are available in the servoCode directory for comparison.

5.4.3.2 Creating your own EPROMs

An alternative approach is to create your own EPROMs using a version of the joint servo code that is already known. We have not actually tried this technique, but it ought to work. The only caveat is that VAL will probably not run with the new EPROMs.

First, select a suitable version of the joint servo code. Check the directory $RCCL/servoCode for files ending in .hex; these are ascii hex dumps of different EPROMs. Pick the file that most closely matches the controller, as indicated by the following table:

RCCL/RCI Release 4.2, July 30,1992

5.5. TESTING THE ROBOT CONNECTION 51

file name robot controller type

mk1_std.hex Mark I
mk2_std.hex Mark II
mk3_std.hex Mark III, with PUMA 260 or 560
mk3_760.hex Mark III, with PUMA 760

Second, burn a new set of EPROMs. They are identical for each joint servo, and you will need six. The EPROM type is a 4 Kbyte 2716 (or equivalent). Each .hex file describes the top 2 Kbytes of the EPROM; the bottom 2 Kbytes should be a duplicate of the top. When the EPROMs are ready, use them to replace the existing ones in each of the six digital joint servo boards inside the robot controller.

Third, set the include file that follows the comment ?parameter defs:? in the moper config file to one appropriate for the EPROM which you have chosen. The name of the include file has the form

<controller>.<robotType>.c

<robotType> should be the same as the root name of the .hex file that was chosen for the EPROMs. <robotType> should be either 260, 560, or 760, as appropriate. For example, if you have a PUMA 760 and a Mark III controller, you would specify
#include "mk3_760.760.c"

5.5 Testing the Robot Connection

Once you have configured RCI for a particular robot, you should test its operation.

The references to moper in this section are specific to PUMA robots running on Unimation controllers.
First, go to the directory $RCCL/rci and build the program rbtcom. Then run the command

% rbtcom <robotName>

This should initiate a connection to the robot, and start a control session that does nothing except exchange data. The robot power will not be turned on. rbtcom is interactive, driven by the C-tree matcher, and when working properly should display the prompt RBTCOM>. A description of the commands is beyond the scope of this document. However, the command

RBTCOM> show

should print out the number control cycles that have elapsed since the program started. If you get up to a few thousand, everything is probably all right. To get out of rbtcom, enter the command

RBTCOM> quit

For PUMA robots, you may want to look at what moper prints out on the controller console line while rbtcom is running. Connect to the console line using the talkRobotX alias described in section 2.3.1.3, and watch the output. When rbtcom starts, moper should print the message

RCCL/RCI Release 4.2, July 30,1992

52 5. CONFIGURING THE RCCL/RCI SOFTWARE

active

When you quit rbtcom, the message

released
listening

should appear. The ?listening? part of the message indicates that moper is now waiting for a new RCI connection from the host system. If you abort rbtcom (such as with an interrupt) then moper should print a message, similar to

timeout: location (4,0)
listening

indicating that it has timed out, and is listening for another RCI connection.

If rbtcom fails, it should generate some error messages as to what went wrong. Most errors are due to (1) improper configuration of the robot with respect to RCI, or (2) a bad interface connection to the controller.

On PUMA robots, if moper fails, it too should generate some error messages. In most cases, when moper fails, it will simply go back to listening for RCI connections from the host system. If it fails badly, then it will put the controller CPU into ODT, which is distinguished by its familiar @ prompt. moper must then be restarted with the ODT command

10000G

although the condition which caused the failure will probably repeat. Errors which complain of trouble talking to the joint servos indicate that the servo parameters defined for moper are incorrect; see section 5.4.3 in this case. moper itself implements a number of commands; for a list of these, type ? while moper is running.
Once rbtcom is running, you can next run the program primecal. This is a ?standard? program and so you don't have to build it specially.

WARNING: primecal will try to turn the robot power on. When running it
for the first time, or when first trying to move the joints, be prepared to hit the
emergency switch.

Enter the command

% primecal <robotName>

When started, the program will either turn the robot arm power on by itself (if this feature has been wired into the robot controller; see the RCCL/RCI Hardware Installation Notes) or wait for you to do so. Once the power is on, primecal will enter into an interactive loop, driven by the C-tree matcher, with the prompt PRIMECAL>. Commands can then be entered to move individual joints. Try moving each of the robot's joints to verify that this works properly. Note that the robot is not yet calibrated, so you should use only relative joint motions and visually check for joint limits. For more information, see primecal(1).

If you detect problems while running primecal, such as rough joint motion or, in the worst case, the joints just ?take off?, then the servo parameters set by moper are probably wrong and you should see section 5.4.3.
Once these test programs work properly, you should be able to calibrate your robot.

RCCL/RCI Release 4.2, July 30,1992

5.6. ROBOT CALIBRATION PROGRAMS 53

5.6 Robot Calibration Programs

This section describes the calibration programs which you will need to run in order to obtain proper values for some of the fields in the JLS structure.
The information in this section is focused on PUMA robots.

5.6.1 The primecal program

The program primecal should be run on a new robot to determine its calibration vector. primecal was written for PUMA type robots and other robots which use optical encoders.

The purpose of primecal is to determine a set of reference encoder values which are known to lie on wheel index locations. This set of values constitutes the encCalvec field of the JLS structure.

5.6.1.1 How primecal works

To understand what these numbers are used for, consider the robot calibration problem as it applies to PUMA type robots: a joint has just been powered up, and the encoder count associated with the joint is gibberish. To determine the correct encoder count, we need to determine the exact joint position. How do we do this? We start by getting a rough estimate of the joint position, either by knowing approximately where the robot is (in the nest, or at the park position) or by using a course position indicator such as the joint potentiometers. The PUMA 260 does not have potentiometers and so for that robot we must use the former method. Now, each optical encoder wheel has a certain number of marks w on it, plus a single special mark called the ?zero index?. If the estimate of the joint position is accurate to within ?1=2w, we can use the zero index location to figure out exactly where we are. We travel until we reach a zero index (and update our joint position estimate accordingly). Let our estimated joint position be given by ?e. Assume next that we know of some reference position, r, which lies on a zero index and whose encoder position is known exactly. Then, since we have just arrived at a zero index location ourselves, the distance between our real position e and this reference position must be nw, where n is some integer. But since our estimated position ?e is no more than ?1=2w from the real value e, n can be computed from

n = nint(( ?e ? r)=w);

and the real encoder position can then be computed from n:

e = nw + r

This is the method used by the program pumacal. The task of primecal is to determine the reference values r.

5.6.1.2 Running primecal

primecal is an interactive program and it contains commands that allow you to move the robot around until it is at some position which you happen to know exactly. Typically, for PUMA robots,

RCCL/RCI Release 4.2, July 30,1992

54 5. CONFIGURING THE RCCL/RCI SOFTWARE

this is the ?ready? position, where links 2 and 3 are pointing straight up. When you have placed the robot at a known position, enter the command primecal. The program will then ask for the known joint angles, which it uses to compute the correct encoder values for the present position. These encoder values are then loaded into the joint servos explicitly, thus effecting a direct, ?brute-force? calibration of the robot. Next, the program will move all the joints until each one of them finds a zero index. The encoder values at this new zero index position constitute a reference value such as the one described above.

For historical reasons, the program actually outputs a different set of reference values, formed by adding a multiple of w to each of the measured values to make it the smallest number greater than or equal to 32768x. The resulting set of new r values constitutes the calibration vector, which is printed out by the program, and also printed into the file primecal.out. These values should be entered into the encCalvec field of the robot's .jls file.
More information on primecal can be found in the manual pages.

5.6.2 The potcal program

Robots that use potentiometers to estimate their location when calibrating must have their potentiometers calibrated to determine, for each joint, the linear relationship between the pot reading p and the estimated encoder value ?e:
?e = mp + b

The set of slope values m constitute the potSlope field and the set of intercept values b constitute the potIntercept field in the JLS structure. potcal measures both of these by taking numerous potentiometer readings across the range of each joint.

5.6.2.1 Running potcal

It is necessary that the robot be calibrated before running potcal. This presents a bit of a chickenand-egg problem if the robot is normally calibrated using the pots. The initial calibration has to be done using primecal. After this has been done, the robot will remain in calibration until the controller is either turned off or the moper program is halted. potcal may be run at any time during this period. If one does wish to power down the robot in between, then one can move the robot to the park position before powering down, and then recalibrate later by specifying the option -atpark to pumacal.

potcal, like primecal, is an interactive program. The user can position the robot so that the calibration of the different joints can proceed uninterrupted. Calibration ?sweeps? are requested one joint at a time using the calibrate command (except for the wrist, where all the wrist joints may be calibrated together). When doing a sweep, the joint is moved from ?m ? ?s to ?m + ?s, where ?m is the joint mid-range point and ?s is the interactively specified sweep angle. After the sweep is done, the measured slope and intercept are printed out, both on the screen and into the file primecal.out. These values should be entered into the potSlope and potIntercept fields of the robot's .jls file.
x32768 is special only because it corresponds to the mid-range value for 16 bit encoders. Because of this, it is usually defined to be the mid-range point for the joint angles as well.

RCCL/RCI Release 4.2, July 30,1992

5.6. ROBOT CALIBRATION PROGRAMS 55

More information on potcal can be found in the manual pages.

5.6.3 Manually calibrating for current control

This section describes how to adjust the system for proper current control, so that the actual torques resulting from the RCI torque control commands (SET_JTORQUE() and SET_MTORQUE()) are in fact close to the desired result.

Current control is used by some of the supplied RCCL/RCI software, mostly to put joints into a ?zero gravity? mode, where they move freely but with enough current applied to keep them from falling under there own weight. This feature is provided in the program zerograv, and in the ?free joint? mode of the routine rcclTeach() (and its wrapper program, teachdemo). Other programs that presently use current control are free (which frees joints without gravity compensation), and the demo programs demo.rci/zerogDemo and demo.rci/gravity.

The techniques described here are quite ad-hoc, because most systems are not instrumented for measuring joint currents or torques and, consequently, no software is supplied for doing automatic current calibration{. In the absence of proper sensors, all we can really do is adjust the necessary values ?by eye? until programs such as free and zerograv appear to work correctly.
The fields in the JLS structure that are concerned with current control are currentBias and mtorqueToCurrent.

5.6.3.1 Adjusting the currentBias field

Ideally, all the elements in this field are 0, and in fact this is true for most PUMA controllers. However, a few controllers have the problem that a requested output current of 0 will not in fact result in an actual output current of 0. To check this condition on your robot, run the program free, and individually free (i.e., zero the current) on each of the joints. If some joints do not go limp, but still appear to have current applied to them, then the controller has an amplifier balance problem that can be corrected with entries in the currentBias field.

IMPORTANT: When you limp the robot, remember that some of the joints may fall under their own weight. Be sure to hold the joints in question. To detect residual current, move such a joint to a stable position (such as straight up or straight down) and see if it either moves or resists motion differently in different directions.

If you have an amplifier balance problem, you should try to measure its magnitude by finding out what commanded torque actually produces an output torque of zero. Go to the directory $RCCL/rci, and make the program rbttest (the command make rbttest should do nicely). Now run this program with the command
% rbttest <robotName>
{It is, however, possible to add sensors that read the joint currents (see the RCCL/RCI Hardware Installation Notes). These values can then be used to update the jtorque and mtorque fields of the HOW structure.

RCCL/RCI Release 4.2, July 30,1992

56 5. CONFIGURING THE RCCL/RCI SOFTWARE

This is an interactive program, driven by the C-tree matcher, that allows you to enter RCI commands to the robot one at a time. There is no ?trajectory generator? associated with rbttest; only commands which you explicitly type at the keyboard will be sent to the robot. The program should give you the prompt RBTTEST> , and you should then enter the command start:

RBTTEST> start

This initiates communication with the robot controller. To put a joint into ?torque? mode with a particular torque setting, enter the command

RBTTEST> set mtorque <joint> <torvalue>

where <joint> is the number of the joint you want to control (1 through 6, usually), and <torvalue> is a floating point number giving the magnitude of the torque you wish to apply to the motor (in Newton-meters). You probably want to start with a fairly small number, such as .001, and then work up by one or two orders of magnitude until you see some effect. Remember that this is an actuator-level torque.

Be very careful when doing this! If you accidentally enter a large number for the commanded torque, the joint will respond accordingly. Remember also that since you presumably have a current balance problem to begin with, the joint will move (or at least feel a bias force) when you specify a commanded torque of zero.

It is easier to do this with a partner: one person can handle the robot joint(s), and another can handle the keyboard. You may want to flip a coin for the keyboard. The idea is to find a commanded torque value that balances the current bias. For joints where there is no current balance problem, this value will be zero. When you find the correct commanded torque value, compute the corresponding DAC value by multiplying the torque by the value of mtorqueToCurrent for the joint in question. mtorqueToCurrent is a field in the JLS structure containing multipliers to convert motor torques into output DAC values; you can find it in the robot's .jls file. This final value should be entered in the currentBias field of the .jls file.

5.6.3.2 Adjusting the mtorqueToCurrent field

This section assumes that the currentBias is properly set.

IMPORTANT: Make sure that gravity loading terms are actually defined for your robot in its .kyn file. You need to have some rough estimate of these terms to start with. If they are zero, or if the mtorqueToCurrent values in the JLS structure are zero, then zerograv will simply cause the robot to fall under its own weight.

Run the program zerograv, taking care to be ready to shut off power or abort the program if the robot suddenly moves. The desired behaviour of zerograv is that the robot stays still, but can be freely moved into any position with only the friction of the joints resisting. If this is in fact the case, then no further adjustments should be necessary. On the other hand, if the robot tends to drift or fall, then the mtorqueToCurrent values and/or the gravity loading terms need adjusting; the former is discussed here.

RCCL/RCI Release 4.2, July 30,1992

5.6. ROBOT CALIBRATION PROGRAMS 57

To calibrate the mtorqueToCurrent field, place the robot in the vertical (i.e., ?ready?) position. Remove any heavy end effectors because the gravity model will not know about these. Now move the individual joints from side to side. If a joint tends to drift (either down or up) in a manner independent of which side of the vertical it is on, then adjust the corresponding mtorqueToCurrent value. The value should be increased if the joint tends to fall down, and decreased if the joint tends to fall up. Make the adjustments slowly at first. To make each adjustment, edit the appropriate entry in the robot's .jls file, save the file, and then restart the program.

If you can't seem to get zerograv to behave no matter how you adjust the mtorqueToCurrent field, then the gravity loading terms are probably wrong (see section 5.6.4).

5.6.4 Manually calibrating gravity and friction terms

At present, the supplied RCCL/RCI software only uses a robot's gravity loading and friction model in the ?zerograv? software described in 5.6.3, and peripherally in the robot simulator program robotsim. Friction information is used in the ?zerograv? software to compute a restoring force for implementing soft joint limits.

5.6.4.1 Adjusting gravity terms

Calibrating the gravity terms is tricky since the relationship between them and the applied output torque is much more complicated. If you don't have an approximate model to begin with, there is probably no good way to get this right manually.

If you run the program zerograv, and the robot drifts in a way that seems to depend specifically on joint position, then the gravity terms probably need adjusting. You can adjust the gravity terms the same way you adjust the mtorqueToCurrent values: change the appropriate CP values in the .kyn file, save the file, and restart the program. Make the changes slowly at first.

5.6.4.2 Adjusting Coulomb friction terms

Whereas gravity terms are difficult to determine without the right software, friction terms are fairly easy to estimate.

Again, the program zerograv can be used. Start it up with the option -friction. Note that the program is interactive, with command completion provided by the C-tree matcher.
The command

show

will show each joint's current position, as well as a Coulomb friction value. The initial value is read in from the robot's KYN structure.
If you now select some joint j, and enter the command
frictionComp <j> on

RCCL/RCI Release 4.2, July 30,1992

58 5. CONFIGURING THE RCCL/RCI SOFTWARE

the Coulomb friction information for that joint will be used to reduce friction when the joint is moving. That is, if you move the joint in a certain direction, then its Coulomb friction value will be used to give you a ?boost? so that the joint moves more easily. Note that the joint ?sticks? when you change directions; this can't be avoided because only the joint's velocity is being used as feedback.
You can change the Coulomb friction value for a joint using the command

set frictionComp <j>

Try different values until the friction compensation seems right. Ideally, this will be when pushing a joint causes it to move freely and continues to glide gently throughout its range until it bounces off of its limit stop. In practice, things may not be so well behaved because friction is quite irregular and can depend on position.
When you have a set of ?good? friction values, use them to instantiate the COULF terms in the robot's .kyn file. The zerograv program will not do this automatically.
Friction compensation for a joint can be turned off using the command
frictionComp <j> off

5.7 Adding a New Device to the System

If you want to use a new type of communication device to connect the host system to the robot controller, and no driver software is supplied for this device in the system distribution, then you will need to write the appropriate device drivers for it yourself. For instance, you may want to replace the XVME 240 to DRV11 interface (commonly used between Sun4 hosts and Unimate controllers) with a shared memory link.

5.7.1 The RCI I/O driver

Creating a new RCI device involves writing a driver for it and placing it in the directory $RCCL/drivers.

Device drivers are usually given a short alphanumeric name and are defined in a file drivers/XXXDriver.c, where XXX denotes the driver name. An include file, defining bit codes and structures used by the driver, is usually located at h/XXXDevice.h.

Each driver must implement the nine routines described in section 5.1.5. Consult the manual page IOdevice(7) for an overview of what these routines do. The easiest way to actually write the driver is to clone an existing one. The RCCL/RCI Hardware Installation Notes suggests which supplied drivers are likely to resemble the actual drivers needed for some particular types of hardware.

NOTE: Drivers used by VxWorks systems require a couple of other routines to manage
device interrupts (to take the place of the UNIX RCI driver). See the document
RCCL/RCI on VxWorks.

RCCL/RCI Release 4.2, July 30,1992

5.7. ADDING A NEW DEVICE TO THE SYSTEM 59

5.7.1.1 Installing the RCI driver

After you have written the driver, it must be compiled into the system. This is done as follows. The name of the driver, along with pointers to its functions, must be placed in the array IOdriverTable in the file drivers/IOdriverTable.c. After this has been done, running the command
% make libs
in the drivers directory will install the driver in the RCCL/RCI library.

5.7.2 The counterpart driver in moper

Every RCI communication driver needs to interact with some counterpart software in the robot controller. Adding a new RCI driver usually implies writing a driver for the robot controller as well.

The moper software supplied for the Unimate controller contains a set of interface routines that have the general name host<func>. The RCI driver read routine talks to the moper routine hostWrite(), the RCI driver write routine talks to the moper routine hostRead(), etc. These ?hostIO? routines are defined in a module (located in $RCCL/lsi11) whose name is usually related to the hardware. Two hostIO drivers are supplied with the system: drv11.c, which interfaces to a DRV11, and drvj.c, which interfaces to a DRV11-J, but is untested.

To install a driver into the moper for a particular robot, edit the Imakefile in $RCCL/lsi11 and replace the driver in the moper's build directive. Note that build objects in this Imakefile are specified as .s files instead of .o files; this is a quirk of the fact that the loader for the crosscompiler works with assembly files instead of object files. If your robot's name is frank, then the Imakefile build directive for its moper will probably look like

pdp11Program(frank,$(MOPER) frank.s drv11.s)
drv11.s is the old driver module; this should be replaced with the new driver. If the new driver lives in newdriver.c, then the build directive should then be modified to
pdp11Program(frank,$(MOPER) frank.s newdriver.s)
Afterwards, the Makefile should be rebuilt from the Imakefile by running the command rmkmf.

5.7.3 The RCI UNIX driver

If you provide your own interface driver, and you are not running on VxWorks, you will probably also need to write an RCI UNIX driver to handle any interrupts which the device sends to the host system.

The RCI UNIX driver is usually very simple, consisting of an open routine, a close routine, an ioctl routine that provides some interface functions common to all RCI devices, and an interrupt handler that catches incoming interrupts and hands control over to RCI. The driver does not have to do anything else; all actual communication is done by the RCI device driver. The UNIX driver can be most easily written by cloning an existing one, such as rciext/xyd.c, which is the UNIX driver for the XVME 240, or the general RCI driver ?template? provided in rciext/rci_template.c.

RCCL/RCI Release 4.2, July 30,1992

60 6. INSTALLATION SUMMARIES

This driver will need to be configured into UNIX in the same way as all other system device drivers (see section 4.3.4).

5.7.4 Debugging a driver

The program drivertest, in the drivers directory, is an interactive program designed to help test drivers by providing an interface where each of the driver routines can be called individually. It creates an RCI task and uses this to execute the different routines. While no specific documentation exists for drivertest, a rather complete description of the pri driver, the moper driver that interfaces with it, and how drivertest can be used to debug both of them, is presented in the file doc/priDriver.doc.

6. Installation Summaries

This section provides some sample ?check lists? for installing RCCL/RCI with the most commonly used equipment.

6.1 Real-time Installation for VME-based Hosts with PUMA Robots

This encompasses VME-based hosts (Sun4, SGI IRIS, or VxWorks) with connections to PUMA robots controlled by Mark I, II, or III controllers. Each robot controller is assumed to be connected to the host system by a DEC DRV11 and a XYCOM XVME 240.

The hardware aspects of the installation are detailed in the RCCL/RCI Hardware Installation Notes. For VxWorks installations, the manual RCCL/RCI on VxWorks should also be consulted.

6.2 Hardware

1. Equipment needed ? You need a robot, a controller, and a host system. For each robot controller, you need a DEC DRV11 and a XYCOM XVME 240. If you want hardware clock support on the Sun system, you also need a XYCOM XVME 203 or 293. S-bus based Suns should be attached to a VME card cage using a PT-SBS915 S-bus to VME adaptor, with configuration software.

2. Cable interface ? Build a cable interface to connect each DRV11 and XVME 240.

3. Hookup ? Jumper each XVME 240 appropriately and plug it into the host system VME bus. Jumper each DRV11 and plug it into the Unimate controller Q-bus. Connect the two boards via the cable connector. Attach the console serial line from the robot controller to a serial port on the host system. If you have an XVME 203 or 293 for the Sun system, jumper this and plug it into the VME bus.

4. Controller customization ? Upgrade the LSI11 to an LSI11-73, if necessary. Wire up the ?auto power on? circuit, if you desire this feature.

RCCL/RCI Release 4.2, July 30,1992

6.3. SOFTWARE 61

6.3 Software

1. Build RCCL distribution ? See section 3. Unpack the tape, install GNU make, edit the file conf/site.conf, and run ?make World?. Install the simulator network service.

2. Install kernel support, if necessary ? On Sun4 or SGI systems, add kernel support as described in either section 4.3 or 4.4. Include the UNIX genrci drivers, the xyd driver, and (for Sun4 systems with a XVME 203 or 293) the xyclk driver. Create special files for the drivers in /dev. Verify RCI installation with rciCheck (section 4.5).

3. Configure controller serial line connection ? See the RCCL/RCI Hardware Installation Notes. Locate the file in /dev that controls the serial device connected to the robot controller. Verify the connection with termlink.

4. Configure RCI for each robot ? For each robot, give it a name and an entry in robots/robotDataTab.c (section 5.2.1) and conf/robots (section 5.2.2). For VxWorks, use robots.vxw instead of robots. Create a .jls, .kyn, and .pos file for each robot (sections 5.2.3.1, 5.2.4.1, and 5.2.5).

5. Configure moper for each robot ? For each robot, create a moper for it in the lsi11 directory, and adjust its configuration file (section 5.4.1). Build the new moper and load it into the robot controller over the serial line.

6. Test the robot connections ? With moper running in your controller, run the test programs rbtcom and primecal as described in section 5.5.

7. Calibrate the robots ? Calibrate each robot using primecal and potcal as described in sections 5.6.1 and 5.6.2. If you want to use current control programs such as zerograv, then do the calibrations described in section 5.6.3 and 5.6.4 as well.

6.4 Installation for Simulator-only Systems

1. Build RCCL distribution ? See section 3. Unpack tape, install GNU make, edit the file conf/site.conf, and run ?make World?. Install the simulator network service.

2. Configure RCI for each robot ? For each robot, give it a name and an entry in robots/robotDataTab.c (section 5.2.1) and conf/robots (section 5.2.2). Create a .jls, .kyn, and .pos file for each robot (sections 5.2.3, 5.2.4, and 5.2.5).

3. Test the robot connections ? Start the simulator program robotsim with the name of the robot you want to simulate. Try to ?move? this robot using the command move with the -sim option.

7. Adding New Classes of Robots to the System

If you wish to add a new class of robot to the system, then you will need to write implementations of the functions described in section 5.1.

RCCL/RCI Release 4.2, July 30,1992

62 7. ADDING NEW CLASSES OF ROBOTS TO THE SYSTEM

The basic procedure for adding a new robot class looks something like this:

1. Define a class for the robot in the file h/robotClass.h.

2. Define the <CLASS>_KYN and <CLASS>_VAR structures for the robot type, and place these definitions in a file h/<class>_kynvar.h.

3. Create a new directory for the robot class, which bears the same name as that class. Functions specific to the class will be placed in this directory. The easiest way to create this new directory may be to clone one for an existing robot class. The directory for functions specific to the PUMA class of robots is called PUMA.

4. Write the functions <class>_jls() and <class>_kyn() used for instantiating JLS and KYN structures. (See section 7.1 for details.)

5. Write class-specific implementations of the conversion functions described in section 5.1.3.1. (See section 7.2 for details.)

6. Write class-specific implementations of the kinematic functions described in section 5.1.3.2. (See section 7.3 for details.)

7. (If necessary) Write the robot communication functions, described in section 5.1.4, which provide the interface to the robot controller. (See section 7.4 for details.)

8. (If necessary) Add interface device software to be used by the the robot communication functions in communicating with the robot controller. This could include an RCI I/O driver, and/or an RCI UNIX device as described in section 5.7.

9. (If necessary) Create the necessary interface software on the robot controller (this is a moper equivalent). (See section 7.5 for details.)

Some of these steps are now discussed in more detail.

7.1 Writing JLS and KYN Access Functions

The functions <class>_jls() and <class>_kyn() are used by the system functions getJls() and getKyn() to help instantiate the JLS and KYN structures. <class>_jls() sets the JLS structure pointers for the functions described in section 5.1.3.1. <class>_kyn() sets the KYN structure pointers for the functions described in section 5.1.3.2, and also reads in data from the robot's .kyn file.

Instructions on how to write these functions, the arguments they should expect, and how they are loaded into the system are given in the ?Installation? section of the manual page getJls(3).
The functions for the PUMA robot live in puma/puma_jls.c and puma/puma_kynvar.c.

RCCL/RCI Release 4.2, July 30,1992

7.2. WRITING THE JLS CONVERSION ROUTINES 63

7.2 Writing the JLS Conversion Routines

These are implementation functions for the routines described in 5.1.3.1.

All of the parameters needed to perform these computations are defined by data fields in the JLS structure itself, and generic functions, which will work for any robot, are defined in the file robots/gen_convert.c. It is possible to simply use these functions instead of providing private ones for the robot class. However, it is usually better, for speed reasons, to write class-specific functions. This permits loops to be unrolled and joint coupling computations to be optimized. The class-specific functions are given the same names as the generic functions, only prefixed with the name of the class (in lower case) and an underscore (<class>_).
The functions for the PUMA robot live in puma/puma_convert.c.

7.3 Writing the Kinematic Routines

These are implementation functions for the routines described in 5.1.3.2. They take the same arguments as the generic routines. Information on each one is given in the RCI Reference Manual.

The implementation function takes the same name as the generic routine, except the first letter is capitalized and then the name of the robot class (in lower case) is prefixed onto the front. For example, the fwdJacob routine for the PUMA is called pumaFwdJacob().

The functions for the PUMA robot are located in pumaKinematic.c, pumaJacobian.c, pumaConfig.c, and pumaGravload.c, in the puma directory.

Within the puma directory there are some programs which test the kinematic routines. It may be useful to create versions of these for any new robot classes which are defined. Each testing program automatically cycles through a large set of joint angles and applies various combinations of forward and inverse routines, checking that the numbers which go in are close to the numbers that come out. Test angles are chosen to be far from, near, or at singularities. For testing the routines at or near singularities, the programs make use of some support routines defined in the file pumaSingular.c, which detect when a robot is near a singularity, or explicitly set the robot to be a certain distance from a singularity. Documentation for these routines is contained at the top of the file.

7.4 Writing the Robot Communication Functions

These are the routines described in 5.1.4.
Information on what these functions do is provided in the manual page robotComfxns(7). They generally take the names

<pfx>_startup
<pfx>_input
<pfx>_output
<pfx>_release
<pfx>_ready
<pfx>_wakeup

RCCL/RCI Release 4.2, July 30,1992

64 7. ADDING NEW CLASSES OF ROBOTS TO THE SYSTEM

where <pfx> is some distinguishing prefix. If the functions are defined for a particular class of robots, the prefix is the class name. The functions for the PUMA robot are located in puma/puma_comfxns.c.

It may not be necessary to define these functions for a particular class of robots. Their implementation tends to depend much more on the robot controller, and how it interfaces to RCI, than on anything to do with the robot's class. Conversely, different robots of the same class may use different sets of communication functions, depending on what controller they are attached to.

NOTE: There is a set of ?generic? communication functions, named with the prefix gen and defined in robots/gen_comfxns.c. These will work for any robot which is either controlled by a Unimation Mark I, II, or III controller, or run in simulation mode with the program robotsim.

The communication functions used by a particular robot are declared in rciRobotDataTable (see section 5.2.1).

7.5 Interface Software in the Target Controller

When adding a new type of robot to the RCCL/RCI system, it will probably be necessary to write moper equivalent software that runs on the robot controller and interacts with the robot communication functions running on the host system. To this end, it may be convenient to clone the PUMA version of moper, or parts of it. To help in doing this, a brief overview of the ?moper? software is given here.

moper is really just a data concentrator. It wakes up once every control cycle (upon a signal from either the host system or its own timer, depending on whether it is running in ?slave? or ?master? mode), and gathers data from the robot joints and the various sensor devices that are attached to it. It collects this data into one packet, ships it up to the host, and then waits for the host to reply with a packet of commands. The commands are then distributed, as required, to the joints and the I/O devices, ending the control cycle. It is useful to use moper to do this communication because many of the interfaces (particularly those involving serial lines) are interrupt driven, and it may not be particularly convenient to do large amounts of interrupt driven I/O on the RCI host system. This is particularly true if the host system consists of only the UNIX CPU.

A description of the principal modules comprising moper is given in the file lsi11/README.

Moper makes use of a minimal number of system services provided by a ?microkernel? that was written for the LSI-11. These services are mainly connect-to-interrupt, timer services, and support for printf() and scanf(). Porting moper to a different system would largely be an exercise in replacing these services with system calls on the target system. The microkernel interface is defined in the file doc/microkernel.doc. The modules related to the microkernel are also described in lsi11/README.

RCCL/RCI Release 4.2, July 30,1992