Rocker

The rocker, or bell crank, of a small race car’s pushrod suspension turns the travel of the pushrod into the stroke of the damper. It pivots on a bearing in its hub, the rod end of the pushrod sits in the fork of its lower arm, and the damper is bolted to its upper boss. Its outline is one chain of tangent arcs and lines around the hub, the boss and the eye. The bosses stand proud of both faces, and the fork is a slot through the middle of the thickness. Model the rocker from the drawing in planex2d or in any CAD system, then check its volume, mass and center of mass against the values at the end of the page. A solution in planex2d follows.

The rocker exercise: a dimensioned drawing of an L-shaped rocker with a hub, an upper boss and a forked eye, arcs of large radius along its lower arm, in a front view, a section through its middle plane and an isometric

[1]:
import math
import netgen.occ as occ
import planex as px

The outline

The outline is the rocker’s plan, sketched in the xy plane, which becomes the middle plane of its thickness. It is one chain, drawn roughly from the hub out. It runs along the lower arm’s underside, a concave arc that turns right, then around the eye and back along the lower arm’s top. A convex arc of large radius follows, a small arc turning right into the inner corner, the upper arm’s right flank, the boss, the left flank, and the hub back to the start. With auto_constraint=True, every joint of the chain becomes a tangency, and where the chain closes, a coincidence and a tangency are added. The arcs and lines carry ids for the dimensions, which the interactive plot shows under the mouse (Figure 1).

[3]:
rocker = px.Sketch(auto_constraint=True)
rocker.Move((14, -17), dir=(1, 0.8)).Arc(50, -80, id="lower")  # a negative sweep turns right: a concave arc
rocker.Arc(11, 185, id="eye")
rocker.Arc(110, 33, id="upper")
rocker.Arc(10, -72, id="corner")
rocker.Line(42, id="right_flank")
rocker.Arc(14, 162, id="boss")
rocker.Line(65, id="left_flank")
rocker.Arc(22, 132, id="hub")
rocker.Constrain("hub.end", "lower.start", px.Coincident)
rocker.Constrain("hub", "lower", px.Tangent)
rocker.Plot(backend="plotly")

The dimensions

The hub’s center is the origin. The boss, the eye and the center of the inner corner’s arc are placed by their distances from the hub’s center lines, and the radii give the arcs their sizes. The convex arc of 110 and the corner’s arc of 10 could still slide along the eye and the boss together. The corner’s center, 28 across and 32 up from the hub’s center, holds them. With these, nothing in the sketch is left free (Figure 1):

[4]:
rocker.Constrain("hub.center", "origin", px.Coincident)
rocker.Constrain("boss.center", "V", px.Distance, 5, id="boss_x")
rocker.Constrain("boss.center", "H", px.Distance, 70, id="boss_y")
rocker.Constrain("eye.center", "V", px.Distance, 85, id="eye_x")
rocker.Constrain("eye.center", "H", px.Distance, 10, id="eye_y")
rocker.Constrain("corner.center", "V", px.Distance, 28, id="corner_x")
rocker.Constrain("corner.center", "H", px.Distance, 32, id="corner_y")
rocker.Constrain("hub", px.Radius, 22, id="hub_r")
rocker.Constrain("boss", px.Radius, 14, id="boss_r")
rocker.Constrain("eye", px.Radius, 11, id="eye_r")
rocker.Constrain("lower", px.Radius, 50, id="lower_r")
rocker.Constrain("upper", px.Radius, 110, id="upper_r")
rocker.Constrain("corner", px.Radius, 10, id="corner_r")
print("status", rocker.status, "| degrees of freedom", rocker.dof)
status full | degrees of freedom 0
Every dimension and tie of the outline
Figure 1: The outline

The plate and the bosses

px.Pad extrudes the outline 10 to both sides of the xy plane, 20 in all. The bosses, the hub’s of 44 and the upper one of 28, are circles in the same middle plane at the solved centers of the hub’s and the boss’s arcs, which Location gives. px.Fix holds each where it is drawn, with its size. Padded 15 to both sides, they are 30 long and stand 5 proud of each face, and + fuses them with the plate (Figure 2):

[6]:
block = px.Pad(rocker, 10, length2=10)
bosses = px.Sketch()
bosses.Circle(44 / 2, px.Fix, center=rocker.Location("hub.center"), id="hub_boss")
bosses.Circle(28 / 2, px.Fix, center=rocker.Location("boss.center"), id="upper_boss")
block = block + px.Pad(bosses, 15, length2=15)
The plate with its bosses
Figure 2: The bosses

The fork

The fork’s slot, 8 wide, runs through the middle of the thickness from the eye’s end to an arc of radius 60 around the hub, clear of the inner corner. Its profile is a region in the middle plane, a rectangle over the lower arm’s end less a disc of radius 60 around the hub. px.Pocket with length2 cuts 4 to each side of the plane, only where the region meets the rocker (Figure 3):

[8]:
region = px.QuickSketch().Move((30, -40)).Rectangle(90, 80).Face() - px.Face([px.Circle((0, 0), 60)])
block = px.Pocket(block, region, 4, length2=4)  # 4 to each side of the middle plane: a slot 8 wide
The region of the slot in the middle plane
(a) The region of the slot in the middle plane
The slot through the middle of the lower arm
(b) The slot through the middle of the lower arm
Figure 3: The fork

The holes

The bearing seat of 26 in the hub, the hole of 10 for the damper’s bolt in the upper boss and the hole of 8 for the rod end’s bolt in the eye are circles in the middle plane too. Like the bosses, they are fixed at the arcs’ centers. Pocketed 20 to both sides, they go through everything, the eye’s hole through both cheeks of the fork (Figure 4):

[10]:
holes = px.Sketch()
holes.Circle(26 / 2, px.Fix, center=rocker.Location("hub.center"), id="bearing_seat")
holes.Circle(10 / 2, px.Fix, center=rocker.Location("boss.center"), id="damper_hole")
holes.Circle(8 / 2, px.Fix, center=rocker.Location("eye.center"), id="eye_hole")
block = px.Pocket(block, holes, 20, length2=20)
The holes through the bosses and the fork
Figure 4: The holes

The checks

These are the volume, the mass in aluminum EN AW-7075 (2.81 g/cm³) and the center of mass, with the origin at the hub’s center in the middle plane, to compare with your own model. The volume is the outline’s area times 20, plus the bosses’ 10 of length beyond the plate, less the holes and the slot. The eye’s hole runs through the two cheeks, 12 of the thickness, and the slot’s area in plan is where the region and the outline overlap, their intersection *. The rocker is symmetric about its middle plane, so its center of mass lies in it:

[12]:
outline = rocker.Face()
slot = (outline * region).mass  # the slot's area in plan
exact = (outline.mass * 20 + math.pi * (22**2 + 14**2) * 10 - math.pi * (13**2 + 5**2) * 30 - math.pi * 4**2 * 12
         - slot * 8)
c = block.center
print("volume", round(block.mass, 1), "mm³, exact", round(exact, 1))
print("mass", round(block.mass * 2.81e-6, 3), "kg")
print("center of mass", tuple(round(v, 2) for v in (c.x, c.y)), "in the middle plane, off it by", round(abs(c.z), 6))
volume 107811.3 mm³, exact 107811.3
mass 0.303 kg
center of mass (13.22, 22.13) in the middle plane, off it by 0.0

The rocker as STEP, for another CAD system:

[13]:
block.WriteStep("rocker.step")

The rocker as STEP: rocker.step