A PC Implemented Kinematic Synthesis System for Planar Linkages

by

Christodoulos S. Demetriou

Thesis submitted to the Faculty of the

Virginia Polytechnic Institute and State University

in partial fulfillment of the requirements for the degree of

Master of Science

in

Mechanical Engineering

APPROVED:

Charles F. Reinholtz, Chairman

Michael P. Deisenroth John B. Kosmatka

December, 1987

Blacksburg, Virginia A PC Implemented Kinematic Synthesis System for Planar Linkages

by

Christodoulos S. Demetriou

Charles F. Reinholtz, Chairman

Mechanical Engineering

(ABSTRACT)

The purpose of this thesis is to develop a PC implemented kinematic synthe- sis system for four-bar and six-bar planar linkages using Turbo Pascal.

CYPRUS is an interactive program that calculates and displays graphically the designed four-bar and six-bar linkages. This package can be used for three and four position synthesis of path generation, path generation with input timing, body guid- ance, and body guidance with input timing linkages. The package can also be used for function generation linkages where the user may enter a set of angle pairs or chooce one of the following functions: tangent, cosine, sine, exponential, logarithmic, and natural logarithmic. The above syntheses can be combined to design linkages that produce more complex motion.

For each kinematic synthesis case the code calculates a certain number of solutions. Then the designer chooses the most suitable solution for the particular application at hand. After a is synthesized, it can be animated for a check of the mechanical action. Watching this animation allows the designer to judge cri- teria such as clearances, forces, velocities and acceleration of the moving links.

The software operates on an IBM PC or any other PC compatible. The lan- guage used is Turbo Pascal, an extremely effective tool and one of the fastest high level languages in compilation and execution time. Acknowledgements

I would like to extend my deepest gratitude to the chairman of my committee,

Dr. Charles F. Reinholtz, for his guidance, encourangement and support during the

course of this study.

I would like also to thank Dr. Michael P. Deisenroth and Dr. John B. Kosmatka

for their guidance, service on the graduate committee and support.

For their support, my thanks to Mitchel Keil, Ashit Gandhi, Steve Wagner,

Jayaram Sankar and generally all my fellow students, who provided technical help

and moral support. A special thanks to Richard Cobb, a University instructor, for his

help and guidance in Pascal Programming.

Finally, I am indebted to my wife Nitsa and all my family members, especially

my uncle Suhel Turjman, for their continuous love and support, which made my

studies in the United States possible.

Acknowledgements iii Table of Contents

Introduction ...... 1

Literature review ...... 4

Design Considerations and Programming Guides ...... 9

3.1 Planar Linkages ...... 9

3.2 Mechanism Defects ...... 13

3.3 Pascal Programming Language ...... 16

Body Guidance Synthesis ...... 22

4.1 Example Problem ...... 26

Path Generation with Input Timing ...... 30

5.1 Cognate Linkages ...... 31

5.2 Example Problem ...... 36

Function Generation Synthesis ...... 40

Table of Contents iv 6.1 Chebyshev Spacing ...... 40

6.2 Freudenstein's Method ...... 44

6.3 Example Problem ...... 46

Body Guidance Synthesis with Input Timing ...... , ...... 49

7.1 Six-Bar ...... 49

7.2 Example Problem ...... 51

System Structure ...... 55

8.1 Main Procedure ...... 56

8.2 Body Guidance ...... 56

8.3 Body Guidance with Input Timing ...... 58

8.4 Path Generation with Input Timing ...... 58

8.5 Function Generation ...... 60

8.6 Cognates ...... 60

8.7 Animation Routine ...... 63

Concluding Remarks and Recommendations ...... 67

References ...... , ..... , ...... 69

Body Guidance Synthesis Equations ...... 72

A.1 Equations Used for Three Position Synthesis ...... 72

A.2 Equations Used for Four Position Synthesis ...... 74

Pascal Code ...... 77

Table of Contents V Procedures and Functions Used ...... • ...... 190

Vita ...... 208

Table of Contents vi List of Illustrations

Figure 1. Four-Bar linkage ...... 5

Figure 2. Stephenson's I, II, and Ill six-bar linkages ...... 11

Figure 3. Watt's I and II six-bar linkages ...... 12

Figure 4. Function generation mechanism...... 14

Figure 5. A typical body guidance problem...... 15

Figure 6. The two possible branches of a four-bar linkage...... 17

Figure 7. Body guidance solution using complex numbers...... 23

Figure 8. Four-bar body guidance linkage...... 29

Figure 9. Original four-bar linkage...... 32

Figure 10. Cognate linkages...... 33

Figure 11. Cayley's diagram...... 35

Figure 12. Four-bar path generator with input timing...... 39

Figure 13. Synthesis structural error...... 42

Figure 14. Chebyshev spacing for four precision spacing...... 43

Figure 15. Four-bar linkage ...... 45

Figure 16. Four-bar function generator...... 48

Figure 17. Stephenson Ill six-bar linkage...... 50

Figure 18. Cognate of the six-bar linkage...... 52

Figure 19. Six-bar body guidance linkage with input timing...... 54

List of Illustrations vii Figure 20. Logic diagram of the main program...... 57

Figure 21. Logic diagram of dyad presentation...... 59

Figure 22. Description of the function generation routine...... 61

Figure 23. Logic diagram of the cognates routine...... 62

Figure 24. Description of the animation routine...... 64

Figure 25. Logic diagram of the iterative routine ...... 66

List of Illustrations viii List of Tables

Table 1. Software available for mechanism synthesis ...... 8

Table 2. Possible Solutions for Body Guidance Problem ...... 25

Table 3. Body guidance linkage specifications ...... 28

Table 4. Body guidance linkage links' angles ...... 28

Table 5. Resulting cognates ...... 37

Table 6. Path generation linkage link's angles...... 38

Table 7. Function generator specifications...... 47

Table 8. Six-bar linkage specifications ...... : ...... 53

Table 9. Six-bar linkage links' angles ...... 53

List of Tables Ix Chapter 1

Introduction

Linkages are often the simplest and most economical way to generate motion in a wide range of industrial and consumer goods. Linkages are found in automo- biles, aircraft, office equipment, robots, prosthetic devices, production equipment and toys. However, designing a linkage that works can be difficult.

Often, linkage design is done by trial and error. Traditional techniques involve making drawings and building models of proposed linkages. But even after extensive trials, an optimized design may be elusive. In many cases, the difficulty of finding an effective linkage results in the use of more complicated mechanisms including cams, , belts and cables. Erdman [ 1] insists that this problem no longer exists since

improved computer design procedures have been developed that simplify the design of proper linkage.

According to Barker [2] successful mechanism design implies that:

• all the links of the mechanism are of manageable length,

Introduction 1 • the required positions are obtained in the right order,

• the mechanism has the desired mobility, (ie. it does not become locked within the

range of movement required), and

• acute transmission angles requiring large driving torques are avoided.

In some applications where sectors are used, four-bar linkages can pro- vide an acceptable, sometimes better, alternative. Linkages tend to have less inertia than gears, and they are also capable of transmitting higher loads. Another advan- tage of linkages over gears is their lower manufacturing cost. The essential differ- ence between the two alternatives is that the gears can provide perfect geometric accuracy over as long a range as required, whereas linkage provide only an approx- imation and over a limited range [3].

Although robotics is an important component of computer-aided manufactur- ing, many associated problems are best solved by devices simpler than robots [4].

Inexpensive planar and spatial mechanisms are frequently best suited for the solution of these problems. Planar mechanisms, being purely mechanical single-input de- vices, tend to be more reliable and more energy efficient than electronically- controlled multiple-input devices. Many experts, among them Sandor and Erdman

[5]. believe that closed loop devices, such as planar mechanisms are known to be capable of running at higher speeds and carrying greater loads with more precision than open loop devices, such as robotic manipulators.

Pascal is a general purpose high level language originally designed by pro- fessor Niklaus Wirth of the Technical University of Zurich, Switzerland and named it in honor of Blaise Pascal, the famous French seventeen century philosopher and mathematician. According to professor Wirth, the Pascal language was intended to

Introduction 2 aid the teaching of a systematic approach to computer programming, specifically in-

_troducing structured programming. Pascal has since been used to program a wide range of tasks on almost every type of computer. Today it is one of the foremost high level languages, whether the application is education, hobby, or professional pro- gramming [6].

During the early 1980s Borland International introduced Turbo Pascal. Turbo

Pascal is considered one of the fastest high level languages operating on a personal computer [7]. At the same time Borland International also introduced Turbo

Graphix, a graphics software package that accompanies Turbo Pascal. Jones and

Harrow [8] say that the combination of these two codes make what many observers believe to be the best programming system available in the PC market.

The purpose of this thesis is the development of a PC implemented kinematic synthesis package for the synthesis of four and six-bar linkages. A few synthesis packages written for a PC are now available in the market and they are very expen- sive. Industries have been forced towards automation and this has increased the demand for such systems. Our purpose is the production of a kinematic synthesis system that will be freely used by our University and may be marketed in the future at a low price.

Introduction 3 Chapter 2

Literature review

Existing kinematic synthesis programs are primarily used for the design of planar four-bar linkages such as the one shown in Figure 1 on page 5. This is not surprising since four-bar linkages are simple and versatile mechanisms that can produce complex motion. The approach generally used to synthesize these linkages is based on techniques developed in the late 1800s by Dr. Ludwig Burmester, Pro- fessor of Descriptive Geometry and Kinematics in Munich, Germany [9]. Burmester devised a graphical method of designing four-bar linkages to pass through four mo- tion path points, an objective formerly considered to be impossible to achieve except by tedious trial and error techniques. Still Burmester's graphical method was time- consuming and often inaccurate.

A major breakthrough in kinematics came when Burmester's approach was represented mathematically using complex-numbers and a closed form solution was obtained. This work was done in the late 1950s at Columbia University by Dr. George

Sandor and Dr. Ferdinand Freudenstein [9] .

Literature review 4 A

C

Figure 1. Four-Bar linkage

Literature review 5 According to Erdman [ 1] , it was not until 1940 that Svoboda developed nu- merical methods to design a four-bar linkage. The linkages synthesized by Svoboda could generate a desired function with sufficient accuracy for engineering purposes.

In 1951 Hrones and Nelson published an "ATLAS" containing approximately 10,000 four-bar linkage coupler curves [ 10]. This atlas offered a very practical approach for some design engineers. Some software was developed during the 1950s to solve linkage synthesis problems. This includes programs developed by C. W. Mclarnan et al. at Ohio State [ 11] , J. E. Shingley et al. at Michigan [ 12], F. Freudenstein et al. at Columbia [13,14,15] , and J. Denavit and R. Hartenberg at Nortwestern Uni- versity [ 16] .

The computer became more available to University researchers in the early to mid 1960s. Many researchers began to utilize the power of the computer for solv- ing equations which were tedious by either graphical or slide rule techniques. The mid to late 1960s saw synthesis problems being solved in the batch mode on the computer [ 1].

Users waited until early 1970s to see kinematic analysis applications on the computer. Codes such as IMP, developed at the University of Wisconsin, and DRAM and ADAMS [ 12], developed at the University of Michigan, had roots early in this decade. Computing slowly switched from batch mode to interactive, which was a significant step in making techniques more useful to designers. At the same time, computer graphics applied to mechanism design was introduced in the early 1970s by Kaufman [ 17] . KINSYN I, a custom built program at Massachussets Institute of

Technology, is a major milestone in kinematic design.

Activity in computer-aided design of mechanisms has been great during the

1980s for several reasons. Microcomputers became generally available, and several different groups began to develop and market software on micros [18,19]. Many

Literature review 6 researchers have utilized kinematic theories to investigate different aspects of robotics such as three-dimensional animation, workspace prediction, interference calculations, dynamic response etc [20,21,22,23,24,25] . The late 1980s has also been the beginning of integration of mechanism analysis, synthesis and dynamics, with other computer-aided design areas such as drafting, finite elements and simu- lation.

Table 1 on the next page lists some of the available software for mechanism synthesis [ 1]. Most of the software listed in this table is written for large mainframe computers. Those programs are very powerful, but mainframe computers are not easily accessible. KINSYN developed by Kintech and LINKAGES developed by the

University of Minnesota and MINTT, Inc. have versions written for a microcomputer.

MICRO KINSYN is used for the synthesis of body guidance four-bar linkages only.

On the other hand LINKAGES-N is used for the synthesis of path generation, body guidance, and function generation of N-bar linkages. It is a user friendly system and has many capabilities, but it is very expensive.

Literature review 7 Table 1. Software available for mechanism synthesis

2-0 CPU Synthesis Code Name Source 3-0 Availability Capability

CADOM University of 2-D ? Path and Delft, function Netherlands generation

GISK Technical 2-D KRS 4201 Goal function University, Robotron optimization Dresden

KINSYN Kintech, 2-D Vax Motion Mclean, path and Virginia function generation

MICRO Kintech, 2-D Apple II Motion KINSYN Mclean, generation Virginia

LINKAGES_4 University of 2-D Dec Pro 350 Motion, path LINKAGES 6 Minnesota and CDC and function LINKAGES-N MINTT, INC., VAX generation Minneapolis, CADDS 4 four-bar Minnesota IBM PC six bar lnterGraph N-bar Apollo

LINKAGES CDC, 2-0 CDC Motion, path Bloomington Timesharing and function Minnesota generation

MICRO- Terak 2-0 Terak Motion, path LINKAGES Scottsdale, and function Arizona generation

MECSYN Machinesoft, 2-D VAX Four-bar and Blacksburg, IBM some multiloop Virginia mechanisms

Literature review 8 Chapter 3

Design Considerations and Programming Guides

3.1 Planar Linkages

A linkage is a particular type of mechanism in which the links, assumed rigid, are connected by means of only lower pairs. The lower pair, such as a pin joint, has surface contact between the pair elements, while higher pairs, such as cam and fol- lower connections, have line or point contact between elemental surfaces [24]. The purpose of a linkage is to transform one type of motion into another. For example, the slider crank mechanism transforms the uniform rotation of its crank into the reciprocating translation of its slider. As a computing mechanism, the four-bar link- age may be designed to generate some functions with remarkable accuracy.

Having the minimum number of links required for determinate motion, the four-bar mechanism may be regarded as the simplest possible mechanism. It is used

Design Considerations and Programming Guides 9 on all types of machinery because it is simple in concept, easy to manufacture, able to operate at high speeds with great accuracy, and highly efficient.

Six-bar linkages are defined in five basic types; Stephenson I, II, Ill and Watt

I and II [ 11]. These linkages are shown in Figure 2 on page 11 and Figure 3 on page 12. Six-bar linkages are the simplest single-input, single-output mechanisms beyond the four-bar linkage. The two extra links substantially increase linkage ca- pabilities, often making possible the solution of more complex problems, such as body guidance with prescribed input timing [ 11].

According to Mabie and Reinholtz, kinematic synthesis problems are divided into three types [24]:

1. The type of a mechanism to be used,

2. The number of links, cams, gears and connections needed, and

3. The dimensions of the necessary parts.

This thesis is concerned with the dimensional synthesis of four-bar and six-bar link- ages. It investigates the three basic tasks of kinematic synthesis: namely, function generation, path generation and body guidance.

In function generation, rotation or sliding motion of input and output links must be correlated. The kinematic synthesis task may be to design a linkage to correlate input and output such that as the input moves by x, the output moves by y = f(x) for the range x0 x X17 +1 • Values of the independent parameter x,, x2, ... X17 correspond to prescribed precision points. Often the precision points are calculated using

Chebyshev spacing [24], in an effort to minimize the structural error, since functions

Design Considerations and Programming Guides 10

( a )

( b )

Figure 3. Watt's I and II six-bar linkages

Design Considerations and Programming Guides 12 can be exactly generated at only a limited number of precision points. A typical function generation problem is shown in Figure 4 on page 14.

In path generation, a point on a moving link is required to generate a given curve with respect to the fixed frame of reference. If the path points are to be corre- lated with either time or input-link positions, the task becomes path generation with prescribed timing.

Body guidance requires that an entire body be guided through certain pre- scribed motion sequence. A frequently seen body guidance problem is the transfer of parts from one conveyor to another as shown in Figure 5 on page 15. The body to be guided is usually part of the floating link. All three synthesis tasks will be dis- cussed further in Chapters 4, 5, 6 and 7.

3.2 Mechanism Defects

The synthesis methods mentioned above will usually result in mechanisms that can reach the specified positions or generate a certain function. But most of the time, in building a prototype of a given solution, the designer discovers that the mechanism can not satisfy the kinematic design requirements [26]. This happens because the synthesis techniques do not account for mechanism defects. There are three types of defects, namely, branch defect, order defect and Grashof defect.

Branch defect occurs when only some of the prescribed positions points can be reached by the mechanism. To reach the other positions the mechanism has to be physically taken apart and reassembled in its other branch. Therefore, a complete synthesis must include a check of whether all points lie in one branch. If not, the

Design Considerations and Programming Guides 13 X

Input Output

( a )

( b )

Figure 4. Function generation mechanism.

Design Considerations and Programming Guides 14 \ \ \ \ \ I \/

Figure 5. A typical body guidance problem.

Design Considerations and Programming Guides 15 mechanism is unsuitable and suffers from branch defect. The two possible branches of a four-bar linkage are shown in Figure 6 on page 17.

There is a simple analytical technique to determine whether a mechanism suffers from branch defect. The angle O between the follower and the coupler is measured at all precision points. The mechanism will be free of branch defect if and only if either O < 8 < 1t , or n < 8 < 2n in all positions [24].

An equally important problem in mechanism synthesis is the order defect.

This defect can occur when more than three positions have been specified in path generation or body guidance synthesis. In this case the designer may desire that the mechanism follow the positions in a specified order, say 1-2-3-4. Instead the mech- anism passes through all points but in different order, say 1-3-2-4.

The last type of synthesis problem is called Grashof defect. Not surprisingly, it is related to Grashof's law, which states that, for a planar four-bar linkage, the sum of the shortest and longest link lengths cannot be greater than the sum of the re- maining two link lengths if there is to be continued relative rotation between two members. A problem may arise when a crank input link is desired, and instead, a double rocker, or a non-Grashof linkage is obtained.

3.3 Pascal Programming Language

Pascal was developed in the late 1960s by Niklaus Wirth at the Technical Uni- versity of Zurich. It was derived primarily from ALGOL-60 [27]. Wirth's aims were to produce a language suitable for teaching programming concepts clearly and sys- tematically, and to make the language usable on a large numbers of computer. His

Design Considerations and Programming Guides 16 A \ \ \ \ \ \ \-; B

Figure 6. The two possible branches of a four-bar linkage.

Design Considerations and Programming Guides 17 success is obvious; Pascal's popularity has increased rapidly since its introduction , a_nd versions of the language are now available on computers ranging from small and inexpensive personal computers to large mainframe systems [6] .

The primary reason for Pascal's popularity is that Pascal makes the job of writing, reading, and modifying programs easier than do many other programming languages. Here are some of Pascal's excellent features:

• Pascal has structured control statements, (while, repeat, for, case and if-then-

else) , that allow the programmer to write clear and concise code with the flow

of control proceeding from top to bottom. The control flow in programs written

in languages without these control statements often use if tests and go to state-

ments, which are more difficult to understand.

• Pascal permits the programmer to break up large programs into smaller inde-

pendent procedures and functions, each one performing a certain task. Each

module can have its own private variables that are only used when that module

is executed. Each module has well-defined input and output parameters used for

communicating with its calling routine.

• Pascal allows programmers to define their own data types and data structures in

addition to those already built into the language.

• Pascal permits the use of long identifiers for variables, procedures, and functions.

This allows the programmer to use names with mnemonic significance, which is

another aid in understanding the program.

Design Considerations and Programming Guides 18 • Pascal provides recursive procedures and functions, that is, procedures and

functions that can call themselves.

Although Pascal is a very good language, it is not a perfect one. Pascal's file-handling capabilities have been criticized as inadequate and poorly designed.

Another disadvantage of Pascal is that the size of an array is part of its type, making it difficult to write general-purpose modules to process arrays of arbitrary length. In addition, Pascal specifies that variables local to a given routine are "forgotten" on exit from that routine; this means that a variable in order to keep its value between calls to a routine must be declared globally to the routine, making it accessible to a larger part of the program than necessary.

However, Pascal has a large complement of features for arithmetic and logical manipulations, including some that make decision-making statements extremely simple to write. In short, Pascal has all the power of FORTRAN or PL/1, but much greater structure, and is, in fact, only slightly more complex to learn than BASIC. This makes Pascal an excellent language for both beginners and experienced program- mers [27].

Turbo Pascal [28] is a version of a Pascal language used on personal com- puter. It is designed to meet the requirements of all categories of users and offers a friendly interactive programming environment that greatly aids the learning proc- ess. In the hands of an experienced programmer, it becomes an extremelly effective tool providing fast compilation and execution. In addition to standards provided by

Pascal language, the following extensions are also provided:

• Absolute address variables

• Bit/byte manipulation

Design Considerations and Programming Guides 19 • Direct access to CPU memory and data ports

• Free ordering of sections in declaration part

• Full support of operating system facilities

• In line code generation

• Include files

• Logical operation of integers

• Overlay systems

• Program chaining with common variables

• Structured constants

• Type conversion functions and

• Graphics

Borland International also provides Turbo Pascal users with Turbo Graphix software. It is a general-purpose graphics package that provides facilities designed to address a wide range of applications. Although Turbo Graphix appears to be complex, the concepts embodied in the package are quite simple. The drawback of this software is that the programmer must include several files in his program code and this consumes much of the limited amount of memory available to the user.

Design Considerations and Programming Guides 20 As mentioned above, Pascal is a language specifically designed to facilitate

structured, or top down, programming, a technique that has led to great efficiencies

in program writing and maintenance. Hoare's [27] definition, which many feel cap- tures the essence of structured programming, is as follows: "The task of organizing

one's thought in a way that leads, in a reasonable time, to an understandable ex-

pression of a computing task, has come to be called structured programming." Victor

Basili [29] adds that structured programming strives for simplicity and elegance

without sacrificing efficiency.

Design Considerations and Programming Guides 21 Chapter 4

Body Guidance Synthesis

In the body guidance problem, a body is to be guided through a certain num- ber of specified positions. The problem may be a simple translation, or a combina- tion of translation and rotation. Figure 7 on page 23 shows a body in the first and r position. The body is to be driven through n specified positions. To do this the vec- tors R1, R2, ... R" and angles ix1, ix2, ... ix,, must be specified. To find the unknown dyad, a two-link chain composed of the guided body and the constraining link, a loop clo-

sure equation is derived by summing the vectors counterclockwise around the loop from position 1 to position j. This loop contains the vectors R1, P1, S1, Si, P1, and Ri.

[1]

or,

[2]

Note that Ri and R1 are known vectors, and

Body Guidance Synthesis 22 y

X

Figure 7. Body guidance solution using complex numbers.

Body Guidance Synthesis 23 S1 =Se'P1 [3]

S- = Se 1(JJ 1 -P) J [4]

