1. Introduction
Section 2 of this document describes what an RWRCCL/RCI user should do in order to compile and run application programs. Sections 3 and 4 explain how to compile the software and what is required to 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 RWRCCL/RCI user must do is set up an environment. This is best done by making a few entries in the user's .cshrc file or the /etc/profile file on linux machines
2.1 Environment Variables
and the Path
The following environment variables should be set:
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.
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
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
The Linux installation assumes
you are using the gcc supplied with the Linux operating system. Use
of other compilers is at your own risk.
2.2.2 The rcc command
RWRCCL/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 gcc and can be used in place of gcc, 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
Also, test.c could have been compiled using gcc 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, or better still become the local guru yourself, so you don't need a document at all :-).
2.3.1 Loading the moper program into the kernel
For Real-Time linux the moper
modules must be loaded into the kernel prior to execution using the privileged
insmod command. These modules resides in kernel space suspended until
a write on a real-time FIFO activates them. As a consequence, there
is no real performance penalty for having the modules loaded at boot time.
Here are examples entries in my /etc/rc.d/rc.local file.
This file is the accepted location under Linux for the addition of local
commands to be executed at boot time.
# more rc.local
#!/bin/sh
#
# /etc/rc.d/rc.local: Local system initialization script.
#
# Put any local setup commands in here:
/pkg/rwrccl/bin/insrci
/pkg/rwrccl/bin/inssim
#
The insrci and inssim files are small shell scripts that call insmod. For reference, here is the contents of insrci on my system.
# insrci
#!/bin/sh
insmod /usr/src/rtlinux3.1/modules/rtl.o
insmod /usr/src/rtlinux3.1/modules/rtl_time.o
insmod /usr/src/rtlinux3.1/modules/mbuff.o
if [ -f /usr/src/rtlinux3.1/modules/rtl_posixio.o ]; then
insmod /usr/src/rtlinux3.1/modules/rtl_posixio.o
fi
insmod /usr/src/rtlinux3.1/modules/rtl_fifo.o
insmod /usr/src/rtlinux3.1/modules/rtl_sched.o
if [ -f /usr/src/rtlinux3.1/modules/psc.o ]; then
insmod /usr/src/rtlinux3.1/modules/psc.o
fi
insmod /pkg/rwrccl/bin/pumaInterface.o
insmod /pkg/rwrccl/bin/moperx.o
exit 0
#!/bin/sh
#inssim
insmod $RCCL/bin/simdevice.o > /dev/null
Now the absolute path locations of the RTLinux modules are configured in
the site.conf file, and are just included here as an example. The
insrci file is generated during the Make World process, so there is no need
to hand-configure this file based on this example.
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. Load the moper software into the kernel.
3. Calibrate the robot using pumacal.
2.3.2 Manual Calibration
For reasons not entirely clear to us, we have not been able to read the
A/D converter values representing the potentiometers. At RWU were
were able to work around this problem easily enough, so we did not pursue
this problem indefinitely. Our not so perfect solution is to hand
calibrate the robot whenever power is turned on. We do this by manually
releasing the brakes using the break release toggle on the top of the controller
and the break release button on the base of the Puma 560. It is much
easier when two people are available, but in a pinch this can be done alone.
Using the break release we manually move the robot into the ready
position using the structure of the robot as a reference. In the
park position Joint 1 is aligned with the motor, Joint 2 is straight up,
the right side of joint 3 (when viewed from the joint 3 side of joint 2)
is flush with the side of joint 2. Joint 4 is flush with the end of
joint 3, joint 5 is straight up and joint 6 is aligned with a mark on joint
5.
Once manually placed in the ready position we invoke the pumaInttest
program in the RTLinux directory and zero the encoders using the "Z" command.
Then, exit pumaInttest and run primecal with the angles
"0 -90 90 0 0 0" as the current robot position. Primecal moves
the robot slightly (searching for index) then exits, setting the robot's
calibration bit.
2.3.4 When you need to reload or recalibrate
Generally, you need to load moper and calibrate the arm only when you power up the controller. The TRC004 registers will hold the encoder values as long as the chassis power is on, independent of the arm power. So it has often been the case that it is necessary to calibrate only once in several months.
It is occasionally possible that moper or the Linux PC will crash, although
this is extremely unlikely unless you are configuring new moper software.
If moper does crash, it is possible to simply reboot the machine without
recalibrating.
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.
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).
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. Attach the required hardware to your system.
2. Installing the necessary kernel support.
3. Building the main software tree. This involves unpacking the tar, setting up some configuration files, and running make. Instructions for this are given in this section.
There is no particular order to these steps.
3.1 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 a long time ago. 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.
imake is now standard in Linux distributions, or at least I presume
so as I did not have to install it when I loaded Slackware 8.1 onto my machine.
But if you Linux distribution does not include
imake, you must install the appropriate package.
The configuration files used by 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 use imake 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. (Original text: make World will take about four hours or so on an unloaded MicroVAX-II, and about one hour on an unloaded Sun4.) My, how times have changed. make World takes about 15 minutes on my 600Mhz system.
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.
* 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 once created the online manual pages, but now doesn't.
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.
For the Linux installation, the simulator installation requires the steps
above plus one additional step. The simulator itself is a simple unix-based
program and required no modification. However, programs connecting to
the simulator use RCI for trajectory control and timing. This function
is replaced by the RTLinux process that also controls the joint-level servo.
The simulation module (simdevice.o) is a RTlinux module that
generates psuedo-real time interrupts as previously done by RCI but does
not control the joint servos, as we would neither need nor want to be
controlling the real robot while running the simulator. The module
simdevice.o must be loaded into the kernel for the simulator to work.
This module will be automatically loaded at boot time as described in
section 2.3.1.
4. Adding Real-time Support to the System Kernel
4.1 Introduction
A significant departure from the original RCCL/RCI installation is that
special configuration of the kernel for RCI is no longer required. We
are once again impressed that Vince Hayward and John Lloyd worked through
these issues themselves for the purpose of making their own robots work. They
modified the standard unix kernel so that they could run specific processes
in near-real time (by giving themselves top priority on the scheduling queue).
Since their work in the early 1990's, this effort has been frequently duplicated, and as a result one may download open source kernel modifications that perform the same function. For this installation we chose RTLinux, one of several real-time packages available at the time. After verifying that RTLinux worked and was adequate for our needs, we continued with this package and did not evaluate any other packages. We therefore have little to say about the relative value of RTLinux vs. other packages but can say unequivocally that this package has worked perfectly for us.
4.2 RTLinux Installation
Adding real-time support for the kernel therefore requires following the
instructions included in the RTLinux distribution. A few notes based
on our experiences are perhaps worthwhile
5. Configuring the RWRCCL/RCI Software
This section discusses configuring an RWRCCL/RCI system. Much of this section is unchanged from the original RCCL installation, as it was the goal to retain the higher-level functions of RCCL. This section 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, although the original system supported STAN (the Stanford arm), and ELBOW (the elbow manipulator) and others.
5.1 Review of Basic Concepts
The robot support facilities used by RWRCCL/RCI are a component of the RWRCI 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
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)
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.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. The RCI clock tick is provided by the RTLinux module running in real-time. The "interrupt" is in reality a write to a Real-Time FIFO fifo on which the RCI process is (should be) blocked reading. If the process is in the blocked reading state, then the write by the real-time process will cause the read to return an the RCI process to execute as soon as permitted by the linux scheduler. Note that this is not true real-time, and this may produce some noticeable consequences.
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 communicates with a the joint level servo module (moper) through a small block of shared memory. This memory block contains joint positions, joint setpoints, digital signal states and the ability to specify digital I/O writes.
5.2 Adding a Robot to the System
This section outlines, in some detail, the procedures necessary for configuring a new robot into the RWRCCL/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.
As an example, the rciRobotDataTable entry for a PUMA robot attached to a Unimation Mark X controller typically looks like this:
"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>
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). For the RWRCCL, the device is "tri" for the Trident card and the address is the base address of the trident card as configured. Below is the entry in the robots file for the current installation
# The PUMA 560 at Roger Williams University (Trident/RTLinux):
robot = puma device = tri address
= 0x300
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.
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 information on 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.
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:
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 reasonable. 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
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
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 behavior. 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.
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.
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.
For sappy, historical reasons the joint-level servo program in RWRCCL was
also named moper, however it only partially duplicates the original moper
function.
5.4.1 Creating a moper for a new robot
This is definitely the most difficult aspect of configuring an RWRCCL/RCI system, because RCI depends on the low level joint servo interface running in real-time.
The actual joint servo command interface is fairly consistent. What varies is the joint servo control code, and the associated control parameters. The associated control gains are dependent on the joint servo rate, ultimately the rate your system is capable of supporting.
5.4.1.1 Necessary system information
Before creating the moper, you need to know
1. What sort of robot you have (i.e., PUMA, etc.). This should be clear.
2. What sort of controller you have.
3. What type of CPU you have.
5.4.1.2 Modify the program
The moper program for RWRCCL is in the jls directory, a new directory
in the RWRCCL distribution, replacing the LSI11 directory. The file
moperx.c contains the RTLinux joint-level servo code. The code
uses parameters in the mk2_std.560.lin.c file and uses low level communication
routines in the pumaInterface.c file. The interior block of the
program performs simple-minded P-D control of each joint with some setpoint
interpolation for smoother trajectory following.
It should not be too hard to modify this program and add better servo control. Our limiting factor was the inability of our CPU to support floating-point operations in the real-time process. However, our 660MHz PIII is slow even by the standards of the date of this writing.
There is no simple modifications to a configuration file as was common
in the RCCL system. To use a new robot will require a re-write of this
file suited to your current needs.
5.4.1.3 Rebuild the new moper program.
Remake the moperx module with a the make command
% make
Your moper program should now be ready to load into the kernel using the insmod command.
Start by making removing the current moperx.o module (if inserted)
% rmmod moperx
Note that the watchdog timer of the Trident TRC004 card will illuminate red once the moperx module is removed.
Insert the new moperx.o module
%insmod moperx.o
The watchdog counter is reset every read/write to the trident card, and the LED will illuminate green when the timer is being refreshed. Therefore the first check that a new moperx module is executing correctly is the illumination of the green LED.
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.
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.
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,
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.
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.
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 behavior 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.
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
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.
NOTE: The driver for the trident TRC004 card has been added to this directory
with device name "trident"
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.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.
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 adapter, 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.
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.
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.
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
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.
RWRCCL/RCI Release 6.2, January 06, 2004