# No. 267 (Brown 1868): "Friction pulley. When the rim turns in the opposite direction to the arrow, it gives motion to the shaft by means of the
# pivoted eccentric arms; but when it turns in the direction of the arrow, the arms turn on their pivots and the shaft is at rest."
#
# Model (cm, gravity on, the shaft level): the rim (inner radius 8) is the one driven joint, rocked 0.6 rad each way 0.5 times a second by
# hand. Three arms, pivoted on the shaft's hub 4.2 from the centre, reach out to it, each ending in a round eccentric toe (radius 0.9) held to the
# rim by a spring. Each arm leans 18 deg from the rim's normal, less than the friction angle (mu 0.45), so when the rim turns one
# way it drags the toes up the lean, the arms wedge, and the shaft goes with it; turned back, it drags them off the lean, the arms turn on their
# pivots and slip, and the shaft (its bearing friction 0.5 N m) is at rest. The shaft so goes forward a stroke each to-and-fro. Only the toes touch the rim.
# Generator: opencode-runs/batch12/gen267.py.
number: 267
slug: friction-pulley-eccentric-arms
name: Friction pulley with pivoted eccentric arms
brown: "Friction pulley. When the rim turns in the opposite direction to the arrow, it gives motion to the shaft by means of the pivoted eccentric arms; but when it turns in the direction of the arrow, the arms turn on their pivots and the shaft is at rest. The arms are held to the rim by springs."
units: cm
sim:
  timestep: 0.0002
  integrator: implicitfast
  iterations: 100
  solver: CG
  multiccd: true
  duration_s: 8.5
  floor: false