p. = Pei(y+ ") J [5]

Where R 1 and 0i specify the desired positions of the body, !Xi are the specified body orientations, /Ji are the angles of the assumed dyad orientations at each correspond- ing position, and finally P and y are the parameters specifying the position where the dyad is attached to the body. The only scalar unknowns for each case will be y, P,

S, and /Ji where j = 1, 2, ... n.

Only a finite number of parameters can be prescribed in a linkage synthesis problem. By examining the number of scalar unknowns and scalar equations, one can easily determine how many positions may be prescribed.

Table 2 shows the number of scalar equations, the number of scalar un- knowns, the number of free choices, and the number of solutions for two, three, four and five prescribed positions. It is shown that for two positions there are two scalar equations and five unknowns. The two scalar equations correspond to the x and y components of each vector equation. Since there are three free choices, the number of possible solutions for the two position synthesis problem is on the order of infinity cubed, symbolized by Sandor and Erdman [30] as O(oo3 ).

Body Guidance Synthesis 24 Table 2. Possible Solutions for Body Guidance Problem

Number of Number of Scalar Number of Positions Equations Unknowns Solutions 2 2 5(P,S,y,P1,P2) 0( 003 )

3 4 6(above + /J3) 0( 002 )

4 6 ?(above + /J4) 0( 00)

5 8 8(above + /!s) (4,2 or 0)

For three prescribed positions there are only two free choices. Therefore the number of solutions is on the order of infinity squared 0(oo2). For four position syn- thesis there is only one free choice and an infinity of solutions, 0(oo). For the case of five prescribed positions there are no free choices available and the number of solutions may be finite or zero. Therefore five positions is the maximum number of positions that can be specified in a body guidance problem, but this rarely results in a useful linkage. This thesis is only concerned with three and four position synthesis problems.

For a three position synthesis, two free choices must be made. The vector system of equations is obtained by writing equation 2 for j = 2 and j = 3 to give

[6]

[7]

By picking P2 and /J3 as free choices the equations 6 and 7 can be simplified into a form that is easily solved using Cramer's rule. The unknowns y, P, S, and P1, which define a dyad, are found for each set of P2, and /J3. Any two of the resulting dyads is then chosen by the designer to form the four-bar linkage.

Body Guidance Synthesis 25 The system of equations for the four position body guidance synthesis prob- lem is as follows:

[8]

[9]

[10]

In this case the designer is allowed only one free choice. By picking p2 as the free choice a solution is obtained for P, S, p,, fi 3, and fi4• Appendix A shows some of the mathematical manipulations required to solve the above system of equations. To form a four-bar linkage the designer has to choose two out of the infinite number of available solutions.

4.1 Example Problem

In order to complete a computer integrated manufacturing line, a linkage is required to transfer tools from a conveyor belt to an numerically controlled machine. The re- quired positions and orientations of the body are as follow:

P1 - (0,0) and cc 1 = 0°

P2 = (1.8,2.9) and cc 2 = 35°

P3 = (3.7,3.3) and cc 3 = 48°

Body Guidance Synthesis 26 P4 = (6.0,3.0) and a3 = 60°

The Cyprus synthesis program is started, the body guidance task is chosen, and the above data is entered. For free choices the following angles were selected

Dyad 1 : /32 = 10°

Dyad 2 : /32 = 300°

Note that for body guidance or path generation synthesis the user is supposed to enter a range of /32 or /J3 from which a set of two dyads is chosen for the synthesis of a four-bar linkage. The user enters a range of /32 or /33, an increment D./J i= 0, and a set of dyads is displayed on the screen. For this example, an initial value of

/3 2 = 10° , a final value of /12 = 330° , and an increment D./3 2 = 10° were chosen.

Then the two dyads corresponding to {J 2 = 10° and /32 = 300° were chosen to form the four-bar linkage.

After the dyads are displayed and chosen, the dimensions and type of the synthesized linkage is displayed. The following table is a copy of a computer gener- ated output for this example.

Body Guidance Synthesis 27 Table 3. Body guidance linkage specifications

Input link = 4.46 Coupler link = 7.33

Output link = 14.38 Fixed link = 17.18

Type of linkage Crank-Rocker

Input link range 0.00 to 360 Degrees

Finally the linkage is displayed along with the desired body positions and then animated. By observing the animated linkage it becomes clear that it satisfies the

kinematic problem requirements. The following table shows the linkage angles with the corresponding body positions. By observing the angle 03 it is clear that the body

orientation requirements are satisfied. Figure 8 on page 29 shows the synthesized

linkage along with the body positions.

Table 4. Body guidance linkage links' angles.

Body position 82 03 04

1 355.3° 274.4° 212.2°

2 295.3° 309.4° 222.4°

3 271.3° 322.4° 218.4°

4 245.3° 334.4° 210.1°

Body Guidance Synthesis 28 Figure 8. Four-bar body guidance linkage.

Body Guidance Synthesis 29 Chapter 5

Path Generation with Input Timing

In path generation, a mechanism is required to guide a point on a floating link along a prescribed path defined with respect to the fixed frame of reference. The above coupler point is also called a tracer point. In this synthesis task, the path points are to be correlated with input link positions, and therefore the task is called path generation with prescribed timing. Usually one does not attempt to generate the given curve exactly. In fact, only a limited class of motions could be so generated, and in general it suffices if, within a desired interval, the generated curve is a good approximation to the given data.

Path Generation with Input Timing 30 5.1 Cognate Linkages

Four-bar linkages have an unusual property; three different four-bar linkages trace identical coupler curves. This property was discovered in 1875 by Roberts and in 1878 by Chebyshev [ 13] . Figure 9 on page 32 shows the original four-bar linkage

0 1AB02 , with a point P attached to coupler AB. Figure 10 on page 33 shows the or- iginal linkage and its cognates 0,A,C,03 and 0 2B2Cp3 with the cognate linkages shown using short and long dashes. By observing the diagram we can see that there are four similar triangles, with angles ll, p, and y, namely, the three coupler links and tri- angle O,Oz03 •

Because of its special geometry, the ten-bar mechanism is moveable, despite the fact that the mobility equation predicts a structure. Actually the ten-bar mech- anism is overclosed since the links 0 1A1 and 0 28 2 could be removed without affecting the mechanism.

From the above observation, it is clear that each of the three linkages traces identical coupler curves. This allows the designer to replace any four-bar linkage by either one of its two cognate linkages. Cognates can be used where transmission angles, mechanical advantage, velocity, acceleration, or size of the original linkage are not acceptable.

Returning to Figure 10 on page 33 we observe some very useful relations between the links. Since link 0 1A1 is parallel to link AP and link 0 28 2 is parallel to link

BP, it can be seen that the links 0 1A1, 0 28 2 and link AB undergo the same rotations.

This fact must be taken into account when point P is to be driven along a certain path with prescribed input.

Path Generation with Input Timing 31 p

Figure 9. Original four-bar linkage.

Path Generation with Input Timing 32

To solve a path generation problem with input timing, transform the path generation problem into a body guidance problem by using the input link rotations as the body orientations. Once the problem is solved, the cognate linkages can be constructed. Since links 01A1 and 02B2 are grounded, either one can be used as an input link with its corresponding four-bar linkage to satisfy the original path gener- ation with input timing problem.

Cayley's diagram, shown in Figure 11 on page 35, is an easy way to deter- mine the link lengths of the cognate mechanism. This diagram is obtained by imag- ining that frame connections 01, 02, and Q3 are unfastened. These connections are then pulled apart from each other so that a straight line is formed by the crank, cou- pler and follower of each linkage. Note that in this figure, all the links are the same length as the actual ones, except for the fixed link.

By utilizing the fact that the triangles 010203, A1PC1, PB2C2, and ABP are sim- ilar and that 01APA1, C1PC203, and B02B2P are parallelograms we can easily calculate the link lengths. To determine the actual position of the fixed pivot 03 we need to use the Robert-Chebyshev theorem. By carefully examining Figure 10 on page 33 we can see that the triangle 010203 is similar to ABP. therefore we can easily determine the x and y component of the fixed pivot Q3.

[24]

0 2 0 3y = 0 1-.- - sin /3 sin o: [25] Sin y

Path Generation with Input Timing 34 A B

Figure 11. Cayley's diagram.

Path Generation with Input Timing 35 5.2 Example Problem

At the end of a manufacturing line there is a robot performing product in- spection. If the product fails the inspection test, a four bar linkage is activated to pick the product up and discard it. The linkage must be designed according to the desired path. The orientations of the body are arbitrary but the input timing is defined.

Specified quantities are

P2 = (-6,11) t/> 2 = 22°

P3 = ( -17, 13)

where t/> 1 •••

Dyad 1

Dyad 2

In the case of three position synthesis there are two free choices, p2 and p,. p2 can be either common for both dyads or it can be different. In order to enter dif- ferent values of p2 for the two chosen dyads, the user first enters the first value of p2, in this case p2 = 90° , and a range of P,. When the dyads are displayed, the dyad corresponding to P3 = 198° is chosen and an index O is entered for the second dyad.

Then the user returns back to the input menu where a new value of p2 = 40° is en- tered. After a new range of p3 is entered, the second dyad corresponding to

Path Generation with Input Timing 36 p3 = 73° is chosen, which combined with the first dyad will form the four-bar linkage.

In the case where the value of p2 is desired to be common for both dyads, the user has to choose both dyads from the first set of dyads.

Note that by specifying the input rotations about twice as much as the output rotations, the type of the linkage will usually yield to a crank-rocker type. Once the corresponding dyads are chosen, the cognates of the initial linkage are calculated and displayed on the screen. The following table is a copy of a computer printout for this example.

Table 5. Resulting cognates

Original linkage Cognate 1 Cognate 2

Input link 5.775 15.017 6.119

Coupler link 18.595 4.664 6.050

Output link 18.386 14.849 1.900

Fixed link 8.955 7.232 2.947

Type Crank-Rocker Double-Rocker Rocker-Crank

The first cognate is selected and the synthesized linkage is animated. It is seen that the kinematic problem requirements are satisfied. The following table lists the angles of the linkage at each position.

Path Generation with Input Timing 37 Table 6. Path generation linkage link's angles.

Body position 02 03 04

1 37.2° 72.3° 65.5°

2 59.2° 162.5° 105.6°

3 105.2° 270.5° 138.6°

By inspecting the input angle 02, one can see that the input timing is also satisfied, although it is out of phase by 37.2°. Figure 12 on page 39 shows the de- signed linkage that will drive the body through the specified positions according to the specified input timing.

Path Generation with Input Timing 38

Chapter 6

Function Generation Synthesis

In function generation synthesis the output link is required to rotate, oscillate, or reciprocate as a specified function of the input link motion. A simple case is the synthesis of four-bar linkage to generate the function y = f(x). In this example x would represent the input crank motion while the output link may oscillate repres- enting the function y.

6.1 Chebyshev Spacing

The four-bar linkage is not capable of error free generation of an arbitrary function, but can match that function at only a limited number of points. These points, known as accuracy points, or precision points, are found in order to minimize the error generated by the linkage over the entire function.

Function Generation Synthesis 40 Chebyshev's method attempts to minimize the error by spacing the accuracy points within the interval of initial and final points of the function. In other words, the difference between the desired and approximated function is minimized. This struc- tural error variation is shown in Figure 13 on page 42. It is seen that the error is zero at points a,, a2, and 83. These are the accuracy points, which are the roots of the corresponding Chebyshev polynomials [ 16].

Mabie and Reinholtz [24] suggest the following convenient way to locate the accuracy points. From the center of the interval (a-h, a+ h) taken along the x-axis, draw a semicircle with radius h, ie., one half of the above mentioned interval. Then inscribe a half polygon with 2n sides so that two of its sides are perpendicular to the x-axis. The projections of the vertices of this polygon on the x-axis determine the accuracy points. The above construction is shown in Figure 14 on page 43 for n =

3. The following formula can be used to calculate the accuracy points for any number of positions.

nU- J..) 2 a1 = a - h cos[ n J j = 1 ... n [10]

where

n = number of accuracy points

ai = Precision points

a = Center point of the interval

h = half the width of the interval

Function Generation Synthesis 41 e

2h -h +h

0 a a-h a+h X

Figure 13. Synthesis structural error.

Function Generation Synthesis 42 Interval = 2h

-h +h

a a+h 3

Figure 14. Chebyshev spacing for four precision spacing.

Function Generation Synthesis 43 6.2 Freudenstein's Method

Freudenstein's displacement equations for three precision points function generation synthesis is utilized in this thesis. Figure 15 on page 45. shows a four-bar linkage and indicates the way input and output angles are measured for this method.

This is a well known analytical method that synthesizes a four-bar linkage given the input and output angle pairs. The precision angle pairs are given by ; and t/J; for i

= 1 to 3. The final equations [24] are given below. First, for convenience, the fol- lowing substitutions are made

[12]

[13]

[14]

[15]

[16]

[17]

[18]

[19]

[20]

Function Generation Synthesis 44 B

C

Figure 15. Four-bar linkage

Function Generation Synthesis 45 A solution is obtained for link lengths a, b, and c in terms of the fixed link d.

[21]

[22]

I 2 2 2 · c = ya + c + d - 2acR3 [23]

Freudenstein's equation may be used to obtain two infinities of solutions for · the same set of precision points. This is done by shifting all the precision points some amount~. and ~t/1. Each ~¢ and !lt/1 will yield a new solution.

In solving the function generation problem, the input crank pivot will be taken at the origin, since any variation of the location of the pivot will only translate the solution without changing the dimensions of the linkage [31]. Also, since any vari- ation of the direction from 0 1 to 0 2 will only rotate the solution without changing the dimensions of the resulting linkage, this angular direction will be taken as zero de- grees. The length of the fixed link will be taken as unity. After the synthesis, the solution may be scaled to any convenient size.

6.3 Example Problem

The maximum load the tower crane, shown on the top of Figure 16 on page

48, can lift without being toppled over is proportional to the moment arm the load acts through and is given by Lcos(0). Since L is a constant value, the crane operator re-

Function Generation Synthesis 46 quires a readout of cos(O) on the instrument panel to make decisions about lifting a

k_nown load. The existing nonlinear gauge, marked off to read cos(0) from Oto 1 in

0.1 increments, is sometimes difficult to read. Synthesize a function generating four-bar linkage that will give an approximate linear output scale for cos(0) with 0 as the input. Use a range of goo for the input and 120° for the output. This problem

is one of Mabie and Reinholtz's [24] kinematic synthesis problems.

In this case the function generation task was selected and cosine was chosen as the desired function. The chosen initial and final input angles were 180° and goo respectively, while the output angle values were goo and -30°. The initial and final value of x were chosen to be 0° to 90°. A unity was assigned to the length of the fixed

link.

The following table shows the dimensions of the designed linkage. It also in- dicates the type of the linkage as well as the range of the input link.

Table 7. Function generator specifications.

Input link = 1.10 Coupler link = 2.17

Output link = 0.66 Fixed link = 1.00

Type of linkage : Non-Grashot

Input link range 91.92 to 268.08 Degrees

Finally the designed linkage is displayed and animated. Part b of Figure 16 on page 48 shows the designed four-bar function generator. The same figure also

shows the new gauge along with the old one.

Function Generation Synthesis 47 (a)

0 0.2 -~ . 4 0.4 I I 0 I I I I ·

1.0 - 0

(b)

Figure 16. Four-bar function generator.

Function Generation Synthesis 48 Chapter 7

Body Guidance Synthesis with Input Timing

7.1 Six-Bar Linkage

In this Chapter the Stephenson-Ill six-bar linkage, shown in Figure 17 on page

50, is to be designed for body guidance with prescribed input timing. The body guidance problem has been already discussed in Chapter 4. Any three or four posi- tion body guidance problem can be solved using the theory discussed before. To include input timing in a body guidance problem, the designer first solves the usual body guidance problem. Once the guiding four-bar linkage has been found, an addi- tional dyad is synthesized to produce the input timing.

After the guiding four-bar linkage has been found, the body guidance problem is restated with some new point P on the coupler link representing the body posi- tions. Then the required input link rotations are assigned as the body orientations, and an additional dyad is chosen to form a six-bar linkage as shown in Figure 18 on

Body Guidance Synthesis with Input Timing 49 page 52. As a result, link PC satisfies the presribed input timing. By constructing the angular cognate of dyad 0 3CP we get the cognate 0 3 C'P whose input link OC' satis- fies the input timing requirement of the problem.

The Stephenson Ill six-bar linkage, 0 3 C'PO,APB02 shown in Figure 18 on page 52 will guide the body through the specified positions and orientations. Dyad

0 3 C'P satisfies the input timing requirements while the four-bar linkage O,AB02 drives the body through the specified positions and orientations.

7.2 Example Problem

The following input link rotations are required for the body guidance four-bar linkage synthesized in Chapter 4.

The four-bar linkage that will drive the body through the specified positions and orientations is found by simply following the procedure outlined previously with the exception that the six-bar option is chosen from the main menu instead of the body guidance option. Once the user chooses the two dyads, a point on the coupler link is arbitrarily chosen to be at (1,4), relative to the new origin of the moving system.

Then the required input link rotations, assigned as the body orientations, are entered and the angle /32 = 15° is picked as the free choice. Once the new dyad is selected,

Body Guidance Synthesis with Input Timing 51 lected, the six-bar linkage is shown and animated. The following table is a copy of a computer generated output describing the dimensions of the six-bar linkage.

Table 8. Six-bar linkage specifications

Input link = 4.46 Coupler link = 7.33

Output link = 14.38 Fixed link = 17.18

Third dyad

Input link = 7.94 Follower = 9.97

The input angle, defined to be 06 is shown in the following table along with the other angles at each corresponding body position. Note that the input timing is sat- isfied but the pointer is 302.66 degrees out of phase. Also by observing 03, it be- comes clear that the body orientation requirements are also satisfied. Figure 19 on page 54 shows the designed six-bar Stephenson Ill linkage, that will drive the body through the specified positions and orientations with the specified input timing.

Table 9. Six-bar linkage links' angles.

Body position 0e 02 03 04 Os

1 302.665° 45.5° 287.7° 186.5° 36.0°

2 312.665° 55.1° 322.5° 127.5° 50.4°

3 317.665° 51.0° 335.5° 103.4° 45.8°

4 322.665° 42.6° 347.4° 77.4° 35.3°

Body Guidance Synthesis with Input Timing 53 Figure 19. Six-bar body guidance linkage with input timing.

Body Guidance Synthesis with Input Timing 54 Chapter 8

System Structure

CYPRUS is a mechanism design system for the synthesis of body guidance,

path generation with input timing, body guidance with input timing and function gen- eration linkages. High resolution graphics, 640 by 200 pixels, is essential for this application, and therefore a computer graphics adapter and high resolution monitor are absolutely required.

CYPRUS is a relatively large program with more than 180 routines. As men- tioned before, the use of Pascal procedures encourages the programmer to write structured code, which is much easier to debug, expand, modify and also for others to understand. In addition the use of procedures usually reduces the code length a considerable amount depending on the amount of times each procedure is called.

System Structure 55 8.1 Main Procedure

In the main portion of the program, the user chooses the type of synthesis required. Then MAIN makes the necessary calls for input of the required parameters which are stored as global variables. Program execution is then transferred to one of the four synthesis routines where the synthesis is completed. Following this, the execution is transferred back to MAIN where the user may choose to synthesize an- other mechanism or quit. A flowchart that briefly describes the main procedure is shown in Figure 20 on page 57.

8.2 Body Guidance

The data required for a body guidance problem are body positions and orientations.

The required data is stored in global variables and is used by all routines. This por- tion of the program calculates the dyads that will drive the body through the desired positions and orientations. These dyads are displayed on the screen along with the body positions. Numerical values of x and y coordinates of the fixed and moving pivot of each dyad are also displayed in a specified window. Figure 21 on page 59 de- scribes briefly the flow of the procedure that displays the dyads. At this point the user can choose two dyads that will form the four-bar mechanism or get a screen dump hard copy if desired. If the designer believes that the dyads do not satisfy the physical constraints of the problem, he may go back to the main program and alter

System Structure 56 START

CHOOSE TYPE OF SYNTHESIS

N FUNCTION N GENERATION ? y

ENTER BODY POSITIONS ENTER BODY AND POSITIONS AND INPUT TIMING ORIENTATIONS

N

FUNCTION ENTER INPUT TIMING CHOOSE FUNCTION AND POINT ON THE ENTER DATA COUPLER LINK CALCULATE LINKAGE

DYADS CALCULATE, DISPLAY AND CHOOCE DYADS

ANIMATION ANIMATE LINKAGE

STOP

Figure 20. Logic diagram of the main program.

System Structure 57 his initial free choices (/32 and or /13) • Once the dyads are chosen execution is transferred to the animation routine, which is described later.

8.3 Body Guidance with Input Timing

For this problem the user first chooses two dyads as described above that form the four-bar linkage that will drive the body through the described positions and orientations. The program then asks the user to enter the desired input timing as well as a point on the coupler link where the input dyad will be connected to. Once the point and input timing are chosen a set of new dyads is calculated and displayed along with the body positions and the previously found four-bar linkage. The user has to choose a third dyad which is combined with the four-bar linkage to form a six-bar

Stephenson Ill linkage. Once the dimensions of the six-bar are found, execution is transferred to the animation routine.

8.4 Path Generation with Input Timing

This routine works exactly like the body guidance routine, with the difference that in place of orientations, which are arbitrary, the user enters the desired input link rotations. Two dyads are also chosen for this task and the execution is transferred to the cognates routine, which will be described in section 8.6.

System Structure 58 DYAD

DISPLAY DYADS

CHOOSE DESIRED DYADS

N y

y

CALCULATE INPUT TH£ NEW SET OF DATA FOR TH£ DYADS THIRD DYAD

COGNATES CALCULATE COGNATES

ANIMATION ANIMATE LINKAGE SHOW COUPLER CURVE

RETURN

Figure 21. Logic diagram of dyad presentation.

System Structure 59 8.5 Function Generation

For this synthesis task, the user enters a set of angle pairs or chooses one of the following functions: exponential, logarithmic, natural logarithmic, tangent, cosine and sine. Once the function is chosen, and the angular range of the input and output link, the initial and final value of the independed variable x and the length of the fixed link are input, Chebyshev spacing is used to find the precision points. Finally using

Freudenstein's equations, the dimensions of the linkage are found. Once the linkage dimensions are known, the animation routine is called for the display and animation of the designed linkage. A flowchart describing the function generation routine is shown in Figure 22 on page 61.

8.6 Cognates

The corresponding points of the fixed and moving pivots of the two chosen dyads as well as the first body position are transferred to this routine. Using this data and Roberts-Chebyshev theorem, the cognate linkages are calculated and displayed on the screen along with information on the Grashot type of each cognate. The user then chooses one of the two possible cognates and the animation routine is called.

A logic diagram describing the cognates routine is shown in Figure 23 on page 62.

System Structure 60 FUNCTION

CHOOSE DES.IRED FUNCTION

ENTER RANG£ OF X, INPUT AND OUTPUT, ANGLES

CALCULATE CH£BYSH£V SPACING

CALCULATE AND FU>j/CTIONS Yr

CALCULATE LINK LENGTHS

N

AN.IMATION CALL ANIMATION ROUT.IN£

RETURN

Figure 22. Description of the function generation routine.

System Structure 61 COGNATES

CALCULATE COG/VATES

DISPLAY COGNATES

CHOOSE DESIRED COGNATE

ANIMATION CALL ANI"1A TION ROUTINE

RETURN

Figure 23. Logic diagram of the cognates routine.

System Structure 62 8. 7 Animation Routine

This routine handles both four-bar and six-bar linkages. To start, the linkage

is displayed in its initial positionand the user can use the function keys for the fol-

lowing tasks:

1. Turn the input link clockwise.

2. Turn the input link counterclockwise.

3. Animate the linkage and obtain the coupler curve.

4. Choose input link angles for which the linkage is drawn.

5. Specify increments by which the input link angle. is increased or increased.

6. Quit.

A logic diagram describing the animation routine is shown in Figure 24 on page 64.

For the case of a four-bar linkage, a closed-form routine is called to solve for the output angles. This routine utilizes the equations given in Appendix 1 of [24] .

For the Stephenson Ill six-bar mechanism, a closed form solution is not possible

since the input/output equation is a sixth degree polynomial with six different sol-

utions. For this reason an iterative solution is obtained using the Newton-Raphson

method combined with Cholesky's method. The initial guess of the output angles are the corresponding angles calculated at the known configuration at which the first

body position is reached. To avoid finding solution in another branch, the assigned

System Structure 63 ANIMATION

y

y INPUT DESIRED INPUT LINK ANGLE

ENTER DESIRED INPUT LINK INCREHENT

y ANIMATE ANO DRAW TH£ COUPLER CURVE

OUMP SCREEN HAROCOPY

y Tl.RN It.PUT LINK AN AHOUIT OE1. TA Tl-ETA cw

Tl.RN Ii'PUT LINK AN AHOtNT OE1. TA Tl-ETA CCII

RETURN

Figure 24. Description of the animation routine.

System Structure 64 input link angular increment is relatively small, and the user does not have the option of changing it as he does in a case of a four bar linkage. Two loop closure equations are derived by summing the vectors around any two loops of a Stephenson Ill six-bar linkage. Functions F1 ... F4 result from the corresponding real and imaginary parts of the two complex equations, and a solution is reached if those functions go to zero.

A flowchart describing the above routine is shown in Figure 25 on page 66.

Once the option to animate is chosen, the linkage is animated and the coupler curve is displayed. During animation, an order defect can be detected by observing the order in which the body positions are reached. The coupler curve confirms that all positions lie on one branch. Observing the linkage motion, one can also detect possible unacceptable transmission angles and determine whether the mechanism passes through a change point. Mechanisms with these problems are discarded without manufacturing the prototype.

At any point the user has the choice of returning to the calling program and, in turn, to the main program where he may alter the free choices to obtain a new set of solutions, select a new synthesis task, or quit.

Appendix B lists the code with the procedures listed in the order they are called by the main program. Appendix C on the other hand, lists all the procedures global and local with a brief description of each one. Note that the indented proce- dures are local to the first non-indented routine.

System Structure 65 SIX-BAR

CALCULATE FUNCTIONS AND DERIVATIVES

SOLVE FOR DELTA THETA USING CHOLESKY'S METHOD

FIND NEW ESTIMATE OF THETAS

y

RETURN

Figure 25. Logic diagram of the iterative routine.

System Structure 66 Chapter 9

Concluding Remarks and Recommendations

CYPRUS is an interactive program that calculates and displays graphically the designed four-bar and six-bar linkages. This package can be used for three and four position synthesis of path generation, path generation with input timing, body guid- ance, and body guidance with input timing linkages. The package can also be used for function generation linkages where the user may enter a set of angle pairs or chooce one of the following functions: tangent, cosine, sine, exponential, logarithmic, and natural logarithmic. The above syntheses can be combined to design linkages that produce more complex motion.

The program leads the user through a step-by-step design procedure with the aid of computer graphics. Even inexperienced designers can produce kinematically correct mechanisms within a few minutes. Once a linkage has been designed, it is shown on the screen and animated. By animating the linkage the user can detect problems such as order, branch, and Grashof defects.

Concluding Remarks and Recommendations 67 The graphics routines utilized in this package have been created by the author specifically for linkage synthesis. Computer graphics play an essential role in visu- alizing the performance of the synthesized mechanism and they enchance the design process. As a result the designer can complete more of the design process before manufacturing models of the designed mechanism.

One of the disadvantages of this code is the slow speed of execution on a personal computer compared to the fast speed of mainframe computers. The intro- duction of 20 Mhz microprocessors, (lntell 80386) on a personal system, largely eliminates this problem. These systems are capable of running approximately five times faster than the older generation of personal computers.

Although the system has fullfilled most of the basic requirements of linkage synthesis, it has tremendous potential for increased capabilities. The design is based on kinematic considerations only, and does not consider dynamic effects on the linkage. Dynamic effects such as torque, inertia force and angular acceleration are not considered directly.

A major drawback of this project was the limited amount of code that can be compiled by Turbo Pascal. The compiled code could not exceed 64 Kbytes, unless overlay procedures were used. One shortcoming of overlaying is that it significantly slows the program execution. Fortunately Turbo Pascal, version 4.0, is to be released soon and there is no limit to the code size, except for the limit on the size of Random

Access Memory in the computer used. This will allow the programmer to use as many routines as needed to improve the program. As a result, additional routines for a more comprehensive analysis and perhaps some optimization will make CYPRUS a more valuable tool in mechanism design.

Concluding Remarks and Recommendations 68 References

1. Erdman, A. G., "Computer Aided Design of Mechanisms: 1984 and Beyond," Mechanism and Machine Theory, Vol. 20, No. 4, pp. 245-249, 1985.

2. Barker, C. R., "Complete Classification of Planar Four Bar Linkages," Mechanism and Machine Theory, Vol. 20, No. 6, pp. 357-361, 1985.

3. Erdman, G .• "Linkages Versus Gears," Engineering, Vol. 28, No. 4, pp. 352-355, October, 1984.

4. Funashabi, H., "Study on Completely Computer-Assisted Kinematic Analysis of Planar Link Mechanisms," Mechanism and Machine Theory, Vol. 21, No. 6, pp. 473-479, 1986.

5. Sandor, G. N., and Erdman, A. G., Mechanism Design: Analysis and Synthesis, Vol. 1, Prentice Hall, 1984.

6. Schildt, H., Advanced Turbo Pascal: Programming and Techniques, McGraw Hill, 1986.

7. Norton, P.• Programmer's Guide to the IBM PC, Microsoft Press, 1985.

8. Jones, J. A., and Harrow, K., Problem Solving using Turbo Pascal, Prentice Hall, 1986.

9. Freudenstein, F., and Sandor, G. N., "On Burmester Points of Plane." Journal of Applied Mechanics, Vol. 28, No. 1 pp. 41-49, March 1961.

10. Freudenstein, F., "Approximate Synthesis of Four Bar Linkages,'' ASME Paper 54-F-14, September 1954.

11. Mclarnan, C. W., "Synthesis of a Six Link Plane Mechanisms by Numerical Analysis," Journal of Engineering for Industry, Trans. ASME, Series B, Vol. 85, No. 1, pp. 5-11, February 1963.

References 69 12. Shingley, J. E., and Uicker, J. J., Theory of and Mechanisms, McGraw Hill, 1980.

13. Freudenstein, F., and Sandor, G. N., "Synthesis of a Path Generating Mechanism by a Programmed Digital Computer," Journal of Engineering for Industry, Trans. ASME, Series B, Vol. 81, No. 2, pp. 159-168, May 1959.

14. Roth, B., and Freudenstein, F., "Synthesis of a Path-Generating Mechanism by Numerical Methods," Journal of Engineering for Industry, Trans. ASME, Series B, Vol. 85, No. 3, pp. 298-306, August 1963.

15. Freudenstein, F., "An Analytical Approach to the Design of Four-link Mechanisms," Journal of Engineering for Industry, Trans. ASME, Series B, Vol. 76, No. 3, pp. 483-492, April 1954.

16. Denavit, J., and Hartenberg, R. S., "Approximate Synthesis of Spatial Linkages," Journal of Applied Mechanics, pp. 201-206, March 1960.

17. Rubel, A. J., and Kaufman, R. E., "KINSYN Ill: A New Human-Engineered System for Interactive Computer-Aided Design of Planar Linkages," ASME Journal of En- gineering for Industry, Vol. 99, No. 2, pp. 98-106, May 1977.

18. Krouse, J. K., "Designing Mechanisms on a Personal Computer," Machine De- fil.ill1. Vol. 55, No. 6, pp. 94-99, March 24, 1983. 19. Waldron, K. J., and Stevensen, E. N., "Analyzing Mechanisms with the IBM PC," Computers in Mechanical Engineering, Vol. 2, No. 1. pp. 37-44, July 1983.

20. Sinha, D. K., "Microcomputers in Mechanism Design," International Journal of Engineering Education, Vol. 12, No. 4, pp. 263-274, 1984.

21. Mittelstadt, W., "Integrated Computer-Aided Design of Mechanisms," Mechanism and Machine Theory, Vol. 20, No. 4, pp. 303-311, 1985.

22. Rooney, G., "New Software Synthesizes Complex Mechanisms," Machine Design, Vol. 57, No. 19, pp. 107-113, August 22, 1985.

23. Pessen, 0., "Mechanisms Animation on a Personal Computer," Mechanical En- gineering, Vol. 106, No. 10, pp. 33-35, October 19, 1984.

24. Mabie, H. H., and Reinholtz, C. F., Mechanisms and Dynamics of Machinery, 4th edition, John Wiley, 1987.

25. Myklebust, A., Keil, M. J., and Reinholtz, C. F., "MECSYN-IMP-ANIMEC: Founda- tion for a New Computer-Aided Spatial Mechanism Design System," Mechanism and Machine Theory, Vol. 20, No. 4, pp. 257-269, 1985.

26. Waldron, K. J., and Stevensen, E. N., "Elimination of Branch, Grashot, and Order Defects in Path-Angle Generation and Function Generation Synthesis," ASME Journal of Mechanical Design, Vol. 101, No. 3, pp. 428-437, July 1979.

27. Cherry, G. W., Pascal Programming Structures, Reston Publishing Company, 1986.

28. ------, Turbo Pascal Reference Manual, Borland International, Inc., 1986.

References 70 29. Basili, R. V., and Baker, T., Structured Programming, IEEE Computer Society, 1977. 30. Sandor, G. N., and Erdman, A. G., Advanced Mechanism Design: Analysis and Synthesis, Vol. 2, Prentice Hall, 1984. 31. Freudenstein, F., "Four Bar Function Generators," Machine Design, Vol. 30, No. 24, pp. 119-123, November 27, 1958.

References 71 Appendix A

Body Guidance Synthesis Equations

A.1 Equations Used for Three Position Synthesis

In Chapter 4, a body guidance problem is shown in Figure 7 on page 23, at the first and jth position. A loop closure equation was derived by summing the vectors counterclockwise around the loop from position 1 to position j. By combining equations 2 with 3, 4 and 5 we get the following loop closure equation.

j = 1.. 3 [A.1]

By substituting

[A1.2.1]

Body Guidance Synthesis Equations 72 [A1.2.2]

[A1.2.3]

we get

[A1.3]

Using the above equation for three positions we get

[A1.4.1]

[A1.4.2]

By picking /3 2 and /3 3 as the free choices we can solve for P, S, y and /31• This is done by breaking the above two equations into four scalar equations. Then the following two by two system of complex number equations is obtained

[A1.5]

Note that A2, A3, 0 2 and 0 3 are known. P and S are the two vector unknowns. Treat- ing the above system as linear we can solve it using Cramer's rule. Once the system is solved for the two unknown vectors P and S, we can solve for P, S, y and /3 1•

Body Guidance Synthesis Equations 73 A.2 Equations Used for Four Position Synthesis

For four position synthesis equation A.1.3 is written three times corresponding to the three body displacements.

[A2.1.1]

[A2.1.2]

[A2.1.3]

A; and D; , are known since the positions and orientation of the body are given. We still have six unknowns P, S, y, /3,. /3 2, /3 3 and /34• By substituting

[A2.2]

and picking /32 as the free choice, we get the following system of simultaneous equations.

[A2.3]

Assuming that 8 3 and 8 4 are known we observe that eq. A2.3 contains three equations and two unknowns. Since the number of equations is greater than the number of

Body Guidance Synthesis Equations 74 unknowns two of the above equations have to be linearly dependent. In other words the determinant of the augmented matrix must be zero.

[A2.4]

Calculating the determinant of the above system we get

If we let

[A2.6.1]

[A2.6.2]

[A2.6.3]

equation A2.5 becomes

[A2.7]

By expanding out 8 2, 8 3 and 8 4 and separarating unknowns we end up with

[A2.8]

[A2.9]

Body Guidance Synthesis Equations 75 By expanding the above equation into its real and imaginary parts one can eliminate

P3 by squaring and adding the two equations. Once /3 3 is eliminated the only unknown left in this equation is {34 • /34 is then calculated and substituted in equation A2.9 in order to solve for {33• Finally the values of /33 and /14 are substituted back to equation

A2.1. Then using any two of the three rows of the 3 by 2 system one can solve for

P and S and in turn find the values of P, S, y and /11•

Body Guidance Synthesis Equations 76 Appendix B

Pascal Code

{ CYPRUS Ver. 1.0

A kinematic synthesis package

for planar four and six-bar

linkages

Christodoulos S. Demetriou

Virginia Polytechnic Institute and State University Blacksburg, Virginia 24061

Under the guidance of

Dr. Charles F. Reinholtz Dr. Michael P. Deisenroth Dr. John B. Kosmatka

December 11, 1987

Pascal Code 77 Introduction of the program and some important instructions }

Procedure Start_Program; Begin Textmode(c40); Textbackgrou nd(3); Textcolor(15); Window(S,5,35,20); GotoXY(1,6); Writeln(' Welcome to Cyprus !!! '); Writeln(' '); Writeln(' A Kinematic Synthesis '); Writeln(' '); Writeln(' Package '); GotoXY(1, 15); Write('Press Any Key to Continue '); Repeat Until Keypressed; Clrscr;GotoXY(1,3); Writeln(' All Angles Are to Be '); Write In; Writeln(' in DEGREES '); Write In; Writeln(' If More Than One Variable '); Write In; Writeln(' Is to Be Entered, a Blank '); Write In; Writeln(' Must Separate Them and '); Write In; Writeln(' NOT a Comma '); Writeln;Writeln; Write(' ... Press Any Key to Continue '); Repeat Until Keypressed; Textmode(c80); Window( 1, 1,80,25); Clrscr; end;

{ Draws two body positions showing the different ways the input can be entered }

Procedure Photo; Var xx : Plotarray; Dum,Dum1 : Real;

Pascal Code 78 { Initializes Graphics }

Procedure Initialize; Begin Graphcolormode; Graphbackgrou nd(0); Windowcoord(2, 160,0,319, 199); Setwindow(2); xx[ 1, 1] : = 0; xx[1,2] : = O; xx[2, 1] : = 130; xx[2,2] : = 180; Set_View_ Coo rd in ates( 1,2,xx,Du m); end;

{ Draws an arc of any radius from one angle to another }

Procedure My_Arc(Origx,Origy,Radius, lnitial_Angle, Final_Angle : Real; Color : Byte); Var Th1 : Real; i : Integer; Const Step : Real = 0.0523599; Begin Th1 : = lnitial_Angle; i := O; Repeat i := i + 1; xx[i,1] := Origx + Radius* Cos(Th1); xx[i,2] : = Origy + Radius* Sin(Th1); Th1 : = Th1 + Step; if i = 2 then Begin Drawpoints( 1,2,Color,xx); i := O; end; Until Th1 > Final_Angle; end;

{ Draws the necessary lines to form a body position }

Procedure Draw_Position; Var

Pascal Code 79 v1 ,v2 : Real;

Procedure Draw_lt(x0,y0,x,Th : Real; Col : Byte); Begin v1 : = x0 + x • Cos(Th); v2: = y0 + x • Sin(Th); Drawline(x0,y0, v1 ,v2,Col) end;

Begin Draw_lt(O,0, 130, 1.05,3); Oum:= v1; Dum1 : = v2; Draw_lt(Du m,Du m 1,40,0.580, 10); Drawline(Dum + 10,Dum1,Dum + 30,Dum1,3); Draw_lt(Dum,Dum1,40,pi/2 + 0.58, 10); My_Arc(Dum,Dum1 ,25,0.0,0.58,3); Draw_lt(0,0, 120,0.58, 1); Oum:= v1; Dum1 : = v2; Draw_lt(Dum,Dum1 ,40, 1.05, 10); Drawline(Dum + 10,Dum1 ,Dum + 30,Dum1, 1); Draw_lt(Dum,Dum1,40.pi/2 + 1.05,10); My_Arc(Dum,Dum1,25,0.0, 1.05, 1); end;

{ Writes the necessary text on the screen }

Procedure Write_the_Text; Begin Window(40.1,80,25); Textcolor(1); Gotoxy(29,22); Write('Th-1 '); Gotoxy(32, 18); Write('R-1 '); Gotoxy(39, 14); Write(' A-1 '); Gotoxy(37,17); Write('X1,Y1'); Textcolor(3); Gotoxy(27,20); Write('Th-j'); Gotoxy(27, 16); Write('R-j'); Gotoxy(36,9); Write(' A-j'); Gotoxy(26, 10); Write('Xj,Yj'); Textcolor(10); Gotoxy(22,4); Write('Y'); Gotoxy(40,24); Write('X'); Gotoxy(37,7); Write('u'); Gotoxy(28,6); Write('v'); Gotoxy(40, 11 ); Write('u'); Gotoxy(32, 14); Write('v'); Window( 1, 1,40,25);

Pascal Code 80 Writeln; Writeln(' These Are tile '); Writeln(' Required '); Writeln(' Input Parameters '); Writeln;Writeln; Textcolor(1); Writeln(' I. Positions '); Writeln('a > Polar Coordinates'); Write In; Writeln(' R-1 ... R-j'); Writeln(' Th-1 ... Th-2');Writeln; Writeln(' OR ');Writeln; Writeln('b> Rectangular '); Writeln(' Coordinates ');Writeln; Writeln(' X1,Y1 ... Xj,Yj '); Writeln;Writeln; Writeln(' II. Orientation '); Writeln(' Of the Body ');Writeln; Writeln(' A-1 ... A-j '); GotoXY(28, 1); Write(' Any Key to'); GotoXY(28,2); Write(' Continue'); end;

Begin In itia I ize; Drawline(0.0, 130,0, 10); Drawline(0,0,0, 160, 1O); Draw_Position; My_Arc(0,0,35,0.0,0.58, 1); My_Arc(0,0,25,0.0, 1.05,3); Write_the_Text; Repeat Until Keypressed; Textmode(c80); end;

Begin Start_Program; Photo end;.

Pascal Code 81 { Declaration of data structures and Variables }

Const Int Print = $0005; AsciC = $0010;

Type

ViewType = Record vx1,vy1,vx2,vy2,vxw,vyw: Real; end;

lntr_Code = Record Case Integer of 1:(ax,bx,cx,dx,bp,si,di,ds,es,Flags: Integer); 2:(al,ah,bl,bh,cl,ch,dl,dh : Byte); end;

Windowtype = Record wx1 ,wy1 ,wx2,wy2 : Integer; end;

Points = Array[1 .. 2] of Real; Plotarray = Array[1 .. 150,1 .. 2] of Real; Views = Array[ 1. .4] of ViewType; Windows = Array[1 . .4] of WindowType; Check = Array[ 1.. 15] of Boo lean; Vector = Array[0 .. 75] of Real; Matrix = Array[1..3,1 .. 3] of Real; lnout Vector = Array[ 1..3] of Real; A_Linkage = Array[1 . .4] of Real; Strings = String[13];

Var ActiveWindow,ActiveViewPort,Wwidth,Wheight: Integer; GrafBase : Integer; Vwidth,Vheight,Vupper,Vleft : Real; ViewPort : Views; Window1 : Windows; ColorGlb : Byte; ab2 : Vector; a,b,c : Plotarray; Body_Position : Plotarray; Count,nn : Integer; WhatPosition : Integer; ab1 : Real; Coupler_Length : Real; Coupler_Angle_a : Real; Link c : A_Linkage;

Pascal Code 82 Synthesis : Char; Six_Bar : Plotarray; Branch, Pass1 : Boolean; Chaise Over : Boolean;

{ Convert radians to degrees and vice versa }

Function Rad(Th : Real) : Real; Begin Rad : = Th * pi / 180.0 end;

Function Deg(Th : Real) : Real; Begin Deg : = Th * 180.0 I pi end;

{ Computes the arc tangent using two parameters }

Function Atan2(Xreal,Ximag : Real) : Real; Var j : Integer; X: Real; Begin If Xreal = 0.0 then j: = 1; If Xreal > 0.0 then j : = 2; If Xreal < 0.0 then j : = 3; Case j of

1 : Begin If Xi mag < 0.0 then Atan2: = 3. * pi / 2.0; If Xi mag > 0.0 then Atan2 : = pi / 2.0; If Xi mag = 0.0 then Atan2 : = 0.0 end; 2: Begin x : = Arctan(Ximag / Xreal); If x < 0 then Atan2 : = 2*pi + x else Atan2: = x end; 3: Begin Atan2 : = Arctan(Ximag / Xreal) + pi end;

Pascal Code 83 end; end;

{ Calculates the arc cosine }

Function Acos(c:Real):Real; Var s,ac: Real; Begin s: =Sqrt(1-c*c); ac: = Arctan(s/c); If c < 0 then ac: = ac + pi; Acos: = ac; end;

{ It calls an interrupt routine to print the screen }

Procedure Print_Screen; Var Results : lntr_Code; Begin lntr( lnt_Print,Results); end;

{ Pauses asking the user to press any key to continue }

Procedure Pause(pc:Char); Var x: Char; Begin If pc= 'T' then Begin GotoXY(3,24); Write(' Any Key to Continue ... '); end; If pc = 'G' then Begin GotoXY(3,22); Write('Press H for Hard_Copy ... '); GotoXY(3,24); Write('OR Any Key to Continue ... '); end; Read(kbd,x); If (Upcase(x) = 'H') and (pc= 'G') then Begin Textcolor(0);

Pascal Code 84 GotoXY(3,22); Write('Press H for Hard_Copy ... '); GotoXY(3,24); Write('OR Any Key to Continue ... '); Print_screen; end; end;

{ Sets up the window coordinates }

Procedure WindowCoord (Num,x1,y1,x2,y2: Integer); Begin With Window1[Num] Do Begin wx1: = x1; wx2: = x2; wy1: = y1; wy2: =y2; end; end;

{ Initializes variables required for the viewport }

Procedure ViewCoord (Num : Integer; x1 ,y1 ,x2,y2 : Real); Begin With Viewport[Nu rn] Do Begin vx1: = x1; vy1:=y1; vx2: = x2; vy2: =y2; vxw: = x2-x1; vyw: = y2-y 1; end; end;

{ Assigns one of the already defined windows }

Procedure SetWindow(Num : Integer); Begin With Window1[Num] Do Begin GraphWindow(wx1 ,wy1, wx2. wy2); Wwidth: = wx2-wx 1; Wheight: = wy2-wy1; end; ActiveWindow: = Num; end;

Pascal Code 85 { Sets up a viewport }

Procedure SetViewport(Num : Integer); Begin With Viewport[Num] Do Begin Vwidth: = vxw; Vheight: = vyw; Vleft: = vx1; Vupper: = vy2; end; ActiveViewport: = Num; end;

{ Draws a box around the window }

Procedure WindowBox; Var dx,dy : Integer; Begin With Window1[ActiveWindow] Do Begin dx: = wx2-wx1; dy: = wy2-wy1; end; Draw(O,O,dx,O, 1); Draw(dx,O,dx,dy, 1); Draw(dx,dy,O,dy, 1); Draw(O,dy,0,0, 1); end;

{ Draws a line between two points }

Procedure Drawline(x1 ,y1 ,x2,y2 : Real; c:Byte); Var dx1,dy1,dx2,dy2: Integer; Begin dx1: = Round((x1-Vleft)/Vwidth*Wwidth); dx2: = Round((x2-Vleft)/Vwidth*Wwidth); dy1: = Round((Vupper-y1 )/Vheight*Wheight); dy2: = Round((Vupper-y2)/Vheight*Wheight); Draw(dx1 ,dy1 ,dx2,dy2,c); end;

Pascal Code 86 {. Draws polyline connecting a set of points }

Procedure DrawPoints(i,j,k: Integer; xyp:Plotarray); Begin Drawl i ne(xyp[ i, 1],xyp[ i,2],xyp[j, 1],xyp[j,2], k); end;

{ Sets up the view coordinates }

Procedure Set_View_ Coordinates( no, nsp: Integer; xy3p:Plotarray; Var Oum : Real); Var j,m : Integer; a_f,xn,xx,yn,yx,xr,yr,xh,yh,xc,yc,ar : Real; in c : lntr_Code; Begin in_c.ah : = 15; I ntr(Ascic,i n_ c); If in c.al = 6 then ar : = 3.2 else ar : = 1.6; a_f : = 1.4633 • (Wwidth/Wheight)/ar; xn:=xy3p[1,1]; xx:= xn; yn:=xy3p[1,2]; yx: = yn; for j: = 1 to nsp Do Begin xh: = xy3p[j, 1]; yh: = xy3p[j,2]; If xh < xn then xn: = xh; If xh > xx then xx:= xh; If yh < yn then yn: = yh; If yh > yx then yx: = yh; end; xc: =(xx+ xn)/2; ye:= (yx + yn)/2; xr: = (xx-xn)* 1.2; yr:= (yx-yn)* 1.2; If xr < a_f*yr then xr: = a_f*yr else yr:= xr/a_f; Oum:= xr; xn: = xc-xr/2; xx:= xn + xr; yn: = yc-yr/2; yx: = yn + yr; ViewCoord(no,xn,yn,xx,yx); SetViewport(no); end;

Pascal Code 87 { Draws a filled square }

Procedure Draw_Square(x,y,Size : Real; Color : Byte); Var x1 ,x2,y1 ,y2,ym : Real; i : Integer; Begin x1 : = x - (Size/2.0); x2: = x + (Size/2.0); y1 : = y + (Size/2.0); for i : = 0 to 10 Do Begin ym : = y1 - ((i • Size)/10.0); Drawline(x1 ,ym,x2,ym,Color); end; end;

{ Draws a square with or without a cross within it, (Fixed and moving pivots) }

Procedure Draw_Sq_Pivot(x,y,Size : Real; Color : Byte; Cross : Boolean); Var x1,x2,y1,y2,ym : Real; i : Integer; Begin x1 : = x - (Size/2.0); x2 : = x + (Size/2.0); y1 : = y + (Size/2.0); y2 : = y - (Size/2.0); Drawline(x 1,y1 ,x2,y1 ,Color); Drawline(x2.y1 ,x2,y2,Color); Drawline(x2,y2,x1 ,y2,Color); Drawline(x1 ,y2,x1 ,y1 ,Color); If Cross then Begin Drawline(x2,y2,x1 ,y1 ,Color); Drawline(x1 ,y2,x2,y1 ,Color) end; end;

{ Draws a cross at a specified position }

Procedure Draw_Cross(x,y,Size : Real; Color: Byte); Var x1 ,x2,y1 ,y2,ym : Real;

Pascal Code 88 i : Integer; Begin x1 := x- (Size/2.0); x2: = x + (Size/2.0); y1 : = y + (Size/2.0); y2: = y - (Size/2.0); Drawline(x2,y2,x1 ,y1 ,Color); Drawline(x1 ,y2,x2,y1 ,Color) end;

{ Used with the following two procedures to avoid abortion of the program in case of a user error }

Procedure Readnum(Var Rnum:Real; Var lnum:lnteger; Ntype:lnteger); Const gtbg = O; Var x,y,er : Integer; inp : String[18];

Procedure Clear_Window; Var i,j : Integer; Begin for j : = 0 to 1 Do for i : = 0 to 9 Do Begin GotoXY(x + i,y + j); Write(' ') end; GotoXY(x,y) end;

Begin x: =Wherex; y: =Wherey; If (y = 25) then Begin Write In; y: = y-1; end; Clear_Window; Repeat Readln(lnp); Case Ntype of 1 : Val(lnp,Rnum.er); 2: Val(lnp,lnum,er); end; If (er< > 0) then Begin Write(¢G); Textbackground(4); Clear_Window; Gotoxy(x,y); Writeln(lnp);GotoXY(x,y + 1); Write('Error!!!'); Delay(350); Textbackground(gtbg); Clear_Window;

Pascal Code 89 end; until (er=O); Gotoxy(1,y+ 1); end;

{ Reads a real number in order to avoid possible abortion of the program in case of a user error }

Procedure Readrl(Var rr:Real); Var ldum:lnteger; Begin Read nu m(rr,ldu m, 1); end;

{ Reads a integer number in order to avoid possible abortion of the program in case of a user error }

Procedure Readint(Var ii:lnteger); Var Rdum:Real; Begin Readnum(Rdu m,ii,2); end;

{ Calculates the transformation matrix }

Procedure Calc_D_Matrix(x, y, Theta : Real; Var t : Matrix); Var c, s : Real; Begin c : = Cos(Theta); s : = Sin(Theta); t[1,1]: = c; t[1,2] : = -s; t[1,3] : = x; t[2,1] := s; t[2,2] : = c; t[2,3] : = y; t[3, 1] : = O; t[3,2] : = O; t[3,2] : = 1 end;

Pascal Code 90 { Transforms a point into new coordinates according to transformation matrix }

Procedure Transform(t : Matrix; Var x, y :Real); Var i' j : Integer; Inv, Out : lnout_Vector; Begin lnv[1] := x: lnv[2] : = y; lnv[3] : = 1; for i: = 1 to 3 Do Begin Out[i]: = O; for j: = 1 to 3 Do Out[i] : = Out[i] + I nv[j] • t[i,j] end; x : = Out[1]; y : = Out[2] end;

Pascal Code 91 { Calculates the output angles of a four-bar linkage given the link lengths and the position of the input link }

Overlay Procedure Calculate_Angles(a,b,c,d,Th2:Real;Var Th3,Th4: Real; Var OK : Boolean); Var aa, bb, cc, t : Real; Dum1, Dum2, Dum3 : Real;

Procedure Calc_a ; Begin aa : = Sqr(b) - Sqr(d) - Sqr(a) - Sqr(c) + 2 * d * a * Cos(Th2) + 2 * d * c - 2 * a * c * Cos(Th2) end;

Procedure Calc_b ; Begin bb : = 4 * a * c * Sin(Th2) end;

Procedure Calc_c ; Begin cc : = Sqr(b) - Sqr(d) - Sqr(a) - Sqr(c) + 2 * d * a * Cos(Th2) - 2 * d * c + 2 * a * c * Cos(Th2) end;

Begin OK:= True; Calc_a; Calc_b; Calc_c; Dum1 := Sqr(bb) -4 * aa * cc; If Dum1 > = 0.0 then Begin If Branch then t: = (-bb + Sqrt(Dum1))/(2*aa) else t: = (-bb - Sqrt(Dum1))/(2*aa); Dum2 : = (1 - Sqr(t)); Dum3: = 2 • t; Th4 : = Atan2(Dum2,Dum3); Dum2: = d + c *Cos(Th4) - a* Cos(Th2); Dum3: = c *Sin(Th4) - a * Sin(Th2); Th3 : = Atan2(Dum2,Dum3); end; else

Pascal Code 92 OK:= False end;

{ Given the linkage determine the Grashof type as well as the angle range of the input link }

Overlay Procedure Type_of_Link(Link : A_Linkage; Var I_ Type : Strings; Var Th2S, Th2L : Real); Var Flag, Ok : Boolean; Temp : Real; i,j : integer; a : Array[1 ..4] of Real;

{ Checks whether the linkage obeys Grashof law. }

Procedure Grashot Begin Flag : = False; If (a[1] + a[4]) < = (a[2] + a[3]) then Flag : = True; end;

{ Rearranges the links in order of their magnitute }

Procedure Que_Them; Begin for i : = 1 to 4 Do a[i] : = Link[i]; for i : = 1 to 3 Do Begin for j : = 3 Downto 1 Do Begin If a[j] > a[j + 1] then Begin Temp : = a[j]; a[j] : = a[j + 1]; a[j+1] := Temp end; end; end; end;

Pascal Code 93 { Calculates the range of the input link ie.,the minimum and maximum angle of rotation of the input link }

Procedure Range_of_Angles; Var Temp : Real; Begin If ((Link[1] + Link[4]) > (Link[2] + Link[3])) and (Abs(Link[1] - Link[4]) > = Abs(Link[3] - Link[2])) then Begin Th2L: = Acos((Sqr(Link[1]) + Sqr(Link[4]) - Sqr(Link[2] + Link[3]))/(2 * Link[1] * Link[4])); Th2S : = 2 • pi - Th2L; end; If ((Link[1] + Link[4]) < = (Link[2] + Link[3])) and (Abs(Link[1] - Link[4]) < Abs(Link[3] - Link[2])) then Begin Th2S: = Acos((Sqr(Link[1]) + Sqr(Link[4]) - Sqr(Link[3] - Link[2]))/(2 • Link[1] • Link[4])); Th2L : = 2 • pi - Th2S; end; If ((Link[1] + Link(4]) > (Link[2] + Link[3])) and (Abs(Link[1] - Link[4]) < Abs(Link[3] - Link[2])) then Begin Th2S : = Acos((Sqr(Link[1]) + Sqr(Link(4]) - Sqr(Link[3] - Link[2]))/(2 • Link[1] • Link[4])); Th2L: = Acos((Sqr(Link[1 ]) + Sqr(Link(4]) - Sqr(Link[2] + Link[3]))/(2 • Link[1] • Link[4])); end; end;

Begin Que_Them; Grashof; If Flag then Begin If a[1] = Link[1] then Begin I_ Type : = 'Crank-Rocker'; Th2S: = O; Th2L : = 2.0 * pi; end; If a[1] = Link(2] then Begin I_ Type : = 'Double-Rocker'; Range_of_Angles; end;

Pascal Code 94 If a[1] = Link[3] then Begin I_ Type : = 'Rocker-Crank'; Range_of_Angles; end; If a[1] = Link[4] then Begin I_ Type : = 'Drag-Link'; Th2S: = O; Th2L := 2 * pi; end; end; else Begin I_ Type : = 'Non-Grashot'; Range_ of_Angles; If Th2s > Th2I then Th2I : = Th2I + 2 * pi; end; end;

{ Fills the coupler link with hatched lines }

Overlay Procedure Fill(Point1, Point2, Point3 : Points; Color : Byte); Var p1,p2 : Points; Slope2, Slope3, Dum1, Dum2, Dum3, Length, x1, y1, x2, y2 : Real; Angle : Real; I : Integer; Flag : Boolean;

{ Calculates the distance between two points }

Function Magnitude(po1, po2 : Points): Real; Begin Magnitude:= Sqrt(Sqr(po1[1] - po2[1]) + Sqr(po1[2] - po2[2])); end;

{ Solves a system of two equations in two unknowns}

Procedure Matrix_Operation; Begin

Pascal Code 95 p2[1] := (Point1[2] - p1[2] + Slope3 • p1[1] - Slope2 • Point1[1])/(Slope3 - Slope2); p2[2] := Slope2 • (p2[1] - Point1[1]) + Point1[2]; end;

Begin Length : = Magnitude(Point1, Point2); Flag : = True; Dum1 := Point2[1] - Point1[1]; Dum2 := Point3[1] - Point1[1]; Dum3 := Point3[1] - Point2[1]; If (Dum1 = 0.0) or (Dum2 = 0.0) or (Dum3 = 0.0) then Flag : = False; If Flag then Begin Angle:= Atan2(Dum1,(Point2[2] - Point1[2])); Slope2: = (Point3[2] - Point1[2]) / Dum2; Slope3: = (Point3[2] - Point2[2]) / Dum3; For i : = 1 to 15 Do Begin p1[1]: = Point1[1] + ((i * Length)/15.0) • Cos(Angle); p1[2]: = Point1[2] + ((I * Length)/15.0) * Sin(Angle); Matrix_Operation; x1 := p1[1]; y1:=p1[2]; x2 := p2[1]; y2: = p2[2]; Drawline(x1 ,y1 ,x2,y2,Color); end; end; end;

Pascal Code 96 { Given the dimensions of a six_bar linkage as well as the input angle calculate the output angles. The solution is found using a Newton-Raphson iterative technique and Cholesky's method }

Procedure Six_a(r2, r3,r4.r5,r6,Th6 : Real; Var Th2, Th3, Th4,Th5 : Real; Var IS_OK : Boolean); Type Matrices = Array[1..5. 1..5) of Real; Vectors = Array[1..5] of Real;

Var DF : Matrices; F,DTH : Vectors; j : Integer; Coth2, Coth3, Coth4, Coth5 : Real; Ch : Char; Const nm= 4;

{ Solves a system of four equations in four unknowns }

Procedure Simu ltaneous_Solution (n:I nteger;c:Matrices; b:Vectors; Var x:Vectors); Var lrow,M : Integer; Big,Temp,Ab : Real;

Procedure Put_ln_B; Var i : Integer; Begin for i: = 1 to n Do c[i,n + 1]: = b[i]; end;

Procedure Big_Row_First; Var i,j : Integer; Begin lrow: = 1; Big:= Abs(c[1, 1]); for i: = 2 to n Do Begin Ab:= Abs(c[i, 1]); If Big< Ab then Begin

Pascal Code 97 Big:=Ab; lrow:=i; end; end; If I row> 1 then Begin for j: = 1 to n + 1 Do Begin Temp:= c[lrow,j]; c[lrow,j]: = c[1,j]; c[1,j]: = Temp; end; end; end;

Procedure First_Row; Var j : Integer; Begin for j:=2 to n+1 Do c[1,j]:=c[1,j]/c[1,1]; end;

Procedure New_Elements; Var i,j,ii,Jm1,lp1,kk: Integer;

Procedure NE1; Var ii : Integer; Sum: Real; Begin for ii:= j ton Do Begin Sum:=O; Jm1:=j-1; for kk: = 1 to Jm1 Do Sum:= Sum+ c[ii,kk]"c[kk,j]; c[ii,j]: = c[ii,j]-Sum; end; end;

Procedure NE2; Var ii,j : Integer; Begin lrow:=i; Big:= Abs(c[i,i]); lp1:=i+1; for ii:= lp1 to n Do

Pascal Code 98 Begin Ab:= Abs(c[ii,i]); If Big< Ab then Begin Big:= Ab; I row:= ii; end; end; If I row< > i then Begin for j: = 1 to M Do Begin Temp:= c[lrow,j]; c[lrow,j]: = c[i,j]; c[i,j]: = Temp; end; end; end;

Procedure NE3; Var jj,k,lm1 : Integer; Sum : Real; Begin lp1:=i+1; for jj: = lp1 to n + 1 Do Begin Sum:=O; lm1: = i-1; fork:= 1 to lm1 Do Sum:= Sum+ c[i,k]*c[k,jj]; c[i,jj]: = (c[i,jj]-Sum)/c[i,i]; end; end;

Begin for i: = 2 to n Do Begin j: = i; NE1; If i < > n then NE2; NE3; end; end;

Procedure Back_Substitute; Var nn,i,j,L,lp1 : Integer; Sum : Real; Begin X[n]: = c[n,n + 1]; L: = n-1; for nn: = 1 to L Do

Pascal Code 99 Begin Sum:=O; i: = n-nn; lp1:=i+1; for j: = lp1 to n Do Sum:= Sum+ c[i,j)*X[j]; x[i]: = c[i,n + 1]-Sum; end; end;

Begin M:=n+1; Put_ln_B; Big_Row_First; First_Row; New_Elements; Back_Substitute; end;

{ Reinitializes angles whenever necessary in order to obtain a solution in the same branch }

Procedure Set_Angles(Begining : Boolean); Begin If Begining then Begin Coth2 : = Th2; Coth3 : = Th3; Coth4: = Th4; Coth5: = Th5 end; else Begin Th2 : = Coth2; Th3 : = Coth3; Th4 : = Coth4; Th5: = Coth5 end; end;

{ Calculates angles using Newton_Raphson as well as Cholesky's methods }

Procedure Newton_Raphson; Var c2, c3, c4, c5, c6, s2, s3, s4, s5, s6,

Pascal Code 100 c3a, s3a : Real; F, DTH : Vectors; OF : Matrices;

Procedure Calculate_F_D;

{ Calculates the functions at the specified angles }

Procedure Calc_Functions; Begin F[1] :=-(Six_Bar[1,1] + r2 * c2 + r3 * c3- Six_Bar[4,1] - r4 * c4); F[2] :=-(Six_Bar[1,2] + r2 * s2 + r3 * s3 - Six_Bar[4,2] - r4 * s4); F[3] : =-(Six_Bar[1, 1] + r2 * c2 + Coupler_Length * c3a - Six_Bar[7, 1] - r6 * c6 - r5 * c5); F[4] :=-(Six_Bar[1,2] + r2 * s2 + Coupler_Length • s3a - Six_Bar[7,2] - r6 * s6 - r5 * s5); end;

{ Calculates Jacobians at the specified angles }

Procedure Calc_Derivatives; Begin D F[ 1, 1] : = -r2 * s2; DF[1,2] : = -r3 * s3; DF[1,3] := r4 • s4; DF[1 ,4] : = 0.0;

DF[2,1] := r2 * c2; DF[2,2] : = r3 * c3; DF[2,3] : = -r4 * c4; DF[2,4] : = 0.0;

DF[3,1] := -r2 • s2; DF[3,2] : = -Cou pier_Length * s3a; DF[3,3] : = 0.0; DF[3,4] : = r5 • s5;

DF[4,1] := r2 * c2; DF[4,2]: = Coupler_Length * c3a; DF[4,3] : = 0.0; OF[ 4,4] : = -r5 • c5;

end;

Begin c2 : = Cos(Th2);

Pascal Code 101 s2 : = Sin(Th2); c3 : = Cos(Th3); s3: = Sin(Th3); c4 : = Cos(Th4); s4: = Sin(Th4); c5 : = Cos(Th5); s5: = Sin(Th5); c6 : = Cos(Th6); s6 : = Sin(Th6); c3a : = Cos(Th3 + Coupler _Angle_a); s3a: = Sin(Th3 + Coupler_Angle_a); Calc_Functions; Calc_Derivatives; Simu ltaneous_Solution( nm,DF, F,DTH) end;

{ Calculates a new estimate of angles once Jacobians are found }

Procedure New_Estimate; Begin Th2: = Th2 + DTH[1]; Th3 : = Th3 + DTH[2]; Th4 : = TH4 + DTH[3]; Th5 : = Th5 + DTH[ 4]; end;

Begin j: = O; Repeat Calculate_F_D; New_Estimate; j :=j +1; If (Abs(Th2) > 2* pi) or (Abs(Th3) > 2* pi) or (Abs(Th4) > 2*pi) or (Abs(Th5) > 2*pi) then Set_Ang les(False): until ((Abs(F[1]) < 0.01) and (Abs(F[2)) < 0.01) and (Abs(F[3]) < 0.01) and (Abs(F[4]) < 0.01)) or (j > 20); If j > 20 then Begin ls_OK : = False; Set_Angles(False) end; end;

Begin

Pascal Code 102 1s_OK : = True; Set_Angles(True); Newton_Raphson; end;

Pascal Code 103 { It is the main graphics routine of the code. It animates the four-bar linkage and displays the coupler curve. Also the linkage can be driven in any direction with input angle step size specified by the user. }

Procedure Linkage(a,b,c,d : Real);

Procedure Linkages; Var aa, bb, cc, Th4, Th2 : Real; x1 ,x2, y1, y2,Th3 : Real; Delta_Theta, Oum : Real; pp : Plotarray; Counter : Integer; Ch : Char; OK : Boolean; Color : Byte; Link_Type : Strings; Th2s, Th2I : Real; p, Alph, X, y : Real; Trans : Matrix;

{ Clears the dialog }

Procedure Clean; Begin GotoXY(2,24); Write(' ') end;

{ Sets up for the Print_Screen call }

Procedure Print_The_Screen; Begin Clean; Print_Screen end;

{ Echoes "wait" to the user }

Procedure Wait_lt; Begin

Pascal Code 104 GotoXY(2,24); Write('Please Wait ... ') end;

{ Finds maximum and minimum points and calls Set_View_ Coordinates to set view coordinates }

Procedure New_Coord(kk : Integer); Var Dum,lnterval : Real; xl,yl,xs,ys : Real; Point,pp,p1 ,p2 : Plotarray; i : Integer; Begin Interval : = Abs((Th2I - Th2s))/ 26.0; for i : = 1 to 25 Do Begin Th2 : = Th2s + (i * Interval); Calculate_Angles(a,b,c,d,Th2,Th3,Th4, Ok); p1[i,1] :=a* Cos(Th2); p1[i,2] : = a * Sin(Th2); Point[i, 1] : = p1 [i, 1] + P * Cos(Alph + Th3); Point[i,2]: = p1[i,2] + P * Sin(Alph + Th3); p2[i, 1] : = p1 [i, 1] + b * Cos(Th3); p2[i,2] : = p1 [i,2] + b * Sin(Th3); Transform(Trans,Point[i, 1],Point[i,2]); Transform(Trans,p1 [i, 1],p 1[i,2]); Transform(Trans,p2[i, 1],p2[i,2]); end; Xs:= Point[1,1]; Ys : = Point[1,2]; XI:= Point[1,1]; YI:= Point[1,2]; for i : = 1 to 25 Do Begin If Point[i, 1] < Xs then Xs : = Point[i, 1]; If Point[i,2] < Ys then Ys : = Point[i,2]; If Point[i, 1] > XI then XI : = Point[i, 1]; If Point[i,2] > YI then YI : = Point[i,2]; If p1[i,1] < Xs then Xs := p1[i,1]; If p1 [i,2] < Ys then Ys : = p1 [i,2]; If p1[i,1] > XI then XI:= p1[i,1]; If p1 [i,2] > YI then YI : = p1 [i,2]; If p2[i, 1] < Xs then Xs : = p2[i, 1]; If p2[i,2] < Ys then Ys : = p2[i,2]; If p2[i, 1] > XI then XI : = p2[i, 1]; If p2[i,2] > YI then YI : = p2[i,2]; end; pp[1,1]:= O;

Pascal Code 105 pp[1,2]:= 0; pp[2, 1] : = d; pp[2,2] : = 0; pp[3, 1] : = Xs; pp[3,2] : = Ys; pp[4, 1] : = XI; pp[4,2] : = YI; for i : = 1 to 2 Do Transform(Trans,pp[i, 1],pp[i,21); for i : = 1 to Whatposition Do Begin pp[4+i,1] := Body_Position[i,1]; pp[4+ i,2]: = Body_Position[i,2] end; Set_View_Coordinates(kk,4 + Whatposition,pp,Dum) end;

{ Initializes graphics }

Procedure lnitialize_Link; Var Oum : Real; i : Integer; Begin Delta_Theta : = Rad(30); Graphcolormode; Graphbackgrou nd(0); Windowcoord(1,0,0,319, 199); Setwindow(1); Wait_lt; Windowbox; Wi ndowcoord (3,200,0,319, 199); Setwindow(3); Windowbox; Windowcoord(2,0,24,200, 175); Setwindow(2); Windowbox: New_Coord(1); end;

Procedure Say_lt; Begin GotoXY(2,24); Writeln('lmpossible Geometry'); end;

Pascal Code 106 { Draws the linkage, the fixed pivots and the body positions. }

Procedure Draw_lt(Colo : Byte); Var Size : Real; i : Integer; Col : Byte; Begin pp[1,1] := 0; pp[1,2] : = O; pp[4, 1] : = d; pp[4,2] : = O; pp[2,1] := pp[1,1] +a· Cos(Th2); pp[2,2]: = pp[1,2] + a* Sin(Th2); pp[3, 1] : = pp[ 4, 1] + c * Cos(Th4); pp[3,2] : = pp[4,2] + c * Sin(Th4); x : = pp[2, 1] + p * Cos(Th3 + Alph); y : = pp[2,2] + p * Sin(Th3 + Alph); If Synthesis < > 'C' then Begin for i : = 1 to 4 Do Transform(Trans,pp[i, 1],pp[i,2]); Transform(Trans,x,y) end; DrawPoints(1,2,Colo,pp); If Colo = 0 then Col : = 0 else Col : = Colo + 2; Drawline(x,y,pp[2, 1],pp[2,2],Col); DrawPoints(3,2,Col,pp); DrawPoints(3,4,Colo,pp); Size : = (a + b + c + d) / 35.0; If Colo < > 0 then Begin for i : = 1 to WhatPosition Do Draw_Cross( Body _Position[i, 1],Body _Position[i,2],S ize,Colo); Draw_Square(pp[1, 1],pp[1,2],Size,Colo); Draw_Square(pp[ 4, 1],pp[4,2],Size,Colo) end; end;

{ Erases the fixed pivots }

Procedure Erase_Base; Var Size : Real; Begin Size:= (a+ b + c + d )/35.0; Draw_Square(pp[1, 1],pp[1,2],Size,0);

Pascal Code 107 Draw_Square(pp[4, 1],pp[4,2],Size,0); end;

{ Writes the values of each link angle in a specified window }

Procedure Write_Angles; Var d_Th2,d_ Th3, d_Th4 : Real; Begin GotoXY(29, 18); Textcolor(Color + 1); Write In(' ANGLES'); GotoXY(33,20); Writeln(' '); GotoXY(27,20); Write( 'Th2 = '); d_Th2 : = Deg(Th2); Writeln(d_Th2:5:1 ); GotoXY(33,22); Writeln(' '); GotoXY(27,22); Write( 'Th3 = '); d_Th3 : = Deg(Th3); Writeln(d_Th3:5:1 ); GotoXY(33,24); Writeln(' '); GotoXY(27.24); Write( 'Th4 = '); d_Th4 : = Deg(Th4); Writeln(d_Th4:5:1) end;

{ Writes the menu in a specified window }

Procedure Write_Menu; Var d d Th : Real; Begin Textcolor(Color); GotoXY(5,2); Writeln('Four Bar Linkage'); GotoXY(27,2); Writeln(#26 + ' Turn CW'); GotoXY(27,4); Writeln( #27 + ' Turn CCW'); d_d_Th : = Deg(Delta_Theta); GotoXY(27,6); Writeln('F1 Set dTh'); GotoXY(31,8);

Pascal Code 108 Writeln('(',d_d_Th:5: 1,')'); GoToXY(27, 10); Writeln('F2 Choose Th2'); GotoXY(27, 12); Write('F3 C. Curve'); GotoXY(27, 14); Write('F4 Hardcopy'); GotoXY(27, 16); Writeln('F10 Return'); Write_Angles; end;

{ Draws the linkage and echoes "wait" to the user until the drawing is finished }

Procedure Draw_Wait; Begin GotoXY(2,24); Write('Please Wait ... '); Draw_lt(Color); Write_Menu; Clean end;

{ Linkage specifications are written on the screen }

Procedure Write_Specifications; Var xx1 ,xx2 : Real; Begin Clrscr; GotoXY(3,3); Writeln(' Link Specifications'); Writeln;Writeln; Writeln(' Input Link = ',a:5:2,' Coupler Link = ',b:5:2); Write In; Writeln(' Output Link = ',c:5:2,' Fixed Link = ',d:5:2); Writeln; Writeln(' Type of Linkage : ',Link_Type); Write In; xx1 : = Deg(Th2s); xx2 : = Deg(Th2I); If xx1 > 180 then xx1 : = xx1 -360; If xx2 > 360 then xx2 : = xx2 -360; Writeln(' Input Link Range : ',xx1:6:2,' to ',xx2:6:2,' Degrees'); Pause('T'); end;

Pascal Code 109 { Calls the type_of_linkage routine in order to get information about the type of the linkage }

Procedure Start_Link; Var Link : A_Linkage; Begin If Synthesis = 'C' then Begin p := O; Alph := 0 end; else Begin p : = Coupler_Length; Alph : = Coupler_Angle_a end; Link[1] : = a; Link[2] : = b; Link[3] : = c; Link[4] : = d; Type_of_Link(Link,Link_Type,Th2s,Th2I); Write_Specifications; Clrscr end;

{ Draws the linkage in its initial position }

Procedure I nitial_Drawing; Begin Th2 : = Th2s + Abs(Th2I - Th2s)/10.0; Calculate_Angles(a,b,c,d,Th2,Th3,Th4, Ok); If Ok then Draw_Wait else Begin Say_lt; Halt end; end;

{ Turns the input link clockwise an increment specified by the user }

Pascal Code 110 Procedure Clockwise; Var Col : Byte; Begin Wait_lt; If Ok then Draw_lt(0); Th2 : = Th2 - Delta_Theta; Calculate_Angles(a,b,c,d,Th2,Th3,Th4, Ok); If OK then Draw_Wait else Say_lt end;

{ Turns the input link counterclockwise an increment specified by the user }

Procedure Counterclockwise; Begin Wait_lt; If OK then Draw_lt(0); Th2 : = Th2 + Delta_Theta; Calculate_Angles(a,b,c,d,Th2,Th3,Th4, Ok); If OK then Draw_Wait else Say_lt end;

{ Assigns a new value to the input angle 82 and draws the linkage at this position }

Procedure Set_Theta_2; Begin Clean; GotoXY(2,24); Write('Enter '+ 'Th2 ');Read(Dum); Wait_lt; If OK then Draw_lt(0); Th2: = Rad(Dum); Calculate_Angles(a,b,c,d,Th2,Th3,Th4, Ok); If OK then Draw_Wait else

Pascal Code 111 Say_lt end;

{ Assigns a new value to the input angle increment 110. }

Procedure Set_Delta_Theta; Var Oum : Real; Begin Clean; GotoXY(2.24); Write('Enter '+ 'dTh2 ');Read(Dum); Delta_Theta : = Rad(Dum); GotoXY(2,24); Textcolor(Color); Write(' '); GotoXY(27,8); Writeln(' '); GotoXY(31,8); Writeln('(' ,Du m:5: 1,')'); end;

{ Animates and draws the coupler curve }

Procedure Coupler; Var i,j : Integer; Point : Plotarray; Interval : Real; Xs, Ys, XI, YI : Real; Th2d,Th3d,Th4d : Real;

{ Writes the animation message in a specified window. }

Procedure Write_Mess_c; Begin for i : = 2 to 5 Do Begin GotoXY(27,i); Write(' ') end; GotoXY(27,6); Write(' Animation '); for i : = 7 to 9 Do Begin

Pascal Code 112 GotoXY(27,i);Write(' ') end; GotoXY (27, 10); Write(' Coupler '); GotoXY(27, 11);Write(' '); GotoXY(27, 12); Write(' Curve '); for i : = 13 to 16 Do Begin GotoXY(27, i); Write(' ') end; Write_Angles; GotoXY(2,24); Write(' Please Wait ... '); end;

Procedure Animate; Var Dum1, Dum2 : Real; j,k : Integer; ls_Crank : Boolean;

{ Draws the coupler curve }

Procedure Draw_the_Curve(Colo : Byte); Var n : Integer; Begin If Is Crank then n : = 74 else n: = 73; for i : = 1 to n Do Begin j: = 2 * i; k:=j-1; Drawpoints(j,k,Colo,Point) end; end;

{ Animates the four-bar linkage }

Procedure Draw_Anim; Var xx, yy : Real;

Pascal Code 113 Begin If Ok then Begin Draw_lt(0); end; Th2: = Th2s + i • Interval; Calculate_Angles(a,b,c,d,Tl12,Th3,Th4, Ok); If Ok then Begin Write_Angles; Draw_lt(Color); end; end;

Begin ls_Crank : = True; If Ok then Draw_lt(0); Interval : = Abs(Th2I - Th2s)/147; Write_Mess_c; Th2: = Th2s; If (Th2s < > 0) or (Th2I < > (2*pi)) then Begin ls_Crank: = False; for i : = 1 to 146 Do Begin If i Mod 8 = 0 then Begin Draw_Anim; Point[i,1] := X; Point[i,2] : = Y; end; else Begin Th2d : = Th2s + i * Interval; Calculate_Angles(a,b,c,d,Th2d,Th3d,Th4d,Ok); If Ok then Begin Point[i, 1] : = a • Cos(Th2d) + p * Cos(Th3d + Alph); Point[i,2] : = a * Sin(Th2d) + p * Sin(Th3d + Alph); Transform(Trans, Point[i, 1], Poi nt[i,2]) end; end; end; end; else Begin for i : = 0 to 147 Do Begin j: = i + 1;

Pascal Code 114 If i Mod 8 = 0 then Begin Draw_Anim; Point[j,1] := X; Point[j,2] : = Y; end; else Begin Th2d : = Th2s + i * Interval; Calculate_Angles(a,b,c,d,Th2d,Th3d,Th4d,Ok); If Ok then Begin Point[j, 1] : = a * Cos(Th2d) + p * Cos(Th3d + Alph); Point[j,2] : = a * Sin(Th2d) + p * Sin(Th3d + Alph); Transform(Trans.Point[j, 1], Point[j,2]) end; end; end; end; Draw_the_Curve(Color + 1 ); Clean; GotoXY(2,24); Write('F10 Continue F1 Copy'); Repeat Read(kbd,Ch) until Ord(Ch) in [59,68];Clean; If Ord(Ch) = 59 then Print_the_Screen; Draw_the_ Cu rve(0); If Synthesis = 'C' then Begin Draw_lt(0); Erase_Base; end; for i : = 2 to 23 Do Begin GotoXY(27,i); Write(' ') end; end;

Begin Alph: = Coupler_Angle_a; p: = Coupler_Length; If Synthesis = 'C' then Begin Draw_lt(0); Erase_Base; GotoXY(2,24); Write('Distance P = ');Read(P); Clean;

Pascal Code 115 GotoXY(2,24);Write(' Angle Alpha = ');Read(Alph); Alph : = Rad(Alph); Clean; New_Coord(2) end; Animate; If Synthesis = 'C' then Begin p := O; Alph: = O; SetViewport(1 ); lnitial_Drawing end; Write_Menu; end;

{ Generates interaction ie., lets the user animate, rotate, and print the screen interactively }

Procedure Interactive; Var Ch : Char; Begin Repeat Read(kbd,Ch); Case Ord(Ch) of 77 Clockwise; 75 Counterclockwise; 59 Set_Delta_Theta; 60 Set_Theta_2; 61 Coupler; 62 Print_the_Screen; end; until Ord(Ch) = 68; end;

Begin Color:= 1; If Synthesis = 'C' then Begin

Pascal Code 116 Six_Bar[1,1]:= O; Six_Bar[1,2] : = O; Six_Bar[4,1] := d; Six_Bar[4,2] : = O; end; x1 : = Atan2(S ix_Bar[4, 1]-Six_Bar[1, 1],Six_Bar[4,2]-Six_Bar[1,2]); Calc_d_Matrix(Six_Bar[1, 1],Six_Bar[1,2],x1 ,Trans); Start_Link; I nitialize_Link; I nitial_Drawing; Interactive; end;

Begin a:= Abs(a); b: = Abs(b); C: = Abs(c); d : = Abs(d); Linkages; Text mode; end;

Pascal Code 117 { Animates the chosen six-bar linkage displays the coupler curve when the animation is finished. It also allows the user to rotate the input link stepwise in any direction. }

Overlay Procedure Linkage_6(a,b,c,d : Real);

Procedure Linkages; Var Th4, Th2, r5, r6, Th5, Th6, x1 ,x2, y1, y2,Th3, Delta_Theta, Oum, Th6s, Th6I, p, Alph, x, y : Real; pp : Plotarray; Counter : Integer; Ch : Char; OK : Boolean; Color : Byte;

{ Clears the dialog area }

Procedure Clean; Begin GotoXY(2,24); Write(' ') end;

{ Clears the dialog area and calls the Print_Screen routine }

Procedure Print_the_Screen; Begin Clean; Print_Screen end;

{ Echoes "wait" to the user }

Procedure Wait_lt; Begin

Pascal Code 118 GotoXY(2,24); Write('Please Wait ... ') end;

{ Finds maximum and minimum points and calls Set_View _Coordinates to set view coordinates }

Procedure New_Coord; Var Dum,lnterval : Real; xl,yl,xs,ys : Real; po,pp,p1 ,p2 : Plotarray; i, j : Integer; Begin Repeat Th6 : = Th6 - Delta_Theta; S ix_a( a,b,c,r5,r6, Th 6, Th 2, Th 3, Th 4, Th5,O K); until (not OK) or (Th6 < -2*pi); Th6s : = Th6 + Delta_Theta; i := O; Repeat i := i + 1; Th6 : = Th6 + Delta_Theta; Six_a(a,b,c,r5,r6,Th6,Th2,Th3,Th4,Th5,OK); If OK then Begin po[i, 1] : = S ix_Bar[7, 1] + r6 • Cos(Th6); p1[i,1]:= po[i,1] + r5*Cos(Th5); p2[i, 1] : = Six_Bar[1, 1] + a • Cos(Th2) + p * Cos(Th3 + Alph); po[i,2] : = Six_Bar[7,2] + r6 • Sin(Th6); p1 [i,2] : = po[i,2] + r5 • Sin(Th5); p2[i,2] : = Six_Bar[1,2] + a * Sin(Th2) + p * Sin(Th3 + Alph); end; until (not OK) or (Th6 > 2*pi); i : = i - 1; Th61 : = Th6 - Delta_Theta; Xs:= po[1,1]; Ys:= po[1.2]; XI:= po[1,1]; YI : = po[1,2]; for j : = 1 to i Do Begin If po[j,1] < Xs then Xs := po[j,1]; If po[j,2] < Ys then Ys : = po[j,2]; If po[j,1] > XI then XI:= po[j,1]; If po[j,2] > YI then YI : = po[j,2]; If p1[j,1] < Xs then Xs := p1[j,1]; If p1 [j,2] < Ys then Ys : = p1 [j,2]; If p1[j,1] > XI then XI:= p1[j,1];

Pascal Code 119 If p1[j,2] > YI then YI:= p1[j,2]; lfp2[j,1] < XsthenXs:= p2[j,1]; If p2[j,2] < Ys then Ys : = p2[j,2]; If p2[j, 1] > XI then XI : = p2[j, 1]; If p2[j,2] > YI then YI : = p2[j,2]; end; pp[1,1] := Six_Bar[1,1]; pp[1,2] : = Six_Bar[1,2] + a; pp[9, 1] : = S ix_Bar[7, 1]; pp[9,2] : = Six_Bar[7,2]; pp[2,1] := Six_Bar[1,1]; pp[2,2] : = Six_Bar[1,2] - a; pp[3,2] : = S ix_Bar[ 1.2] ; pp[3, 1] : = S ix_Bar[ 1, 1] -a; pp[4,1] := Six_Bar[4.1]; pp[4,2] : = Six_Bar[4,2] + c; pp[5,1] := Six_Bar[4.1]; pp[5,2] : = Six_Bar[4,2] -c; pp[6,1] := Six_Bar[4,1] +c; pp[6,2] : = S ix_Bar[ 4,2) ; pp[7, 1) : = Xs; pp[7,2] : = Ys; pp[8, 1] : = XI; pp[8,2] : = YI; for i : = 1 to Whatposition Do Begin pp[9 + i, 1] : = Body _Position[i, 1]; pp[9 + i,2] : = Body_Position[i,2] end; i : = 9 + Whatposition; Set_View_Coordinates(1,i,pp,Dum) end;

{ Initializes graphics }

Procedure lnitialize_Link; Var Oum : Real; i : Integer; Begin Delta_Theta : = Rad(6); Graphcolormode; Graphbackgrou nd(0); Windowcoord(1,0,0,319, 199); Setwindow(1); Wait_lt; Windowbox; Wi ndowcoord (3,200,0,319, 199); Setwi ndow(3);

Pascal Code 120 Windowbox; Windowcoord(2,0,24,200, 175); Setwi ndow(2); Window box; New_Coord; end;

Procedure Say_lt; Begin GotoXY(2,24); Writeln('lmpossible Geometry'); end;

{ Draws the linkage, the fixed pivots and the body positions in the specified window }

Procedure Draw_lt(Colo : Byte); Var Size : Real; i : Integer; Col : Byte; Begin pp[1,1] := Six_Bar[1,1]; pp[1,2] : = Six_Bar[1,2]; pp[4,1] := Six_Bar[4,1]; pp[4,2] : = Six_Bar[4,2]; pp[2,1] := pp[1,1] +a* Cos(Th2); pp[2.2] : = pp[1,2] + a * Sin(Th2); pp[3,1] := pp[4,1] + c * Cos(Th4); pp[3,2] : = pp[4,2] + c * Sin(Th4); x : = pp[2, 1] + p * Cos(Th3 + Alph); y : = pp[2,2] + p * Sin(Th3 + Alph); pp[7,1] := Six_Bar[7,1]; pp[7.2] : = Six_Bar[7,2]; pp[6, 1] : = pp[7, 1] + r6 * Cos(Th6); pp[6,2] : = pp[7.2] + r6 * Sin(Th6); pp[5, 1] : = pp[6, 1] + r5 * Cos(Th5); pp[5,2] : = pp[6,2] + r5 * Sin(Th5); DrawPoints( 1,2,Colo,pp); If Colo = 0 then Col : = 0 else Col : = Colo + 2; Drawl i ne(x, y ,pp[2, 1].pp[2,2],Col); DrawPoints(3,2,Col,pp); DrawPoints(2,5,Col,pp); DrawPoints(3.4,Colo,pp); DrawPoints(6,5,Colo,pp); DrawPoints(6,7,Colo,pp);

Pascal Code 121 Size : = (a + b + c + d) / 35.0; If Colo < > 0 then Begin for i : = 1 to What Position Do Draw_Cross( Body _Position[i, 1 ],Body _Position[i,2],S ize,Colo); Draw_Square(pp[1, 1],pp[1,2].Size,Colo); Draw_Square(pp[4, 1],pp[4,2],Size,Colo); Draw _Square(pp[7, 1],pp[7,2],Size,Colo) end; end;

{ Writes the values of each link angle in a especified window }

Procedure Write_Angles; Var d_Th2,d_ Th3, d_Th4 : Real; Begin GotoXY(29, 14); Textcolor(Color+ 1); Writeln(' ANGLES'); GotoXY(33, 16); Writeln(' '); GotoXY(27, 16); Write( 'Th6 = '); d_Th2 : = Deg(Th6); Writeln(d_Th2:5: 1); GotoXY(33, 18); Writeln(' '); GotoXY(27,18); Write( 'Th2 = '); d_Th2: = Deg(Th2); Writeln(d_Th2:5:1 ); GotoXY(33,20); Writeln(' '); GotoXY(27,20); Write( 'Th3 = '); d_Th3 : = Deg(Th3); Writeln(d_Th3:5:1 ); GotoXY(33,22); Writeln(' '); GotoXY(27,22); Write( 'Th4 = '); d_Th4 : = Deg(Th4); Writeln(d_Th4:5:1 ); GotoXY(33,24); Writeln(' '); GotoXY(27,24); Write( 'Th5 = '); d_Th4 : = Deg(Th5); Writeln(d_Th4:5: 1) end;

Pascal Code 122 { Writes the menu in a specified window. }

Procedure Write_Menu; Var d d Th : Real; Begin Textcolor(Color); GotoXY(S,2); Writeln(' Six-Bar Linkage'); GotoXY(27,2); Writeln(#26 + ' Turn CW'); GotoXY(27,4); Writeln( #27 + ' Turn CCW'); GoToXY(27,6); Writeln('F1 Choose Th6'); GotoXY(27,8); Write('F2 C. Curve'); GotoXY(27, 10); Write('F3 Hardcopy'); GotoXY(27, 12); Writeln('F10 Return'); Write_Angles; end;

{ Draws the linkage and displays a wait message on the screen until the construction of the drawing is over }

Procedure Draw_Wait; Begin GotoXY(2,24); Write('Please Wait ... '); Draw_lt(Color); Write_Menu; Clean end;

{ Linkage specifications are written on the screen }

Procedure Write_Specifications; Begin Clrscr; GotoXY(3,3); Writeln(' Link Specifications');Writeln;Writeln; Writeln(' Four Bar Linkage '); Writeln;Writeln; Writeln(' Input Link = ',a:5:2,' Coupler Link = ',b:5:2);

Pascal Code 123 Write In; Write In(' Output Link = ',c:5:2,' Fixed Link = ',d:5:2); Write In; Write In(' Third Dyad ');Writeln;Writeln; Writeln(' Input Link = ',r6:5:2,' Follower = ', r5:5:2); Writeln; Pause('T'); end;

{ Given the moving and fixed pivot of a dyad, the length of the link is calculated }

Function Link_Size(i,k: Integer) : Real; Begin Link_Size: = Sqrt(Sqr(Six_Bar[i, 1] - Six_Bar[k. 1]) + Sqr(Six_Bar[i,2] - Six_Bar[k,2])) end;

{ Calculates the angle between two links }

Function Angle(i,k : Integer) : Real; Begin Angle:= Atan2((Six_Bar[i,1] - Six_Bar[k,1]), (Six_Bar[i.2] - Six_Bar[k,2])); end;

{ Calculates the distance and angle of the tracing point relative to the other joints of the coupler }

Procedure Get_c; Var xx, yy : Real; Begin xx:= Atan2((Body_Position[1,1] -Six_Bar[2,1]), (Body_Position[1,2] - Six_Bar[2,2])); yy : = Angle(3,2); Alph : = xx - yy; p := Sqrt(Sqr(Body_Position[1,1] -Six_Bar[2,1]) + Sqr(Body_Position[1,2] - Six_Bar[2,2])); xx : = Angle(5,2); Coupler_Angle_a: = xx - yy; Coupler_Length : = Link_Size(5,2) end;

Pascal Code 124 {. Calls the type_of_linkage routine to determine the type of the linkage. }

Procedure Start_Link; Begin Get_c; Th2 := Angle(2.1); Th3 : = Ang le(3.2); Th4 : = Angle(3.4); Th5 : = Angle(5.6); Th6 : = Angle(6,7); r5: = Link_Size(5.6); r6: = Link_Size(7,6); Write_Specifications; Clrscr end;

{ Draws the linkage in its initial position }

Procedure lnitial_Drawing; Begin Th6: = Th6I; Six_a(a,b,c,r5,r6,Th6,Th2,Th3,Th4,Th5,OK); If Ok then Draw Wait else Begin Say_lt; end; end;

{ Turns the input link clockwise an increment ~0 specified by the user }

Procedure Clockwise; Begin Wait_lt; If Ok then Draw_lt(0); Th6 : = Th6 - Delta_Theta; Six_a(a,b,c,r5,r6,Th6,Th2,Th3,Th4,Th5,OK); If OK then Draw_Wait else Say_lt

Pascal Code 125 end;

{ Turns the input link counterclockwise an increment t:i.O specified by the user }

Procedure Counterclockwise; Begin Wait_lt; If OK then Draw_lt(0); Th6 : = Th6 + Delta._ Theta; Six_a(a,b,c,r5,r6,Th6,Th2,Th3,Th4,Th5,OK); If OK then Draw Wait else Say_lt end;

{ Assigns a new value to the input angle Os }

Procedure Set_Theta_2; Begin Clean; GotoXY(2,24); Write('Enter Th6 ');Read(Dum); Wait_lt; If OK then Draw_lt(0); Th6: = Rad(Dum); Six a(a,b,c,r5,r6,Th6,Th2,Th3,Th4,Th5,OK); If OK then Draw_Wait else Say_lt end;

{ Animates and draws the coupler curve }

Procedure Coupler; Var i,j, n : Integer; po : Plotarray; Interval : Real; Xs, Ys, XI, YI : Real;

Pascal Code 126 { Writes the animation message in a specified window. }

Procedure Write_Mess_c; Begin GotoXY(27,2); Write(' '); GotoXY(27 ,3); Write(' '); GotoXY(27,4); Write(' Animation '); for i : = 5 to 7 Do Begin GotoXY(27,i);Write(' ') end; GotoXY(27,8); Write(' Coupler '); GotoXY(27,9);Write(' '); GotoXY(27, 10); Write(' Curve '); for i : = 11 to 14 Do Begin GotoXY(27,i); Write(' ') end; Write_Angles; GotoXY(2,24); Write(' Please Wait ... ') end;

Procedure Animate; Var Dum1, Dum2 : Real; j,k : Integer;

{ Draws the coupler curve }

Procedure Draw_the_Curve(Colo : Byte); Begin for i : = 1 to Trunc(n/2) Do Begin j : = 2 * i; k:=j-1; Drawpoints(j,k,Colo,po) end; end;

Pascal Code 127 { Animates the four-bar linkage }

Procedure Draw_Anim; Begin If Ok then Draw_lt(0); Repeat Th6 : = Th6 - Delta_Theta; Six_a(a,b,c,r5,r6,Th6,Th2,Th3,Th4,Th5,OK); If Ok then Begin Write_Angles; Draw_lt(Color); Delay(200); Draw_lt(0); end; until (Th6 > 2*pi) or (not OK) or (Th6 < -2*pi); n := O; Repeat n:=n+1; Th6 : = Th6 + Delta_Theta; Six_a(a,b,c,r5,r6,Th6,Th2,Th3,Th4,Th5,OK); If Ok then Begin Write_Angles; Draw_lt(Color); po[n,1] := X; po[n,2] : = Y; Draw_lt(0); end; until (Tl16 > 2*pi) or (not OK) or (Th6 < -2*pi); If not OK then Begin n : = n-1; Th6: = Th6 - Delta_Theta; Six_a(a,b,c,r5,r6,Th6,Th2,Th3,Th4,Th5,OK); Draw_lt(Color) end; end;

Begin Write_Mess_c; Draw_Anim; Draw _the_ Curve(Color + 1); Clean; GotoXY(2,24); Write('F10 Continue F1 Copy'); Repeat

Pascal Code 128 Read(kbd,Ch) until Ord(Ch) in [59,68];Clean; If Ord(Ch) = 59 then Print_the_Screen; Draw_the_Curve(0); for i : = 2 to 23 Do Begin GotoXY(27,i); Write(' ') end; end;

Begin Animate; Write_Menu; end;

{ Generates interaction ie., lets the user animate, rotate, and print the screen interactively }

Procedure Interactive; Var Ch : Char; Begin Repeat Read(kbd,Ch); Case Ord(Ch) of 77 Clockwise; 75 Counterclockwise; 59 Set_Theta_2; 60 Coupler; 61 Print_the_Screen end; until Ord(Ch) = 68; end;

Begin Color:= 1; Start_Link; I nitialize_Link; I nitial_Drawing; Interactive;

Pascal Code 129 end;

Begin a:= Abs(a); b: = Abs(b); c : = Abs(c); d : = Abs(d); Linkages; Text mode; end;

Pascal Code 130 { Using Cayley's diagram as well as Robert's-Chebyshev theorem the cognates of a given linkage are found. Those cognates and their properties are displayed on the screen and the user has to choose one of the two possible cognates to be the mechanism that will satisfy the path generation with input timing problem }

Overlay Procedure Cognates(p1 ,p2,p3,p4,Pop : Points); Type Flag_Array = Array[1 .. 2] of Boolean;

Var OAA,AB,OBB,OAOB,OAOC,OBOC, OAA1 ,A 1C1 ,OCC1 ,OBB2,B2C2, OCC2,aa, bb,cc, OAO Be : Real; Th2, Th3, Th4 : Real; OAOCc, OBOCc,Dum1 : Real; pp.Ppr : Plotarray; OK : Boolean; Color : Byte; Above, Below, Online : Boolean; Ans : Char; Trans Matrix : Matrix;

{ Calculates the length of the links required to construct the Cayley's diagram }

Overlay Procedure Calculate_Lengths; Var m2, m3, m4 : Real; Begin m2 : = Sin(aa); m3 : = Sin(bb); m4 : = Sin(cc); OAOBc : = OAA + AB + OBS; OCC2: = (OAA * OB82)/AB; OCC1 := (OBS* OAA1)/AB; OAOCc : = (OAOBc • m3)/ m4; OBOCc: = (OAOBc * m2)/ m4; A1C1 : = OAOCc - OAA1 - OCC1; B2C2: = OBOCc - OBB2 - OCC2; end;

{ Calculates the required points for the construction of Cayley's diagram }

Pascal Code 131 Overlay Procedure Calculate_Points; Var m1, m2 : Real; Begin m1 : = Cos(aa); m2 : = Sin(aa); pp[1,1] := 0; pp[1,2]: = 0; pp[2, 1] : = OAA; pp[2,2] : = 0; pp[3,1] := OAA + AB; pp[3,2] : = 0; pp[4,1] := OAOBc; pp[4,2] : = 0; pp[5,1] := pp[4,1] + OBB2 * Cos(pi - bb); pp[5,2] : = OAA 1 * m2; pp[?. 1] : = OAA 1 * m 1; pp[7,2] : = pp[5,2]; pp[6,1] := pp[2,1] + pp[7,1]; pp[6,2] : = pp[7,2]; pp[8,1] := (OAA1 + A1C1) * m1; pp[8,2]:= (OAA1 + A1C1)* m2; pp[9,1] := pp[6,1] + OCC1 * m1; pp[9,2] : = (OAA 1 + OCC1) * m2; pp[10,1] := OAOCc * m1; PP[10,2] : = OAOCc * m2; end;

{ Initializes graphics }

Overlay Procedure lnitial_Graphics; Begin GraphColorMode;GraphBackground(0); Windowcoord(1,0,0,319, 199); Setwindow(1); Windowbox end;

{ Sets up the screen to be printed }

Overlay Procedure Print_the_Screen; Var i : Integer; Begin GotoXY(1,24); for i : = 1 to 79 Do Write(' '); Print_Screen

Pascal Code 132 end;

{ Writes out the menu and it waits for input }

Procedure Fu nction_Keys_ 1; Var Ch : Char;

{ Writes the menu in a specified window }

Procedure Write_Key_m; Begin GotoXY(2,24); Write('F1: Print Screen'); GotoXY(24,24); Write('F10: Continue'); end;

Begin Write_Key_m; Repeat Read(kbd,ch); If Ord(ch) = 59 then Begin Print_the_Screen; Write_Key_m end; until Ord(ch) = 68; end;

{ Sets up graphics, windows and view coordinates for Cayley's diagram }

Procedure lnitialize_C; Var Oum : Real; Begin Cal cu late_Lengths; Calculate_Points; I nitial_Graphics; WindowCoord(2,25,40, 145,160); Setwindow(2); Windowbox; Set_View_Coordinates( 1, 10,pp,Dum); end;

Pascal Code 133 { Calculates the end points of the coupler to be filled and calls necessary procedures (Cayley's diagram). }

Overlay Procedure Fill_the_Coupler_C; Var pp1, pp2, pp3 : Points; Size, x1, y1 : Real; Begin pp1[1]:= pp[8,1]; pp1 [2] : = pp[8,2]; pp2[1]:= pp[6,1]; pp2[2] : = pp[6,2]; pp3[1]:= pp[7,1]; pp3[2] : = pp[7 ,2]; Fill(pp1 ,pp2,pp3,Color); pp1[1]:= pp[6,1]; pp1 [2] : = pp[6,2]; pp2[1]: = pp[3,1]; pp2[2] : = pp[3,2]; pp3[ 1] : = pp[2, 1]; pp3[2] : = pp[2,2]; Fill(pp1 ,pp2,pp3,Color); pp1[1]:= pp[5,1]; pp1[2] : = pp[5,2]; pp2[1] := pp[6,1]; pp2[2] : = pp[6,2]; pp3[ 1] : = pp[9, 1]; pp3[2] : = pp[9,2]; Fill(pp1 ,pp2,pp3,Color); Size : = (OAA 1 + 0882 + OAA + AB + OBS + OAOB)/ 40.0; x1 : = pp[10, 1]; y1 : = pp[10,2]; Draw_Square(x1 ,y1 ,Size.Color); x1 := pp[1,1]; y1 : = pp[1,2]; Draw_Square(x1 ,y1 ,Size,Color); x1 : = pp[4, 1]; y1 : = pp[4,2]; Draw_Square(x1 ,y1 ,Size,Color); end;

{ Calculates points necessary for the construction of Robert's diagram }

Overlay Procedure Roberts; Var

Pascal Code 134 m1 : Real; i : Integer; Begin Ppr[1,1]:= O; Ppr[1,2] := O; Ppr[2, 1] : = OAOB; Ppr[2,2] : = O; Ppr[3, 1] : = OAA * Cos(Th2); Ppr[3,2] : = OAA * Sin(Th2); Ppr[4,1] := Ppr[2,1] + OBS* Cos(Th4); Ppr[4,2] : = Ppr[2,2] + OBS • Sin(Th4); OAOC : = (OAOB * Sin(bb))/Sin(cc); OBOC : = (OAOB * Sin(aa))/Sin(cc); If Above then Begin Ppr[6, 1] : = OAA 1 * Cos(Th3 + aa); Ppr[6,2]:= OAA1 *Sin(Th3 + aa); Ppr[5,1] := Ppr[6,1] + OAA * Cos(Th2); Ppr[5,2] : = Ppr[6.2] + OAA * Sin (Th2); Ppr[7,1]:= Ppr[2,1] + OBB2*Cos(pi + Th3-bb); Ppr[7,2] : = O8B2 * Sin(pi + Th3 -bb); Ppr(8, 1] : = Ppr[6, 1] + A 1C 1 * Cos(Th2 + aa); Ppr[8,2] : = Ppr(6,2] + A 1C1 * Sin(Th2 + aa); Ppr[9, 1] : = Ppr[?, 1] + B2C2 • Cos(Th4 -bb); Ppr[9,2] : = Ppr[7,2] + B2C2 * Sin(Th4 -bb); Ppr[10, 1] : = OAOC * Cos(aa); Ppr[10,2] : = OAOC * Sin(aa) end; If Below then Begin Ppr[6,1]: = OAA1 * Cos(Th3 - aa); Ppr[6,2] : = OAA 1 * Sin(Th3 - aa); Ppr[5, 1] : = Ppr[6, 1] + OAA * Cos(Th2); Ppr[5,2] : = Ppr[6,2] + OAA * Sin (Th2); Ppr[7,1] := Ppr[2,1] + OB82 * Cos(pi + Th3 + bb); Ppr[7,2] : = OB82 * Sin(pi + Th3 + bb); Ppr[8,1] := Ppr[6,1] + A1C1 * Cos(Th2- aa); Ppr[8,2] : = Ppr[6,2] + A 1C1 * Sin(Th2 - aa); Ppr[9, 1] : = Ppr[?, 1] + B2C2 * Cos(Th4 + bb); Ppr[9,2] : = Ppr[7,2] + B2C2 * Sin(Th4 + bb); Ppr[10,1] := OAOC * Cos(-aa); Ppr[10,2] : = OAOC * Sin(-aa) end; for i : = 1 to 10 Do Transform(Trans_Matrix,Ppr[i, 1],Ppr[i,2]); end;

{ Calculates the end points of the couplers to be filled and make necessary calls (Robert's diagram). }

Pascal Code 135 Overlay Procedure Fill_the_Coupler_R; Var pp1, pp2, pp3 : Points; x1, y1, Size : Real; Begin pp1[1] := Ppr[5,1]; pp1 [2] : = Ppr[5,2]; pp2[ 1] : = Ppr[3, 1]; pp2[2] : = Ppr[3,2]; pp3[1] := Ppr[4,1]; pp3[2] : = Ppr[4.2]; Fill(pp 1,pp2,pp3,Color); pp1[1]: = Ppr[5, 1]; pp1 [2] : = Ppr[5,2]; pp2[ 1] : = Ppr[6, 1]; pp2[2] : = Ppr[6,2]; pp3[1] := Ppr[8,1]; pp3[2] : = Ppr[8,2]; Fi ll(pp1 ,pp2,pp3,Color); pp1[1] := Ppr[5,1]; pp1[2]: = Ppr[5,2]; pp2[1] := Ppr[7,1]; pp2[2] : = Ppr[7,2]; pp3[ 1] : = Ppr[9, 1]; pp3[2] : = Ppr[9,2]; Fi ll(pp 1,pp2,pp3,Color); Size : = (OAA 1 + 0882 + OAA + AB + OBS + OAOB)/ 40.0; x1 := Ppr[10,1]; y1 : = Ppr[10,2]; Draw_Square(x1 ,y1 ,S ize,Color); x1 : = Ppr[1, 1]; y1 : = Ppr[1,2]; Draw_Square(x1 ,y1 ,Size.Color); x1 := Ppr[2,1]; y1 : = Ppr[2,2]; Draw_Square(x1 ,y1 ,Size.Color); end;

{ Draws Cayley's diagram }

Procedure Draw_Cayleys; Var x1 ,y1 ,x2,y2 : Real; Colo : Byte; Begin DrawPoints( 1,4,Color,pp); Colo:= Color + 2; DrawPoints(4, 10,Colo,pp);

Pascal Code 136 Colo:= Color + 1; DrawPoints(1, 1O,Colo,pp); DrawPoints(2,9,Colo,pp); DrawPoints(5, ?,Colo.pp); Draw Poi nts(3. 8. Co lo,pp ); Fill_the_Coupler _c; end;

{ Draws Roberts-Chebyshev diagram }

Procedure Draw_Roberts; Var x1,y1,x2,y2 : Real; Colo : Byte; Begin DrawPoints(1,3,Color,Ppr); DrawPoints(3,4,Color,Ppr); DrawPoints(2,4,Color,Ppr); DrawPoints(3,5.Color,Ppr); Draw Points( 4,5, Color, Ppr); Colo:= Color+ 1; DrawPoints(6, 1,Colo,Ppr); Draw Points( 6,8,Co lo, Ppr); DrawPoints(S, 1O,Colo,Ppr); Colo : = Color + 2; Draw Poi nts(2. 7, Colo, Ppr); Draw Poi nts(7, 9,Colo, Ppr); DrawPoints(9, 1O,Colo,Ppr); DrawPoints(6,5,Colo,Ppr); DrawPoints(5,8,Colo,Ppr); DrawPoi nts(5, 7.Colo, Ppr); DrawPoints(5,9,Colo,Ppr); Fill_the_Coupler_R; end;

{ Sets up graphics, windows and view coordinates for Robert's diagram }

Procedure Setup_R; Var Dum : Real; Begin Roberts; WindowCoord(3, 170,40,290, 160); Setwindow(3); Windowbox; Set_View_Coordinates(1, 1O,Ppr,Du m);

Pascal Code 137 end;

{ Writes figure headings on the screen }

Procedure Write_Headings; Begin W i ndowCoord( 4,0,0,319.40); Setwindow(4); GotoXY(4,2); Write('Cayley"s Diagram');GotoXY(26,2); Write('Cognates'); Function_Keys_ 1; Textmode; end;

{ Writes out the kind of generated linkages and their dimensions and lets the user choose the desired linkage }

Procedure Write_Results; Var I_ Type1 ,I_Type2,I_ Type3 : Strings; Link_ 123 : A_Linkage; Th2s,Th2I : Real; Flag : Flag_Array;

{ Displays the resu Its on the screen }

Procedure Write_the_Results; Begin Clrscr; GotoXY(1,3); Textcolor(1); Writeln(' Original Mechanism 'Cognate 1 Cognate 2'); Writeln;Writeln; Textcolor(5); Writeln(' Input Link ',OAA:6:3, ' ',OAA 1:6:3,' ',OBB2:6:3); Write In; Writeln(' Coupler Link ',AB:6:3, ' ',A1C1:6:3,' ',B2C2:6:3); Write In; Writeln(' Output Link ',088:6:3, ' ',OCC1 :6:3,' ',OCC2:6:3); Write In;

Pascal Code 138 Writeln(' Fixed Link ',OAOB:6:3, ',OAOC:6:3,' ',OBOC:6:3); Write In; Writeln(' Type ',I_Type1,' , I_ Type2,' ',I_Type3); end;

{ Displays menu, lets the user choose one of the cognates, assigns values to the required variables and calls the animation program }

Procedure Function_Keys_2; Var Ch : Char;

Procedure Clearscreen; Var i, j : Integer; Begin for i : = 20 to 24 Do Begin GotoXY(1,i); for j : = 1 to 79 Do Write(' ') end; end;

{ Allows the user to choose the desired mechanism, assigns values to some variables and calls the animation program }

Procedure Choose; Var i : Integer; Ch : Char; OK : Boolean; a,b,c,d : Real; Begin Repeat GotoXY(20,20); Write('Please Enter Desired Mechanism '); Repeat Readint(i); until i in [1, 2]; Clearscreen;

Pascal Code 139 until Flag[i]; If i = 1 then Begin a:= OAA1; b:= A1C1; c: = OCC1; d := OAOC; Six_Bar1,1] := Ppr[1,1]; Six_Bar1 ,2] : = Ppr[1,2]; S ix_Bar2, 1] : = Ppr[6, 1]; S ix_Bar[2,2] : = Ppr[6,2]; S ix_Bar[3, 1] : = Ppr[8, 1]; Six_Bar[3,2] : = Ppr[8,2]; Six_Bar4,1]: = Ppr[10,1]; Six_Bar[4,2] : = Ppr[10.2]; Coupler_Length : = OAA; Coupler_Angle_a : = -aa end; else Begin a:= 0882; b := B2C2; c := OCC2; d := OBOC; Six_Bar[1,1] := Ppr[2,1]; Six_Bar[1,2] : = Ppr[2,2]; Six_Bar[2,1] := Ppr[7,1]; Six_Bar[2,2] : = Ppr[7,2]; Six_Bar[3,1] := Ppr[9,1]; Six_Bar[3,2] : = Ppr[9,2]; Six_Bar[4,1] := Ppr[10,1]; Six_Bar[4,2] : = Ppr[10,2]; Coupler_Length : = OBB; Coupler_Angle_a : = bb end; S ix_Bar[S, 1] : = Ppr[5, 1]; Six_Bar[5,2] : = Ppr[5,2]; Linkage(a,b,c,d); Write_the_Resu Its end;

{ Writes the menu in a specified window }

Procedure Write_Key_m; Begin GotoXY(S,24); Write('F1: Choose Mechanism'); GotoXY(35,24); Write('F2: Print Screen');

Pascal Code 140 GotoXY(60,24); Write('F10: Quit'); end;

Begin Write_Key_m; Repeat Read(kbd,ch); Case Ord(ch) of 59 Begin Choose; Write_Key_m end; 61 Begin Print_the_Screen; Write_Key_m end; end; until Ord(ch) = 68; end;

Begin Flag[1] : = True; Flag[2] : = True; Link_123[1] := OAA; Link_123[2] := AB; Link_ 123[3] : = OBS; Link_ 123[4] : = OAOB; Type_of_Link(Link_ 123,1_Type1 ,Th2s,Th2I); If (OAA1 = 0) or (A1C1 = 0) or (OCC1 = 0) or (OAOC = 0) then Begin Flag[1] : = False; I_ Type2 : = 'Non Existent'; Th2s: = O; Th2I := 0 end; else Begin Link_ 123[1) : = OAA 1; Link_123[2) := A1C1; Link_123[3]:= OCC1; Link_ 123[4) : = OAOC; Type_of_Link(Link_ 123,1_Type2,Th2s,Th2I) end; If (0882 = 0) or (82C2 = 0) or (OCC2 = 0) or (OBOC = 0) then Begin Flag[2) : = False;

Pascal Code 141 I_Type3 : = 'Non Existent'; Th2s: = O; Th2I := 0 end; else Begin Link_123[1] := OBB2; Link_ 123[2] : = B2C2; Link_ 123[3]: = OCC2; Link_ 123[4): = OBOC; Type_of_Link(Link_ 123.1_ Type3,Th2s,Th2I) end; Write_the_Resu Its; Function_Keys_2; Clrscr end;

{ Calculates link lengths, angles of the coupler link and it checks whether the coupler point is above, below or in line with respect to the other coupler link joints }

Overlay Procedure Start; Var Dum1, Dum2, Oum3 : Real;

{ Calculates the angles of the coupler link }

Function Angle(Point1 ,Point2,Point3 : Points) : Real; Begin Dum1 : = Atan2(Point2[1]-Point1[1],Point2[2]-Point1[2]); Ou m2 : = Atan2(Point3[1 ]-Point1 [ 1],Point3[2]-Poi nt1 [2]); Angle:= Dum2 - Dum1; end;

{ Calculates the length of the original four bar linkage }

Function Size(Point1, Point2: Points) : Real; Begin Size:= Sqrt(Sqr(Point2[1] -Point1[1]) + Sqr(Point2[2] - Point1[2]}) end;

Begin

Pascal Code 142 Above : = False; Below : = False; Online : = False; OAA : = Size(p1 ,p2); AB : = Size(p3,p2); 088 : = Size(p3,p4); OAOB : = Size(p1 ,p4); 0882 : = Size(p3,Pop); OAA 1 : = Size(Pop,p2); aa : = Angle(p2.p3,Pop); If ((aa > 0) and (aa < pi)) or ((aa > (-2*pi) ) and (aa < (-pi))) then Above : = True else Begin If (aa = 0) or (aa = pi ) or (aa = -pi) or (aa = 2*pi) or (aa = -2*pi) then Online : = False else Below : = True end; aa : = Abs(aa); If aa > pi then aa : = 2 *pi - aa; bb : = Abs(Angle(p3,Pop,p2)); If bb > pi then bb : = 2 *pi - aa; cc : = pi - aa -bb; end;

{ Displays the original linkage specifications }

Overlay Procedure Write_Sp; Var I_Type1 ,I_Type2,I_ Type3 : Strings; Link_ 123 : A_Linkage; Th2s,Th2I : Real; Begin Link 123[1] : = OAA; Link 123[2] := AB; Link_123[3] := OBS; Link_123[4] := OAOB; Type_of_Link(Link_ 123,1_Type1 ,Th2s,Th2I); Clrscr; GotoXY(1,5); Writeln(' Original Linkage');Writeln; Writeln(' Fixed Link = ',OAOB:6:2); Writeln(' Input Link = ',OAA:6:2); Writeln(' Coupler Link = ',AB:6:2); Write In(' Output Link = ',OBB:6:2);Writeln; Write In(' Alpha = ',Deg(aa):6:2); Writeln(' Beta = ',Deg(bb):6:2); Writeln(' Gamma = ',Deg(cc):6:2);

Pascal Code 143 Write In; Writeln(' Range of Angle Theta 2 ');Writeln; If Th2s > pi Then Th2s : = Th2s - 2*pi; If Th2I > 2*pi then Th2I : = Tt12I - 2*pi; Writeln(' Minimum = ',Deg(Th2s):6:2); Writeln(' Maximum = ',Deg(Th2I):6:2); Writeln;Writeln; Write(' Please Enter Angle Theta 2 ---> '); Readrl(Th2);Th2 : = Rad(Th2); end;

{ Calculates cognates, sets up coordinates and draws the cognates for the case when the three joints of the coupler link are in line }

Overlay Procedure On_Line;

{ Calculates the size of a given link. }

Function Link_Size(x, y : Real) : Real; Begin Link_Size : = Sqrt(Sqr(x) + Sqr(y)) end;

{ Calculates the necessary points to draw the cognates }

Procedure Calc_Points; Var x1, x2, y1, y2, Slope1, Slope2 : Real; Theta, Thetax, x3, y3 : Real; : Integer;

{ Given the slope of two lines and points on these lines calculate the point of intercection }

Procedure lntercept(x1 ,y1 ,x2,y2,Slope1 ,Slope2 : Real; Var x3, y3 : Real); Begin x3: = (y1 - y2 - Slope1*x1 + Slope2*x2)/(Slope2 - Slope1); y3: = Slope1 * (x3-x1) + y1 end;

Pascal Code 144 Begin IF (0882 > OAA1) and (0882 > AB) then Begin Ppr[10, 1] : = -(OAA 1/ AB) • OAOB; Theta : = Th3 + pi end; else Begin Ppr[10,1] := (OAA1/AB) • OAOB; Theta : = Th3 end; Ppr[10,2] : = O; Ppr[1,1] := O; Ppr[1,2] : = O; Ppr[2, 1] : = OAOB; Ppr[2,2] : = O; Ppr[3, 1] : = OAA • Cos(Th2); Ppr[3,2] : = OAA • Sin(Th2); Ppr[4, 1] : = OAOB + OBS • Cos(Th4); Ppr[4,2] : = OBB • Sin(Th4); Ppr[5, 1] : = Ppr[3, 1] + OAA 1 • Cos(Theta); Ppr[5,2] : = Ppr[3,2] + OAA 1 • Sin(Theta); Ppr[6, 1] : = OAA 1 • Cos(Theta); Ppr[6,2] : = OAA 1 • Sin(Theta); Thetax: = Atan2(Ppr[5, 1]-Ppr[4, 1],Ppr[5,2]-Ppr[4,2]); Ppr[?, 1] : = Ppr[2, 1] + OB82 • Cos(Thetax); Ppr[7,2] : = Ppr[2,2] + O8B2 • Sin(Thetax); Slope1 : = Sin(Th2)/Cos(Th2); Slope2 : = Sin(Th4)/Cos(Th4); x1 := Ppr[10,1]; y1 : = Ppr[ 10,2]; x2 := Ppr[5,1]; y2 : = Ppr[5,2]; I ntercept(x 1, y1 ,x2, y2,S lope 1,S lope2,x3, y3); Ppr[9, 1] : = x3; Ppr[9,2] : = y3; I ntercept(x1 ,y1 ,x2,y2,Slope2,Slope1 ,x3,y3); Ppr[8, 1] : = x3; Ppr[8,2] : = y3; for i : = 1 to 1O Do Transform(Trans _Matrix, Ppr[i, 1], Ppr[i,2]); end;

{ Calls link_size to calculate the length of the links of the cognates }

Procedure Calc_Lengths; Begin

Pascal Code 145 OCC1 : = Link_Size( Ppr[10, 1]-Ppr[S, 1], Ppr[10,2]-Ppr[S,2]); OCC2 : = Link_S ize(Ppr[10, 1]-Ppr[9, 1],Ppr[10,2]-Ppr[9,2]); A 1C1 : = Link_S ize( Ppr[6, 1]-Ppr[S, 1].Ppr[6,2]-Ppr[8.2]); B2C2 : = Link_S ize(Ppr[9, 1]-Ppr[?, 1], Ppr[9,2]-Ppr[7,2]); OAOC := Link_Size(Ppr[10,1]- Ppr[1,1],Ppr[10,2] - Ppr[1,2]); OBOC := Link_Size(Ppr[10,1]- Ppr[2,1],Ppr[10,2]- Ppr[2,2]) end;

Procedure Set_Up_Coord; Var Oum :Real; Begin WindowCoord(3,25,25,290, 175); Setwindow(3); Windowbox; Set_View_ Coordinates( 1, 10, Ppr ,Du m) end;

{ Draws the cognates }

Procedure Drawit; Var Colo : Byte; x1, y1 ,Size : Real; Begin GotoXY(6,2); Writeln('Cognates For Binary Coupler'); Colo:= Color+ 1; Draw Poi nts(7 ,2,Colo, Ppr); DrawPoints(9, 10,Colo,Ppr); Draw Poi nts(9, 7,Colo, Ppr); Draw Poi nts(5, 7,Colo, Ppr); DrawPoints(9,5,Colo,Ppr); Colo : = Color + 2; DrawPoints(1,6,Colo,Ppr); DrawPoints(5,6,Colo,Ppr); DrawPoints(5,8,Colo,Ppr); DrawPoints(S,6,Colo,Ppr); DrawPoints(S, 10,Colo,Ppr); DrawPoints( 1,3,Color,Ppr); DrawPoints(5,3,Color,Ppr); DrawPoints(4,3,Color,Ppr); DrawPoints(4,5,Color,Ppr); DrawPoints(4,2,Color,Ppr); Size:= (OAA + OAOB + OBB + AB + OAA1 + OBB2)/70; x1 : = Ppr[10, 1]; y1 : = Ppr[10,2]; Draw_Square(x 1,y1 ,S ize,Color);

Pascal Code 146 x1 := Ppr[1,1]; y1 : = Ppr[1,2]; Draw_Square(x1 ,y1 ,Size.Color); x1 := Ppr[2,1]; y1 : = Ppr[2,2]; Draw_Square(x1 ,y1 ,Size,Color); x1 := Ppr[5,1]; y1 : = Ppr[5,2]; Size : = Size/2; Draw_Square(x1 ,y1 ,Size.Color); Fu nction_Keys_ 1; Text mode; end;

Begin Initial_Graphics; Calc_Points; Calc_Lengths; Set_Up_Coord; Drawit; end;

{ Sets up the color, and calls for the calculation of the transformation matrix }

Procedure Initialize; Var x1 : Real; Begin Color:= 1; x1 := Atan2(p4[1]-p1[1],p4[2]-p1[2]); Cale_ d_Matrix(p1 [1 ],p1 [2],x 1, Trans_Matrix); Start; Write_Sp; end;

Begin Initialize; Calculate_Angles(OAA,AB,OBB,OAOB,Th2,Th3,Th4,OK); If Ok then Begin If Online then On_Line else

Pascal Code 147 Begin lnitialize_C; Draw_Cayleys; Setup_R; Draw_Roberts; Write_Headings end; Write_Resu Its end; else Begin Clrscr; GotoXY(24, 10); Write('lmpossible Geometry') end; end;

Pascal Code 148 { Calculates a linkage to satisfy a certain function. The functions implemented are: exponential, logarithmic, natural logarithmic, cosine, tangent and sine }

Overlay Procedure Function_Generation;

Type Arrays = Array [0 . .4] of Real; Typestring = String[70];

Var Phi, Psi, x, y : Arrays; w1, w2, w3, w4, w5, w6, r1, r2, r3,a,b,c,d : Real; j : Integer; Flag,OK,Over : Boolean; Afile : File; Stringm : Typestring; Ans : Char; Continue, Check : Boolean;

{ Calculates the precision points using Chebyshev spacing }

Procedure Chebyshev; Begin For j : = 1 to 3 Do x[j] : = (x[4] + x[0])/2.0 - ((x[4] - x[0]) * Cos(pi * (2.0 * j - 1.0)/6.0))/2.0 end;

{ Converts degrees to radians }

Function Rad(Th : Real) : Real; Begin Rad:= Th* pi /180.0 end;

{ Creates the heading of a choice menu }

Procedure Chaise; Begin Textcolor(2); Writeln;Writeln;Writeln;

Pascal Code 149 Writeln(' Please Enter Your Chaise '); Writeln;Writeln;Writeln; end;

Procedure Arrow; Begin Writeln;Writeln; Write(' ---- > '); end;

{ Writes the menu in a specified window }

Procedure Write_Menu(Mess : Typestring); Type String1 = String[17]; String2 = String[53]; Var St1 : String1; St2 : String2; Begin Textcolor(14); St1 : = Copy(Mess, 1, 17); Write(St1 ); St2 : = Copy(Mess, 18,53); Textcolor(3); Writeln(St2); Textcolor(14); end;

{ Gets required data from the user }

Procedure Enter _Data; Begin Clrscr; If Check then Begin Repeat Gotoxy(1,3); Write(' Enter the Initial Value of X '); Readrl(x[0]) ;Write In; Write(' Enter the Final Value of X '); Readrl(x[ 4]);Writeln; until (x[0] > 0) and (x[4] > 0) end; else

Pascal Code 150 Begin Gotoxy( 1,3); Write(' Enter the Initial Value of X '); Readrl(x[0]);Writeln; Write(' Enter the Final Value of X '); Readrl(x[4]);Writel n end; Write(' Enter the Initial Value of the Input Angle '); Readrl(Phi[0]);Writeln; Write(' Enter the Final Value of the Input Angle '); Readrl(Phi[4]);Writeln; Write(' Enter the Initial Value of the Output Angle < DEGREES> '); Readrl(Psi[0]);Writeln; Write(' Enter the Final Value of the Output Angle '); Readrl( Psi[ 4 ]);Write I n;Writel n; Write(' Enter the Value of the Fixed Link '); Readrl(d); Phi[0] : = Rad(Phi[0]); Phi[4] : = Rad(Phi[4]); Psi[0] : = Rad(Psi[0]); Psi[4] : = Rad(Psi[4]); Chebyshev; end;

{ Calculates the function parameters Y1 ... Y4 for a natural logarithm function }

Procedure Natural; Begin Enter_Data; For j : = 0 to 4 Do y[j] := ln(x[j]) end;

{ Calculates the function parameters Y1 ... Y4 for an exponential function }

Procedure Exponential; Var Number, Oum : Real; Begin Enter_Data; Write In; Write(' Please Enter the Exponent Number '); Readrl(Number); For j : = 0 to 4 Do Begin

Pascal Code 151 Oum : = ln(x[j]); y[j] : = Exp( Du m • Number); end; end;

{ Calculates the function parameters Y1 ... Y4 for a sine function }

Procedure Sine; Begin Clrscr; GotoXY( 10, 1O);Textcolor( 14 + 15); Write(' Enter the Initial and Final Values of X in ', 'DEGREES');Textcolor(14); Delay( 1500); Enter _Data; For j : = 0 to 4 Do Begin x[j] : = Rad(x[j]); y[j] : = Si n(x[j]); end; end;

{ Calculates the function parameters Y1 ... Y4 for a cosine function }

Procedure Cosine; Begin Clrscr; GotoXY(10,10);Textcolor(14+ 15); Write(' Enter the Initial and Final Values of X in ', 'DEGREES');Textcolor(14); Delay(1500); Enter_Data; For j : = 0 to 4 Do Begin x[j] : = Rad(x[j]); y[j] : = Cos(x[j]); end; end;

{ Calculates the function parameters Y1 ... Y4 for a tangent function }

Procedure Tangent;

Pascal Code 152 Begin Clrscr; GotoXY( 10, 10);Textcolor( 14 + 15); Write(' Enter the Initial and Final Values of X in ', 'DEGREES ');Textcolor( 14); Delay(3000); Enter _Data; For j : = 0 to 4 Do Begin x(j] : = Rad(x[j]); y[j] : = Sin(x[j])/Cos(x[j]); end; end;

{ Calculates the function parameters Y1 ... Y4 for a common logarithm function }

Procedure Common; Begin Enter_Data; For j : = 0 to 4 Do y[j] : = ln(x[j])/ln(10) end;

{ Calculates dummys w1 ... ws See section 5.2 }

Procedure Calculate_Omegas; Begin w1 : = Cos(Phi[1]) - Cos(Phi[2]); w2: = Cos(Phi[1]) - Cos(Phi[3]); w3: = Cos(Psi[1]) - Cos(Psi[2]); w4: = Cos(Psi[1]) - Cos(Psi[3]); w5: = Cos(Phi[1] - Psi[1]) - Cos(Phi[2] - Psi[2]); w6: = Cos(Phi[1] - Psi[1]) - Cos(Phi[3] - Psi[3]); end;

{ Calculates dummys R1 ... R3 See section 5.2 }

Procedure Calculate_rs; Begin r1 : = (w3*w6 - w4*w5)/(w2*w3 - w1 *w4); r2 : = (w1 *w6 - w2*w5)/(w2*w3 - w1 *w4); r3: = Cos(Phi[1] - Psi[1]) + r2 • Cos(Psi[1]) -

Pascal Code 153 r1 • Cos(Phi[1]); end;

{ Calculates the length of the links }

Procedure Calcu late_Link_Lengths; Var Oum : Real; Begin a : = d / r2; c : = d / r1; Oum : = Sqr(a) + Sqr(c) + Sqr(d) - 2.0 • a • c • r3; If Oum < 0.0 then Flag : = False else b : = Sqrt(Ou m); end;

{ Calculates the input angles 1 ... $3 and the output angles '1'1 ... 'J'3 }

Procedure Calculate_Angles; Var Oelta_Phi, Oelta_Psi, Oelta_x, Oelta_y : Real; Begin Oelta_Phi : = Phi[4] - Phi[O]; Oelta_Psi : = Psi[4] - Psi[O]; Oelta_x : = x[4] - x[O]; Oelta_y : = y[4] - y[O]; Phi[1] : = Phi[O] + ((x[1] - x[O]) * Oelta_Phi/Oelta_x); Phi[2] : = Phi[1] + ((x[2] - x[1]) * Oelta_Phi/Delta_x); Phi[3] : = Phi[1] + ((x[3] - x[1]) * Oelta_Phi/Oelta_x); Psi[1]: = Psi[O] + ((y[1] - y[O]) * Oelta_Psi/Oelta_y); Psi[2] : = Psi[1] + ((y[2] - y[1]) * Oelta_Psi/Oelta_y); Psi[3] : = Psi[1] + ((y[3] - y[1]) • Oelta_Psi/Oelta_y); end;

{ Shows on the screen the function menu and lets the user choose the desired function }

Procedure Choose_Function; Begin Check : = False; Continue : = True;

Pascal Code 154 Clrscr; GotoXY(5,5); Writeln(' FUNCTION TO BE SYNTHESIZED '); Chaise; Stringm : = ' F1 ... Common Logarithm'; Write_Menu (String m); Stringm : = ' F2 ... Natural Logarithm'; Write_Menu(Stri ng m); Stringm : = ' F3 ... Exponenticil Function'; Write_Menu (String m); Stringm : = ' F4 ... Sinusoidal Function'; Write_Menu (String m); Stringm : = ' F5 ... Tangential Function'; Write_Menu (String m); Stringm : = ' F6 ... Cosine Function'; Write_Menu(Stri ng m); Stringm : = ' F10 ... Quit'; Write_Menu (String m); Arrow; Repeat Read(kbd,Ans) until Ord(Ans) in [59,60,61,62,63,64,68]; Case Ord(Ans) of 59 : Begin Check : = True; Common end; 60 Begin Check : = True; Natural end; 61 Begin Check : = True; Exponential end; 62 Sine; 63 Tangent; 64 Cosine; 68 Continue:= False; end; end;

{ Writes the synthesized linkage specifications }

Procedure Write_Results;

Pascal Code 155 Begin Clrscr; GotoXY(S,5); Writeln;Writeln;Textcolor( 10); Writeln(' Designed Mechanism Specifications'); Writeln;Writeln; Textcolor(14); Write(' Length of Fixed Link = '); Textcolor( 1S);Writeln( d:7:4);Textcolor( 14); Write(' Length of Input Link = '); Textcolor( 1S);Writel n( a:7:4);Textcolor( 14); Write(' Length of Coupler Link = '); Textcolor( 15);Writel n( b:7:4);Textcolor( 14); Write(' Length of Output Link = '); Textcolor( 15);Writeln( c:7:4);Textcolor( 14); Writeln;Writeln; If (a<0) or (b<0) or (c<0) or (d<0) then Write(' NOTE·· - Indicates Links 180 Degrees Out of Phase'); Writeln;Writeln; Write(' Press Any Key to Continue... '); Repeat until Keypressed; end;

Procedure Start; Begin Choose_Function; If Continue then Begin Calcu late_Angles; Cal cu late_Omegas; Calculate_rs; Calcu late_Link_Lengths end; end;

Begin { of the Main Program} Repeat Over : = False; Repeat Flag : = True; Start; If not Flag then Begin Writeln(' Impossible Design. Try Again ... '); Delay(2000); end; until Flag; If Continue then

Pascal Code 156 Begin Repeat Whatposition : = O; OK := False; Clrscr; Choise; Stringm · = ' F1 Diagram-Animation of Linkages'; Write_Menu (String rn); Stringm : = ' F2 .. Linkage Specifications'; Write_Menu (String m); Stringm : = ' F3 .. Try a New Case'; Write_Me nu (String m) ;Write I n;Writel n; Stringm : = ' F10 .. Quit...'; Write_Menu (Stringm); Arrow; Repeat Read(kbd,Ans) until Ord(Ans) in [59, 60, 61, 68]; Case Ord(Ans) of 59: Li nkage(a,b,c,d); 60: Write_Results; 61 : OK:= True; 68: Begin OK : = True; Over : = True; end; end; until OK; end; else Over : = True; until Over;

Clrscr; end;

Pascal Code 157 { Displays the dyads passed to it and allows the user to choose two of those dyads for the synthesis of a four-bar linkage or three dyads for the synthesis of a six_bar linkage. After the required dyads are chosen. a call is made to the animation procedure to check for possible linkage defects. }

Procedure Onepolygon;

Var i, Ix : Integer; x1,x2 : Real; Color : Byte; Oum, Xrange : Real; Flag, More : Boolean; Link_Type : Strings;

{ Sets up the screen for a hard copy }

Procedure Print_the_Screen; Var I : Integer; Begin GotoXY(2,24); for i : = 1 to 79 Do Write(' '); Print Screen end;

{ Sets up window coordinates and view coordinates }

Procedure Initialize; Var Dum1 : Plotarray; i ,j : Integer; Begin i : = nn + Whatposition; for j : = 1 to Whatposition Do Begin c[nn + j, 1] : = Body_Position[j, 1]; c[nn + j,2] : = Body_Position[j,2] end; Clrscr; HiRes;

Pascal Code 158 HiResColor(Red); Windowcoord(1,0,0,639, 199); Setwindow(1); Draw(353,8,365.8, 1); Draw(365,8,365, 14, 1); Draw(365, 14,353, 14, 1); Draw(353, 14,353,8, 1); Draw(353,8,365, 14, 1); Draw(353, 14,365,8, 1); Draw(488,8,500.8, 1); Draw(S00,8,500, 14, 1); Draw(500, 14,488, 14, 1); Draw( 488, 14,488,8, 1); Draw(604, 14,616,8, 1); Draw(616, 14,604,8, 1); Windowcoord(2,270,0,639,25); Setwi ndow(2); Windowbox; GotoXY(37 ,2); Write('Fixed '); GotoXY(53,2); Write('Moving'); GotoXY (70,2); Write('Body'); Windowcoord(3,270,25,639, 179); Setwindow(3); Windowbox; Set_View_Coordinates(1,i,c,Xrange); end;

{ Displays the dyads and the body positions on a specified window }

Procedure Draw_Links; Var i : Integer; Size: Real; Begin Size : = Xrange/50; for i : = 1 to Count Do Begin Draw_Sq_Pivot(a[i, 1],a[i,2],Size,Color,False); Draw_Sq_Pivot(b[i, 1],b[i,2],Size,Color,True); Drawline(a[i, 1],a[i,2],b[i, 1],b[i,2],Color) end; for i : = 1 to WhatPosition Do Draw_Cross( Body_Position[i, 1], Body_Position[i,2],S ize,3); end;

Pascal Code 159 { Writes in a specified window the X and Y coordinates of the moving and fixed pivots of each dyad. }

Procedure W_Pivot; Begin Gotoxy(1,5); for i : = 5 to 19 Do Write In(' '); Gotoxy( 1,5); Repeat Ix:= Ix+ 1; Write I n(ix:2,' ',ab2[ix]:5: 1,' ',b[ix, 1]:5: 1,' ',b[ix,2]:5: 1, '',a[ix,1]:5:1,' ',a[ix,2]:5:1); until (Ix = Count) or ((ix Mod 13) = O); If More then Begin GotoXY(13, 19); Write('F5 for More ... ') end; If ix = Count then ix:= 0 end;

{ Writes the headings and calls W_Pivot }

Procedure Result; Begin GotoXY(1,1); Ix:= O; If WhatPosition = 4 then Begin GotoXY(3, 1 ); Writeln(' B2 Fixed Moving'); Writeln; end; else Begin Writeln(' B2 = ',ab1:6:2); Write In; Writeln(' B3 Fixed Moving'); Write In; end; W_Pivot; end;

{ Clears out the dialog window }

Pascal Code 160 Procedure Clear_Dialog; Var K : Integer; Begin for k : = 20 to 23 Do Begin GotoXY(1,k); Write(' ') end; end;

{ Allows the user to choose the desired dyad for the formation of a six-bar linkage }

Procedure Ch_Dyads; Var Slope1, Slope2,x3,y3 : Real;

{ Given the slopes of two lines and points on these lines calculate their intercection }

Procedure I ntercept(x1 ,y1 ,x2,y2,Slope1 ,Slope2 : Real; Var x3, y3 : Real); Begin x3: = (y1 - y2 - Slope1*x1 + Slope2*x2)/(Slope2 - Slope1); y3: = Slope1 • (x3-x1) + y1 end;

Begin Repeat GotoXY(1,20); Write('Enter the Index Number of..'); GotoXY(1,21); Write('Chosen Input Dyad --> '); Readint(i); until (i in [1 .. Count]); Clear_Dialog; Six_Bar[5, 1] : = Body_Position[5, 1]; Six_Bar[5,2] : = Body_Position[5,2]; Slope 1 : = (Six_Bar[5,2]-a[i,2])/ (Six_Bar[5, 1]-a[i, 1]); Slope2 := (b[i,2]-a[i.2])/(b[i,1]-a[i,1]); I ntercept(b[i, 1],b[i,2],Six_Bar[5, 1],S ix_Bar[i,2],S lope1 ,Slope2,x3,y3); Six_Bar[6,1] := x3; Six_Bar[6,2] : = y3; Six_Bar[?,1] := b[i,1];

Pascal Code 161 Six_Bar[7,2] : = b[i.2]; Linkage_6(Li nk_c[ 1] .Link_c[2],Li nk_ c[3],Li nk_c[ 4]) end;

{ Allows the user to choose the desired dyads for a four-bar linkage. It makes the necessary assignments and calls the required procedures ie., cognates for path generation with input timing or the animation routine for body quidance problem }

Procedure Choose_Dyad; Var i,j : Integer;

{ Calculates the coupler angle and length and makes the necessary assignments }

Procedure Assign_Linkage(i,j : Integer); Var xx, yy :Real; Begin If Synthesis < > 'D' then Begin Six_Bar[5,1]: = Body_Position[1,1]; Six_Bar[5,2] : = Body_Position[1,2]; Coupler_Length : = Sqrt(Sqr(Six_Bar[5.1] - Six_Bar[2, 1]) + Sqr(Six_Bar[5.2] - Six_Bar[2,2])); xx:= Atan2((Six_Bar[5,1] -Six_Bar[2,1]), (Six_Bar[5,2] - Six_Bar[2,2])); yy: = Atan2((Six_Bar[3, 1] - Six_Bar[2, 11) , (Six_Bar[3,2] - Six_Bar[2,2])); Coupler_Angle_a: = xx - yy; end; end;

{ Calculates the size of a link }

Function Link_Size(i,r: Real) : Real; Begin Link_Size : = Sqrt(Sqr(i) + Sqr(r)) end;

Pascal Code 162 { Lets the user choose the desired dyads }

Procedure Enter_Choise; Var Sound_YN : Boolean; Oum : Boolean; Begin Sound_YN : = False; Oum : = Choise_Over; Repeat Repeat Choise_Over: = Oum; If Sound YN then Begin Sound(440); Delay(300); Nosound end; GotoXY(1,20); Write('Enter the Index Number of.. '); If Choise_Over then Begin GotoXY(1,21); Write(' Chosen Dyad # 1 --- > '); Readint(i); Six Bar[1,1] := b[i,1]; Six_Bar[1,2]: = b[i,2]; Six_Bar[2, 1] : = a[i, 1]; Six Bar[2,2] : = a[i,2] end; GotoXY(1,22); Write(' Chosen Dyad # 2 --- > '); Readint(j); If j = 0 then Begin Choise_Over: = False; If i < Count then j: = i + 1 else j : = i - 1; end; else Begin Six Bar[3, 1] : = a[j, 1]; Six_Bar[3,2] : = a[j,2]; Six_Bar[4,1] := b[j,1]; Six_Bar[4,2] : = b[j,2]; Sound_YN : = True; If j < Count then i: = j + 1

Pascal Code 163 else i : = j - 1; Choise_Over : = True end; until (i in [1 .. Count]) and (j in [1 .. Count]) and (j < > i); until ((Abs(Six_bar[2,1] - Six_bar[3,1]) > 0.01) or (Abs(Six_bar[2,2] - Six_bar[3.2]) > 0.01 )) and ( (Abs(S ix_bar[ 1, 1] - S ix_bar[ 4. 1]) > 0.01) or (Abs(Six_bar[1,2] - Six_bar[4,2]) > 0.01)) and ((Abs(Six_bar[2, 1] - Six_bar[4, 1]) > 0.01) or (Abs(Six_bar[2,2] - Six_bar[4,2]) > 0.01)) and ((Abs(Six_bar[1, 1] - Six_bar[3,1]) > 0.01) or (Abs(Six_bar[1,2] - Six_bar[3,2]) > 0.01 )) or not Choise_Over; Clear_Dialog; end;

{ Once the dyads are chosen the necessary calculations are made to "assemble" the link in the branch in which is able to reach the first body position }

Procedure Cal cu late; Var Temp,Th2,Th3,Th4 : Real; Tern : Integer; OK : Boolean;

{ Calculates the angle between two dyads }

Function Cal_Th(k,j : Integer) : Real; Var xx, yy : Real; Begin xx:= Atan2((Six_Bar[k,1] - Six_Bar[j,1]), (Six_Bar[k,2] - Six_Bar[j.2])); yy := Atan2((Six_Bar[4,1] - Six_bar[1,1]), (Six_Bar[4,2] - Six_bar[1,2])); Cal_Th : = xx - yy end;

Begin Link_c[1] : = Link_S ize(Six_bar[1, 1]-Six_Bar[2, 1], Six_bar[1,2]-S ix_Bar[2,2]); Link_c[2] : = Link_Size(Six_Bar[2, 1]-Six_Bar[3, 1], S ix_Bar[2,2]-S ix_Bar[3,2]);

Pascal Code 164 Link_c[3] : = Link_Size(Six_Bar[4, 1]-Six_Bar[3, 1], S ix_Bar[ 4,2]-S ix_Bar[3,2]); Link_c[4]: = Link_Size(Six_bar[1,1]-Six_Bar[4,1], S ix_bar[ 1,2]-S ix_Bar[ 4,2]); Th2 : = Cal_Th(2, 1); Temp : = Cal_Th(3,4); Branch : = True; Cal cu late_Ang les(Li nk_ c[ 1]. Link_c[2] ,Link_c[3], Link_c[ 4 ], Th2, Th3, Th4, OK); If Temp < 0 then Temp : = 2*pi + Temp; lf(Th4 > Temp + Rad(3)) or (Th4 < Temp-Rad(3)) then Branch : = False end;

{ Calls the Cognate procedure if the synthesis is path generation with input timing }

Procedure Call_Cognates; Var p1 ,p2,p3,p4,pop : Points; Begin p1[1] := Six_bar[1,1]; p1 [2] : = Six_bar[1,2]; p2[1] : = Six_Bar[2, 1]; p2[2] : = Six_Bar[2,2]; p4[1] := Six_Bar[4,1]; p4[2] : = Six_Bar[4.2]; p3[1] := Six_Bar[3,1]; p3[2] : = Six_Bar[3,2]; pop[ 1] : = Body_Position[1, 1]; pop[2] : = Body_Position[1,2]; Cognates(p1 ,p2,p3,p4,pop); end;

Begin Flag : = True; Clear_Dialog; Enter_Choise; If Chaise Over then Begin Calculate; Assign_Linkage(i,j); If Synthesis = 'B' then Call_Cognates; end; end;

Pascal Code 165 { Calls the animation procedure after it checks that enough dyads have been chosen }

Procedure See_Linkage; Var Dum1, Dum2 : Real; Begin If Flag then Li nkage(Link_c[1 ],Li nk_c[2],Li nk_c[3],li nk_c[ 4]) else Begin Sound(440); Delay(500); Nosound; GotoXY(1,21); Write(' Dyads Unspecified'); GotoXY(1,22); Write(' Choose Dyads First'); Delay(1000); Clear_Dialog; end; end;

{ Displays the function key menu }

Procedure Write_Key_M; Begin GotoXY(5,24); Write('F1: Choose Dyads'); GotoXY(25,24); If Synthesis = 'A' then Write('F2: Observe Linkage'); GotoXY(48,24); Write('F3: Print Screen'); GotoXY(66,24); Write('F10 : Return'); end;

{ Initializes the procedure }

Procedure Start; Var Size : Real; Col : Byte; Begin

Pascal Code 166 Flag : = False; Color:= 1; In itia I ize; If Count > = 2 then Begin Draw_Links; Result; Write_Key_M; end; Col:= Red+ 15; If (not Pass1) and (Synthesis = 'D') then Begin Drawpoints(1,2.Col,Six_Bar); Drawpoints(2,3,Col,Six_Bar); Drawpoints(4,3,Col,Six_Bar); Size : = Xrange/50; Draw_Sq_Pivot(Six_Bar[1, 1],Six_Bar[1,2],Size,Col,True); Draw_Sq_Pivot(S ix_Bar[ 4, 1],S ix_Bar[ 4,2],Size,Col,True) end; end;

{ Utilization of the PF keys for a body quidance problem. }

Procedure Function_Keys_1; Var Ch : Char; Begin Repeat Read(kbd,Ch); Case Ord(Ch) of 59 If Synthesis = 'D' then Begin Ch_Dyads; Start end; else Choose_Dyad; 60 Begin See_Linkage; If Flag then Start end; 61 Begin Print_the_Screen; Write_Key_M

Pascal Code 167 end; 63 : If More then W_Pivot; end; until Ord(Ch) = 68; end;

{ Utilization of the PF keys for a path generation with input timing problem. }

Procedure Function_Keys_2; Var Ch : Char; Begin Repeat Read(kbd,Ch); Case Ord(Ch) of 59 Begin Choose_Dyad; Start end; 61 Begin Print_the_Screen; Write_Key_M end; 63 : If More then W_Pivot; end; until Ord(Ch) = 68; end;

{ The required synthesis task is chosen and the corresponding routine is called. }

Procedure Choose_Synthesis; Var Ch : Char; Begin Case Synthesis of 'A': Begin Start; Function_Keys_ 1 end; 'B': Begin Start;

Pascal Code 168 Function_Keys_2; end; 'D': Begin Start; If Pass1 then Begin Repeat Read(kbd,Ch); If (Ord(Ch) = 63) and More then W_Pivot; until Ord(Ch) in (59,61,68]; Case Ord(Ch) of 59 : Begin Choose_Dyad; If Chaise Over then Pass1 : = False end; 61 : Begin Print_the_Screen; Write_Key_M; end; end; end; else Fu nction_Keys_ 1 end; end; end;

Begin More : = False; Window(1, 1,80,25); If Count > 15 then More : = True; Choose_Synthesis; Textmode end;

Pascal Code 169 Program Cyprus; {$1 Vasiko.Pas} {$1 Utility.Inc} {$1 Six.Pas} {$1 Link.Pas} {$1 Cognates.Pas} {$1 Fun_Gen.Pas} {$1 Polyaxis.Pas}

Type Complex = Record r,i : Real end; Typestring = String[?O]; Reserve = Array [ 1.. 13] of Real;

Var X1 ,X2,Th1 ,Th2,Th3,A 1,A2,A3 : Real; R 1,R2,R3,P,Gamma,S,B1 ,82 : Real; B3,B4,Th4,A4,R4 : Real; N,I : Integer; Ok, Qu it_AI I : Boolean; Stringx : Typestring; Filename : String[14]; Afile : File; Ans : Char; Xxx : Reserve; Checks : Boolean;

{ Complex number multiplication }

Procedure CM(a,b:Complex; Var c:Complex); Begin c.r: = a.r*b.r-a.i*b.i; c.i: = a.r*b.i + a.i*b.r; end;

{ Complex number addition }

Procedure CA(a,b:Complex; Var c:Complex); Begin c.r: = a.r + b.r; c.i: = a.i + b.i; end;

Pascal Code 170 { Complex number subtraction }

Procedure CS(a,b:Complex; Var c:Complex); Begin c.r: = a.r-b.r; c.i: = a.i-b.i; end;

{ Complex number division }

Procedure CD(a,b:Complex; Var c:Complex); Var n: Complex; d: Real; Begin b.i: =-b.i; CM(a.b,n); d: = b.r*b.r + b.i*b.i; If (d = 0) then Begin Ok:= False; end; else Begin c.r: = n.r/d; c.i: = n.i/d; end; end;

{ Indents the cursor X spaces from the first column }

Procedure lndent(i : Integer); Var j : Integer; Begin For j : = 1 to I Do Write(' '); end;

{ Reassigns the values of body positions and orientation }

Procedure Reset_V(xx : Boolean);

Pascal Code 171 Begin If xx then Begin Xxx[1] : = r1; Xxx[2] : = r2; Xxx[3] : = r3; Xxx[5]: = Th1; Xxx[6] : = Th2; Xxx[7] : = Th3; Xxx[9] : = a1; Xxx[10] : = a2; Xxx[11] : = a3; If Whatposition = 4 then Begin Xxx[ 4] : = r4; Xxx[8] : = Th4; Xxx[12] : = a4 end; else Xxx[13] : = b2 end; else Begin r1 : = Xxx[1]; r2 : = Xxx[2]; r3 : = Xxx[3]; Th 1 : = Xxx[5]; Th2 : = Xxx[6]; Th3 : = Xxx[7]; a1 : = Xxx[9]; a2 : = Xxx[10]; a3:= Xxx[11]; If Whatposition = 4 then Begin r4 : = Xxx[4]; Th4 : = Xxx[8]; a4 : = Xxx[12] end; else b2 : = Xxx[13] end; end;

{ Centers the text written on the screen }

Procedure C_Write(String2 : Typestring); Var i, j : Integer; Begin

Pascal Code 172 i : = Length(String2); j : = Trunc((80 - i)/2); for i : = 1 to j Do Write(' '); Writeln(String2); end;

Procedure Choice; Begin Textcolor(2); Writeln;Writeln;Writeln; Writeln(' Please Enter Your Choice '); Writeln;Writeln;Writeln; end;

Procedure Arrow; Begin Writeln;Writeln; Write(' --- > '); end;

{ Given the two components of a vector, its size is calculated }

Function Size(Xreal,Ximag : Real ) : Real; Begin Size : = Sqrt(Sqr(Ximag) + Sqr(Xreal)) end;

{ Calculates the complex numbers D2 ... D4 (See Appendix C) }

Procedure Delta( Var d2, d3, d4: Complex); Var Dummy : Real; Begin Dummy : = r1 • Cos (Tt11 ); d2.r : = r2 • Cos (Th2) - Dummy; d3.r : = r3 * Cos (Th3) - Dummy; d4.r := r4 * Cos (Th4) - Dummy; Dummy:= r1 • Sin (Th1); d2.i : = r2 * Sin (Th2) - Dummy; d3.i : = r3 * Sin (Th3) - Dummy; d4.i : = r4 * Sin (Th4) - Dummy; end;

Pascal Code 173 { Calculates the complex numbers A2 •.• A4 (See Appendix C) }

Procedure Alpha( Var a_2, a_3,a_ 4 : Complex); Var Dummy: Real; Begin Dummy:= Cos (a1); a_2.r : = Dummy - Cos(a2); a_3.r : = Dummy - Cos(a3); a_4.r : = Dummy - Cos(a4); Dummy:= Sin (a1); a_2.i Dummy - Sin(a2); a_3.i Dummy - Sin(a3); a_4.i Dummy - Sin(a4); end;

{ Calculates angles b4 and b3 (See Appendix C) }

Procedure Calc_b4_b3( t1 ,t2: Real;d,d4 : Complex); Var Dum1,Dum2 : Real; Begin b4 : = -2.0 • Arctan(t1 ); Dum1 : = d.i + d4.i * Cos(-b4) + d4.r * Sin(-b4); Dum2: = d.r + d4.r * Cos(-b4) - d4.i * Sin(-b4); b3: = -Atan2(Dum2,Dum1); end;

{ Calculates intermediate results and then calls for the cal cu lat ion of the angles b3 and b4. }

Procedure a_b_c(d,d4 :Complex); Var aa,bb,cc,k 1,k2,k3 : Real; t1 ,t2,Dum,Dum1 : Real; Begin aa : = Sqr(d.r) + Sqr(d4.r) + Sqr(d.i) + Sqr(d4.i) - 1.0; bb : = 2.0 * d.r * d4.r + 2.0 * d.i * d4.i; cc : = 2. * d.i * d4.r - 2.0 * d.r * d4.i; k1 : = aa - bb; k2 : = 2.0 * cc; k3: = aa + bb; Oum : = Sqr(k2) - 4.0 * k1 • k3; If Du m > 0.0 then

Pascal Code 174 Begin Dum1 : =Sqrt(Dum); t1 := (-k2 + Dum1)/(2 * k1); t2 := (-k2- Dum1)/(2 * k1); Calc_b4_b3(t1 ,t2,d,d4); end; else Ok:= False; end;

{ Calculates the complex numbers d2 ... d4 (See Appendix C) }

Procedure Big_Delta(d2,d3,d4,aa2,aa3,aa4 : Complex);

Var bd2,bd3,bd4,bd1,bd : Complex; Dum2,Dcom,d4dom,Dum1 : Complex; Begin CM(aa2,d3,Dum1); CM(aa3,d2,Dum2); CS(Dum2,Dum1 ,bd4); CM(aa4,d2,Dum1); CM(aa2,d4,Dum2); CS(Dum2.Dum1 .bd3); CM(aa3,d4,Dum1); CM(aa4,d3,Dum2); CS(Dum2.Dum1 ,bd2); CA(bd2,bd3,Dum1); CA(Dum1,bd4,Dum2); Dum1.i := 0.0; Dum1.r := 0.0; CS(Dum1,Dum2,bd1); Dum1 .r : = Cos(-b2); Dum1 .i : = Sin(-b2); CM(bd2,Dum1 ,Dum2); CA(bd1 ,Dum2,Dum1); Dum2.r: = 0.0; Dum2.i : = 0.0; CS(Dum2,Dum1 ,bd); CD(bd,bd3,Dcom); CD(bd4,bd3,Dum1); Dum2.r: = 0.0; Dum2.i : = 0.0; CS(Dum2,Dum1,d4com); If Ok then a b c(Dcom,d4com) end;

{ Solves the system of equations ( eq. A 1.5) using Cramer's rule }

Overlay Procedure Calculate; Var dr,di,drp,dip,dis,drs : Real; srp,sip,srs,sis : Real; Ch : Char;

Pascal Code 175 { Calculation of ,1 }

Procedure Deter; Begin dr: = Cos(a1 - b3) - Cos(a2 - b3) + Cos(a2) - Cos(a1 - b2) + Cos(a3 - b2) - Cos(a3); di : = Sin(a1 - b3) - Sin(a2 - b3) + Sin(a2) - Sin(a1 - b2) + Sin(a3 - b2) - Sin(a3) end;

{ Calculation of ,1P of p = ,1p--;-,1 }

Procedure Deterp; Begin drp: = r1 * (Cos(Th1 - b2) - Cos(Th1 - b3)) + r2 • (Cos(Th2 - b3) - Cos(Th2)) + r3 • (Cos(Th3) - Cos(Th3 - b2)); dip : = r1 * (Sin(Th1 - b2) - Sin(Th1 - b3)) + r2 * (Sin(Th2 - b3) - Sin(Th2)) + r3 * (Sin(Th3) - Sin(Th3 - b2)); end;

{ Calculation of -1. of s = '1.--:-'1 }

Procedure Deters; Begin drs : = r1 • (Cos(Th1 + a2) - Cos(Th1 + a3)) + r2 • (Cos(Th2 + a3) - Cos(Th2 + a 1)) + r3 • (Cos(Th3 + a1) - Cos(Th3 + a2)); dis : = r1 * (Sin(Th1 + a2) - Sin(Th1 + a3)) + r2 * (Sin(Th2 + a3) - Sin(Th2 + a1)) + r3 * (Sin(Th3 + a1) - Sin(Th3 + a2)); end;

{ Uses the results of the above three procedures and calculates P, the coupler length, S, the dyad length, gamma, the coupler angle, and beta1 the dyad angle at which the body position is reached. }

Procedure Solut; Var Dummy: Real;

Pascal Code 176 Begin Dummy:= Sqr(dr) + Sqr(di); srs : = ((drs • dr) + (dis • di)) / Dummy; sis:= ((dis• dr) - (drs • di))/ Dummy; srp: = ((drp • dr) + (dip • di))/ Dummy; sip:= ((dip* dr) - (drp • di))/ Dummy; end;

Begin Deter; Deterp; Deters; Solut; s : = Size(srs,sis); b1 : = Atan2(srs,sis); p : = Size(srp,sip); Gamma : = Atan2(srp,sip); a[Count,1] := r1*Cos(Th1) + p*Cos(Gamma + a1); b[Count,1] := a[Count,1] - s*Cos(b1); a[Count,2]: = r1*Sin(Th1) + P*Sin(Gamma + a1); b[Count,2] : = a[Count,2] - s*Sin(b1); end;

{ Input procedure. Allows the user to enter the body positions in polar coordinates. }

Overlay Procedure I nput_R_A_Th; Var x1 ,x2,x3,x4: Real; Ch : Char; Begin Repeat Clrscr; Writeln; Writeln(' Enter the Distances '); Write I n;I ndent(31 ); Write(' R 1 --- > '); Readrl(r1 ); I nde nt(31 ); Write(' R 2 --- > '); Readrl(r2);I ndent(31 ); Write(' R 3 --- > '); Readrl(r3); If Whatposition = 4 then Begin I ndent(31 ); Write(' R 4 --- > '); Readrl(r4); end; Writeln;Writeln;

Pascal Code 177 Writeln(' Enter the Following'); Writeln(' Angles in DEGREES'); Writeln;I ndent(31 ); Write(' Theta 1 ---> '); Readrl (x 1); I nde nt(31 ); Write(' Theta 2 --- > '); Readrl(x2);I ndent(31 ); Write(' Theta 3 --- > '); Readrl(x3); If Whatposition = 4 then Begin lndent(31 ); Write(' Theta 4 --- > '); Readrl(x4); Th4 : = Rad (x4); end; Writeln; Th1 : = Rad (x1); Th2 : = Rad (x2); Th3 : = Rad (x3); lndent(31); Write(' Alpha 1 --- > '); R eadrl (x 1); I ndent(31 ); Write(' Alpha 2 --- > '); Readrl(x2);I ndent(31 ); Write(' Alpha 3 --- > '); Readrl(x3); If Whatposition = 4 then Begin lndent(31 ); Write(' Alpha 4 ---> '); Readrl(x4); a4 : = Rad (x4); end; Write In; a1 : = Rad (x1); a2 : = Rad (x2); a3 : = Rad (x3); Write(' Are You Satisfied ? < Y/N > '); Repeat Read(kbd,Ch); Ch : = Upcase(Ch); until Ch in ['Y','N']; until Ch = 'Y'; end;

{ Input procedure. Allows the user to enter the body positions in rectangular coordinates. }

Pascal Code 178 Overlay Procedure lnput_Pos_A; Var I : Integer; x3,x4 : Real; Ch : Char;

Begin Repeat Clrscr; For I : = 1 to Whatposition Do Begin Write In; Writeln(' Enter Position ',i);Writeln; Write(' X --> '); Readrl(Body _Position[!, 1]); Write(' Y --> '); Readrl(Body_Position[l,2]); end; Writeln; Writeln(' Enter Angles Alpha '); Writeln;I ndent(31 ); Write(' Alpha 1 --- > '); R eadrl(x 1); I ndent(31 ); Write(' Alpha 2 --- > '); Readrl(x2); I ndent(31 ); Write(' Alpha 3 --- > '); Readrl(x3); If Whatposition = 4 then Begin lndent(31); Write(' Alpha 4 --- > '); Readrl(x4); a4 : = Rad (x4); r4 : = Size(Body_Position[4, 1],Body_Position[4,2]); Th4 : = Atan2(Body_Position[4, 1],Body_Position[4,2]); end; Writeln; Write(' Are You Satisfied ? '); Repeat Read(kbd,Ch); Ch : = Upcase(Ch); until Ch in ['Y','N']; until Ch = 'Y'; a1 := Rad (x1); a2 : = Rad (x2); a3 : = Rad (x3); r1 : = Size(Body_Position[1,1],Body_Position[1,2]); r2 : = Size(Body_Position[2, 1],Body_Position[2,2]); r3 : = Size(Body_Position[3, 1],Body _Position[3,2]); Th1 : = Atan2(Body_Position[1, 1],Body_Position[1,2]); Th2 : = Atan2(Body_Position[2, 1],Body_Position[2,2]);

Pascal Code 179 Th3 : = Atan2(Body_Position[3, 1],Body_Position[3,2]); end;

{ Once the body positions are entered in polar coordinates, the corresponding rectangular coordinates of the body positions are calculated. }

Overlay Procedure Find_Body_Positions(i : Integer); Begin Body_Position[1,1] := r1 • Cos(Th1); Body_Position[1,2] := r1 • Sin(Th1); Body Position[2, 1] : = r2 • Cos(Th2); Body_Position[2,2] : = r2 * Sin(Th2); Body _Position[3, 1] : = r3 * Cos(Th3); Body_Position[3,2] : = r3 • Sin(Th3); If i = 4 then Begin Body_Position[4, 1] : = r4 • Cos(Th4); Body_Position[4,2] : = r4 • Sin(Th4) end; end;

{ Allows the user to enter the range of the free choices as well as their increment }

Procedure Get_Range(i : lnteger;Var x1,x2,Deltax: Real); Var Ch: Char; Begin Repeat Clrscr; Write In; Write(' Enter Initial B',i,' ?---> '); Readrl(x1); x1 : = Rad(-x1); Write In; Write(' Enter Final B',i,' < DEGREES> ? ---> '); Readrl(x2); x2 : = Rad(-x2); Writeln; Write (' Enter Increment ? --- > '); Readrl(Deltax); Deltax : = Rad(-Deltax); GotoXY( 10,24); Write(' Are You Satisfied ? '); Repeat Read(kbd,Ch); Ch : = Upcase(Ch); until Ch in ['Y','N']; until Ch = 'Y';

Pascal Code 180 end;

{ Writes the menu in two different colors for easier understanding. }

Procedure Write_Menu(Mess : Typestring); Type String1 = String[17]; String2 = String[53]; Var st1 : String1; st2 : String2; Begin Textcolor(14); st1 : = Copy(Mess, 1, 17); Write(st1); st2 : = Copy(Mess, 18,53); Textco lor(3); Writeln(st2); Textcolor(14); end;

{ Calls the procedure to get the range of the free choices and also calls the procedure for the calculation of the dyads. Once the dyads are found, the procedure to display the dyads is called (four position synthesis). }

Overlay Procedure Range( d2,d3,d4,aa2,aa3,aa4 : Complex); Var x1 p,x1 ,x2,Deltax : Real; Dumm : Real; Begin Get_Range(2,x 1,x2,Deltax); Clrscr;GotoXY(25, 12); Write(' Calculating ... Please Wait '); Count:= O; x1p := x1; Repeat b2 := x1p; Ok:= True; Big_Delta( d2,d3,d4,aa2,aa3,aa4); If Ok then Begin Count:= Count + 1; ab2[Cou nt] : = Deg(-b2); Calculate;

Pascal Code 181 end; x1p:= x1p + Deltax; until x1p < x2; nn := 2 • Count; For Dumm : = 1 to Count Do Begin c[Dumm,1] := a[Dumm,1]; c[Dumm,2]: = a[Dumm,2]; c[Dumm+Count,1] := b[Dumm,1]; c[Dumm + Count,2] : = b[Dumm,2]; end; If Count > = 2 then Onepolygon end;

{ Lets the user choose in what coordinates to input the body positions and calls the desired input procedure. }

Overlay Procedure Input; Var Stringm : Typestring;

Begin Checks : = True; Clrscr;Choice; Stringm: = ' F1 Enter Positions in Rectangular Coordinates'; Write_Menu(Stringm); Writeln; Stringm: = ' F2 Enter Positions in Polar Coordinates'; Write_Menu(Stringm); Writeln; Writeln;Writeln; Stringm: = ' F10 Return'; Write_Menu(Stringm); Writeln;Arrow; Repeat Read(kbd,Ans) until Ord(Ans) in [59, 60, 68];

Clrscr; Case Ord(Ans) of 59: Begin lnput_Pos_A; end; 60: Begin lnput_R_A_Th; Find_Body_Positions(Whatposition); end;

Pascal Code 182 68 : Checks : = False end; If Checks and (Whatposition = 3) then Begin Clrscr; Gotoxy(5, 1O); Write('Enter Angle Beta 2 ---> '); Readrl(b2); b2 : = Rad(-b2) end; end;

{ The user is asked to enter the position of an arbitrary point on the coupler of a four-bar linkage on which the 5th bar will be connected to the coupler to form the six-bar linkage. The user must also enter the desired input timing for which the body quidance linkage is to be driven }

Overlay Procedure Six_Bar1; Var pp,aa,Dum1,Dum2,Dum3,Dum4 : Real; Begin Clrscr; GotoXY(1,5); Writeln(' Enter the pivot point relative to the first body position'); Writeln(' with respect to its local coordinate system '); GotoXY(1,8); Write(' X Coordinates ---> '); Readrl(Dum1); Write(' Y Coordinates ---> '); Readrl(Dum2); pp:= Size(Dum1,Dum2); aa: = Atan2(Dum1 ,Dum2); Body_Position[5,1]:=Body_Position[1,1] + pp•Cos(aa+a1); Body_Position[5,2]: = Body_Position[ 1,2] + pp·Sin(aa + a 1); r1: = Size(Body_Position[S, 1],Body_Position[S,2]); Th1: = Atan2(Body_Position[5, 1],Body_Position[5,2]); Dum3:=Body_Position[2,1] + pp·cos(aa+a2); Dum4: = Body_Position[2,2] + pp•Sin(aa + a2); r2: = Size(Dum3,Dum4); Th2: = Atan2(Dum3,Dum4); Dum3:=Body_Position[3,1] + pp•cos(aa+a3); Dum4: = Body _Position[3,2] + pp•Sin(aa + a3); r3: = Size(Dum3,Dum4); Th3: = Atan2(Dum3,Dum4); Writeln(' Enter the desired input timing angles '); Write In; Write(' Alpha 1 ---> ');Readrl(a1); a1 : = Rad(a1);

Pascal Code 183 Write(' Alpha 2 --- > ');Readrl(a2); a2 : = Rad(a2); Write(' Alpha 3 ---> ');Readrl(a3); a3: = Rad(a3); If Whatposition = 4 then Begin Dum3:=Body_Position[4,1] + pp*Cos(aa+a4); Dum4: = Body_Position[4,2] + pp*Sin(aa + a4); r4: = Size(Dum3,Dum4); Th4: = Atan2(Dum3,Dum4); Write(' Alpha 4 ---> ');Readrl(a4); a4: = Rad(a4); end; end;

{ Calls the necessary procedures to get the range of the free choices. The procedures for the calculation of the dyads are then called. Finally, the dyad display procedure is called (three position synthesis). }

Overlay Procedure Range_b3; Var x1p, Deltax, x1,x2 : Real; Dumm : Integer; Begin Get_Range(3,x1 .x2,Deltax); Clrscr;GotoXY(25, 12); Write(' Calculating ... Please Wait '); ab1 : = Deg(-b2); Count:= O; x1p:= x1; Repeat Count:= Count + 1; b3 : = x1 p; ab2[Count] : = Deg(-b3); Calculate; x1p:= x1p + Deltax; untilx1p < x2; n n : = 2 * Count; for Dumm : = 1 to Count Do Begin c[Dumm,1] := a[Dumm,1]; c[Dumm,2] : = a[Dumm,2]; c[Dumm+Count,1] := b[Dumm,1]; c[Dumm+Count,2] := b[Dumm,2]; end; If Count > = 2 then Onepolygon end;

Pascal Code 184 { Angle P2 is entered for the three position synthesis }

Procedure Enter_b2_3; Var x1 : Real; Begin Clrscr; GotoXY( 10, 15); Write('Enter Angle Beta_2 in DEGREES ---> '); Readrl(x1); b2 := Rad(-x1); end;

{ Initializes the necessary variables and controls the flow of the four-position synthesis }

Overlay Procedure Four_Position; Var d_2,d_3,d_4,a_2,a_3,a_ 4 : Complex; n : Integer; Stringm : Typestring; Task : Boolean; Begin Whatposition : = 4; Input; If Checks then Begin Reset_ v(True); Delta(d_2,d_3,d_ 4); Alpha(a_2,a_3,a_4); Task : = False; Repeat Pass1 : = True; Clrscr;Choice; Stringm : =' F1 Enter Range of 82'; Write_Menu(Stringm); Writeln;Writeln; Stringm : =' F10 Return'; Write_Menu(Stringm); Arrow; Repeat Read(kbd,Ans) until Ord(Ans) in [59,68]; Clrscr; Case Ord(Ans) of 59: Begin Range(d_2,d_3,d_ 4,a_2,a_3,a_ 4); If (Synthesis = 'D') and (not Pass1) then Begin Six_Bar1; Range(d_2,d_3,d_ 4,a_2,a_3,a_4); Reset_v(False);

Pascal Code 185 end; end; 68: Begin Clrscr; Task : = True; end; end; until Task; end; end;

{ Initializes the necessary variables and controls the flow of three position synthesis. }

Overlay Procedure Three_Position; Var Stringy : Typestring; Task : Boolean; Begin Whatposition : = 3; I:= 1; Input; If Checks then Begin Reset_ v(True); Clrscr; Task : = False; Repeat Pass1 : = True; Clrscr; Choice; Stringy:= ' Type --> F1 to Reinitialize ALL'; Write_Menu(Stringy);Writeln; Stringy : = ' Type -- > F2 to Enter New b2 '; Write_Menu(Stringy);Writeln; Stringy:= ' Type --> F3 to Enter Range of b3'; Write_Menu(Stringy);Writeln; Writeln;Writeln; Stringy:=' Type--> F10 Return'; Write_Menu(Stringy);Arrow; Repeat Read(kbd,Ans) until Ord(Ans) in [59,60,61,68]; Case Ord(Ans) of 59: Begin Input; Reset_v(True) end; 60:

Pascal Code 186 Enter_b2_3; 61 : Begin Range_b3; If (Synthesis = 'D') and (not Pass1) then Begin Six_Bar1; Enter _b2_3; Range_b3; Reset v(False) end; end; 68: Begin Task : = True; Clrscr end; end; until Task end; end;

Type Vil = Byte;

{ Checks the number of position synthesis and calls the appropriate routine. }

Overlay Procedure Burmester; Var Correcto : Boolean; Begin Correcto : = False; Repeat Clrscr; Choice; Stringx: = ' F1 Four Position Synthesis'; Write_Menu(Stringx);Writeln; Stringx : = ' F2 Three Position Synthesis'; Write_Menu(Stringx);Writeln; Writeln;Writeln; Stringx : = ' F10 Return '; Write_Menu (Stringx); Arrow; Repeat Read(kbd,Ans) until Ord(Ans) in [59,60,68); Case Ord(Ans) of 59: Begin Four_Position;

Pascal Code 187 end; 60: Begin Three Position; end; 68: Begin Correcto : = True; Clrscr; end; end; u nti I Correcto end;

{ Gives the user instructions of how to proceed and then calls the Burmester procedure. }

Overlay Procedure Path_Generation; Begin Clrscr; GotoXY(1,5); Textcolor(Red); C_Write(' ATTENTION'); Textcolor(Blue); GotoXY(1,8); C_Write('For this Synthesis you will also be asked for body position'); C_Write('and orientation'); Writeln; C_Write('lnstead of body orientation you have to enter the desired'); C_Write('input timing');Writeln; C_Write('Therefore when asked for angles ALPHA enter the desired'); C_Write('input link rotations'); GotoXY(5,22); Write('Press Any Key to Continue ');GotoXY(1, 1); Repeat until Keypressed; Burmester end;

{ Displays the program's main menu and allows the user to choose the desired synthesis }

Procedure Main_Menu; Begin Repeat Clrscr; Choice; Stringx: F1 Body Guidance '· = ' ' Write_Menu(Stringx);Writeln;

Pascal Code 188 Stringx : = ' F2 Path w/ Input Timing '; Write_Menu(Stringx);Writeln; Stringx : = ' F3 Function Generation '; Write_Menu(Stringx);Writeln; Stringx : = ' F4 Six Bar Linkage ,. ' Write_Menu(Stringx);Writeln; Writeln;Writeln; ,. Stringx : = ' F10 to QUIT ' Write_Menu(Stringx); Arrow; Repeat Read(kbd,Ans) until Ord(Ans) in [59,60,61,62,68]; Case Ord(Ans) of 59: Begin Synthesis : = 'A'; Burmester; end; 60: Begin Synthesis : = 'B'; Path_ Generation; end; 61 : Begin Synthesis : = 'C'; Fu net ion_Generation; end; 62: Begin Synthesis : = 'D'; Burmester; end; 68: Begin Quit_AII : = True; Clrscr end; end; until Quit_AII end;

Begin Choise_Over : = True; Branch : = True; Quit_AII : = False; Main_Menu end;.

Pascal Code 189 Appendix C

Procedures and Functions Used

All Pascal procedures and functions developed during the course of this research are listed below. Note that indented routines are simply local procedures to the previous non-indented one. Each of the procedures is followed by a brief description of what their function is.

1. Start_Program: Introduces the program and gives some instructions to the user.

2. Photo: Draws two body positions showing the different ways the input can be

entered.

a. Initialize: Initializes Graphics.

b. My_arc: Draws an arc of any radius from one angle to another.

c. Draw_position: 'Draws the necessary lines to form a body position.

Procedures and Functions Used 190 d. Write_the_text: Writes the necessary text on the screen.

3. Atan2: Computes the arc tangent using two parameters.

4. Acos: Calculates the arc cosine.

5. Print_Screen: It calls an interrupt routine to print the screen.

6. Pause: Pauses asking the user to press any key to continue.

7. WindowCoord: Sets up the window coordinates.

8. ViewCoord: Initializes variables required for the viewport.

9. SetViewport: Sets up a viewport.

10. WindowBox: Draws a box around the window.

11. DrawLine: Draws a line between two points.

12. DrawPoints: Draws polyline connecting a set of points.

13. Set_View_Coordinates: Sets up the view coordinates.

14. Draw_Square: Draws a filled square.

15. Draw_Square_Pivot: Draws a square with or without a cross within it, (Fixed and

moving pivots).

Procedures and Functions Used 191 16. Draw_Cross: Draws a cross.

17. Readrl: Reads a real number in order to avoid possible abortion of the program

in case of a user error.

18. Readint: Reads a integer number in order to avoid possible abortion of the pro-

gram in case of a user error.

19. Calc_D_Matrix: Calculates the transformation matrix.

20. Transform: Transforms a point into new coordinates according to transformation

matrix.

21. Calculate_angles: Calculates the output angles, given the length and position of

the input link.

22. Type_of_link: Given the linkage, determine the Grashof type as well as the angle

range of the input link.

a. Grashof: Checks whether the linkage obeys Grashot law.

b. Que_them: Rearranges the links in order of their magnitude.

c. Range_of_angles: Calculates the range of the input link ie., the minimum and

maximum angle of rotation of the input link.

· 23. Fill: Fills tile coupler link with hatched lines.

a. Magnitude: Calculates the distance between two points.

Procedures and Functions Used 192 b. Matrix_Operation: Solves a system of two equations in two unknowns.

24. Six_a: Given the dimensions of a six-bar linkage as well as the input angle cal-

culate the output angles. The solution is found using a Newton-Raphson iterative

technique and Cholesky's method.

a. Simultaneous_Solution: Solves a system of four equations in four unknowns

using Cholesky's method.

b. Set_Angles: Reinitializes angles whenever necessary in order to obtain a

solution in the same branch.

c. Newton_Raphson: Calculates angles using Newton-Raphson as well as

Cholesky's methods.

1) Calc_Functions: Calculates the functions at the specified angles.

2) Calc_Derivatives: Calculates the Jacobians at the specified angles.

d. New_Estimate: Calculates a new estimate of angles once the Jacobian sys-

tem is solved.

25. Linkage: It is the main graphics routine of the code. It animates the four-bar

linkage and displays the coupler curve. Also the linkage can be driven in any

direction with input angle step size specified by the user.

a. Clean: Clears the dialog.

Procedures and Functions Used 193 b. Print_the_Screen: Sets up for the Print_Screen call.

c. Wait_it: Echoes "wait" to the user.

d. New Coard: Finds maximum and minimum points and calls

Set-- View Coordinates to set view coordinates.

e. lnitialize_Link: Initializes graphics.

f. Draw_it: Draws the linkage, the fixed pivots and the body positions.

g. Erase_Base: Erases the fixed pivots.

h. Write_Angles: Writes the value of each link angle in a specified window.

i. Write_Menu: Writes the menu in a specified window.

j. Draw_Wait: Draws the linkage and echoes "wait" to the user until the drawing

is finished.

k. Write_Specifications: Linkage specifications are written on the screen.

I. Start_link: Calls type_of_linkage routine to determine the linkage Grashot

type.

m. lnitial_Drawing: Draws the linkage in its initial position.

n. Clockwise: Turns the input link clockwise an angular increment specified by

the user.

Procedures and Functions Used 194 o. Counterclockwise: Turns the input link counterclockwise an angular incre-

ment specified by the user.

p. Set_Theta_2: Assigns a new value to the input link angle and draws the link-

age at this position.

q. Set_Delta_Theta: Assigns a new value to the angular increment of the input

link angle.

r. Coupler: Animates and draws the coupler curve.

1) Write_Mess_C: Writes the animation message in a specified window.

2) Draw_the_Curve: Draws the coupler curve.

3) Draw_anim: Animates the four-bar linkage.

s. Interactive: Generates interaction ie., lets the user animate and rotate a link-

age, and if desired print the screen interactively.

26. Function_Generation: Calculates a linkage to satisfy a certain function. The

functions implemented are: exponential, logarithmic, natural logarithmic, cosine,

tangent and sine.

a. Chebyshev: Calculates the precision points using Chebyshev spacing.

b. Rad: Converts degrees to radians.

c. Choice: Creates the heading of a choice menu.

Procedures and Functions Used 195 d. Write_menu: Writes tt,e menu in a specified window.

e. Enter_Data: Gets required data from the user.

f. Natural: Calculates the function parameters Y, ... Y4 for a natural logarithm

function.

g. Exponential: Cal cu Iates the function parameters Y1 ... Y4 for an exponential

function.

h. Sine: Calculates the function parameters Y1 ... Y4 for a sine function.

i. Cosine: Calculates the function parameters Y1 ... Y4 for a cosine function.

j. Tangent: Calculates the function parameters Y1 ••• Y4 for a tangent function.

k. Common: Calculates the function parameters Y1 ... Y4 for a common logarithm

function.

I. Calculate_Omegas: Calculates dummy variables w1 ••• w6 • See section 5.2.

m. Calculate_rs: Calculates dummy variables R, ... R3 • See section 5.2.

n. Calculate_Link_Lengths: Calculates the length of the links.

o. Calulate_angles: Calculates the input and output angles at the already calcu-

lated precision points.

Procedures and Functions Used 196 p. Choose_Function: Shows on the screen the function menu and lets the user

choose the desired function.

q. Write_Results: Writes the synthesized linkage specifications.

27. Cognates: Using Cayley's diagram and Robert-Chebyshev theorem tt1e cognates

of a given linkage are found. Those cognates and their properties are displayed

on the screen and the user has to choose one of the two possible cognates to

be the mechanism that will satisfy the path generation with input timing problem.

a. Calculate_Lengths: Calculates the length of the links required to construct the

Cayley's diagram.

b. Calculate_Points: Calculates the required points for the construction of

Cayley's diagram.

c. lnitial_graphics: Initializes graphics.

d. Print_the_Screen: Sets up the screen to be printed.

e. Function_keys_ 1: Writes out the menu and it waits for input.

1) Write_key_m: Writes the menu in a specified window.

f. lnitialize_C: Sets up graphics, windows and view coordinates for Cayley's

diagram.

g. Fill_the_Coupler_C: Calculates the end points of the coupler to be filled.

Procedures and Functions Used 197 h. Roberts: Calculates points necessary for the construction of Robert's dia-

gram.

i. Fill_the_coupler_R: Calculates the end points of the coupler to be filled.

j. Draw_Cayleys: Draws Cayley's diagram.

k. Draw_Roberts: Draws Roberts-Chebyshev diagram.

I. Set_Up_R: Sets up graphics, windows and view coordinates for Robert's dia-

gram.

m. Write_Headings: Writes figure headings on the screen.

n. Write_Results: Writes out the kind of generated linkages and their dimensions

and lets the user choose the desired linkage.

1) Write_the_Results: Displays the results on the screen.

2) Function_Keys_2: Displays menu , lets the user choose one of the cog-

nates, assigns values to the required variables and calls the animation

program.

a) Choose: Allows the user to choose the desired mechanism, assigns

values to some variables and calls the animation program.

b) Write_Key_m: Writes the menu in a specified window.

Procedures and Functions Used 198 o. Start: Calculates link lengths, angles of the coupler link and it checks whether

the coupler point is above, below or in line with respect to the other coupler

link joints.

1) Angle: Calculate the angles of the coupler link.

2) Size: Calculates the link lengths of the original four bar linkage.

p. Write_Sp: Displays the original linkage specifications.

q. On_Line: Calculates cognates, sets up coordinates and draws the cognates

for the case when three joints of the coupler link are in line.

1) Link Size: Calculates the link size.

2) Calc_Points: Calculates the necessary points to draw the cognates.

3) Intercept: Given the slopes of two lines and a point on each line calculate

the point of intercection.

4) Calc_Lengths: Calls Link_Size to calculate the length of the links of the

cognates.

5) Draw_it: Draws the cognates.

r. Initialize: Sets up the color, and calls for the calculation of the transformation

matrix.

Procedures and Functions Used 199 28. Linkage_6: Animates the chosen six-bar linkage and displays the coupler curve

when the animation is finished. It also allows the user to rotate the input link

stepwise in any direction.

a. Clean: Clears the dialog.

b. Print_the_Screen: Clears the dialog area and calls the Print_Screen routine.

c. Wait_it: Echoes "wait" to the user.

d. New_Coord: Finds maximum and minimum points and calls

Set-- View Coordinates to set view coordinates.

e. lnitialize_Link: Initializes graphics.

f. Draw_it: Draws the linkage, with fixed pivots and the body positions in a

specified window.

g. Write_Angles: Writes the value of each link angle in a specified window.

h. Write_Menu: Writes the menu in a specified window.

i. Draw_Wait: Draws the linkage and dispays a wait message on the screen

until the construction of the drawing is over.

j. Write_Specifications: Linkage specifications are written on the screen.

k. Link_Size: Given the moving and fixed pivot of a dyad, the length of the link

is cal cu lated.

Procedures and Functions Used 200 I. Angle: Calculates the angle between two links.

m. Get_C: Calculates the distance and angle of the tracing point relative to the

other joints of the coupler.

n. Start link: Calls type_of_link routine to determine the Grashof type of the

linkage.

o. lnitial_Drawing: Draws the linkage in its initial position.

p. Clockwise: Turns the input link clockwise a specified angular increment.

q. Counterclockwise: Turns the input link counterclockwise a specified angular

increment.

r. Set_Theta_2: Assigns a new value to the input link angle and draws the link-

age in this position.

s. Coupler: Animates and draws the coupler curve.

1) Write_Mess_C: Writes the animation message in a specified window.

2) Oraw_the_Curve: Draws the coupler curve.

