Play (Planar Linkage AnalYser) has been my pet project since engineering days. The current version accepts linkage data in text files and shows the schematic linkage in motion.
I should mention that people not familiar with the concepts of loops and linkages (from basic Kinematics courses) will probably find it difficult to understand the program. Making the program user friendly and adding a nice GUI is one of my long term goals in life. ;-)
Here are two screenshots:
Wiper mechanism found in older BEST buses
Automatic forging hammer (inverted)
Download the source and untar it.
In addition to the main program files, there are 3 subdirectories.
"houdini/" contains the Windows graphics library being used. "CVCanvas/"
contains the Linux classes which emulate the houdini classes. The
"linkages/" directory contains the example linkage files.
Before starting, make sure that the correct OS macro is defined in "playos.h".
# cplay linkagefile
On Windows: Open the workspace file "Play2.dsw" in
Visual Studio and build. You may need to set some directories etc.
qt is required to build for Linux. (I have worked with qt-2.3.1). The
makefiles assume that the environment variable QTDIR is set and also the
qt bin directory is in the path.
Running "make" should give you the executable "cplay". If you encounter
any problems let me know.
The parameter is essential. Crashes otherwise.
Pressing 'a' in the graphics window advances the linkage by one step. Keep it pressed for a continuous animation.
Designing mechanical machines involves study and experimentation with interconnected moving parts. The functionality
of the machine is usually derived from shapes of the moving parts. eg. Consider a mechanical forging hammer. It is driven by a motor and some mechanism converts the rotary motion into hammering action. To design such a machine the engineer needs to experiment with variables such as lengths, velocities, accelerations and shapes of various parts at different configurations.
This project is intended to simulate mechanisms. Such a collection of interconnected moving parts is called a linkage. In the mathematical analysis of a linkage, the concept of loops and links are introduced. To obtain the various parameters at a particular configuration, the linkage is "solved".
# cplay linkages/wipermech.txt
# cplay linkages/hammermech.txt
The user defines the loop by specifying the following:
Link: A link designates a rigid mechanical part.
Loop: When several links are movably connected
together by joints, they are said to form a kinematic chain. If every link in
a chain is connected to atleast two other links, it is said to form a loop.
Linkage: One or many interconnected loops having 'n'
links common between them form a linkages.
Types of Links : Link is defined by its length and angle with respect to some reference line. A Link can vary its length, angle, both or none.
All the links invloved in the linkage have two properties each (its length and angle). Out of these some are constants and remaining are variable.
The user has to give the exact values of these constant attributes to define the linkage and approximate values of the variable attributes which will define the unique configuration of the linkage in a 2D plane.
The number of dependent variables in a linkage is always twice the number of loops.
All input files are text files.
The format is specified below in printf format specifier terms.
Explanatory comments appear in parantheses (...)
Number of loops.
For each loop number of links, their type, and the way they are connected to form the loop.
The linkage file has the following format.
%d (Number of loops)
%d (Number of links in loop 0)
%d %d %d %c %s %d %d %d (Link 0)
%d %d %d %c default (Link 1)
%d %d %d %c %s %d %d %d (Link 2)
%d (Number of links in loop 1)
%d %d %d (Link 0)
%d %d %d %c %s %d %d %d (Link 1)
%d %d %d %c %s %d %d %d (Link 2)
%d %d %d %c %s %d %d %d (Link 3)
All lines that do not start with a digit are ignored.
Remember that sscanf(3) is being used to read the values.
Number of loops should be a positive integer. There is no error checking, so a negative value might crash the program.
Number of links in a loop should be a positive integer.
There are 2 types of links from the input point of view.
"New" links and "Ref" links. A link which has not been specified yet is a new
link. A ref link is actually a place holder for another link which has already
been specified in an earlier loop. (Remember that loops can, and mostly do, have links in common). This common link is the "ref" link.
For new links:
Take a look at Link 0 of Loop 0 in the above format specification.
The first number is 0 (zero) for a "new" link
(i.e. a link which has not been specified yet). A number other than 0
implies this is a "ref" link. Ref links can only be specified in the
second way (see below).
The second number is the length of the link
The third number is the angle in degrees of the
link vector. Standard co-ordinates are used. Horizontal right is zero
degrees, Vertical up is 90 degrees.
The fourth input is a character, which can be F, A, L or B.
'F' indicates a fixed link.
'A' indicates that the angle of this link
vector is variable.
'L' indicates that the length of this link
vector is variable.
'B' indicates that both angle and length for this link vector are variable.
The fifth input is a string specifying a shape
file for this link. The shape file must be present in the same directory
as the linkage file.
The next three numbers indicate the x, y, and theta offsets of the shape with respect to the centre of the link vector.
See Link 1 of Loop 0 above. The first
four inputs have the same meaning as mentioned above. But if the fifth input
is "default", it means there is no shape file associated with this link and
the default shape (a line) will be drawn for this link.
For ref links:
Take a look at Link 0 of Loop 1 in the above format specification.
The first number is 1 (not 0), indicating its a
The second and third inputs are numbers
indicating the loop number and the link number of the link vector being
The fourth input is a character. If it is 'R' or 'r', it implies the direction of this link vector is reverse compared to the link it is referring to. Any other character implies same direction.
Input links are those whose variable components are incremented in the animation.
Presently, only one input link is allowed. It must always be the first link of the
first loop (See the 'vc' struct in main.cpp). It must also be a vector with
variable angle only. (In other words, we are only looking at linkages driven
by a rotary prime mover. eg: electric motor)
Now, take a look at the file "wipermech.txt" in the linkages/ directory. This is a linkage file illustrating the old style wiper
mechanism which existed in BEST buses. It has two loops, each containg four
links. All except the third links of each loop have default shapes. Note that
the shape file "wiper.txt" has been reused. Also note that the first link of
the second loop is a ref link. It refers to link 0 in loop 0. The direction
character is 'S' (not 'R') which means it is in the same direction. Study each
parameter and make sure you understand it. Run the program and see "wipermech"
in the initial position. Corelate the links drawn to the values of the lengths
and angles in the input file. Also note the "wiper" shapes and default line
Currently there are only four kinds of shapes. Rectangle, Line, Circle and Composite.
The shape is defined by the first character of the file. 'R' for rectangle, 'L' for line, 'C' for circle and 'X' for composite. Lower case letters are also OK.
The other characters in the first line are ignored.
The next line gives details about the shape.
For a rectangle, two numbers indicating length and
For a line, a number indicating length.
For a circle, a number indicating radius.
A composite is basically a collection of these 3 primitive shapes. After the first line, the file contains specifications for these shapelets, one on each line.
A shapelet line is of the form:
%s %d %d %d
The first input is a valid shape file name. (note
possible infinite recursion)
The next three numbers indicate the x, y, and theta offsets of the shapelet with respect to the centre of the shape.
Note that there are no comment lines in a shape file.
Now take a look at "wiper.txt".
Its a composite shape file with 4 shapelets. Note that "hinge.txt" is reused.
Open the files "stick.txt", "hinge.txt" etc and try to make sense of the
The Linkage object is a container of Loop objects.
The Loop object in turn is a container of Link objects.
Design (Classes and Relationships)
Each Link object has a Shape object associated with it.
Shape is an abstract class and some of its child classes are Line, Rectangle, Circle, CompositeShape.
CompositeShape object is composed of one or more Shape objects.
Due to this inheritence and polymorphism, any Shape object can be associated with a Link object at run time.
Taking the input for the Links, Shapes, Loops and Linkage from the user can be done in many ways such as text file input or a GUI based input. An abstract class LinkageCreator is defined which create a Linkage object. Two classes are derived from this, viz.
FLinkageCreator - all the user input is through text files. The job of FLinkageCreator is to read and parse the text files and create Links, Loops, Linkages, Shapes. Add Links to Loops, Loops to Linkage, associate Links to Shapes.
GUILinkageCreator- provides GUI based user input. (not implemented)
Once the Linkage is created, user should be able to solve the Linkage for any input parameters. For this, an abstract class LinkageSolver is provided, whose job is to take input parameters from the user and solve the Linkage.
Again, two classes are derived from it viz.,FLinkageSolver and GUILinkageSolver for taking user input from file and GUI respectively.
Outputing all the Linkage parameters in text mode or graphical mode is achieved by TextOutput and LGraphicsOutput (abstract class) respectively. LGraphicsOutput has some methods for drawing basic shapes like Line, Rectangle, Circle. A class LCanvas inherits from LGraphicsOutput and hoCadCanvas(houdini). hoCadCanvas is the platform dependent class providing the actual drawing functionality and the methods in the LGraphicsOutput act as wrappers for these methods.
The Linkage has the responsibility of solving itself for which it requires matrix maipulation. Hence a Matrix class (thanks Amit) is used as a utility for this purpose which takes care of all the required matrix manipulation functions.
First wrote a linkage simulator in 1996 (I think). In DOS, using Turbo C++
3.0. Based on the algorithm given in "Kinematics of mechanisms" - Shigley. Have lost the code due to hard disk crashes.
Initially it was thought that the Linkage class
should only deal with solving for different inputs and that Linkage object
should be passed to an Output class which can use the data in the Linkage
to give output in differenet formats such as graphical or text based
output. In other words, the Linkage class would not have any Write() or
We have used arrays of pointers for dynamic
storage of Links and Loops. This data structure was found to be unwieldly
to handle for getting the data from deep within the links. So we have a
draw function method in all Linkage , Loop and Link classes. The elegant
and clean way to achieve this was to use standard C++ containers.
During the initial class design, enough thought
was not given to the implementation of solving the Linkage. While
implementing it was found that it could have been a cleaner approach to
use additional utility classes like DependentVariable class, InputVariable
class etc. Presently these concepts are implemented as structures.
Extensibility for graphical output is provided through the abstract class GraphicsOutput which acts as interface
for primitive drawing methods.
Rewrote the entire thing as a C++ project while doing PGDST at NCST. (May
2000). Used the houdini library provided by an instructor at NCST.
In May-June 2002, did the Linux port using qt.
Input links. Should be properly specifiable. Should be multiple. (Reciprocating?)
Scaling. Currently everything is in pixel units.
Output data to file.
GUI input for linkage specification.
Rewrite using "good" C++ (remove mallocs, use STL
Invert the co-ordinate system so user can specify in first quadrant.
Back to personal home