home *** CD-ROM | disk | FTP | other *** search
/ Between Heaven & Hell 2 / BetweenHeavenHell.cdr / 500 / 470 / rccl017 < prev    next >
Text File  |  1987-03-02  |  25KB  |  930 lines

  1. .ND
  2. .EQ
  3. delim $$
  4. .EN
  5. .nr H1 3
  6. .NH 1
  7. Basic Components : Numbers, Vectors, Transformations, Differential motions, Forc
  8. .PP
  9. We shall now describe in more detail the meaning and form of a first set of
  10. RCCL primitives and how they can be used in manipulator programs.
  11. .SH
  12. REMARKS
  13. .PP
  14. All RCCL functions returning a structure, follow the
  15. convention that the result is the left argument (output argument)
  16. and that first argument is returned as the
  17. .B value
  18. of the function (in the same style as
  19. .B strcat
  20. does).
  21. This allows to code in the following style :
  22. .br
  23. .cs R 23
  24. .DS L
  25.         trans = rot(newtrans("TRANS", const), zunit, 90.);
  26. .DE
  27. .cs R
  28. which in one line, allocates a transform and sets it to a pure rotation
  29. around the Z direction.
  30. Because the type of each function is declared in the file
  31. .B rccl.h
  32. , the program lint will complain if the returned value is not used.
  33. Each function of this style is associated with a macro that
  34. capitalizes the first letter.
  35. In case of `rot', the macro is :
  36. .br
  37. .cs R 23
  38. .DS L
  39. #define Rot     (void) rot
  40. .DE
  41. .cs R
  42. such that the same above code can be written as:
  43. .br
  44. .cs R 23
  45. .DS L
  46.         trans = newtrans("TRANS", const);
  47.         Rot(trans, zunit, 90.);
  48. .DE
  49. .cs R
  50. without complains from lint.
  51. .NH 2
  52. Numbers
  53. .PP
  54. The
  55. .B rccl.h
  56. include file contains structured definitions of vectors
  57. and transformations that
  58. should be used in connection with the corresponding functions.
  59. These structure declarations are preceded with C `typedef' definitions that
  60. better describe the implementations of basic data types :
  61. .br
  62. .cs R 23
  63. .DS L
  64. typedef int bool;
  65.  
  66. typedef float real;
  67. .DE
  68. .cs R
  69. C knows two floating point variable types : double and float.
  70. They correspond on most machines to single and double precision floating
  71. point representation and arithmetic.
  72. For efficiency, all calculations are performed in single precision.
  73. In order to insure consistency throughout the RCCL code, the type `real'
  74. has been declared as a C typedef.
  75. Every single floating point variable
  76. is declared as such.
  77. Because C structures are always passed by address, and
  78. because `double' and `float' variables have different sizes,
  79. the proper address calculations are insured.
  80. However, automatic type conversions will give meaningful results
  81. if type `double' variables are assigned to or from RCCL variables.
  82. .PP
  83. A set of math constant global variables is included in the library :
  84. .br
  85. .cs R 23
  86. .DS L
  87.         real pi_m      is    PI
  88.         real pib2_m    is    PI / 2
  89.         real pit2_m    is    PI * 2
  90.         real dgtord_m  is    PI / 180
  91.         real rdtodg_m  is    180 / PI
  92. .DE
  93. .cs R
  94. .PP
  95. The purpose of those variables is to avoid a unnecessary
  96. increase of the size of process data region (see end(2)) and
  97. they are initialized at compile time.
  98. Setting them to any other values guarantees unpredictable results.
  99. .NH 2
  100. Vectors
  101. .PP
  102. The type `vector' is described by the following structure :
  103. .br
  104. .cs R 23
  105. .DS L
  106. typedef struct vector {
  107.                 real x, y, z;
  108. } VECT, *VECT_PTR;
  109. .DE
  110. .cs R
  111. The C `typedef' feature is a way of giving another name to basic data
  112. types.
  113. .PP
  114. A C structure variable `k' implementing a vector can either be coded as:
  115. .br
  116. .cs R 23
  117. .DS L
  118.         struct vector k;
  119. or
  120.         VECT k;
  121. .DE
  122. .cs R
  123. .PP
  124. A pointer to a vector variable can either be coded as :
  125. .br
  126. .cs R 23
  127. .DS L
  128.         struct vector *pk;
  129. or
  130.         VECT *pk;
  131. or
  132.         VECT_PTR pk;
  133. .DE
  134. .cs R
  135. The choice is according to taste and coding habits.
  136. Using this structure gives access to the following functions:
  137. .B dot,
  138. .B assignvect,
  139. .B cross,
  140. and
  141. .B unit.
  142. In order to describe the argument types of these functions
  143. and the type of the value that they return,
  144. their heading declarations are displayed :
  145. .br
  146. .cs R 23
  147. .DS L
  148.         real dot(u, v)
  149.         VECT_PTR u, v;
  150.  
  151.         VECT_PTR assignvect(v, u)
  152.         VECT_PTR v, u;
  153.  
  154.         VECT_PTR cross(r, u, v)
  155.         VECT_PTR r, u, v;
  156.  
  157.         VECT_PTR unit(v, u)
  158.         VECT_PTR v, u;
  159. .DE
  160. .cs R
  161. The function
  162. .B dot
  163. returns the dot product of two vectors.
  164. The function
  165. .B assignvect
  166. copies its second argument into the first one.
  167. Likewise, the function
  168. .B cross
  169. returns in its left argument the cross product of the two remaining
  170. arguments.
  171. The function
  172. .B unit
  173. computes a vector collinear with its right argument vector
  174. but of unit magnitude.
  175. Taking the cross product of two identical vectors is meaningless.
  176. By contrast, the
  177. .B unit
  178. function can perfectly take two identical arguments.
  179. In that case, the magnitude of the vector would be set to unity `in place'.
  180. .NH 2
  181. Transformations
  182. .PP
  183. The corresponding C structure is :
  184. .br
  185. .cs R 23
  186. .DS L
  187. typedef int(* TRFN)();
  188.  
  189. typedef struct transform {
  190.                 char *name;
  191.                 TRFN fn;
  192.                 VECT n, o, a, p;
  193.                 int timeval;
  194. } TRSF, *TRSF_PTR;
  195. .DE
  196. .cs R
  197. The first entry in the structure is a pointer to a string that stands
  198. for the transform name.
  199. The second, is a pointer to a function.
  200. The function pointer can be set to one of the user's background
  201. real-time function
  202. or to one of the system functions
  203. .B const,
  204. .B varb,
  205. or
  206. .B hold.
  207. A more complete discussion of this point occurs later.
  208. For now, we can assume that this pointer will most
  209. of the time point to the
  210. .B const
  211. function, meaning that the transform is constant transformation
  212. and will not change throughout the execution of the task.
  213. The next entry contains the value of the transform itself built in terms
  214. of four vectors: the
  215. .B normal,
  216. .B orientation,
  217. .B approach,
  218. and
  219. .B position
  220. vectors.
  221. The last row the transform is assumed to be : {0 0 0 1}.
  222. In other words, the transforms can only be orthogonal transforms.
  223. The last entry is the time of the last evaluation of the function,
  224. needed in the case of functionally described transforms.
  225. .PP
  226. This type declaration gives access to the following functions :
  227. .br
  228. .cs R 23
  229. .DS L
  230.         TRSF_PTR assigntr(t1, t2)
  231.         TRSF_PTR t1, t2;
  232.  
  233.         TRSF_PTR taketrsl(t1, t2)
  234.         TRSF_PTR t1, t2;
  235.  
  236.         TRSF_PTR takerot(t1, t2)
  237.         TRSF_PTR t1, t2;
  238.  
  239.         TRSF_PTR trmult(r, t1, t2)
  240.         TRSF_PTR r, t1, t2;
  241.  
  242.         TRSF_PTR trmultinp(r, t)
  243.         TRSF_PTR r, t;
  244.  
  245.         TRSF_PTR trmultinv(r, t)
  246.         TRSF_PTR r, t;
  247.  
  248.         TRSF_PTR invert(r, t)
  249.         TRSF_PTR r, t;
  250.  
  251.         TRSF_PTR invertinp(t)
  252.         TRSF_PTR t;
  253. .DE
  254. .cs R
  255. The
  256. .B assigntr
  257. function is quite similar to the
  258. .B assignvect
  259. function above and the same remarks can be made.
  260. It must, however, be noticed that only the value part of the transform
  261. is copied and not the other components of the structure.
  262. The functions
  263. .B taketrsl
  264. and
  265. .B takerot
  266. perform a selective copy of the translational (resp. rotational) part,
  267. and leaves untouched the rotational (resp. translational) part.
  268. The function
  269. .B trmult
  270. multiplies the two right arguments transforms and leaves the
  271. result in the left argument.
  272. This function requires the three arguments to be different.
  273. The function
  274. .B trmultinp
  275. multiplies the two arguments and leaves the result in the
  276. left argument.
  277. The function
  278. .B trmultinv
  279. multiplies the left argument by the inverse of the right one and leave the
  280. result in the left argument.
  281. The function
  282. .B invert
  283. leaves in the left argument the inverse the right one.
  284. Since the arguments must be different, the function
  285. .B invertinp
  286. performs an inversion `in place'.
  287. .PP
  288. The following functions selectively set the terms of the transformations :
  289. .br
  290. .cs R 23
  291. .DS L
  292.         TRSF_PTR trsl(t, px, py, pz)
  293.         TRSF_PTR t;
  294.         real px, py, pz;
  295.  
  296.         TRSF_PTR vao(t, ax, ay, az, ox, oy, oz)
  297.         TRSF_PTR t;
  298.         real ax, ay, az, ox, oy, oz;
  299.  
  300.         TRSF_PTR rot(t, k, h)
  301.         TRSF_PTR t;
  302.         VECT_PTR k;
  303.         real h;
  304.  
  305.         TRSF_PTR eul(t, phi, the, psi)
  306.         TRSF_PTR t;
  307.         real phi, the, psi;
  308.  
  309.         TRSF_PTR rpy(t, phi, the, psi)
  310.         TRSF_PTR t;
  311.         real phi, the, psi;
  312. .DE
  313. .cs R
  314. All these functions use a transformation pointer as left argument, which
  315. as usual is returned as a value of the function.
  316. The function
  317. .B trsl
  318. sets the terms of the $p$ vector of the transformation and leaves
  319. the rotational part untouched.
  320. All distances in RCCL are expressed in millimeters.
  321. The function
  322. .B vao
  323. sets the vectors $n$, $o$, and $a$ of the transformation.
  324. Since the vectors $n$, $o$ and $a$ are orthogonal,
  325. .B vao
  326. only needs the terms of $o$ and $a$ and builds the vector $n$.
  327. The vectors whose components are passed as arguments do not need to
  328. be orthogonal.
  329. The rotational part of the transform is built as follows: take the
  330. user's supplied $a$ vector, normalize it and use it as the final $a$ vector,
  331. take
  332. the user's supplied $o$ vector (which may not be orthogonal) and
  333. build a possibly non unit vector $n$ but orthogonal with $o$ and $a$,
  334. reconstruct $o$ as to be orthogonal with $n$ and $a$,
  335. normalize it, and finally
  336. derive $n$ from $o$ and $a$.
  337. The function
  338. .B rot
  339. sets the rotational part of the transformation as a rotation around
  340. a vector possibly unnormalized, second argument,
  341. of a given angle, third argument, expressed in
  342. degrees.
  343. The function
  344. .B eul
  345. sets the rotational part of the transformation as a rotation expressed
  346. with Euler angles in degrees.
  347. Finally, the function
  348. .B rpy
  349. sets the rotational part of the transformation as a rotation expressed
  350. with roll, pitch, and yaw angles in degrees.
  351. These rotation setting functions leaves the translational part
  352. of the transform untouched.
  353. .PP
  354. The next set of functions are similar in form to the previous ones, except
  355. that the transform, left argument, is multiplied by a translation
  356. or a rotation (which is quite a different thing).
  357. As usual, the left argument transformation pointer is returned as value of the
  358. function.
  359. .br
  360. .cs R 23
  361. .DS L
  362.         TRSF_PTR trslm(t, px, py, pz)
  363.         TRSF_PTR t;
  364.         real px, py, pz;
  365.  
  366.         TRSF_PTR vaom(t, ax, ay, az, ox, oy, oz)
  367.         TRSF_PTR t;
  368.         real ax, ay, az, ox, oy, oz;
  369.  
  370.         TRSF_PTR rotm(t, k, h)
  371.         TRSF_PTR t;
  372.         VECT_PTR k;
  373.         real h;
  374.  
  375.         TRSF_PTR eulm(t, phi, the, psi)
  376.         TRSF_PTR t;
  377.         real phi, the, psi;
  378.  
  379.         TRSF_PTR rpym(t, phi, the, psi)
  380.         TRSF_PTR t;
  381.         real phi, the, psi;
  382. .DE
  383. .cs R
  384. As stated at the beginning of this section, when the value of the function
  385. is unwanted, a set a macros is provided.
  386. They produce the following list
  387. of names :
  388. .br
  389. .cs R 23
  390. .DS L
  391. Assignvect      Cross           Unit
  392. Assigntr        Taketrsl        Takerot
  393. Trmult          Trmulinp        Trmultinv
  394. Invert          Invertinp
  395. Trsl            Vao             Rot             Eul            Rpy
  396. Trslm           Vaom            Rotm            Eulm           Rpym
  397. .DE
  398. .cs R
  399. As we are able to specify the rotational part of transforms with
  400. Euler or roll, pitch, yaw angles, we may need to derive them from
  401. a given transformation.
  402. These representations are not unique for
  403. a given rotation.
  404. The functions are :
  405. .br
  406. .cs R 23
  407. .DS L
  408.         noatoeul(phi, the, psi, t)
  409.         real *phi, *the, *psi;
  410.         TRSF_PTR t;
  411.  
  412.         noatorpy(phi, the, psi, t)
  413.         real *phi, *the, *psi;
  414.         TRSF_PTR t;
  415. .DE
  416. .cs R
  417. Please note that the three first arguments are
  418. .B pointers
  419. to the three results of the pseudo type `real'.
  420. .PP
  421. We now need to use transformation as easily as
  422. we would use simple data types in C.
  423. At the beginning of manipulation functions, one needs
  424. to declare transformations and to allocate memory for them.
  425. This can be done in the following manner :
  426. .br
  427. .cs R 23
  428. .DS L
  429. pumatask()
  430. {
  431.         TRSF base;
  432.  
  433.         ...
  434.         ...
  435. }
  436. .DE
  437. .cs R
  438. This way of allocating memory for transformations presents three major
  439. drawbacks.
  440. The first one is that dynamic variables, allocated in the
  441. stack, only live the duration of the function call.
  442. Since the execution of manipulator programs is not explicitly synchronized
  443. with the calculation of trajectories,
  444. the function may well exit before the requested motions
  445. are completed.
  446. All the memory space allocated in the stack would be allocated for
  447. other purposes.
  448. This will surely cause a lot a trouble because the values of the
  449. transformations are used for the trajectory calculations.
  450. One may go around this by writing :
  451. .br
  452. .cs R 23
  453. .DS L
  454.         static TRSF base;
  455. .DE
  456. .cs R
  457. but the space would remain permanently allocated.
  458. The second trouble is that the value of the transforms and other
  459. entries in the structure need to be initialized.
  460. If one chooses to use dynamic stack allocations,
  461. one also need to synchronize the function such as it does not exit
  462. before the transforms are no longer in use :
  463. .br
  464. .cs R 23
  465. .DS L
  466. pumatask()
  467. {
  468.         TRSF base;
  469.  
  470.         base.name = "NAME";             /* set the name */
  471.         base.fn = const;                /* tell it's constant */
  472.         Assigntr(&base, unitr);         /* init to unit transform */
  473.         Trsl(&base, 0., 0., 200.);      /* set it to a translation */
  474.         base.timeval = 0;               /* reset time eval */
  475.  
  476.         ...
  477.  
  478.         waitfor(completed)              /* make sure not any more in use */
  479. }
  480. .DE
  481. .cs R
  482. The third drawback is that we will most of the time refer to transforms
  483. by pointers, and it would lead to a heavy use the the `&' operator.
  484. The initialization statement for a static `TRSF' variable would not be
  485. any more convenient and would be very error prone:
  486. .br
  487. .cs R 23
  488. .DS L
  489.         static TRSF base = {"BASE",
  490.                             const,
  491.                             1.,0.,0.,
  492.                             0.,1.,0.,
  493.                             0.,0.,1.,
  494.                             0.,0.,200.
  495.                             0,
  496.                            };
  497. .DE
  498. .cs R
  499. .PP
  500. Although the techniques described above are perfectly viable,
  501. RCCL provides a built-in dynamic memory allocation
  502. system for transforms (and positions).
  503. The basic call is the function
  504. .B newtrans :
  505. .br
  506. .cs R 23
  507. .DS L
  508.         TRSF_PTR newtrans(n, fn)
  509.         char *n, TRFN fn;
  510. .DE
  511. .cs R
  512. This function returns a pointer to a transform initialized to the
  513. unit transform.
  514. The second argument is a pointer to a function, either one
  515. of the user's functions which ,as we will see,
  516. have to possess certain properties,
  517. or one of the predefined functions
  518. .B
  519. const, varb, hold.
  520. .R
  521. Since
  522. .B newtrans
  523. dynamically allocate memory in user space,
  524. the creation of too many transforms will
  525. cause a program exit with the message ``mem. alloc error''.
  526. The statement :
  527. .br
  528. .cs R 23
  529. .DS L
  530.         freetrans(t);
  531. .DE
  532. .cs R
  533. permits the system to free the allocated memory when needed (it is implemented
  534. as a macro).
  535. .PP
  536. Other RCCL functions make use of
  537. .B newtrans
  538. as a short hand for common coding patterns:
  539. .br
  540. .cs R 23
  541. .DS L
  542.         TRSF_PTR gentr_trsl(name, px, py, pz)
  543.         char *name;
  544.         real px, py, pz;
  545.  
  546.         TRSF_PTR gentr_rot(name, px, py, pz, k, h)
  547.         char *name;
  548.         real px, py, pz, h;
  549.         VECT_PTR k;
  550.  
  551.         TRSF_PTR gentr_pao(name, px, py, pz, ax, ay, az, ox, oy, oz)
  552.         char *name;
  553.         real px, py, pz, ax, ay, az, ox, oy, oz;
  554.  
  555.         TRSF_PTR gentr_eul(name, px, py, pz, phi, the, psi)
  556.         char *name;
  557.         real px, py, pz, phi, the, psi;
  558.  
  559.         TRSF_PTR gentr_rpy(name, px, py, pz, phi, the, psi)
  560.         char *name;
  561.         real px, py, pz, phi, the, psi;
  562. .DE
  563. .cs R
  564. These functions permit us to create transformations and initialize
  565. them all at once.
  566. They all return a pointer to the created transforms
  567. by default set as
  568. .B const
  569. transforms.
  570. The first four arguments are : the name (string), and the components of
  571. the $p$ vector.
  572. For creating transforms containing non unit rotations,
  573. the expression of the rotational part is analogous to the previous
  574. family of functions.
  575. For example :
  576. .br
  577. .cs R 23
  578. .DS L
  579.         TRSF_PTR t1, t2, t3;    /* declare transform pointers */
  580.  
  581.         ...
  582.  
  583.         t1 = trsl(eul(newtrans("T1", const), 10., 20., 30.), 1., 2., 3.);
  584.  
  585.         t2 = gentr_eul("T2", 1., 2., 3., 10., 20., 30.);
  586.  
  587.         t3 = gentr_trsl("T3", 1., 2., 3.);
  588.         Eul(t3, 10., 20., 30);
  589. .DE
  590. .cs R
  591. give three identical transforms.
  592. .PP
  593. The last group of transformation related functions are for output :
  594. .br
  595. .cs R 23
  596. .DS L
  597.         printr(t, fp)
  598.         TRSF_PTR t;
  599.         FILE *fp;
  600.  
  601.         printe(e, fp)
  602.         TRSF_PTR e;
  603.         FILE *fp;
  604.  
  605.         printy(e, fp)
  606.         TRSF_PTR e;
  607.         FILE *fp;
  608.  
  609.         printrn(t, fp)
  610.         TRSF_PTR t;
  611.         FILE *fp;
  612. .DE
  613. .cs R
  614. The function
  615. .B printr
  616. prints the numerical value of the transform, first argument.
  617. The functions
  618. .B printe
  619. and
  620. .B printy
  621. respectively print the Euler and pith, roll, yaw angles.
  622. The function
  623. .B printrn
  624. prints the name, the numerical value and the angles altogether.
  625. All these functions take as a second argument a UNIX file pointer.
  626. As an example, the output of the following sequence of calls :
  627. .br
  628. .cs R 23
  629. .DS L
  630.         TRSF_PTR t1, t2, t3;
  631.  
  632.         t1 = gentr_eul("T1", 10., 20., 30., 11., 12., 13.);
  633.         printf("part 1\\\\n");
  634.         printe(t1, stdout);
  635.         printrn(t1, stdout);
  636.  
  637.         t2 = newtrans("T2", const);
  638.         printf("part 2\\\\n");
  639.         printr(t2, stdout);
  640.         Rot(t2, yunit, 90.);
  641.         Trslm(t2, 10., 20., 30.);
  642.         printrn(t2, stdout);
  643.  
  644.         t3 = newtrans("T3", const);
  645.         printf("part 3\\\\n");
  646.         printrn(trmult(t3, t1, t2), stdout);
  647.  
  648.         printf("part 4\\\\n");
  649.         printrn(trmult(t3, t2, t1), stdout);
  650. .DE
  651. .cs R
  652. would be :
  653. .br
  654. .cs R 23
  655. .DS L
  656. part 1
  657. EUL x:10.000  y:20.000  z:30.000  phi:11.000  the:12.000  psi:13.000
  658. T1 :
  659.    0.893   -0.402    0.204   10.000
  660.    0.403    0.914    0.040   20.000
  661.   -0.203    0.047    0.978   30.000
  662. EUL x:10.000  y:20.000  z:30.000  phi:11.000  the:12.000  psi:13.000
  663. RPY x:10.000  y:20.000  z:30.000  phi:24.280  the:11.688  psi:2.738
  664. part 2
  665.    1.000    0.000    0.000    0.000
  666.    0.000    1.000    0.000    0.000
  667.    0.000    0.000    1.000    0.000
  668. T2 :
  669.    0.000    0.000    1.000   30.000
  670.    0.000    1.000    0.000   20.000
  671.   -1.000    0.000    0.000  -10.000
  672. EUL x:30.000  y:20.000  z:-10.000 phi:0.000   the:90.000  psi:0.000
  673. RPY x:30.000  y:20.000  z:-10.000 phi:0.000   the:90.000  psi:0.000
  674. part 3
  675. T3 :
  676.   -0.204   -0.402    0.893   26.700
  677.   -0.040    0.914    0.403   49.973
  678.   -0.978    0.047   -0.203   15.076
  679. EUL x:26.700  y:49.973  z:15.076  phi:24.280  the:101.688 psi:2.738
  680. RPY x:26.700  y:49.973  z:15.076  phi:-169.000 the:78.000  psi:167.000
  681. part 4
  682. T3 :
  683.   -0.203    0.047    0.978   60.000
  684.    0.403    0.914    0.040   40.000
  685.   -0.893    0.402   -0.204  -20.000
  686. EUL x:60.000  y:40.000  z:-20.000 phi:2.323   the:101.776 psi:24.240
  687. RPY x:60.000  y:40.000  z:-20.000 phi:116.707 the:63.207  psi:116.922
  688. .DE
  689. .cs R
  690. This should also suffice to remind us that the matrix product (and also
  691. orthogonal transforms products) is not commutative.
  692. .NH 2
  693. Differential Motions and Forces.
  694. .PP
  695. Although RCCL do not explicitly use the structured representation of
  696. differential motions
  697. or generalized forces
  698. in manipulation primitive
  699. calls, they are made available to the user.
  700. A differential motion is expressed in terms of a differential
  701. translation vector and differential rotation vector.
  702. A generalized force is expressed in terms of a linear force vector
  703. and a moment vector.
  704. The corresponding structures are :
  705. .br
  706. .cs R 23
  707. .DS L
  708. typedef struct diff {
  709.                 VECT t, r;
  710. } DIFF, *DIFF_PTR;
  711.  
  712. typedef struct force {
  713.                 VECT f, m;
  714. } FORCE, *FORCE_PTR;
  715. .DE
  716. .cs R
  717. The associated functions are :
  718. .br
  719. .cs R 23
  720. .DS L
  721.         DIFF_PTR assigndiff(t, o)
  722.     DIFF_PTR t, o;
  723.  
  724.         TRSF_PTR df_to_tr(t, d)
  725.     TRSF_PTR t;
  726.     DIFF_PTR d;
  727.  
  728.         DIFF_PTR tr_to_df(d, t)
  729.     DIFF_PTR d;
  730.     TRSF_PTR t;
  731.  
  732.         DIFF_PTR difftr(dt, d, tr)
  733.     DIFF_PTR dt, d;
  734.     TRSF_PTR tr;
  735.  
  736.         printd(d, fp)
  737.         DIFF_PTR d;
  738.         FILE *fp;
  739.  
  740.         FORCE_PTR assignforce(t, o)
  741.     FORCE_PTR t, o;
  742.  
  743.         FORCE_PTR forcetr(ft, f, tr)
  744.     FORCE_PTR ft, f;
  745.     TRSF_PTR tr;
  746.  
  747.         printm(d, fp)
  748.         FORCE_PTR d;
  749.         FILE *fp;
  750. .DE
  751. .cs R
  752. The function
  753. .B assigndiff
  754. performs a copy of a differential motion structure.
  755. The function
  756. .B df_to_tr
  757. builds a transformation out of a differential motion.
  758. The function
  759. .B tr_to_df
  760. builds a differential motion structure, given a transformation.
  761. The function
  762. .B difftr
  763. transforms a differential motion expressed with respect
  764. to one frame into the same differential motion expressed with respect to
  765. another frame.
  766. For example if $P1$ if a frame expressed in base coordinates
  767. and $P2$ its transformation by $T$ such as :
  768. .EQ
  769. ~P2~=~T~P1
  770. .EN
  771. A differential motion expressed with respect
  772. to P1, is obtained expressed with respect
  773. to $P2$.
  774. The left argument of
  775. .B difftr
  776. is the output argument : the transformed differential motion,
  777. the second argument is the original differential motion and the
  778. third argument is the transform expressing the differential relationship.
  779. The
  780. .B prind
  781. function prints on one line a differential motion.
  782. .PP
  783. The functions
  784. .B
  785. assignforce, forcetr, printm
  786. .R
  787. perform analogous processing of generalized forces and torques.
  788. Note that if the forces are expressed in Newtons, torques must be expressed
  789. in Newton-millimeters since distances are in millimeters, the conversions
  790. are straightforward.
  791. As for other functions of that kind the following name can be used instead,
  792. if the returned pointer is not used :
  793. .br
  794. .cs R 23
  795. .DS L
  796. Assigndiff      Difftr          Df_to_tr        Tr_to_df
  797. Assignforce     Forcetr
  798. .DE
  799. .cs R
  800. For example, the following sequence of program statements :
  801. .br
  802. .cs R 23
  803. .DS L
  804.         DIFF  Dp1, Dp2;
  805.         FORCE Fp1, Fp2;
  806.         TRSF_PTR t = gentr_pao("T", 10., 5., 0., 1., 0., 0., 0., 0., 1.);
  807.  
  808.         printrn(t, stdout);
  809.  
  810.         Dp2.t.x = 1.;
  811.         Dp2.t.y = 0.;
  812.         Dp2.t.z = .5;
  813.         Dp2.r.x = 0.;
  814.         Dp2.r.y = .1;
  815.         Dp2.r.z = 0.;
  816.         printd(&Dp2, stdout);
  817.         printd(difftr(&Dp1, &Dp2, t), stdout);
  818.  
  819.         Fp2.f.x = 10.;
  820.         Fp2.f.y = 0.;
  821.         Fp2.f.z = 0.;
  822.         Fp2.m.x = 0.;
  823.         Fp2.m.y = 100.;
  824.         Fp2.m.z = 0.;
  825.         printm(&Fp2, stdout);
  826.         printm(forcetr(&Fp1, &Fp2, t), stdout);
  827. .DE
  828. .cs R
  829. will produce the following output :
  830. .br
  831. .cs R 23
  832. .DS L
  833. T :
  834.    0.000    0.000    1.000   10.000
  835.    1.000    0.000    0.000    5.000
  836.    0.000    1.000    0.000    0.000
  837. EUL x:10.000  y:5.000   z:0.000   phi:0.000   the:90.000  psi:90.000
  838. RPY x:10.000  y:5.000   z:0.000   phi:90.000  the:0.000   psi:90.000
  839. tx  1.0e+00  ty  0.0e+00  tz  5.0e-01   rx  0.0e+00 ry  1.0e-01 rz  0.0e+00
  840. tx  0.0e+00  ty -5.0e-01  tz  1.0e+00   rx  1.0e-01 ry  0.0e+00 rz  0.0e+00
  841. fx  1.0e+01  fy  0.0e+00  fz  0.0e+00   mx  0.0e+00 my  1.0e+02 mz  0.0e+00
  842. fx  0.0e+00  fy  0.0e+00  fz  1.0e+01   mx  1.0e+02 my  5.0e+01 mz  0.0e+00
  843. .DE
  844. .cs R
  845. .NH 2
  846. Events
  847. .PP
  848. RCCL uses the notion of
  849. .I event
  850. to synchronize the user's program with the manipulator motions.
  851. .I
  852. Motion requests
  853. .R
  854. are entered into a queue at a given moment, and executed
  855. on the basis of the first in, first out,
  856. when
  857. all the previous request are served.
  858. The first snare one can run into is depicted by the following :
  859. .br
  860. .cs R 23
  861. .DS L
  862.         for (i = 0; i < 10000; ++i) {
  863.                 move(p1);
  864.                 move(p2);
  865.         }
  866. .DE
  867. .cs R
  868. The almost `infinite' loop being asynchronously executed, the queue
  869. will be become saturated in a few milliseconds.
  870. In this situation, we have chosen to cause an error condition since
  871. it will most of the time be the result of a program flaw.
  872. In many occasions an
  873. .I event
  874. will be needed to explicitly synchronize
  875. the program with the arm motions, say for opening and closing a gripper.
  876. .KS
  877. .PP
  878. An
  879. .I event,
  880. is defined in RCCL as an integer :
  881. .br
  882. .cs R 23
  883. .DS L
  884. typedef int event;
  885. .DE
  886. .cs R
  887. An event is essentially a count, if positive, it represents the number
  888. of processes waiting for the occurrence.
  889. Occurrence of an event decreases the count by one, when the count
  890. drops to zero, no process is waiting for it.
  891. RCCL maintains the built in event
  892. .B completed
  893. that occurs when the motion queue becomes empty.
  894. The user's program may use the primitive
  895. .B waitfor
  896. implemented as a macro, to synchronize with events, for example :
  897. .KE
  898. .br
  899. .cs R 23
  900. .DS L
  901.         move(p1);
  902.         move(p2);
  903.         move(p3);
  904.         waitfor(completed)
  905.         printf("the arm has reached 'p3', proceeding...\\\\n");
  906. .DE
  907. .cs R
  908. or else, using the
  909. .I event
  910. called `end' associated with each position :
  911. .br
  912. .cs R 23
  913. .DS L
  914.         move(p1);
  915.         move(p2);
  916.         move(p1);
  917.         move(p2);
  918.         OPEN;
  919.         waitfor(p1->end)
  920.         CLOSE;
  921.         waitfor(p2->end)
  922.         OPEN;
  923.         waitfor(p1->end)
  924.         CLOSE;
  925.         waitfor(p2->end)
  926.         OPEN;
  927. .DE
  928. .cs R
  929. to realize synchronization of gripper actions.
  930.