3) Draw_anim: Animates the four-bar linkage.

t. Interactive: Generates interaction ie., lets the user animate, rotate, print the

screen and display the coupler curve interactively.

Procedures and Functions Used 201 29. Onepolygon: Displays the dyads passed to it and allows the user to choose two

of those dyads for the synthesis of a four-bar linkage or three dyads for the syn-

thesis of a six-bar linkage. After the required dyads are chosen a call is made to

the animation procedure to check for possible linkage defects.

a. Print_the_Screen: Sets up the screen for a hard copy.

b. Initialize: Sets up window coordinates and view coordinates.

c. Draw_Links: Displays the dyads and the body positions in a specified window.

d. W_Pivot: Writes in a specified window the X and Y coordinates of the moving

and fixed pivots of each dyad.

e. Result: Writes the headings and calls W_Pivot.

f. Clear_Dialog: Clears out the dialog window.

g. Ch_Dyads: Allows the user to choose the desired dyad for the formation of a

six-bar linkage.

1) Intercept: Given the slopes of two lines and a point on each line, calculate

their intercection.

h. Choose_Dyad: Allows the user to choose the desired dyads for a four-bar

linkage. It makes the necessary assignments and calls the required proce-

dures ie., cognates for path generation with input timing or the animation

routine for body guidance problem.

