# No. 49 (Brown 1868): "Alternate circular motion of the horizontal shaft produces a continuous rotary
# motion of the vertical shaft, by means of the ratchet-wheels secured to the bevel-gears, the
# ratchet-teeth of the two wheels being set opposite ways, and the pawls acting in opposite
# directions. The bevel-gears and ratchet-wheels are loose on the shaft, and the pawls attached to arms
# firmly secured on the shaft."
#
# Model (cm): the horizontal shaft runs along y and is rocked by the hand (a velocity servo of its own
# swing, +-0.6 rad at 0.5 Hz: the one driven joint). Two 20-tooth miter bevels turn loose on it
# either side of the upright shaft, each cast with a 32-tooth ratchet wheel outboard; the teeth of the
# two wheels are set opposite ways. An arm keyed to the shaft outside each wheel carries a pawl on a pin,
# a light spring holding it in to the teeth. The upright shaft's bevel meshes both. Rocked one way, A's
# pawl drives A and B is turned backwards by the upright gear under its pawl, which clicks over; rocked
# back, B's pawl drives B. Either way the upright shaft turns the same way. It carries a load (damping)
# and a flywheel. Generated by batch7/gen049.py.
number: 49
slug: ratchet-bevel-gears
name: Alternate into continuous rotary motion
brown: "Alternate circular motion of the horizontal shaft produces a continuous rotary motion of the vertical shaft, by means of the ratchet-wheels secured to the bevel-gears, the ratchet-teeth of the two wheels being set opposite ways, and the pawls acting in opposite directions. The bevel-gears and ratchet-wheels are loose on the shaft, and the pawls attached to arms firmly secured on the shaft."
units: cm
sim:
  timestep: 0.0002
  integrator: implicitfast
  iterations: 100
  duration_s: 8
  solver: PGS
  multiccd: true
  floor: false
bodies:
  - id: shaft
    shape: part
    pos: [0, 0, 0]
    density: 7800
    color: "#b8ad97"
    pieces:
      - {kind: rod, from: [0, -13, 0], to: [0, 13, 0], radius: 0.5, color: "#8f8a80"}
      - {kind: rod, from: [0, 7.7, 0], to: [5.8961, 7.7, 2.2193], radius: 0.35}
      - {kind: disc, center: [0, 0], radius: 1.0, inner: 0.5, y: [7.3, 8.1]}
      - {kind: disc, center: [5.8961, 2.2193], radius: 0.25, y: [6.0, 8.1], color: "#8f8a80"}
      - {kind: rod, from: [0, -7.7, 0], to: [5.8961, -7.7, -2.2193], radius: 0.35}
      - {kind: disc, center: [0, 0], radius: 1.0, inner: 0.5, y: [-8.1, -7.3]}
      - {kind: disc, center: [5.8961, -2.2193], radius: 0.25, y: [-8.1, -6.0], color: "#8f8a80"}
      - {kind: rod, from: [0, -12.5, 0], to: [0, -12.5, -7], radius: 0.4}
      - {kind: rod, from: [0, -12.5, -7], to: [0, -14.5, -7], radius: 0.45, color: "#a39d90"}
  - id: gearA
    shape: part
    pos: [0, 0, 0]
    density: 7800
    friction: 0.15
    color: "#d9cfb6"
    pieces:
      - {kind: wheel, center: [0, 0], teeth: 32, tooth: [[4.5, 0], [3.85, -0.02], [3.85, -0.16634954084936207]], phase: 0, root: 4.0, rim: 1.4, hub: 1.0, spokes: 0, y: [6.0, 7.0], collide: 2}
      - {kind: disc, center: [0, 0], radius: 1.2, inner: 0.55, y: [4.4, 6.0]}
  - id: pawlA
    shape: part
    pos: [5.8961, 0, 2.2193]
    mount: shaft
    density: 7800
    friction: 0.15
    color: "#a39d90"
    pieces:
      - {kind: poly, points: [[6.0322, 2.1015], [4.3285, 0.134], [4.0564, 0.3697], [5.7601, 2.3372]], y: [6.06, 6.94], collide: 1}
  - id: gearB
    shape: part
    pos: [0, 0, 0]
    density: 7800
    friction: 0.15
    color: "#e2d8bf"
    pieces:
      - {kind: wheel, center: [0, 0], teeth: 32, tooth: [[4.5, 0], [3.85, 0.02], [3.85, 0.16634954084936207]], phase: 0, root: 4.0, rim: 1.4, hub: 1.0, spokes: 0, y: [-7.0, -6.0], collide: 2}
      - {kind: disc, center: [0, 0], radius: 1.2, inner: 0.55, y: [-6.0, -4.4]}
  - id: pawlB
    shape: part
    pos: [5.8961, 0, -2.2193]
    mount: shaft
    density: 7800
    friction: 0.15
    color: "#a39d90"
    pieces:
      - {kind: poly, points: [[6.0322, -2.1015], [4.3285, -0.134], [4.0564, -0.3697], [5.7601, -2.3372]], y: [-6.94, -6.06], collide: 1}
  - {id: upright, shape: assembly, pos: [0, 0, 0], color: "#e8dec6"}
  - id: frame
    shape: part
    pos: [0, 0, 0]
    fixed: true
    color: "#cfc6b4"
    pieces:
      - {kind: poly, points: [[-1.2, 0], [1.2, 0], [1.6, -15], [-1.6, -15]], y: [10.0, 11.0]}
      - {kind: disc, center: [0, 0], radius: 1.2, y: [10.0, 11.0]}
      - {kind: poly, points: [[-1.2, 0], [1.2, 0], [1.6, -15], [-1.6, -15]], y: [-11.0, -10.0]}
      - {kind: disc, center: [0, 0], radius: 1.2, y: [-11.0, -10.0]}
      - {kind: poly, points: [[-3, -16], [3, -16], [3, -15], [-3, -15]], y: [-12, 12], color: "#b9b09c"}
      - {kind: poly, points: [[8.5, -15], [9.5, -15], [9.5, 15.5], [8.5, 15.5]], y: [-0.6, 0.6]}
      - {kind: poly, points: [[-1.2, 14.5], [9.5, 14.5], [9.5, 15.5], [-1.2, 15.5]], y: [-0.6, 0.6]}
      - {kind: poly, points: [[-6, -16], [11, -16], [11, -15], [-6, -15]], y: [-1.5, 1.5], color: "#b9b09c"}
