# No. 80 (Brown 1868): "Rectilinear motion is imparted to the slotted bar, A, by the vibration of the
# lever, C, through the agency of the two hooked pawls, which drop alternately into the teeth of the slotted
# rack-bar, A."
#
# Model (cm): A, a rack-bar with 0.6 cm ratchet teeth on its top, slides on a fixed stud in its slot. The
# upright lever C turns on a fulcrum 5.5 cm over A and is vibrated about 11 deg each way by a crank (the
# one driven joint, 30 turns a minute) whose pin works in a slot at C's top. The two hooked pawls hang from C,
# one 2.5 cm below the fulcrum and one 2.5 cm above it, so their pins go to and fro oppositely, about 1.6 teeth.
# Each leans forward onto A's teeth, and pushes a tooth on the stroke its pin goes forward; on the
# return it slides back over a tooth and drops in behind the next. So the pawls drive alternately and A moves on
# both strokes, a tooth each, 2 teeth a crank turn. A's friction on its stud holds it while a pawl slides back.
# Generator: opencode-runs/batch8/gen080.py.
number: 80
slug: lever-hooked-pawls-slotted-rack
name: A slotted rack-bar driven by a lever and two hooked pawls
brown: "Rectilinear motion is imparted to the slotted bar, A, by the vibration of the lever, C, through the agency of the two hooked pawls, which drop alternately into the teeth of the slotted rack-bar, A."
units: cm
sim:
  timestep: 0.0002
  integrator: implicitfast
  iterations: 100
  solver: PGS
  multiccd: false
  duration_s: 13
  floor: false