bodies:
  - id: rim
    shape: part
    pos: [0, 0, 0]
    density: 2700
    friction: 0.45
    color: "#d9c9a3"
    pieces:
      - {kind: poly, points: [[8.0, 0.0], [9.5, 0.0], [9.4638, 0.828], [7.9696, 0.6972]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[7.9696, 0.6972], [9.4638, 0.828], [9.3557, 1.6497], [7.8785, 1.3892]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[7.8785, 1.3892], [9.3557, 1.6497], [9.1763, 2.4588], [7.7274, 2.0706]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[7.7274, 2.0706], [9.1763, 2.4588], [8.9271, 3.2492], [7.5175, 2.7362]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[7.5175, 2.7362], [8.9271, 3.2492], [8.6099, 4.0149], [7.2505, 3.3809]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[7.2505, 3.3809], [8.6099, 4.0149], [8.2272, 4.75], [6.9282, 4.0]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[6.9282, 4.0], [8.2272, 4.75], [7.7819, 5.449], [6.5532, 4.5886]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[6.5532, 4.5886], [7.7819, 5.449], [7.2774, 6.1065], [6.1284, 5.1423]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[6.1284, 5.1423], [7.2774, 6.1065], [6.7175, 6.7175], [5.6569, 5.6569]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[5.6569, 5.6569], [6.7175, 6.7175], [6.1065, 7.2774], [5.1423, 6.1284]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[5.1423, 6.1284], [6.1065, 7.2774], [5.449, 7.7819], [4.5886, 6.5532]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[4.5886, 6.5532], [5.449, 7.7819], [4.75, 8.2272], [4.0, 6.9282]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[4.0, 6.9282], [4.75, 8.2272], [4.0149, 8.6099], [3.3809, 7.2505]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[3.3809, 7.2505], [4.0149, 8.6099], [3.2492, 8.9271], [2.7362, 7.5175]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[2.7362, 7.5175], [3.2492, 8.9271], [2.4588, 9.1763], [2.0706, 7.7274]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[2.0706, 7.7274], [2.4588, 9.1763], [1.6497, 9.3557], [1.3892, 7.8785]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[1.3892, 7.8785], [1.6497, 9.3557], [0.828, 9.4638], [0.6972, 7.9696]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[0.6972, 7.9696], [0.828, 9.4638], [0.0, 9.5], [0.0, 8.0]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[0.0, 8.0], [0.0, 9.5], [-0.828, 9.4638], [-0.6972, 7.9696]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-0.6972, 7.9696], [-0.828, 9.4638], [-1.6497, 9.3557], [-1.3892, 7.8785]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-1.3892, 7.8785], [-1.6497, 9.3557], [-2.4588, 9.1763], [-2.0706, 7.7274]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-2.0706, 7.7274], [-2.4588, 9.1763], [-3.2492, 8.9271], [-2.7362, 7.5175]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-2.7362, 7.5175], [-3.2492, 8.9271], [-4.0149, 8.6099], [-3.3809, 7.2505]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-3.3809, 7.2505], [-4.0149, 8.6099], [-4.75, 8.2272], [-4.0, 6.9282]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-4.0, 6.9282], [-4.75, 8.2272], [-5.449, 7.7819], [-4.5886, 6.5532]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-4.5886, 6.5532], [-5.449, 7.7819], [-6.1065, 7.2774], [-5.1423, 6.1284]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-5.1423, 6.1284], [-6.1065, 7.2774], [-6.7175, 6.7175], [-5.6569, 5.6569]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-5.6569, 5.6569], [-6.7175, 6.7175], [-7.2774, 6.1065], [-6.1284, 5.1423]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-6.1284, 5.1423], [-7.2774, 6.1065], [-7.7819, 5.449], [-6.5532, 4.5886]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-6.5532, 4.5886], [-7.7819, 5.449], [-8.2272, 4.75], [-6.9282, 4.0]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-6.9282, 4.0], [-8.2272, 4.75], [-8.6099, 4.0149], [-7.2505, 3.3809]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-7.2505, 3.3809], [-8.6099, 4.0149], [-8.9271, 3.2492], [-7.5175, 2.7362]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-7.5175, 2.7362], [-8.9271, 3.2492], [-9.1763, 2.4588], [-7.7274, 2.0706]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-7.7274, 2.0706], [-9.1763, 2.4588], [-9.3557, 1.6497], [-7.8785, 1.3892]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-7.8785, 1.3892], [-9.3557, 1.6497], [-9.4638, 0.828], [-7.9696, 0.6972]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-7.9696, 0.6972], [-9.4638, 0.828], [-9.5, 0.0], [-8.0, 0.0]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-8.0, 0.0], [-9.5, 0.0], [-9.4638, -0.828], [-7.9696, -0.6972]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-7.9696, -0.6972], [-9.4638, -0.828], [-9.3557, -1.6497], [-7.8785, -1.3892]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-7.8785, -1.3892], [-9.3557, -1.6497], [-9.1763, -2.4588], [-7.7274, -2.0706]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-7.7274, -2.0706], [-9.1763, -2.4588], [-8.9271, -3.2492], [-7.5175, -2.7362]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-7.5175, -2.7362], [-8.9271, -3.2492], [-8.6099, -4.0149], [-7.2505, -3.3809]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-7.2505, -3.3809], [-8.6099, -4.0149], [-8.2272, -4.75], [-6.9282, -4.0]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-6.9282, -4.0], [-8.2272, -4.75], [-7.7819, -5.449], [-6.5532, -4.5886]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-6.5532, -4.5886], [-7.7819, -5.449], [-7.2774, -6.1065], [-6.1284, -5.1423]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-6.1284, -5.1423], [-7.2774, -6.1065], [-6.7175, -6.7175], [-5.6569, -5.6569]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-5.6569, -5.6569], [-6.7175, -6.7175], [-6.1065, -7.2774], [-5.1423, -6.1284]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-5.1423, -6.1284], [-6.1065, -7.2774], [-5.449, -7.7819], [-4.5886, -6.5532]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-4.5886, -6.5532], [-5.449, -7.7819], [-4.75, -8.2272], [-4.0, -6.9282]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-4.0, -6.9282], [-4.75, -8.2272], [-4.0149, -8.6099], [-3.3809, -7.2505]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-3.3809, -7.2505], [-4.0149, -8.6099], [-3.2492, -8.9271], [-2.7362, -7.5175]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-2.7362, -7.5175], [-3.2492, -8.9271], [-2.4588, -9.1763], [-2.0706, -7.7274]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-2.0706, -7.7274], [-2.4588, -9.1763], [-1.6497, -9.3557], [-1.3892, -7.8785]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-1.3892, -7.8785], [-1.6497, -9.3557], [-0.828, -9.4638], [-0.6972, -7.9696]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-0.6972, -7.9696], [-0.828, -9.4638], [-0.0, -9.5], [-0.0, -8.0]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[-0.0, -8.0], [-0.0, -9.5], [0.828, -9.4638], [0.6972, -7.9696]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[0.6972, -7.9696], [0.828, -9.4638], [1.6497, -9.3557], [1.3892, -7.8785]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[1.3892, -7.8785], [1.6497, -9.3557], [2.4588, -9.1763], [2.0706, -7.7274]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[2.0706, -7.7274], [2.4588, -9.1763], [3.2492, -8.9271], [2.7362, -7.5175]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[2.7362, -7.5175], [3.2492, -8.9271], [4.0149, -8.6099], [3.3809, -7.2505]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[3.3809, -7.2505], [4.0149, -8.6099], [4.75, -8.2272], [4.0, -6.9282]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[4.0, -6.9282], [4.75, -8.2272], [5.449, -7.7819], [4.5886, -6.5532]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[4.5886, -6.5532], [5.449, -7.7819], [6.1065, -7.2774], [5.1423, -6.1284]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[5.1423, -6.1284], [6.1065, -7.2774], [6.7175, -6.7175], [5.6569, -5.6569]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[5.6569, -5.6569], [6.7175, -6.7175], [7.2774, -6.1065], [6.1284, -5.1423]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[6.1284, -5.1423], [7.2774, -6.1065], [7.7819, -5.449], [6.5532, -4.5886]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[6.5532, -4.5886], [7.7819, -5.449], [8.2272, -4.75], [6.9282, -4.0]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[6.9282, -4.0], [8.2272, -4.75], [8.6099, -4.0149], [7.2505, -3.3809]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[7.2505, -3.3809], [8.6099, -4.0149], [8.9271, -3.2492], [7.5175, -2.7362]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[7.5175, -2.7362], [8.9271, -3.2492], [9.1763, -2.4588], [7.7274, -2.0706]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[7.7274, -2.0706], [9.1763, -2.4588], [9.3557, -1.6497], [7.8785, -1.3892]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[7.8785, -1.3892], [9.3557, -1.6497], [9.4638, -0.828], [7.9696, -0.6972]], y: [0.0, 1.6], collide: 1}
      - {kind: poly, points: [[7.9696, -0.6972], [9.4638, -0.828], [9.5, -0.0], [8.0, -0.0]], y: [0.0, 1.6], collide: 1}
      - {kind: rod, from: [0, -0.6, 0], to: [0, -0.1, 0], radius: 1.0, collide: 0, color: "#8f8a80"}   # the rim's own boss, loose on the shaft
      - {kind: poly, points: [[-0.5, 0.9], [0.5, 0.9], [0.5, 8.0], [-0.5, 8.0]], y: [-0.6, -0.2], collide: 0}   # its web arm (behind the arms)
      - {kind: poly, points: [[-0.5, -8.0], [0.5, -8.0], [0.5, -0.9], [-0.5, -0.9]], y: [-0.6, -0.2], collide: 0}
  - id: hub
    shape: part
    pos: [0, 0, 0]
    density: 7800
    color: "#e4d9bf"
    pieces:
      - {kind: rod, from: [0, -3, 0], to: [0, 5, 0], radius: 0.6, collide: 0, color: "#8f8a80"}   # the shaft
      - {kind: disc, center: [0, 0], radius: 2.6, y: [0.2, 1.4], collide: 0}   # its hub
      - {kind: poly, points: [[-0.25, 0.6], [0.25, 0.6], [0.25, 2.4], [-0.25, 2.4]], y: [1.4, 1.5], collide: 0, color: "#4f493f"}   # a mark
  - id: arm1
    shape: part
    pos: [4.2, 0.8, 0.0]
    mount: hub
    density: 2700
    friction: 0.45
    color: "#a89a7e"
    pieces:
      - {kind: poly, points: [[3.9649, 0.3837], [6.716, 1.9635], [7.0921, 1.3496], [4.4351, -0.3837]], y: [0.35, 1.25], collide: 0}   # the arm
      - {kind: disc, center: [6.904, 1.6565], radius: 0.9, y: [0.1, 1.5], collide: 2}   # its eccentric toe, on the rim
      - {kind: disc, center: [4.2, 0.0], radius: 0.5, y: [0.2, 1.4], collide: 0, color: "#6f675a"}   # its pivot
  - id: arm2
    shape: part
    pos: [-2.1, 0.8, 3.6373]
    mount: hub
    density: 2700
    friction: 0.45
    color: "#a89a7e"
    pieces:
      - {kind: poly, points: [[-2.3148, 3.2419], [-5.0585, 4.8345], [-4.7148, 5.4672], [-1.8852, 4.0327]], y: [0.35, 1.25], collide: 0}   # the arm
      - {kind: disc, center: [-4.8866, 5.1508], radius: 0.9, y: [0.1, 1.5], collide: 2}   # its eccentric toe, on the rim
      - {kind: disc, center: [-2.1, 3.6373], radius: 0.5, y: [0.2, 1.4], collide: 0, color: "#6f675a"}   # its pivot
  - id: arm3
    shape: part
    pos: [-2.1, 0.8, -3.6373]
    mount: hub
    density: 2700
    friction: 0.45
    color: "#a89a7e"
    pieces:
      - {kind: poly, points: [[-1.6502, -3.6256], [-1.6575, -6.798], [-2.3773, -6.8167], [-2.5498, -3.649]], y: [0.35, 1.25], collide: 0}   # the arm
      - {kind: disc, center: [-2.0174, -6.8074], radius: 0.9, y: [0.1, 1.5], collide: 2}   # its eccentric toe, on the rim
      - {kind: disc, center: [-2.1, -3.6373], radius: 0.5, y: [0.2, 1.4], collide: 0, color: "#6f675a"}   # its pivot
  - id: frame
    shape: part
    pos: [0, 0, 0]
    fixed: true
    color: "#cfc6b4"
    pieces:
      - {kind: poly, points: [[-6, -12], [6, -12], [6, -11], [-6, -11]], y: [-5, 7], collide: 0, color: "#b9b09c"}   # the bed
      - {kind: poly, points: [[-1.2, -11], [1.2, -11], [1.2, 0.9], [-1.2, 0.9]], y: [3.4, 4.4], collide: 0}   # the shaft's bearing
      - {kind: poly, points: [[-1.2, -11], [1.2, -11], [1.2, 0.9], [-1.2, 0.9]], y: [-3.0, -2.0], collide: 0}