Procedures and Functions Used 202 1) Assign_Linkage: Calculates the coupler angle and coupler length and it

makes the necessary assignments.

2) Link_Size: Calculates the size of a link.

3) Enter_Choice: Lets the user choose the desired dyads.

4) Calculate: Once the dyads are chosen the necessary calculations are

made to "assemble" the link in the branch in which is able to reach the

first body position.

a) Cale_ Th: Calculates the angle between two dyads.

5) Call_Cognates: Calls the Cognate procedure if the synthesis is path gen-

eration with input timing.

i. See_linkage: Calls the animation procedure after it checks that enough dyads

have been chosen.

j. Write_Key_M: Displays the function key menu.

k. Start: Initializes the procedure.

I. Function_Keys_ 1: Utilization of the PF keys for a body guidance problem.

m. Function_Keys_2: Utilization of the PF keys for a path generation with input

timing problem.

Procedures and Functions Used 203 n. Choose_Synthesis: The required synthesis is chosen and the corresponding

routine is called.

30. CM: Complex number multiplication.

31. CA: Complex number addition.

32. CS: Complex number subtraction.

33. CD: Complex number division.

34. Indent: Indents the cursor X spaces from the first column.

35. Reset_V: Reassigns the values of body positions and orientation.

36. C_Write: Centers the text written on the screen.

