#10. Example 1. Programming an ideal manipulator. This example is based on work done by the author jointly with S.N.Baranov and A.N.Terekhov back in 1974. It was implemented on ODRA 1204 computer using an ALGOL 60 compiler (ALGOL 1204); to simulate attributes and other necessary primitives some rather complicated tricks were used with intervention in internal compiler structures. The problem arose from cooperation with Central research and experimental design institute for robotics attached to Leningrad polytechnical institute, where the result was tested on one example.

We consider a manipulator assembling rigid structures out of rigid parts. It is an ideal manipulator in that it is assumed that the coordinates of all parts are known with due accuracy and the motions are performed accurately, so one can first prepare a program of motions in a computer then output it and transfer to the actual manipulator; no attention is given to obstacles in the way of the manipulator or to possibility of bringing the manipulator to a required position.

It is assumed that the manipulator has one hand with six degrees of freedom plus opening or closing the hand.

To represent data in the net one additional vertex type is introduced, part position data. For each part its own rectangular system of coordinates is specified. The position of a part is described with respect to another rectangular system, the reference system, by means of formulas representing coordinates in the reference system in terms of coordinates relative to the part. The reference system is either the fundamental absolute system or a system attached to some other part. The transformation formulas contain 12 parameters, viz., 9 coefficients for coordinate values (only 3 of them are independent) and 3 offsets. A part position data block consists of 13 computer words, the 12 parameters and a pointer to a similar block for the reference coordinate system. The pointer is zero when the reference system is the absolute system. A reference to the coordinate system of another part means that the two parts are rigidly connected. At any moment one can traverse the whole chain of references and compute the absolute coordinates of any part. In any rigid assembly made up of parts there is one part (any one of them) that is described with respect to the absolute system, while the rest refer to this part, possibly in several steps. The position of the hand is represented in the same way.

The vertex of this new type is attached to the node representing the part itself by means of an arc named "coordinates".

Along with proper parts "subparts" are considered, i.e., elements of parts that are directly joined with respective elements of other parts. A subpart has its own coordinate system; it is a good idea to choose coordinate systems for subparts to be joined in such a way that they coincide when the parts are joined. One can consider "super- parts" (assemblies) as well and treat them as single objects.

For every part type there is a library module. This module contains nodes representing the necessary subparts together with their relative coordinates, particular procedures for handling the part, some parameters, etc. There can be an arc going from the main node to a subpart node, with a name describing the subpart function. The subpart node has a reference to its own library module to be acsribed to it at fetch time.

Consider some procedures for handling such objects.

1. Recompute coordinates of a part in the absolute system. If the coordinates of a part are specified with a reference to other parts, one has to trace the whole chain of references and to reverse the references so the coordinates of the given part become absolute while the other parts get a reference to this part. Clearly, all coefficients are recomputed. The parts not in the chain just traced remain unchanged.

2. Establish a rigid link between two parts (no physical action, make a record of a physical connection established earlier). For one of the parts the coordinates are recomputed in the absolute system, then replaced by coordinates referring to the second part. This might be a two-parameter procedure but it is better to attach it to one part passing the second part as a parameter. Of the two parts, it is better to attach this procedure to the part regarded as the active part in the process of joining. The same remarks on parameters apply to the next two procedures.

3. Break the link between two parts, a reverse operation for the previous one. It can be applied only to those part pairs that had been linked with the preceding operation. In such a pair the coordinates of one part have a reference to the other part (the direction of the reference might have been changed by operations of coordinate recomputation). This reference is replaced by zero while the coordinate values are replaced by absolute coordinates.

4. Bring two parts together (intended for parts designed for joining, with ther coordinate systems becoming identical). One of the parts (the one to which this procedure is attached) must move, thus one ought to make sure that it has been rigidly connected with the hand of the manipulator by previous actions (i.e., to check that chains of references from coordinates of this part and of the hand end in the same part). To do this, first recompute the coordinates of the part in the absolute system (with some references redirected), then replace them with the coordinates of the second part. Thus (before the actual motion is performed) the first part and all parts connected to it (including the hand) get new coordinates. Then the hand should be actually moved to the position now computed for it (i.e., data should be sent to the manipulator control device or to an external medium to be later transferred to the manipulator).

5. Grasp a part with the hand. If the part has been designed to be grasped, it should have a predefined "subpart" coming into contact with the hand. Find the subpart by walking in the net from the node representing the part along the arc whose name conforms to this function of the subpart (let us use the name "handle"). Open the hand, use the preceding procedure to bring it together with the handle of the part, close the hand, and establish a rigid link between the hand and the part (we establish the link with the part rather than with its handle in order to avoid finding the handle once more when the link is to be broken).

6. Release the grasped part. Break the previously established link between the part and the hand. Open the hand. (Probably, the hand should then be moved backwards; to do this, one has to provide a hand subpart named "backward position", and to bring the hand to this position).

7. Find a part of a specific type. By fetching a library module make an "image" of the required part. To transform the imagined part to an actual part one has to give the image coordinates of a really existing part of this type. To do this, on has either to include in the net the set of all available parts and to search this set (e.g., using the image as a matching pattern like in #7), or to ask the operator.

8. Insert one part into another. It is assumed that in both parts there are defined subparts directly joined at insertion and that functional names are agreed upon for arcs leading in the net to those subparts from the main parts (say, "tenon" and "mortise"). To perform the operation one cannot directly bring the tenon of one part to the mortise of the other part because they can be joined only when the tenon moves to the mortise from a specific direction. One should define a special subpart of the mortise, the starting position of a tenon (actually the subpart has only the coordinate system). The insertion can be performed in the following steps: find the tenon of the first part; find the mortise of the second part; from the mortise find the starting position; grasp the first part (with the above procedure); bring the tenon to the starting position; bring the tenon to the mortise; establish a link between the two parts; release the first part. This example shows a method of bypassing obstacles using a predefined assembling plan.

9. Put a ring on a vertical rod (in assembling a toy pyramid). Find the "hole" subpart of the ring and the "top" subpart of the rod (a little bit higher than the actual end of the rod), grasp the ring, bring its hole to the rod top, release the ring. However this is not sufficient, because the system would believe that the ring remains flying over the rod. The rod should have one more attribute, the level up to which it is occupied by rings, and one more attribute of the ring, its thickness. Using these attributes compute the new position of the ring after it falls and the new level of rings in the rod.

10. Close a vessel. The module describing the vessel must contain a specific procedure for closing. If the vessel is, e.g., a bottle closed with a cork, the procedure can be like the following: find the attribute named "cork type", find a cork of this type, insert the cork into the bottle neck (using the procedure described above).

This system can be improved, e.g., to avoid impossible variants of actions. This can be done with the techniques of failure and restoring (see #6), but it requires (in contrast to PLANNER-like languages) that the necessary choice operations (e.g., choosing one of a number of part "handles" for grasping) be done before entering the procedure that can produce a failure. Besides of this, in the procedure of bringing parts together the motion should be replaced with making an entry in the plan of motions, and changes in coordinates and the motion plan should be done with a special system primitive securing restoration at failure.

A simplified version of this approach to representation of a system of geometrical objects has been used for automatic part drawing from descriptions of fragments (see pic.7).