Four Bar Linkage

We will simulate a four bar linkage and introduce the command for handling kinematic loops like this. The system will move in the x-z-plane, thus the revolute joints all rotate around the y-axis of the world. If you want to try it first, or look at the complete source code, see fourbar_linkage.py.

As usual, we start with importing PyMbs, creating a model system and adding various parameters. Here, they are the lengths, masses and interiae of the bars to be connected:

from pymbs.input import MbsSystem, diag, pi

world = MbsSystem([0, 0, -1])

# Parameter
l1 = world.addParam('l1', 1)
...

Now we create our additional three bars (world will act as the first bar) and add the coordinate systems A through D at the corners:

m2 = world.addParam('m2', 1)
l2 = world.addParam('l2', 4)
I2 = world.addParam('I2', m2 / 12 * l2**2)

m3 = world.addParam('m3', 1)
l3 = world.addParam('l3', 4)
I3 = world.addParam('I3', m3 / 12 * l3**2)

m4 = world.addParam('m4', 1)
l4 = world.addParam('l4', 5)
I4 = world.addParam('I4', m4 / 12 * l4**2)

# Create bodies with coordinate systems
world.addFrame(name='CS_A')
world.addFrame(name='CS_D', p=[l1, 0, 0])

bar2 = world.addBody(name='Bar2', mass=m2, cg=[l2 / 2, 0, 0],
                     inertia=diag([0, I2, I2]))
bar2.addFrame(name='CS_A')
bar2.addFrame(name='CS_B', p=[l2, 0, 0])

bar3 = world.addBody(name='Bar3', mass=m3, cg=[l3 / 2, 0, 0],
                     inertia=diag([0, I3, I3]))
bar3.addFrame(name='CS_B')
bar3.addFrame(name='CS_C', p=[l3, 0, 0])

bar4 = world.addBody(name='Bar4', mass=m4, cg=[l4 / 2, 0, 0],
                     inertia=diag([0, I4, I4]))
bar4.addFrame(name='CS_D')
bar4.addFrame(name='CS_C', p=[l4, 0, 0])

Then we can connect three of them using regular revolute joints:

jA = world.addJoint(world.CS_A, bar2.CS_A, 'Ry', pi / 2)
jB = world.addJoint(bar2.CS_B, bar3.CS_B, 'Ry')
jD = world.addJoint(world.CS_D, bar4.CS_D, 'Ry')

However, the last one (here its C) has to be connected using the command addLoop.FourBar to correctly handle the kinematic loop:

world.addLoop.FourBar(bar3.CS_C, bar4.CS_C, posture=1)

With the posture parameter, either 1 or -1, you can choose which solution is being used. Usually, this switches between the bars intersecting or not.

In the end, we add a line of each of the bars for visualisation, generate our equations of motion and start the GUI:

world.addVisualisation.Line(bar2, 4)
world.addVisualisation.Line(bar3, 4)
world.addVisualisation.Line(bar4, 5)

world.genEquations.Recursive()
world.show('FourBarLinkage')

The result should look roughly like this:

../_images/fourbar_linkage.gif

In the end, the complete source looks like this:

"""
Model for a closed loop four-bar linkage.
"""

# Warning: The source code of the examples is quoted in the documentation. If
# you change this file, you'll have to change the corresponding file in the
# documentation (see doc/examples).

from pymbs.input import MbsSystem, diag, pi

world = MbsSystem([0, 0, -1])

# Parameter
l1 = world.addParam('l1', 1)

m2 = world.addParam('m2', 1)
l2 = world.addParam('l2', 4)
I2 = world.addParam('I2', m2 / 12 * l2**2)

m3 = world.addParam('m3', 1)
l3 = world.addParam('l3', 4)
I3 = world.addParam('I3', m3 / 12 * l3**2)

m4 = world.addParam('m4', 1)
l4 = world.addParam('l4', 5)
I4 = world.addParam('I4', m4 / 12 * l4**2)

# Create bodies with coordinate systems
world.addFrame(name='CS_A')
world.addFrame(name='CS_D', p=[l1, 0, 0])

bar2 = world.addBody(name='Bar2', mass=m2, cg=[l2 / 2, 0, 0],
                     inertia=diag([0, I2, I2]))
bar2.addFrame(name='CS_A')
bar2.addFrame(name='CS_B', p=[l2, 0, 0])

bar3 = world.addBody(name='Bar3', mass=m3, cg=[l3 / 2, 0, 0],
                     inertia=diag([0, I3, I3]))
bar3.addFrame(name='CS_B')
bar3.addFrame(name='CS_C', p=[l3, 0, 0])

bar4 = world.addBody(name='Bar4', mass=m4, cg=[l4 / 2, 0, 0],
                     inertia=diag([0, I4, I4]))
bar4.addFrame(name='CS_D')
bar4.addFrame(name='CS_C', p=[l4, 0, 0])

# Insert joints
jA = world.addJoint(world.CS_A, bar2.CS_A, 'Ry', pi / 2)
jB = world.addJoint(bar2.CS_B, bar3.CS_B, 'Ry')
jD = world.addJoint(world.CS_D, bar4.CS_D, 'Ry')

world.addLoop.FourBar(bar3.CS_C, bar4.CS_C, posture=1)

world.addVisualisation.Line(bar2, 4)
world.addVisualisation.Line(bar3, 4)
world.addVisualisation.Line(bar4, 5)

world.genEquations.Recursive()
world.show('FourBarLinkage')