37. Size: Given the two components of a vector, its size is calculated.

38. Delta: Calculates the complex numbers D2 ... D4 (See Appendix C).

39. Alpha: Calculates the complex numbers A2 ... A4 (See Appendix C).

40. Calc_b4_b3: Calculates angles b4 and b3 (See Appendix C).

41. A_B_C: Calculates intermediate results and then calls for the calculation of the

angles b3 and b4•

42. Big_Delta: Calculates the complex numbers d2, d3 and d4 (see Appendix C).

Procedures and Functions Used 204 43. Calculate: Solves the system of equations (eq. A 1.5) using Cramer"s rule.

a. Deter: Calculation of L\

L\p b. DeterP: Calculation of L\P of p -- L\

L\. C. Deters: Cal cu lat ion of L\. of s -- L\

d. Solut: Uses the results of the above three procedures and calculates the

coupler length P, the dyad lenght S, the coupler angle y, and the dyad angle

at the first body position is reached fi 1•

44. lnput_R_A_Th: Input procedure. Allows the user enter the body positions in polar

coordinates.

45. lnput_Pos_A: Input procedure. Allows the user to enter the body positions in

rectangular coordinates.

46. Find_Body_Position: Once the body positions are entered in polar coordinates,

the corresponding rectangular coordinates of the body positions are calculated.