joints:
  - {id: j_shaft, type: hinge, body: shaft, axis: [0, 1, 0], damping: 0.01}
  - {id: j_A, type: hinge, body: gearA, axis: [0, 1, 0], damping: 0.002}
  - {id: j_B, type: hinge, body: gearB, axis: [0, 1, 0], damping: 0.002}
  - {id: j_pawlA, type: hinge, body: pawlA, axis: [0, -1, 0], damping: 0.0002, range: [-0.04, 0.28], stiffness: 0.01, springref: -0.35}
  - {id: j_pawlB, type: hinge, body: pawlB, axis: [0, 1, 0], damping: 0.0002, range: [-0.04, 0.28], stiffness: 0.01, springref: -0.35}
  - {id: j_up, type: hinge, body: upright, axis: [0, 0, 1], damping: 0.05}   # the work it drives
bevels:
  - {id: gA, body: gearA, teeth: 20, pitch_radius: 4, cone_angle: 0.7853982, face_width: 1.6, backlash: 0.04, phase: 0.0}
  - {id: gB, body: gearB, teeth: 20, pitch_radius: 4, cone_angle: 0.7853982, face_width: 1.6, backlash: 0.04, phase: 0.0, quat: [0, 0, 0, 1]}
  - {id: gV, body: upright, teeth: 20, pitch_radius: 4, cone_angle: 0.7853982, face_width: 1.6, backlash: 0.04, phase: 0.1570796, quat: [0.7071068, 0.7071068, 0, 0]}
shafts:
  - {id: sh_up, body: upright, from: [0, 0, 4.4], to: [0, 0, 16.5], radius: 0.5}
  - {id: sh_fly, body: upright, from: [0, 0, 11], to: [0, 0, 12.2], radius: 4.5, inner: 0.5}   # the flywheel
contact: {solref: [0.001, 1], solimp: [0.95, 0.99, 0.0005], margin: 0}
driver: {joint: j_shaft, kind: velocity, rpm: 0, swing: {amplitude: 0.6, hz: 0.5}, kv: 20, max_torque: 40}
checks:
  # each swing (2 x amp of the shaft) turns the upright as much, less the lost motion at the reversal:
  # the pawl taking over must travel up to one ratchet tooth (pitch 2pi/32) to find its tooth
  - {type: advance, joint: j_up, beat: j_shaft, expect: -1.0037, tol: 0.06, settle_s: 1, window_s: 6.5}
  - {type: monotonic, joint: j_up, direction: -1, max_back: 0.05, settle_s: 0.5, window_s: 7}
  - {type: clicks, joint: j_pawlA, lift: 0.1, min: 10, settle_s: 0.5, window_s: 7}
  - {type: clicks, joint: j_pawlB, lift: 0.1, min: 10, settle_s: 0.5, window_s: 7}
  - {type: penetration, max: 0.001, settle_s: 0.5}
camera: {target: [2, 0, 1], position: [70, -60, 40], fov: 30}
display:
  tiers:
    - {id: full, label: Full, ms: 0.21}
    - {id: light, label: Light, timestep: 0.0008, ms: 0.0953}
  output: j_up
  labels: {j_shaft: "Horizontal shaft (rocked by the hand)", j_A: "Bevel A with its ratchet", j_B: "Bevel B with its ratchet", j_up: "Upright shaft", j_pawlA: "Pawl of A", j_pawlB: "Pawl of B"}
  proof: {label: "Pawls off the teeth", sub: "the shaft still rocks, but neither bevel is driven: the upright shaft stands"}