bodies:
  - id: rack_a
    shape: part
    pos: [0, 0, 0]
    friction: 0.1
    color: "#d9cfb6"
    pieces:
      - {kind: poly, points: [[-11.52, -0.35], [13.48, -0.35], [13.48, 0], [-11.52, 0]], y: [-0.9, 0.9]}   # the bar, over its slot
      - {kind: poly, points: [[-11.52, -1.6], [13.48, -1.6], [13.48, -1.25], [-11.52, -1.25]], y: [-0.9, 0.9]}   # under the slot
      - {kind: poly, points: [[-11.52, -1.6], [-11.02, -1.6], [-11.02, 0], [-11.52, 0]], y: [-0.9, 0.9]}   # the slot's ends
      - {kind: poly, points: [[12.98, -1.6], [13.48, -1.6], [13.48, 0], [12.98, 0]], y: [-0.9, 0.9]}
      - {kind: poly, points: [[-11.02, 0], [-11.02, 0.35], [-10.42, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[-10.42, 0], [-10.42, 0.35], [-9.82, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[-9.82, 0], [-9.82, 0.35], [-9.22, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[-9.22, 0], [-9.22, 0.35], [-8.62, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[-8.62, 0], [-8.62, 0.35], [-8.02, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[-8.02, 0], [-8.02, 0.35], [-7.42, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[-7.42, 0], [-7.42, 0.35], [-6.82, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[-6.82, 0], [-6.82, 0.35], [-6.22, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[-6.22, 0], [-6.22, 0.35], [-5.62, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[-5.62, 0], [-5.62, 0.35], [-5.02, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[-5.02, 0], [-5.02, 0.35], [-4.42, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[-4.42, 0], [-4.42, 0.35], [-3.82, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[-3.82, 0], [-3.82, 0.35], [-3.22, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[-3.22, 0], [-3.22, 0.35], [-2.62, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[-2.62, 0], [-2.62, 0.35], [-2.02, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[-2.02, 0], [-2.02, 0.35], [-1.42, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[-1.42, 0], [-1.42, 0.35], [-0.82, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[-0.82, 0], [-0.82, 0.35], [-0.22, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[-0.22, 0], [-0.22, 0.35], [0.38, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[0.38, 0], [0.38, 0.35], [0.98, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[0.98, 0], [0.98, 0.35], [1.58, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[1.58, 0], [1.58, 0.35], [2.18, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[2.18, 0], [2.18, 0.35], [2.78, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[2.78, 0], [2.78, 0.35], [3.38, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[3.38, 0], [3.38, 0.35], [3.98, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[3.98, 0], [3.98, 0.35], [4.58, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[4.58, 0], [4.58, 0.35], [5.18, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[5.18, 0], [5.18, 0.35], [5.78, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[5.78, 0], [5.78, 0.35], [6.38, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[6.38, 0], [6.38, 0.35], [6.98, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[6.98, 0], [6.98, 0.35], [7.58, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[7.58, 0], [7.58, 0.35], [8.18, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[8.18, 0], [8.18, 0.35], [8.78, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[8.78, 0], [8.78, 0.35], [9.38, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[9.38, 0], [9.38, 0.35], [9.98, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[9.98, 0], [9.98, 0.35], [10.58, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[10.58, 0], [10.58, 0.35], [11.18, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[11.18, 0], [11.18, 0.35], [11.78, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[11.78, 0], [11.78, 0.35], [12.38, 0]], y: [-0.9, 0.9], collide: 1}
      - {kind: poly, points: [[12.38, 0], [12.38, 0.35], [12.98, 0]], y: [-0.9, 0.9], collide: 1}
  - id: lever_c
    shape: part
    pos: [0, 0, 5.5]
    color: "#b8ad97"
    pieces:
      - {kind: poly, points: [[-0.35, 2.6], [0.35, 2.6], [0.35, 10.3], [-0.35, 10.3]], y: [-1.6, -1.0]}   # the lever
      - {kind: disc, center: [0, 5.5], radius: 0.6, inner: 0.25, y: [-1.6, -1.0]}
      - {kind: poly, points: [[-0.67, 10.3], [-0.27, 10.3], [-0.27, 14.7], [-0.67, 14.7]], y: [-1.6, -1.0], collide: 2}   # the slot's cheeks
      - {kind: poly, points: [[0.27, 10.3], [0.67, 10.3], [0.67, 14.7], [0.27, 14.7]], y: [-1.6, -1.0], collide: 2}
      - {kind: poly, points: [[-0.67, 14.7], [0.67, 14.7], [0.67, 15.1], [-0.67, 15.1]], y: [-1.6, -1.0]}
      - {kind: rod, from: [0, -1.6, 3.0], to: [0, -0.10000000000000003, 3.0], radius: 0.18, color: "#8f8a80"}   # the pawls' pins
      - {kind: rod, from: [0, -1.6, 8.0], to: [0, 0.7, 8.0], radius: 0.18, color: "#8f8a80"}
  - id: pawl_1
    shape: part
    pos: [0, 0, 3.0]
    mount: lever_c
    friction: 0.1
    color: "#6b5a44"
    pieces:
      - {kind: rod, from: [0, -0.4, 3.0], to: [2.6, -0.4, 0.255], radius: 0.12, capsule: true, collide: 2}
      - {kind: disc, center: [0, 3.0], radius: 0.3, y: [-0.55, -0.25]}
  - id: pawl_2
    shape: part
    pos: [0, 0, 8.0]
    mount: lever_c
    friction: 0.1
    color: "#6b5a44"
    pieces:
      - {kind: rod, from: [0, 0.4, 8.0], to: [5.6, 0.4, 0.255], radius: 0.12, capsule: true, collide: 2}
      - {kind: disc, center: [0, 8.0], radius: 0.3, y: [0.25, 0.55]}
  - id: crank
    shape: part
    pos: [0, 0, 12.5]
    color: "#a39d90"
    pieces:
      - {kind: disc, center: [0, 12.5], radius: 1.9608, y: [-2.4, -1.8]}   # the crank disc, in front
      - {kind: rod, from: [0, -2.0, 13.8608], to: [0, -0.8, 13.8608], radius: 0.25, capsule: true, collide: 1}   # its pin, in C's slot
  - id: frame
    shape: part
    pos: [0, 0, 0]
    fixed: true
    color: "#cfc6b4"
    pieces:
      - {kind: rod, from: [0, -1.0, 5.5], to: [0, 1.6, 5.5], radius: 0.25, color: "#8f8a80"}   # C's fulcrum
      - {kind: poly, points: [[-0.8, -4], [0.8, -4], [0.6, 5.5], [-0.6, 5.5]], y: [1.2, 1.8]}   # its standard, behind
      - {kind: rod, from: [0, -1.1, -0.8], to: [0, 1.6, -0.8], radius: 0.4, color: "#8f8a80"}   # the stud in A's slot
      - {kind: rod, from: [0, -3.0, 12.5], to: [0, -2.4, 12.5], radius: 0.3, color: "#8f8a80"}
      - {kind: poly, points: [[-12, 12.9], [-11, 12.9], [-11, -4], [-12, -4]], y: [-3.2, -3.0]}
      - {kind: poly, points: [[-12, 12.9], [0.4, 12.9], [0.4, 12.1], [-12, 12.1]], y: [-3.2, -3.0]}   # the crank's bracket, in front
      - {kind: poly, points: [[-13.52, -5], [15.48, -5], [15.48, -4], [-13.52, -4]], y: [-3.4, 2.0], color: "#b9b09c"}
      - {kind: poly, points: [[3.5, -4], [4.5, -4], [4.5, -0.8], [3.5, -0.8]], y: [1.2, 1.8]}
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.6, 0.6], stiffness: 0.005, springref: 0.2}   # + : tip down
  - {id: j_p2, type: hinge, body: pawl_2, axis: [0, 1, 0], damping: 0.0002, range: [-0.6, 0.6], stiffness: 0.005, springref: 0.2}
  - {id: j_a, type: slide, body: rack_a, axis: [1, 0, 0], damping: 0.05, frictionloss: 0.05}   # + : to the right
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.0, max_torque: 20}
checks:
  - {type: ratio, out: j_a, in: j_k, expect: 0.00191, tol: 3.8e-05, settle_s: 3, window_s: 10}   # a tooth a stroke: 2 teeth a crank turn (m per rad)
  - {type: penetration, max: 0.001, settle_s: 0.5}
camera: {target: [1, 0, 4.5], position: [1, -60, 6], fov: 32}
display:
  output: j_a
  labels: {j_k: "Crank (driver)", j_c: "Lever C", j_p1: "Lower pawl", j_p2: "Upper pawl", j_a: "Rack-bar A"}
  proof: {label: "Pawls out of contact", sub: "the lever vibrates but A never moves"}