joints:
  - {id: j_r, type: hinge, body: rim, axis: [0, 1, 0], damping: 0.001}   # the rim: the one driven joint
  - {id: j_s, type: hinge, body: hub, axis: [0, 1, 0], damping: 3}   # the shaft, working against a load (3 N m s/rad)
  - {id: j_a1, type: hinge, body: arm1, axis: [0, 1, 0], range: [-0.35, 0.35], damping: 0.001, stiffness: 0.05, springref: 0.25}   # arm 1 on its pivot; its spring holds the toe to the rim
  - {id: j_a2, type: hinge, body: arm2, axis: [0, 1, 0], range: [-0.35, 0.35], damping: 0.001, stiffness: 0.05, springref: 0.25}   # arm 2 on its pivot; its spring holds the toe to the rim
  - {id: j_a3, type: hinge, body: arm3, axis: [0, 1, 0], range: [-0.35, 0.35], damping: 0.001, stiffness: 0.05, springref: 0.25}   # arm 3 on its pivot; its spring holds the toe to the rim
contact: {solref: [0.002, 1], solimp: [0.95, 0.99, 0.0005], margin: 0}
driver: {joint: j_r, kind: velocity, rpm: 1, kv: 100.0, max_torque: 20.0, swing: {amplitude: 0.6, hz: 0.5}}
checks:
  - {type: follow, out: j_s, in: j_r, expect: 1.0, tol: 0.05, min_r2: 0.99, settle_s: 3.75, window_s: 0.5}   # turned against the arrow: the arms wedge and the shaft goes with the rim
  - {type: still, joint: j_s, max: 0.1, settle_s: 2.75, window_s: 0.5}   # turned with the arrow (the rim at up to 1.9 rad/s): the arms slip and the shaft is at rest
  - {type: advance, joint: j_s, beat: j_r, expect: 0.6, tol: 0.08, settle_s: 0.5, window_s: 7.5}   # so it goes on one stroke in two: the rim's amplitude a beat
  - {type: monotonic, joint: j_s, direction: 1, max_back: 0.03, settle_s: 0.5, window_s: 7.5}
camera: {target: [0, 0, -6.5], position: [8.0, -60.0, 6.0], fov: 44.0}
display:
  output: j_s
  labels: {j_r: "The rim (driver)", j_s: "The shaft", j_a1: "Arm 1", j_a2: "Arm 2", j_a3: "Arm 3"}
  proof: {label: "One way only", sub: "the arms wedge and carry the shaft one way, and turn on their pivots and slip the other"}