47. Get_Range: Allows the user enter the range of the free choices as well as their

increment.

48. Write_Menu: Writes the menu in two different colors for easier understanding.

Procedures and Functions Used 205 49. Range: Calls the procedure to get the range of the free choices and also calls the

procedure for the calculation of the dyads. Once the dyads are found, the pro-

cedure to display the dyads is called (four position synthesis).

50. Input: Lets the user choose in what coordinates to input the body positions and

calls the desire input procedure.

51. Six_Bar1: The user is asked to enter the position of an arbitrary point on the

coupler of a four-bar linkage on which the 5th bar will be connected to the coupler

to form a six-bar linkage. The user must also enter the desired input timing for

which the body guidance linkage is to be driven.

52. Range_b3: Calls the necessary procedures to get the range of free choices. The

procedures for the calculation of the dyads are then called. Finally the dyad dis-

play procedure is called (three position synthesis).

53. Enter_b2_3: Angle /3 2 is entered for the three position synthesis.

54. Four_Position: Initializes the necessary variables and controls the flow of the four

position synthesis.

55. Three_Position: Initializes the necessary variables and controls the flow of three

position synthesis.

56. Burmester: Checks the number of position synthesis and calls the appropriate

routine.

Procedures and Functions Used 206 57. Path_Generation: Gives the user instructions how to proceed and then calls the

Burmester procedure.

58. Main_Menu: Displays the program's main menu and allows the user to choose

the desired synthesis.

Procedures and Functions Used 207 The vita has been removed from the scanned document