Assignment 5 - Computational Linkage Design

Due Sunday 10/29 at 11:59 pm. You must work individually.


A linkage is an assembly of bodies connected to manage forces and movement. In this assignment you will design some interesting linkages, which can be physically manufactured. We will be only looking at kinematics and ignore forces, and furthermore, we will limit ourselves to 2D planar structures with revolute joints. Provided with this assignment is a fully functional Matlab code for simulating linkages.

Here are some sample linkages.

Image source: Wikipedia. s = smallest link length; l = longest link length; p, q = other two lengths.

In this assignment you will be responsible for:

  1. Adding tracer particles for display.
  2. Modifying the code to allow oscillatory driver input (instead of rotational).
  3. Designing several other linkages.
  4. Adding support for slider mechanisms.

Running the Code

Download the Matlab base code. The provided code is standalone and does not require any external libraries. Copy or move linkages.m to WORKINGDIR. Then open Matlab, go to the command window, and type:

>> linkages(0)

Matlab will then open a figure window that shows the simulation of the sample linkage. The pin constraint between the right and top links is randomized, so if you run the code multiple times, you will get a slightly different mechanism each time. The argument 0 specifies the scene to run, which in this case is a crank-rocker mechanism. Each new linkage mechanism that you create should have a new scene number.

Note: You will also need the Optimization Toolbox, which should be available from TAMU through whatever link you used to obtain Matlab.

How to Create Scenes

A link defined by its orientation, \theta (a scalar), and position, p (2D vector).

To create a scene, we need a list of links and a list of constraints between the links. These are called links and pins in the code. Scene creation is done inside the switch statement at the top of the code. The sample four-bar linkage scene is defined in case 0.

A link is modeled as a rigid body, and in 2D, it has three degrees of freedom: \theta \in R and p \in R^2 (see figure above). \theta specifies the orientation of the link with respect to the positive x-axis, and p specifies the position of the center of rotation. Given a 2D point, r, in the link's local coordinates, the world coordinates of that point can be computed as

x = R(\theta) \, r + p,

where R is the 2x2 rotation matrix given by

R = \begin{pmatrix} \cos \theta & -\sin \theta\\ \sin \theta & \cos \theta \end{pmatrix}.

For example, the following code creates a horizontal link at the origin.

links(1).angle = 0;
links(1).pos = [0,0]';

The kinematics of a link is fully expressed using \theta and p. In order to draw it on screen, however, we need to give it a mesh. In this assignment, we simply assign to each link a list of vertices expressed in the link's local coordinates and transform these vertices into world coordinates whenever we move the link. Note that the mesh is for display only--the simulation would work just fine even if we do not have a mesh. To specify the vertices, we write to the verts field of the link object. For example,

