# No. 77 (Brown 1868): "The vibration of the lever, C, on the center or fulcrum, A, produces a rotary
# movement of the wheel, B, by means of the two pawls, which act alternately. This is almost a continuous movement."
#
# Model (cm): B, a 30-tooth ratchet-wheel, turns on a fixed centre and is held by its bearing friction.
# The upright lever C turns on the fulcrum A beside and above B (on the right, as in the plate). It is vibrated by a crank (the one driven
# joint, 30 turns a minute) whose pin works in a slot at C's lower end. Two pawls are pinned on C,
# one 2.0356 cm above A and one 2.0357 cm below it, and lie by their weight on B's teeth at the top of the wheel.
# The two pins move in opposite directions: on one stroke the upper pawl pushes a tooth on while the lower
# one slides back over the teeth, and on the other stroke they change places. B goes a tooth each stroke,
# two each double stroke, always the same way. Generator: opencode-runs/batch8/gen077.py.
number: 77
slug: lever-two-pawls
name: Nearly continuous rotation from a vibrating lever by two alternate pawls
brown: "The vibration of the lever, C, on the center or fulcrum, A, produces a rotary movement of the wheel, B, by means of the two pawls, which act alternately. This is almost a continuous movement."
units: cm
sim:
  timestep: 0.0002
  integrator: implicitfast
  iterations: 100
  solver: PGS
  multiccd: false
  duration_s: 14
  floor: false
bodies:
  - id: wheel_b
    shape: part
    pos: [0, 0, 0]
    friction: 0.1
    color: "#d9cfb6"
    pieces:
      - {kind: disc, center: [0, 0], radius: 4.3, inner: 0.6, y: [-0.5, 0.9]}
      - {kind: poly, points: [[0.5482, 4.1641], [0.6526, 4.9572], [-0.3295, 4.1871]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[-0.3295, 4.1871], [-0.3923, 4.9846], [-1.1929, 4.027]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[-1.1929, 4.027], [-1.4201, 4.7941], [-2.0041, 3.691]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[-2.0041, 3.691], [-2.3858, 4.3941], [-2.7277, 3.1937]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[-2.7277, 3.1937], [-3.2472, 3.802], [-3.3321, 2.5568]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[-3.3321, 2.5568], [-3.9668, 3.0438], [-3.7909, 1.8081]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[-3.7909, 1.8081], [-4.5129, 2.1526], [-4.084, 0.9805]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[-4.084, 0.9805], [-4.8618, 1.1672], [-4.1986, 0.1099]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[-4.1986, 0.1099], [-4.9983, 0.1309], [-4.1297, -0.7654]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[-4.1297, -0.7654], [-4.9163, -0.9112], [-3.8803, -1.6073]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[-3.8803, -1.6073], [-4.6194, -1.9134], [-3.4613, -2.3789]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[-3.4613, -2.3789], [-4.1206, -2.832], [-2.8911, -3.0466]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[-2.8911, -3.0466], [-3.4418, -3.6269], [-2.1945, -3.5811]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[-2.1945, -3.5811], [-2.6125, -4.2632], [-1.402, -3.9591]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[-1.402, -3.9591], [-1.669, -4.7132], [-0.5482, -4.1641]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[-0.5482, -4.1641], [-0.6526, -4.9572], [0.3295, -4.1871]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[0.3295, -4.1871], [0.3923, -4.9846], [1.1929, -4.027]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[1.1929, -4.027], [1.4201, -4.7941], [2.0041, -3.691]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[2.0041, -3.691], [2.3858, -4.3941], [2.7277, -3.1937]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[2.7277, -3.1937], [3.2472, -3.802], [3.3321, -2.5568]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[3.3321, -2.5568], [3.9668, -3.0438], [3.7909, -1.8081]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[3.7909, -1.8081], [4.5129, -2.1526], [4.084, -0.9805]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[4.084, -0.9805], [4.8618, -1.1672], [4.1986, -0.1099]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[4.1986, -0.1099], [4.9983, -0.1309], [4.1297, 0.7654]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[4.1297, 0.7654], [4.9163, 0.9112], [3.8803, 1.6073]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[3.8803, 1.6073], [4.6194, 1.9134], [3.4613, 2.3789]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[3.4613, 2.3789], [4.1206, 2.832], [2.8911, 3.0466]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[2.8911, 3.0466], [3.4418, 3.6269], [2.1945, 3.5811]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[2.1945, 3.5811], [2.6125, 4.2632], [1.402, 3.9591]], y: [-0.5, 0.9], collide: 1}
      - {kind: poly, points: [[1.402, 3.9591], [1.669, 4.7132], [0.5482, 4.1641]], y: [-0.5, 0.9], collide: 1}
  - id: lever_c
    shape: part
    pos: [10.0, 0, 3.4449]
    friction: 0.1
    color: "#b8ad97"
    pieces:
      - {kind: poly, points: [[9.55, 6.0805], [10.45, 6.0805], [10.45, -1.1551000000000005], [9.55, -1.1551000000000005]], y: [-1.6, -1.0]}   # the lever, in front
      - {kind: disc, center: [10.0, 3.4449], radius: 0.8, inner: 0.35, y: [-1.6, -1.0]}
      - {kind: poly, points: [[9.33, -7.7551000000000005], [9.73, -7.7551000000000005], [9.73, -1.3551000000000002], [9.33, -1.3551000000000002]], y: [-1.6, -0.2], collide: 2}   # the slot's cheeks
      - {kind: poly, points: [[10.27, -7.7551000000000005], [10.67, -7.7551000000000005], [10.67, -1.3551000000000002], [10.27, -1.3551000000000002]], y: [-1.6, -0.2], collide: 2}
      - {kind: poly, points: [[9.33, -1.3551000000000002], [10.67, -1.3551000000000002], [10.67, -0.9551000000000003], [9.33, -0.9551000000000003]], y: [-1.6, -0.2]}
      - {kind: poly, points: [[9.33, -8.155100000000001], [10.67, -8.155100000000001], [10.67, -7.7551000000000005], [9.33, -7.7551000000000005]], y: [-1.6, -0.2]}
      - {kind: rod, from: [10.0, -1.0, 5.480525985583057], to: [10.0, 0.6, 5.480525985583057], radius: 0.18, color: "#8f8a80"}   # the pawls' pins
      - {kind: rod, from: [10.0, -1.0, 1.4092268735233557], to: [10.0, 0.6, 1.4092268735233557], radius: 0.18, color: "#8f8a80"}
  - id: pawl_1
    shape: part
    pos: [10.0, 0, 5.480525985583057]
    mount: lever_c
    friction: 0.1
    color: "#6b5a44"
    pieces:
      - {kind: rod, from: [10.0, 0.5, 5.480525985583057], to: [0.8248, 0.5, 4.6778], radius: 0.15, capsule: true, collide: 2}
  - id: pawl_2
    shape: part
    pos: [10.0, 0, 1.4092268735233557]
    mount: lever_c
    friction: 0.1
    color: "#6b5a44"
    pieces:
      - {kind: rod, from: [10.0, -0.1, 1.4092268735233557], to: [2.6562, -0.1, 3.9379], radius: 0.15, capsule: true, collide: 2}
  - id: crank
    shape: part
    pos: [10.0, 0, -4.5551]
    color: "#a39d90"
    pieces:
      - {kind: disc, center: [10.0, -4.5551], radius: 2.9, y: [1.2, 2.0]}   # the crank disc, behind
      - {kind: rod, from: [10.0, -1.5, -2.2551], to: [10.0, 1.2, -2.2551], radius: 0.25, capsule: true, collide: 1}   # its pin, in C's slot (at the top to start)
  - id: frame
    shape: part
    pos: [0, 0, 0]
    fixed: true
    color: "#cfc6b4"
    pieces:
      - {kind: rod, from: [0, -0.6, 0], to: [0, 2.4, 0], radius: 0.6, color: "#8f8a80"}
      - {kind: poly, points: [[-1, -8.5551], [1, -8.5551], [0.8, 0], [-0.8, 0]], y: [1.6, 2.4]}
      - {kind: rod, from: [10.0, -2.4, 3.4449], to: [10.0, -1.0, 3.4449], radius: 0.35, color: "#8f8a80"}   # A
      - {kind: poly, points: [[10.3, 3.0449], [12.2, 3.0449], [12.2, 3.8449], [10.3, 3.8449]], y: [-2.4, -1.8]}
      - {kind: poly, points: [[11.4, -8.5551], [12.2, -8.5551], [12.2, 3.8449], [11.4, 3.8449]], y: [-2.4, -1.8]}   # A's standard
      - {kind: rod, from: [10.0, 2.0, -4.5551], to: [10.0, 2.8, -4.5551], radius: 0.35, color: "#8f8a80"}
      - {kind: poly, points: [[9.5, -8.5551], [10.5, -8.5551], [10.5, -4.5551], [9.5, -4.5551]], y: [2.2, 2.8]}   # the crank's standard
      - {kind: poly, points: [[-7, -9.5551], [14.0, -9.5551], [14.0, -8.5551], [-7, -8.5551]], y: [-3, 3], color: "#b9b09c"}
