home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Between Heaven & Hell 2
/
BetweenHeavenHell.cdr
/
500
/
470
/
rccl015
< prev
next >
Wrap
Text File
|
1987-03-02
|
56KB
|
1,739 lines
.ND
.EQ
delim $$
.EN
.nr H1 5
.NH 1
Sensor Integration
.PP
By using sensors, the user has the ability to write
programs that may depend on information acquired at run time.
The behavior of the manipulator can be influenced
by modifying the locations it is moving to or by interrupting a motion.
If the location can be determined ahead of time, we shall call that
presetting the world model.
A special case is the transforms initializations.
If the locations can be determined synchronously and permit us
to influence the manipulator's path, we shall call that tracking.
If the locations can be determined by stopping the manipulator on
condition, we shall call that guarded motions.
If the final position of the manipulator is to be retained for
the determinations of locations, we shall call that updating the world
model.
.NH 2
Presetting the World Model.
.PP
In the section `Synchronization' we have already met such a situation.
The example of a program interacting with a user was given :
.br
.cs R 23
.DS L
for (; ; ) {
printf("enter Z increment ");
scanf("%f", &iz);
b->p.z += iz;
move(p);
}
.DE
.cs R
The
.I hold
transform feature allowed us the specify different locations ahead
at time and no synchronization is specified.
.PP
Let us consider the integration of a computer vision system.
We assume that a camera has been attached to the link 4 of
the PUMA manipulator.
The computer vision is described in terms of a functions `snapshot'
which is supposed to take a picture of the scene and store it in memory, and
of a function `getobj' able to extract the position and orientation
of an object in the camera coordinate frame.
The operation of taking the picture is expected to be short but the task
is programmed in such a way that the processing time of `getobj' does not
require to stop the arm.
The strategy consist of moving the manipulator toward a position
where we expect an object to be captured in the field of the camera.
We synchronize the program such as the picture is taken at a given
point of the trajectory.
We also record at this instant the position of the manipulator
given by $T6$ and we reconstruct the camera coordinate frame from
the transform $U5$ internally maintained by the system.
We could also compute the values of the transform $T4$ since we can know
at any moment the joint angles values (see include files).
Thus we have all the information necessary to perform an
approach motion where the object has been found, grasp it, and move it
to some other place.
.PP
A bare bone version of the task is described
in terms of three position equations : the position where to expect
an object to be seen by the camera, the position where to grasp the object,
and the position where to put it :
.br
.cs R 23
.DS L
1 #include "rccl.h"
2 #include "hand.h"
3 #include "which.h"
4 #include "kine.h"
5
6 pumatask()
7 {
8 TRSF_PTR z, e, cam, o, coord, t6r, u5i, expect, drop;
9 POS_PTR look, get, put;
10
11 z = gentr_trsl("Z", 0., 0., 864.);
12 e = gentr_trsl("E" , 0. , 0. , 170.);
13 cam = gentr_rot("CAM", 0., 0., 50., xunit, 90.);
14 expect = gentr_rot("EXPECT", 500. , 100., 600., yunit, 180.);
15 drop = gentr_rot("DROP", 400. , -100., 500., yunit, 180.);
16 o = newtrans("O", hold);
17 coord = newtrans("COORD", hold);
18
19 u5i = newtrans("U5I", varb);
20 t6r = newtrans("T6R", varb);
21
22 look = makeposition("LOOK", z, t6, e, EQ, expect, TL, e);
23 get = makeposition("GET", t6, e, EQ, coord, cam, o, TL, e);
24 put = makeposition("PUT" , z, t6, e, EQ, drop, TL, e);
25
.DE
.cs R
.br
.cs R 23
.DS L
26
27 setvel(200, 100);
28 for (; ; ) {
29 move(look);
30 waitas(goalpos == look && look->scal > .8);
31 snapshot();
32 Assigntr(t6r, t6);
33 Invert(u5i, &sncs_d.u5);
34 Trmult(coord, t6r, u5i);
35 if (!getobj(o)) {
36 break;
37 }
38 get->end = 0;
39 distance("dz", -30.);
40 move(get);
41 move(get);
42 stop(50);
43 distance("dz", -30.);
44 move(get);
45
46 waitfor(get->end);
47 waitfor(get->end);
48 CLOSE;
49 printf("closing\\\\n");
50 move(put);
51 waitfor(put->end);
52 OPEN;
53 printf("opening\\\\n");
54 }
55 move(park);
56 }
57
58 snapshot()
59 {
60 printf("snap\\\\n");
61 }
62
63 getobj(t)
64 TRSF_PTR t;
65 {
66 static int number = 5;
67
68 Trsl(t, 0., 0., 200. + number * 30.);
69 Rot(t, yunit, 10. * number);
70 return(number--);
71 }
.DE
.cs R
.PP
Line 1 includes RCCL declarations.
Line 2 includes the file
.B hand.h
that contain the two macros `OPEN' and `CLOSE' to actuate the pneumatic
gripper.
Line 4 includes the file
.B kine.h
that contains manipulator dependent informations about the kinematics.
This file contains the structure declarations and external
declarations of variables internally used by RCCL.
Since this file depends on the manipulator type it must be preceded
with the definition of the particular manipulator
(`PUMA' for the Puma 600, `STAN' for the stanford arm).
The file
.B which.h
included line 3 contains the line : ``#define PUMA'' that describe
the current implementation.
We are primarily interested in the variable called
.B snsc_d
declared in
.B kine.h
as :
.br
.cs R 23
.DS L
typedef struct sincos {
real c1, s1, c2, s2, c23, s23, c3, s3, c4, s4, c5, s5, c6, s6;
real d1x, d1y, d1z, r1x, r1z, d2x, d2y, d2z, d3x, d3y, d3z;
real h;
TRSF u5;
} SNCS, *SNCS_PTR;
extern SNCS sncs_d;
.DE
.cs R
The elements of
.B sncs_d
are kinematic parameters updated at sample time that the user may
use.
For the Puma manipulator,
the first line is the list of sines and cosines values of each joint
angles.
The second and third line exhibit the coefficients
of the Jacobian matrix that contain multiplications computed
in link 4 [9].
The fourth line of type `TRSF' is the transform $U5$ and we shall
make use of it.
.PP
Back to the program, after the pointer declaration we find, lines 11 through 20,
the allocation of transforms.
For simplicity, we will name them the same way as
the frames that they describe.
.IP "Z : "
a reference frame at the base of the manipulator.
.IP "E : "
the end effector frame.
.IP "CAM : "
the camera frame described with respect to link 4.
.IP "EXPECT : "
the position where we expect to find an object in the camera field
with respect to the Z frame.
.IP "DROP : "
the position from where we would like the manipulator to drop the
object.
.IP "O : "
The position of the object in camera coordinates that we declare as
.I hold
since it will be changed at during the task execution.
.IP "COORD : "
The position of the camera in base coordinates that is changing as the
manipulator moves.
.IP "U5I and T6R : "
auxiliary transforms that are used to hold the inverse of U5 and a copy
of T6 at the moment of taking the picture.
They will be used to compute the transform COORD, but are not used
in a position equations.
.PP
The three calls to makeposition, lines 22, 23, and 24 define to following
transform graphs :
.br
.cs R 23
.DS L
LOOK :
T6 E
-----> ----->
| |
| |
<----- ----->
Z EXPECT
.DE
.cs R
.PP
This first graph is quite ordinary.
.br
.cs R 23
.DS L
GET :
T6 E
-----> -----> <-----
| |
| |
<----- -----> ----->
COORD CAM O
.DE
.cs R
This graph describes the final position entirely in manipulator coordinates.
The transforms $COORD$ and $O$ are measured at the moment of taking
the picture and their values memorized in the motion queue.
It is mapped on the equivalent graph :
.br
.cs R 23
.DS L
GET :
CAM O
-----> ----->
| |
T4 | U5 E |
----->|-----> ----->|
| | |
| T6 | |
|------------> |
| |
<----- -----> ----->
COORD CAM O
.DE
.cs R
from which we can derive :
.EQ
~COORD~=~T6~U5 sup -1
.EN
.br
.cs R 23
.DS L
PUT :
T6 E
-----> ----->
| |
| |
<----- ----->
Z DROP
.DE
.cs R
.PP
Again, an ordinary graph.
.PP
Statement, line 27, sets the velocity and one can notice that
the motion type is left in
.I joint
mode, since we are more interested in the end of path segment
position than with the trajectories.
The body of the program is essentially a loop that will exit when the
function `getobj' returns zero value.
The function `getobj' is simulated and returns five different successive
values for the $O$ transform.
.PP
At the beginning of the loop, line 29, a motion is requested toward
the `LOOK' position.
The program is then synchronized such that `snapshot' is called at
80 per cent of the trajectory.
Note that a `waitas(look->scal > .8)' statement may not be sufficient
since after execution of the first loop the value of `look->scal'
is left at 1. as a side effect of the previous loop,
and no synchronization would be achieved.
Values of $T6$ and $U5$ are copied on the fly, and the $COORD$
transform value computed, lines 32 to 34.
The function `getobj' has the remaining trajectory time
to obtain of value for $O$.
An `approach - grasp - depart' sequence is then performed before
the next loop, lines 39 to 44.
.PP
This program is only a sketch and many improvements
are possible.
For example, we may like to interrupt the motion and proceed to
the grasp sequence as soon as a value for $O$ is obtained.
We shall see in the next section how to achieve this result.
Another variation would be to introduce a conveyor carrying objects
in the vision field of the camera.
The only required modifications would be the position equation for `GET' :
.br
.cs R 23
.DS L
get = makeposition("GET", z, t6, e, EQ, conv, coord, cam, o, TL, e);
.DE
.cs R
This is because the object position information is entirely contained
in the transforms $T4$, $CAM$, and $O$, and the position `GET'
would be tracking the conveyor.
.NH 2
Guarded Motions
.PP
This section explains how to interrup a motion
on condition.
Interrupting a motion can allow us to stop or to start the arm,
to suspend or resume a motion toward a position.
This can be achieved in all cases by setting the flag called
.B nextmove
at a non zero value.
This causes the motion currently being performed to be interrupted
and the next in the queue to begin.
The value to which the flag
.B nextmove
has been set is returned in the `code' field of the structure `POS',
described earlier.
When using this feature, the user must be careful not to conflict
with values that have a predetermined meaning for RCCL :
.br
.cs R 23
.DS L
#define OK -1
#define LIMIT -2
#define ONF -3
#define OND -4
.DE
.cs R
For example, one could use only positive values.
.PP
There are basically two ways of using the
flag
.B nextmove.
It can be set either from a background function,
or from the user's foreground process.
Let us illustrate this by an example using a simple sensor which
is a small linear potentiometer.
The distance of which the shaft is inside the body of the potentiometer
can be measured through analog channels.
The robot controller
performs analog to digital conversions
when specified via the function
.B adcopen
and the values can be read from a global array updated at sample intervals [6].
We will make use of this information to program guarded motions.
.br
.cs R 23
.DS L
1 #include "rccl.h"
2 #include "hand.h"
3 #include "rtc.h"
4 #include "umac.h"
5
6 extern struct how how;
7
8 static int sensor;
9
10 #define TOUCHED 10
11
12 pumatask()
13 {
14 int touchfn();
15 TRSF_PTR z, b1, b2, fing, getit, flip;
16 POS_PTR get, p1, p2;
17 int q;
18
19 z = gentr_trsl("Z", 0., 0., 864.);
20 b1 = gentr_trsl("B1", 600. ,-200., 400.);
21 b2 = gentr_trsl("B2", 600. ,-100., 400.);
22 fing = gentr_rot("FING", 0., 0., 200., zunit, -90.);
23 getit = gentr_rot("GETIT", 600. , 0., 600., yunit, 180.);
24 flip = gentr_rot("FLIP", 0., 0., 0., yunit, 180.);
25
26 p1 = makeposition("P1" , z, t6, fing, EQ, b1, flip,TL , fing);
27 p2 = makeposition("P2" , z, t6, fing, EQ, b2, flip,TL , fing);
28 get = makeposition("GET", z, t6, EQ, getit, TL, t6);
29
30 setvel(300, 100);
31 move(get);
32 waitfor(completed);
33 OPEN;
34 printf("put the sensor in the jaws ");
35 QUERY(q);
36 CLOSE;
37 printf("go ahead ");
38 QUERY(q);
39 if (q == 'n') {
40 move(park);
41 return;
42 }
.DE
.cs R
.br
.cs R 23
.DS L
43 sensor = adcopen(7);
44 setvel(100, 100);
45 for (; ; ) {
46 p1->end = p2->end = 0;
47 move(p1);
48 evalfn(touchfn);
49 setime(0, 0);
50 distance("dz", 100.);
51 move(p1);
52 move(p1);
53
54 move(p2);
55 evalfn(touchfn);
56 setime(0, 0);
57 distance("dz", 100.);
58 move(p2);
59 move(p2);
60
61 waitfor(p1->end)
62 printf("guarded motion 1 starts\\\\n");
63 waitfor(p1->end)
64 if (p1->code == TOUCHED)
65 printf("touched\\\\n");
66 else
67 printf("not touched\\\\n");
68
69 waitfor(p2->end)
70 printf("guarded motion 2 starts\\\\n");
71 waitfor(p2->end)
72 if (p2->code == TOUCHED)
73 printf("touched\\\\n");
74 else
75 printf("not touched\\\\n");
76
77 printf("more ? ");
78 QUERY(q); if (q == 'n') break;
79 }
80 setvel(300, 100);
81 move(park);
82 waitfor(completed);
83 OPEN;
84 }
85
86
87 touchfn()
88 {
89 if (how.adcr[sensor] > 1) {
90 nextmove = TOUCHED;
91 }
92 }
.DE
.cs R
.PP
We are now familiar with lines 1 and 2.
Line 3 includes the real time interface declarations [6], in order
to gain access to the analog conversions.
Line 4 includes the file
.B umac.h
that contains a set of useful macros (see include files),
among them we shall use
the macro `QUERY' that causes the prompt `` (y/n) '' to be printed on the termin
and will return when the user has typed a `y' or a `n'.
The typed character is then returned in the macro's argument.
Line 6 declares the type of the array in which we get the analog readings.
Line 8 allocates an integer that will be the index in the array `adcr'
of the readings of the opened analog channel.
Line 10 defines the return code of the guarded motion.
Let us skip the transforms and position initializations that
do not show anything special.
With a combination of queries we ask the operator to place
the sensor in the gripper's jaws and to command the gripper to close.
We leave to the operator the option of canceling the task on line 39
if something goes wrong.
Line 43 allocates analog channel number 7 to the sensor.
In the body of the loop, lines 45 to 78, the manipulator performs two
guarded motions : moves to a position next to an expected obstacle,
moves along the Z direction in the
.I tool
frame, while evaluating at sample intervals the monitoring function `touchfn'.
The call to
.B setime
specifies a zero transition time at the end of the motion in order to
obtain a fast reaction time.
The null transition time can be specified here as we have made sure
that the velocities are small.
We also make sure that the motion queue contains a position
such as the arm will back up when the obstacle in encountered.
This is the purpose of the move statements lines 52 and 59.
.PP
Using the
.B waitfor
macro, the program can print information
at the terminal as the task proceeds.
In particular, it is possible to decided if the guarded motion
did encounter an obstacle.
The value `TOUCHED' is returned in the `code' part of the positions if
the monitoring function caused a motion interruption, otherwise
the value `OK' is returned.
The monitoring function, lines 86 to 91, checks the analog conversion
reading and sets the flag
.B nextmove
when appropriate.
.PP
Some other combinations are possible, as shown by the following
code patterns :
.br
.cs R 23
.DS L
move(p);
evalfn(monitorfn);
setime(100, 10000);
move(p);
waitfor(completed)
if (p->code != EXPECTED) {
printf("timeout after 10 seconds\\\\n");
error();
}
move(p1);
.DE
.cs R
causes the arm to stop at the position `p' while evaluating a monitor
function, and the motion to resume on condition.
It is not possible to use a
.B stop
statement here, since
.B stop
keeps all the attributes of the previous motion and we need to specify
a new
.B move
request.
The sequence of code :
.br
.cs R 23
.DS L
evalfn(monitorfn);
move(p);
stop(1000);
move(p);
.DE
.cs R
does not causes a motion to be interrupted for one second, unless
the position `p' has been reached when the
.B stop
request is executed because it is equivalent to a new motion to the last
position.
Similarly, one must be careful that the
.B stop
statement does not necessarily mean that the manipulator will
stop in absolute coordinates if the position equation for `p' contains
moving coordinate frames.
When an absolute stop is needed or when a motion has to stop
and the manipulator has to remain exactly at the position where
it stopped, RCCL provides a built-in position equation of the
following form :
.EQ
~T6~=~HERE
.EN
where $HERE$ is a transform internally maintained by the system
to be always equal to $T6$ at the end of any path segment.
At startup time, the system issues the following call :
.br
.cs R 23
.DS L
there = makeposition("THERE", t6, EQ, here, TL, t6);
.DE
.cs R
to implement this feature, where
.B here
is of type TRSF_PTR and
.B there
of type POS_PTR.
The following code pattern shows how we can use the fact that
the flag
.B nextmove
can be set from the user's process to implement a stop on terminal input :
.br
.cs R 23
.DS L
move(p);
move(there);
printf("hit return to interrupt motion ");
getchar();
nextmove = YES;
.DE
.cs R
When `return' is hit, the system interrupts the motion toward `p',
and starts a transition to the position `there' that causes the arm to over
shoot by a magnitude as great as the velocity was high.
When the velocity is small and a sharp stop is needed we can write :
.br
.cs R 23
.DS L
move(p);
setime(0, 0);
move(there);
printf("hit return to interrupt motion ");
getchar();
nextmove = YES;
.DE
.cs R
In the same way monitoring can achieved with :
.br
.cs R 23
.DS L
move(p);
waitas(goalpos == p)
p->end = 1; /* preset event */
while(p->end) {
if (condition) {
nextmove = YES;
}
suspendfg();
}
.DE
.cs R
This way of coding can be useful in the cases when
it is not possible to place the condition calculations in the
background function.
.PP
RCCL internally monitors if the joint physical limits are
going to be reached (within a few degrees for each joint).
If such an error condition occurs, the system automatically
issues a move to the `there' position, that causes an immediate stop
next to the limit position and returns the code `LIMIT'
for the motion that caused the error condition.
A new motion is then taken out of queue and the error condition
is reset.
If the new motion persists in causing a joint limit error, the whole
task will abort.
If motions are likely to cause such joint limit errors,
the returned codes should be checked and the appropriate action
undertaken.
.NH 2
Tracking
.PP
Tracking is obtained by synchronously updating functionally defined
transforms from sensor readings.
All the examples given in the section ``Functionally defined motions''
would become examples for tracking motions if we would replace the
parameter `time' by some sensor readings reflecting the position
of the moving coordinate frames.
We shall however explain yet another example using the simple
potentiometer based position sensor introduced in the previous section.
The sensor, placed in the
.I tool
frame, allows the manipulator to track an arbitrary surface intersecting
the Z axis of the tool frame.
The tracking function is written in such a way that it causes the
motion velocity to be proportional to the distance the shaft of the linear
potentiometer
is protruding out of the sensor.
A velocity control of the manipulator
end effector is implemented such as that the shaft is partially inside the
body of the sensor, the velocity along the Z axis
of the
.I tool
frame is controlled to be zero.
.br
.cs R 23
.DS L
1 #include "rccl.h"
2 #include "rtc.h"
3 #include "umac.h"
4
5 extern struct how how;
6
7 int sensor;
8
9 pumatask()
10 {
11 TRSF_PTR z, b1, b2, fing, fins, over;
12 POS_PTR p1, p2, get;
13 int fingfn();
14 int q;
15
16 fing = newtrans("FING",fingfn);
17 Rot(fing, zunit, -90.);
18 fins = gentr_rot("FINS", 0., 0., 0., zunit, -90.);
19 z = gentr_rot("Z", 0., 0., 864., zunit, 0.);
20 b1 = gentr_rot("B1", 600. ,-300., 450., yunit, 180.);
21 b2 = gentr_rot("B2", 600. , 300., 450., yunit, 180.);
22 over = gentr_rot("OVER", 600., 0., 600., yunit, 180.);
23
24 p1 = makeposition("P1" , z, t6, fins, EQ, b1, TL, fins);
25 p2 = makeposition("P2" , z, t6, fing, EQ, b2, TL, fing);
26 get = makeposition("GET", z, t6, EQ, over, TL, t6);
27
28
29 sensor = adcopen(7);
30
31 setmod('c');
32 for (; ; ) {
33 setvel(400, 300);
34 move(get);
35 move(p1);
36 setvel(100, 100);
37 sample(15);
38 move(p2);
39 sample(30);
40 printf("more ?"); QUERY(q); if (q == 'n') break;
41 }
42 setvel(400, 300);
43 setmod('j');
44 move(park);
45 }
46
47
48
49 fingfn(t)
50 TRSF_PTR t;
51 {
52 t->p.z += (how.adcr[sensor] * .01 - 3.) / 3.;
53 }
.DE
.cs R
.PP
This example uses three positions equations.
The position P1 from where the tracking motion begins, uses
a $TOOL$ transform FINS set as a translation and a rotation
such as to present the sensor with a proper angle.
The position P2 is the end of the tracking motion, the
$TOOL$ transform FING is initialized to be equal to FINS.
However, as the motion progresses, its $p sub z$ element will
be changed by the function `fingfn' in order modify
the trajectory in the desired direction.
The function `fingfn', lines 49 to 53, implements the control law whose
parameters have been experimently determined, in terms of a gain
and an offset.
The sample rate is set at a higher value during the tracking
motion in order to obtain a faster response.
.PP
An interresting variation of this program would be
to record the value of $T6$ as the tracking proceeds.
Since it is not possible to perform any input-output
from a background function, a buffer alternating technique
would need to be implemented : while the background function fills
one buffer, the user's foreground process could dump another one on file.
It would then become possible to replay very long motion sequences,
as they have been recorded or in such a way that the
.I tool
frame would have a fixed angle with respect to the tracking
trajectory as required in welding applications (Section ``Functionally
defined motions'', example 4).
.PP
When the sensory input is too slow or when computations are too lengthy
to be performed in a background function (10 ms cpu time every 28 ms
would really tie the machine down), a pseudo tracking can be obtained
by using an asynchronous loop in the user's process updating a
.I varb
type transform.
For example :
.br
.cs R 23
.DS L
TRSF_PTR z, e, b, r;
POS_PTR p0, p1, ... , pt;
TRSF changes;
z = ...
e = ...
b = ...
r = ...
upd = newtrans("UPD", varb);
p0 = makeposition(...);
p1 = makeposition(...);
pt = makeposition("P", z, t6, e, EQ, b, upd, r, TL, e);
...
move(p0);
move(p1);
move(pt);
waitas(goalpos == pt)
while(goalpos == pt) {
getsensor(&changes);
Trmultinp(upd, &changes);
suspendfg();
}
....
.DE
.cs R
.PP
The function `getsensor' returns alterations to be performed on the
transform $UPD$, that are accumulated by successive multiplications.
The function
.B suspendfg
is used to allow the machine to ``breath''.
The changes should not cause more than a few millimeters or degrees position
steps at the end effector.
.PP
Another way to obtain this type of tracking is to use very short motions and
to synchronize them with the sensory input.
We can take advantage of the fact that no time is spend for parsing
the
.B move
instructions and the motions can be very short.
We will preferably
use the
.I joint
mode because it requires far less computations and the path approximation
remains good if the path segments are small.
As opposed to the previous method, we need to use a
.I hold
transform to keep track of all the successive values.
The
.I hold
transforms have also the property of being retained by the system
from one path to another for the transition calculations.
The code pattern may look like :
.br
.cs R 23
.DS L
...
upd = newtrans("UPD", hold);
...
move(pt);
waitfor(completed);
setmod('j');
rtime = 0;
while (rtime < tracktime) (
getsensor(&changes);
Trmultinp(upd, &changes);
move(pt);
waitas(nbrequest < 2);
}
.DE
.cs R
At the end of the loop, the
.B waitas
primitive allows the loop to proceed an perform another sensorial input
while the arm is still moving.
A look ahead is thus implemented although
it may lead to an unstable control.
If the loop is strongly synchronized by a `waitas(nbrequest < 1)',
the manipulator will stop at each loop before proceeding.
Since the successive motions are expected to be small, we
can afford to suppress of the transitions by a call to `setime(0, 0)'.
In the above examples, we have implemented the tracking in terms of
.B changes
with respect to the current position.
In other words, we assume that the sensor is linked with the
manipulator and that the changes to be performed represent the tracking
error.
.PP
Guarded motions can also be implemented using a similar technique :
.br
.cs R 23
.DS L
setmod('j');
while (getsensor() == goahead) {
Trmulinp(upd, &step);
setime(0, 0);
move(pt);
waitfor(pt->end);
}
.DE
.cs R
.PP
According to the situation, different path segment times
or velocities
as well as strategies can to be experimented.
.NH 2
Updating the World Model
.PP
For all motions terminated on a condition, keeping track of
the position where the manipulator stopped is another way
of acquiring information from the environment.
Instead of merely recording the position of the manipulator,
the
.B update
primitive allows the user to record positions in a structured manner.
The
.B update
function takes two arguments, a transform pointer, and a position
equation pointer :
.br
.cs R 23
.DS L
update(trans, pos)
TRSF_PTR trans;
POS_PTR pos;
.DE
.cs R
The
.B update
function causes the position equation `pos'
to be solved for the transform `trans',
using the value of $T6$ at the end of the corresponding path segment.
Of course, the transform must belong to the position equation.
The transform must also be of type
.I varb.
The second argument, a position equation pointer, is not necessarily
the same argument as the one of the corresponding motion statement.
For example, we can update a transform on user request :
.br
.cs R 23
.DS L
a = gentr...
e = gentr...
y = gentr...
z = gentr...
x = newtrans("X", varb);
p1 = makeposition("P1", z, t6, e, EQ, a, TL, e);
p2 = makeposition("P2", z, t6, e, EQ, x, y, TL, e);
...
update(x, p2);
move(p1);
move(p2);
printf("hit return to interrupt motion ");
getchar();
nextmove = YES;
.DE
.cs R
An update request is associated with position P1.
When the user hits `return', the motion toward P1 is interrupted and
the transform X is solved as :
.EQ
X~=~Z~T6~E~Y sup -1
.EN
and the position P2 corresponds exactly to the position the manipulator
was and a stop is obtained.
Subsequent motions to this position are therefore possible.
The transform X can also be used in other position equations.
One must notice that all the positions containing X are consequently changed.
This leads to
numerous applications of
.B update.
.bp
.NH
Force Control
.PP
In assembly tasks, objects are required to be brought into contact,
and motions have to be stopped when the collision occurs.
Once objects are in contact the task is said to be constrained
because arbitrary motions are no longer possible in every direction.
The notion of guarded motion has been introduced earlier and
force guarded motions are quite similar.
The force monitoring function is built into the system
considering that it is somewhat dependent on the installation and
that force specifications are really an integral part of a motion
description.
Force specifications are transmitted to the background process via
the
.B limit
primitive.
When the task is constrained, the arm is requested to exert
forces on objects and is no longer position servoed for
each of the six degrees of freedom.
Depending on the geometry of the task, one or several directions
are selected to provide for compliance.
The arm is then said to enter a
.I comply
mode which is specified by the
.B comply
primitive.
When the contact between objects ceases,
or when constraints disappear,
the arm has to gain back position servoed directions.
This is achieved by the
.B lock
primitive.
The cessation of contact can be detected by
differential motions of the arm when the constraints disappear.
The primitive
.B limit
is also used for this purpose.
.NH 2
Stop, Go on Force, on Displacement
.PP
As we have seen before, stop and go are not essentially different, they
both correspond to the interruption of a motion.
When a limit condition is specified, a monitor function is internally
activated for the subsequent motion.
The form of
.B limit
is :
.br
.cs R 23
.DS L
limit(dirs, value [, value] ...)
char *dirs;
double value;
.DE
.cs R
The limit directions specifications are expressed in the string
first argument with a combination of the following, separated by one
or several spaces :
.br
.cs R 23
.DS L
fx fy fz : force along X Y Z
tx ty tz : torque about X Y Z
dx dy dz : displacement along X Y Z
rx ry rz : rotation about X Y Z
.DE
.cs R
All limit specifications are expressed in the
.I tool
frame of the corresponding position equation and
take effect for the subsequent
.I move
request.
To each direction specification must correspond a value, for example :
.br
.cs R 23
.DS L
limit("fx tz", 10., 5.);
.DE
.cs R
will request a force of 10
.B Newtons
along X, and of a torque 5.
.B Newton-meter
about Z to be monitored.
When either of the specifications
is exceeded, the corresponding motion is interrupted
and the task proceeds with the next request in the motion queue.
The `code' field of the corresponding position is set to `ONF'.
Likewise, distance specifications can be coded as :
.br
.cs R 23
.DS L
limit("dx ry", 3., 1.);
.DE
.cs R
that causes the motion to be interrupted when the distance
change along X exceeds 3
.B millimeters
or when the rotations about Y exceeds 1
.B degree.
Only absolute values of the limit specifications are taken into account.
.NH 2
Servo Modes, Comply and Lock
.PP
A comply servo mode is requested via the
.B comply
primitive according to the following format :
.br
.cs R 23
.DS L
comply(dirs, value [, value] ...)
char *dirs;
double value;
.DE
.cs R
The
.B comply
primitive causes the subsequent motion request to
be executed such that forces and/or torques are maintained in the
.I tool
frame instead of positions and/or rotations.
The arm then enters the specified
.I comply
mode in the corresponding motion and all the following motions until
the
.B lock
primitive brings the manipulator back into position servo mode for
the selected directions.
The format for
.B lock
is :
.br
.cs R 23
.DS L
lock(dirs)
char *dirs;
.DE
.cs R
.PP
The first argument of
.B comply
and
.B lock
is a string containing direction specifications made up of
a combination of the following :
.br
.cs R 23
.DS L
fx fy fz : force along X Y Z
tx ty tz : torque about X Y Z
.DE
.cs R
.PP
The second argument of
.B comply
is the signed magnitude of the desired forces and/or torques.
.PP
Care must be taken that the sequence of servo mode specification is
consistent.
Requiring the arm to comply along or about a direction already in
.I comply
servo mode or locking a direction not in
.I comply
servo mode will cause an error.
In order to keep track of the different specifications, line
indentation is advised :
.br
.cs R 23
.DS L
move(p0);
comply("dy", 0.);
move(p1);
move(p2);
comply("dx ry", 5., 3.);
move(p3);
lock("ry");
move(p4);
move(p5);
lock("dx");
move(p6);
lock("dy");
move(p7);
.DE
.cs R
.PP
Either
.I Cartesian
or
.I joint
motion modes can used for complying motion sequences.
However, they behave differently.
In
.I Cartesian
mode, the system automatically compensate for position errors due to
unwanted accommodating joint motions [2].
In
.I joint
mode, there is no compensation.
.NH 2
Carrying Loads
.PP
The function
.B massis
allows the user to specify that a mass is to be carried by the manipulator.
The mass of the object, expressed in kilograms, causes the system
to compute gravity compensation terms in the motions using
force control.
The mass of object is initially set to 0. and can be set or
reset via
.B massis :
.br
.cs R 23
.DS L
massis(mass)
double mass;
.DE
.cs R
As usual, the new value is taken into account the next motion request.
.NH 2
Examples
.PP
.B
1)
.R
The first example involves a solid horizontal surface.
The manipulator is programmed to reach to the table
in a motion normal to the expected surface.
It then enters the
.I comply
mode in order to slide along.
During the second sliding motion, it detects an edge of the surface by
exerting a preload force and monitoring the position changes in the
Z direction of the
.I tool
frame.
.br
.cs R 23
.DS L
1 #include "rccl.h"
2 #include "umac.h"
3
4 pumatask()
5 {
6 TRSF_PTR z, e , b1, b2, b3, b4, b5;
7 POS_PTR p1, p2, p3, p4, p5;
8 int q;
9
10 z = gentr_trsl("Z", 0., 0., 864.);
11 e = gentr_trsl("E" , 0. , 0. , 170.);
12 b1 = gentr_rot("B1", 600. ,-100., 300., yunit, 180.);
13 b2 = gentr_rot("B2", 600. , 200., 300., yunit, 180.);
14 b3 = gentr_rot("B3", 600. , 200., 400., yunit, 180.);
15 b4 = gentr_rot("B4", 600. ,-100., 400., yunit, 180.);
16 b5 = gentr_rot("B5", 500. ,-100., 300., yunit, 180.);
17
18 p1 = makeposition("P1" , z, t6, e, EQ, b1, TL, e);
19 p2 = makeposition("P2" , z, t6, e, EQ, b2, TL, e);
20 p3 = makeposition("P3" , z, t6, e, EQ, b3, TL, e);
21 p4 = makeposition("P4" , z, t6, e, EQ, b4, TL, e);
22 p5 = makeposition("P5" , z, t6, e, EQ, b5, TL, e);
23
24
.DE
.cs R
.br
.cs R 23
.DS L
25 setmod('c');
26 setvel(200, 100);
27 move(p4);
28 for (; ; ) {
29 QUERY(q); if (q == 'n') break;
30
31 p1->end = 0;
32
33 setvel(20, 20);
34 limit("fz", 20.);
35 move(p1);
36
37 setvel(100, 50);
38 comply("fz", 10.);
39 move(p2);
40 lock("fz");
41
42
43 waitfor(p1->end);
44 if (p1->code != ONF) {
45 nextmove = YES;
46 printf("where is the table ?\\\\n");
47 setvel(200, 100);
48 move (park);
49 return;
50 }
51
52 move(p3);
53 move(p4);
54
55 limit("fz", 20.);
56 setvel(50, 50);
57 move(p1);
58
59 limit("dz", 3.);
60 comply("fz", 10.);
61 move(p5);
62 lock("fz");
63
64 move(p4);
65
66 waitfor(p5->end);
67 if (p5->code != OND) {
68 printf("where is the edge ?\\\\n");
69 }
70 }
71 setvel(300, 50);
72 move(park);
73 }
.DE
.cs R
.PP
The transforms and positions define a set of five position
next to the surface.
The surface if assumed to be less than 100 millimeters below the
position P4, such that a collision should occur when moving from
P4 to P1, located 100 millimeter below P4.
Position P3 is at the same level than P4 and above P2.
Position P5 is assumed to bring the end effector off the
boundaries of the table, when moving from P1 to P5.
As we may have more motions toward P1 that waits for the end of motion,
the `p1->end' event is reset for each loop line 31.
Lines 33 to 40, implement a sequence of motion requests so as
to program the manipulator to enter the
.I comply
when the obstacle in encountered.
Lines 43 through 50, we make sure that the limit have actually
been met, otherwise the motion toward P2 is canceled as well as the task.
In the normal case, lines 52 and 53 bring the arm back above the surface.
The same guarded motion is then performed toward P1, but now
the motion in
.I comply
servo mode is performed toward P5 where the edge of the surface is
expected to be found.
The termination of this last motion is also checked at lines 66 through 69.
A preload force in the Z direction
is applied for all motions to make sure that
the contact is maintained.
.bp
.PP
.B
2)
.R
In this second example, the manipulator is programmed for the task of
turning a crank.
Two compliant directions are required in this operation.
During the compliant motion, the
.I tool
frame rotates so as to keep a constant
orientation with respect to the crank handle.
We define the compliant directions with respect to this frame.
A grasp position is also defined to allow for some clearance.
The task will turn the crank a given number of times.
One turn is programmed to last 4 seconds.
.br
.cs R 23
.DS L
1 #include "rccl.h"
2 #include "umac.h"
3 #include "hand.h"
4
5 int turns;
6
7 pumatask()
8 {
9 TRSF_PTR z, e, shaft, handle, apro, grasp, rotpx, rotnx;
10 POS_PTR get, away;
11 POS_PTR turn;
12 int pxfn(), nxfn();
13 int q;
14
15 rotpx = newtrans("ROTPX", pxfn);
16 rotnx = newtrans("ROTNX", nxfn);
17 z = gentr_trsl("Z", 0., 0., 864.);
18 e = gentr_trsl("E" , 0. , 0. , 170.);
19 shaft = gentr_trsl("SHAFT", -200., 500., 600.);
20 shaft->fn = varb;
21 handle = gentr_trsl("HANDLE", 0., 0., 50.);
22 apro = gentr_trsl("APRO", -50., 0., 0.);
23 grasp = gentr_rpy("GRASP", 0., 0., 0., 0., 190., 0.);
24
25 get = makeposition(
26 "GET", z, t6, e, EQ, shaft, handle, grasp, TL, e);
27
28 away = makeposition(
29 "AWAY", z, t6, e, EQ, shaft, handle, grasp, apro, TL, e);
30
31 turn = makeposition(
32 "TURN", z, t6, e, EQ, shaft, rotpx, handle, rotnx, grasp, TL, ro
33
34 setvel(300, 300);
35 move(away);
36 OPEN;
37 if (!teach(shaft, get)) {
38 move(away);
39 move(park);
40 return;
41 }
.DE
.cs R
.br
.cs R 23
.DS L
42 shaft->fn = const;
43 optimize(turn);
44 turns = 4;
45 waitfor(completed);
46 CLOSE;
47 comply("fx fz ", 0., 0.);
48 movecart(turn, 200, 4000 * turns);
49 lock("fx fz ");
50 move(get);
51 waitfor(turn->end);
52 OPEN;
53 distance("dx", -30.);
54 move(get);
55 setvel(200, 50);
56 setmod('j');
57 move(park);
58 }
59
60 pxfn(t)
61 TRSF_PTR t;
62 {
63 Rot(t, xunit, goalpos->scal * 360 * turns);
64 }
65
66 nxfn(t)
67 TRSF_PTR t;
68 {
69 Rot(t, xunit, - goalpos->scal * 360 * turns);
70 }
.DE
.cs R
.PP
The manipulator is first moved to a safe position away from
obstacles.
Lines 37 to 41, the manual teach mode built in RCCL is called.
This teach mode makes use of the
.B update
function to record a position.
That is why the transform $SHAFT$ is first declared as a
.I varb
transform.
Once this transform is taught, its type can be changed, line 42, and the
position $TURN$ optimized line 43.
Gripper actions are obtained as usual.
Once these preliminary operations are performed, the turning motion
can begin.
It is obtained in terms of a functionally defined motion, line 48,
executed in
.I comply
servo mode.
The duration of the motion is the number of turns times four seconds.
Care has been taken line 32, such that the compliance frame is
properly specified.
.bp
.PP
.B
3)
.R
The third example illustrates the peg in a hole insertion task.
The strategy consists of moving toward the expected location of
the hole with a small approach angle.
Even with a poor position accuracy the end of the peg will enter
the hole with a high degree of confidence.
As soon as a collision occurs, the manipulator is programmed to
go in
.I comply
mode in the Z direction with a preload force in the same direction.
While complying, the peg is rotated so as to be aligned with the axis of
the hole.
The manipulator is then programmed to comply in the normal directions
of the hole axis and
a motion inside the hole is immediately started.
The presence of a small chamfer helps the peg not to slip off the
initial insertion position.
The force in Z is also limited since the insertion may jam
due to a misalignment.
The fit is not very tight, and we can expect that a
portion of the peg is inserted before the jam occurs.
A sequence of four accommodation rotating motions
using
.B update,
allows the
manipulator to ``feel'' the walls of the hole and to record a correct alignment.
In a final effort, the peg is inserted all the way.
Finally, the peg is pulled out with no difficulty since the alignment
has been corrected.
The moment when the task becomes unconstrained is detected by
monitoring the differential motions.
.br
.cs R 23
.DS L
1 #include "rccl.h"
2 #include "umac.h"
3 #include "hand.h"
4
5 pumatask()
6 {
7 TRSF_PTR z, e, peg, hole, roty, bottom, angle;
8 POS_PTR align, in, touch;
9 int q;
10
11 z = gentr_trsl("Z", 0., 0., 864.);
12 e = gentr_trsl("E" , 0. , 0. , 140.);
13 peg = gentr_trsl("PEG", 0., 0., 10.);
14 hole = gentr_trsl("HOLE", -50., 450., 500.);
15 hole->fn = varb;
16 bottom = gentr_trsl("BOTTOM", 0., 0., -20.);
17 roty = gentr_rot("ROTY", 0., 0., 0., yunit, 180.);
18 angle = gentr_rot("ANGLE", 0., 0., 0., yunit, 12.);
19
20 align = makeposition(
21 "ALIGN", z, t6, e, peg, EQ, hole, roty, TL, peg);
22
23 touch = makeposition(
24 "TOUCH", z, t6, e, peg, EQ, hole, angle, roty, TL, peg);
25
26 in = makeposition(
27 "IN", z, t6, e, peg, EQ, hole, bottom, roty, TL, peg);
28
29 setvel(300, 50);
30 move(align);
31 if (!teach(hole, align)) {
32 setvel(300, 50);
33
34 distance("dz", -100.);
35 move(align);
36
37 setmod('j');
38 move(park);
39 return;
40 }
41 setmod('c');
42 setvel(100, 100);
43
44 distance("dz", -10.);
45 move(touch);
46
47 QUERY(q);
48
49 if (q == 'n') {
50 setvel(300, 100);
51 setmod('j');
52 move(park);
53 return;
54 }
.DE
.cs R
.br
.cs R 23
.DS L
57 setvel(4, 7);
58 distance("dz", -4.);
59 move(touch);
60
61 limit("fz", 25.);
62 distance("dz", 5.);
63 move(touch);
64
65 comply("fz", 15.);
66 move(align);
67 lock("fz");
68
69 comply("fx fy", 0., 0.);
70 limit("fz", 20.);
71 move(in);
72
73 update(hole, in);
74 limit("fz tx", 40., 10.);
75 distance("rx", 2.);
76 move(in);
77
78 update(hole, in);
79 limit("fz tx", 40., 10.);
80 distance("rx", -2.);
81 move(in);
82
83 update(hole, in);
84 limit("fz ty", 40., 10.);
85 distance("ry", 2.);
86 move(in);
87
88 update(hole, in);
89 limit("fz ty", 40., 10.);
90 distance("ry", -2.);
91 move(in);
92
93 update(hole, in);
94 limit("fz", 20.);
95 distance("dz", 10.);
96 move(in);
97
98 limit("dx dy", 1., 1.);
99 move(align);
100 lock("fx fy");
101
102 setvel(50, 50);
103 distance("dz", -50.);
104 move(align);
105
106 setvel(300, 50);
107 setmod('j');
108 move(park);
109 }
.DE
.cs R
.PP
The beginning of this task is quite similar to the previous example and
also makes use of the manual teach mode to record an approximate
initial position.
Lines 44 and 45, the manipulator moves to an approach position
and a chance is given to the user to cancel the task.
Line 57 to 63, an approach motion and a purposely over shooting motion
is programmed in order to obtain the initial phase of the insertion
process.
While complying and exerting a preloading force the peg is rotated,
lines 65 to 67, to the aligned position.
The first insertion attempt is performed line 70 and 71.
Lines 70 to 91, are programmed the accommodation motions using
.B update
to record the successive alignments.
The final phase of the insertion process is performed lines at 93 to 96.
The peg is then pulled out of the hole, while monitoring the
differential motions signaling that the motion becomes unconstrained.
The peg is then taken away lines 102 to 104.
.bp
.PP
.B
4)
.R
The last example demonstrates how compliant degrees of freedom
can be accumulated as constraints are met.
The manipulator is programmed to detect the walls of a corner and to
record the position of the corner.
The program then uses this position information to move the manipulator
next to the corner within a very small distance.
.br
.cs R 23
.DS L
1 #include "rccl.h"
2 #include "umac.h"
3
4 pumatask()
5 {
6 TRSF_PTR z, e, peg, corner, roty;
7 POS_PTR pcor;
8 int q;
9
10 z = gentr_trsl("Z", 0., 0., 864.);
11 e = gentr_trsl("E" , 0. , 0. , 140.);
12 peg = gentr_trsl("PEG", 0., 0., 10.);
13 corner = gentr_trsl("CORNER", -50., 500., 550.);
14 corner->fn = varb;
15 roty = gentr_rot("ROTY", 0., 0., 0., yunit, 180.);
16
17 pcor = makeposition(
18 "PCOR", z, t6, e, peg, EQ, corner, roty, TL, peg);
19
20 setvel(300, 50);
21 move(pcor);
22 if (!teach(corner, pcor)) {
23 setvel(300, 50);
24
25 setmod('j');
26 move(park);
27 return;
28 }
29 setmod('c');
30 setvel(100, 100);
31
32 distance("dz", -50.);
33 move(pcor);
34
35 QUERY(q);
36
37 if (q == 'n') {
38 setvel(300, 100);
39 setmod('j');
40 move(park);
41 return;
42 }
43 move(pcor);
44
45 setvel(5, 20);
.DE
.cs R
.br
.cs R 23
.DS L
46
47 limit("fz", 20.);
48 distance("dz", 10.);
49 move(pcor);
50 comply("fz", 10.);
51 limit("fy", 15.);
52 distance("dy", -10.);
53 move(pcor);
54 comply("fy", -10.);
55 update(corner, pcor);
56 limit("fx", 25.);
57 distance("dx", 10.);
58 move(pcor);
59 lock("fz fy");
60 setvel(50, 50);
61 distance("dx dy dz", -10., 10., -50.);
62 move(pcor);
63
64 setvel(300, 50);
65 setmod('j');
66 move(park);
67 distance("dx dy dz", -10., 10., -50.);
68 move(pcor);
69 setmod('c');
70 setvel(50, 50);
71 distance("dx dy dz", -1., 1., -1.);
72 move(pcor);
73 distance("dx dy dz", -10., 10., -50.);
74 move(pcor);
75 setvel(300, 50);
76 setmod('j');
77 move(park);
78 }
.DE
.cs R
.PP
Again the preliminary phase is quite similar to the previous
example.
The approximate location of the corner is taught by an operator and
a chance is also given, line 32 to 43, to cancel the task.
The reader may notice that in this example, the corner is oriented
in such a way that approaching it corresponds to positive
displacements in the X and Z directions, and a negative one in the Y
direction.
The manipulator approaches the first wall of the corner moving along the
Z direction, lines 48 and 49, and enters the first
.I comply
mode, line 50, before moving to the next wall.
The same process is repeated for the Y and Z directions.
In each case a preload force is exerted in the appropriate direction
in order to maintain contact with the walls.
The last accommodation motion, line 58, is associated to a call
to
.B update
so as to record the final position.
Two compliance degrees of freedom are accumulated and the
manipulator is brought back to position servo mode line 59.
The peg is then taken away, lines 60 to 62.
Before going back to the recorded position, the arm is
moved at high velocity to the PARK position.