links(1).verts = [
    -1.0  21.0  21.0 -1.0
    -1.0  -1.0   1.0  1.0

would define four vertices

\begin{pmatrix}-1.0\\-1.0\end{pmatrix}, \quad \begin{pmatrix}21.0\\-1.0\end{pmatrix}, \quad \begin{pmatrix}21.0\\1.0\end{pmatrix}, \quad \begin{pmatrix}-1.0\\1.0\end{pmatrix}.

In other words, these vectors are stored column wise in the links(1).verts matrix. Note that these four vertices need not be centered with respect to the origin of the link's frame. Since the mesh is not used for the simulation but only for the display, we can place the mesh anywhere with respect to the frame (or conversely the frame with respect to the mesh). Also note that we don't need to use rectangular shapes, as illustrated by the top link. You can add more vertices to create any shape you like.

Additionally, we specify that:

  1. One of the links is grounded, meaning that it cannot move. This link is shown in red.
  2. Another link is the driver, meaning that its orientation and position are specified procedurally. This link is shown in green.

For example,

grounded = 1;
driver = 2;

specifies that links(1) is grounded, and links(2) is the driver. You can set the motion of the driver to be anything. However, for this assignment, only rotational (or oscillatory) motion is needed. The easiest way to achieve this is to set the location of the pin constraint (described below) between the driver link and the grounded link to be at the origin of the driver link, and then specifying just the rotation of the driver link, keeping the position of the driver link fixed.

Pin Constraints

A pin between two links. The locations r_A and r_B (2D vectors)
define where the pin location is with respect to the links.

A "pin" constrains two links with a revolute joint. It stores the indices of the two links to constrain as well as where on the two links the pin constraint is located. See r_A and r_B in the figure above. The constraint should then make sure that, if r_A and r_B are transformed to world space, their locations match.

The following code creates a pin between links(1) and links(2) as shown in the figure above.

pins(1).linkA = 1;
pins(1).linkB = 2;
pins(1).pointA = [4,0]';
pins(1).pointB = [-4,0]';

In this case,

r_A = \begin{pmatrix}4\\0\end{pmatrix}, \quad r_B = \begin{pmatrix}-4\\0\end{pmatrix}.

HINT: When creating scenes, the links do not need to be precisely positioned, since they will snap to configurations that satisfy all the constraints, as long as those constraints are satisfiable.


To accentuate the interesting motions of linkages, we can add tracer particles to the links (like the green lines in the 1st figure). The following code creates a particle.

particles(1).link = 4;
particles(1).point = [0.5,0.1]';

The link field specifies the parent link, and the point field specifies where on this parent link the particle is located (expressed in the parent link's coordinates).

How the Simulation Works

NOTE: This section is optional, but may be needed for designing slider joints (extra credit for 489, required for 689).

After the scene creation process finishes, we have a list of links, pins, and particles. The simulator then takes this information and does the following:

while simulating
    1. Procedurally set the driver angle
    2. Solve for linkage orientations and positions
    3. Update particle positions
    4. Draw scene

In Step 1, we manually specify the target angle of the driver link. As long as the mechanism has a single degree of freedom, the orientations and the positions of the rest of links can be solved for in Step 2 using nonlinear least squares. In Step 3, we compute the world positions of the particles given the newly updated link configurations. Finally, in Step 4, we draw the scene on the screen.

The meat of the simulator is in Step 2. The optimization variables in the nonlinear least squares problem are the orientations, \theta, and positions, p, of all the links, including grounded and driver links. We will use q_i = (\theta_i,p_i)^T to denote the configuration of the ith link. We are looking for q_1,\cdots,q_n so that all of the constraints are satisfied. There are two types of constraints implemented so far: "prescribed" and "pin". In both cases, we’ll express the constraint in the form c(q) = 0. This is a vector function--c is a concatenation of all the constraints added to the system.


Grounded and driver links have their configurations manually specified. We can express this as a constraint on the orientation \theta and the position p of the link.

c_\theta(q) = \theta - \theta_{{target}}, \quad c_p(q) = p - p_{{target}}.

Here, c_\theta(q) is a scalar, and c_p(q) is a 2D vector. (Thus, with these two constraints, c(q) is a 3x1 vector.) For grounded links, the target orientation and position are fixed throughout the simulation (i.e., \theta_{{target}} is fixed), whereas for driver links, they are specified procedurally (i.e., \theta_{{target}} changes over time).


A pin constrains two links so that they share a common point. Let the two links be denoted by A and B. We can express the constraint as

c_{{pin}}(q) = x_A - x_B,

where x_A and x_B are both in world coordinates, which must be computed from the local coordinates, r_A and r_B. In other words, we are looking for orientations and positions of the two links such that this constraint function evaluates to zero. The orientations and positions of the two links, \theta and p, are the variables of this constraint function, whereas the locations of the pin joints expressed in local coordinates, r_A and r_B, are the parameters of this constraint function.


Let \vec{c}(\vec{q}) be the concatenation of all the constraints. We are looking for the orientations and positions of all the joints (\theta_i and p_i) such that the constraint violations are minimized:

\underset{\vec{q}}{\text{minimize}} \quad \frac{1}{2} \vec{c}^T \vec{c}.

We can solve this easily in Matlab using the function lsqnonlin. What we need to provide is a function that evaluates the vector-valued function \vec{c}. This is implemented in the function objFun(...) in the code. In this function, each scalar element of \vec{c} must be evaluated using the current angles and positions of the links, which is \vec{q} = (q_1,\cdots,q_n)^T = (\theta_1, p_1, \cdots, \theta_n, p_n)^T.

The optimization process can be sped up by providing the derivatives of \vec{c}, called the Jacobian, J = \frac{\partial \vec{c}}{\partial \vec{q}}. The "ground/driver" constraint and the "pin" constraint have the Jacobians implemented. You can turn on/off these Jacobians by changing the arguments to optimoptions().

Your Tasks

A sample scene with a slider constraint. Your scene should be more complex.


For a grade of B, you must finish:

For a grade of A, you must also finish:

What to hand in

Please follow these instructions carefully. If you fail to follow these instructions, you will be docked some points.

Please provide a report with your submission (PDF). The report should include the following:

Create a zip file named NETID.zip (your email ID; e.g., sueda.zip) so that when you extract it, it creates a folder called NETID/ (e.g., sueda/) that has (ONLY) the following in it:

Generated on Wed Oct 25 09:52:42 CDT 2017