joints:
  - {id: j_k, type: hinge, body: crank, axis: [0, -1, 0], damping: 0.0005}   # the one driven joint
  - {id: j_c, type: hinge, body: lever_c, axis: [0, -1, 0], damping: 0.0005}
  - {id: j_p1, type: hinge, body: pawl_1, axis: [0, -1, 0], damping: 0.0002, range: [-0.9, 0.7]}   # - : lifting off the teeth
  - {id: j_p2, type: hinge, body: pawl_2, axis: [0, -1, 0], damping: 0.0002, range: [-0.9, 0.7]}
  - {id: j_b, type: hinge, body: wheel_b, axis: [0, -1, 0], damping: 0.002, frictionloss: 0.01}   # + : against the clock
contact: {solref: [0.002, 1.0], solimp: [0.95, 0.99, 0.0005], margin: 0}
driver: {joint: j_k, kind: velocity, rpm: 30.0, kv: 2, max_torque: 20}
checks:
  - {type: ratio, out: j_b, in: j_k, expect: 0.0667, tol: 0.001, settle_s: 3, window_s: 10}   # two teeth a crank turn
  - {type: penetration, max: 0.001, settle_s: 0.5}
camera: {target: [3, 0, -2.2776], position: [3, -52, -0.2776], fov: 34}
display:
  output: j_b
  labels: {j_k: "Crank (driver)", j_c: "Lever C", j_p1: "Upper pawl", j_p2: "Lower pawl", j_b: "Ratchet-wheel B"}
  proof: {label: "Pawls out of contact", sub: "the lever vibrates but B never moves"}

