# No. 73 (Brown 1868): intermittent rotary motion by a bent spring pressed into a ratchet by a fixed spring.
#
# As drawn (cm; the drawing plane is x-z, depth y): D (the one motor-driven shaft, turning against the clock)
# carries the bent spring B, here a sprung catch on a pin whose spring holds it out against a stop. The
# ratchet A (12 teeth) turns freely on D's axis. The strong spring C, a lever on a fixed centre preloaded onto
# its stop, has a shoe over the top: B's heel runs under it, B's point is pressed into a tooth of A and
# carries A on; leaving the shoe, B springs out and A rests until D comes round again. The shoe's arc is
# 1.5 teeth, so A is carried one tooth a turn whichever tooth B first meets.
# Generator: opencode-runs/batch8/gen073.py.
number: 73
slug: bent-spring-ratchet
name: Intermittent motion by a bent spring pressed into a ratchet
brown: "To the driving-wheel, D, is secured a bent spring, B; another spring, C, is attached to a fixed support. As the wheel, D, revolves, the spring, B, passes under the strong spring, C, which presses it into a tooth of the ratchet-wheel, A, which is thus made to rotate. The catch-spring, B, being released on its escape from the strong spring, C, allows the wheel, A, to remain at rest till D has made another revolution. The spring, C, serves as a stop."
units: cm
sim:
  timestep: 0.0002
  integrator: implicitfast
  iterations: 100
  solver: PGS
  multiccd: false
  duration_s: 24
  floor: false
bodies:
  - id: wheel_d
    shape: part
    pos: [0, 0, 0]
    friction: 0.1
    color: "#e8dec6"
    pieces:
      - {kind: disc, center: [0, 0], radius: 5.0, y: [1.0, 1.8]}   # D
      - {kind: disc, center: [0.0, -4.4], radius: 0.25, y: [-0.5, 1.0], color: "#8f8a80"}   # B's pin
      - {kind: disc, center: [0, 0], radius: 1.6, y: [1.8, 5.0], color: "#8f8a80"}   # a flywheel behind
  - id: catch_b
    shape: part
    pos: [0.0, 0, -4.4]
    mount: wheel_d
    friction: 0.1
    color: "#6b5a44"
    pieces:
      - {kind: rod, from: [0.0, 0, -4.4], to: [1.8086, 0, -2.9656], radius: 0.15, capsule: true, collide: 2}   # B's blade and point
      - {kind: rod, from: [0.7234, 0, -3.8262], to: [0.2581, 0, -5.4613], radius: 0.2, capsule: true, collide: 2}   # its heel
  - id: ratchet_a
    shape: part
    pos: [0, 0, 0]
    friction: 0.1
    color: "#d9cfb6"
    pieces:
      - {kind: disc, center: [0, 0], radius: 2.4, y: [-0.5, 0.5]}
      - {kind: poly, points: [[2.3, 0.0], [2.835, 0.9813], [1.9919, 1.15]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[1.9919, 1.15], [1.9645, 2.2673], [1.15, 1.9919]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[1.15, 1.9919], [0.5676, 2.9458], [0.0, 2.3]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[0.0, 2.3], [-0.9813, 2.835], [-1.15, 1.9919]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-1.15, 1.9919], [-2.2673, 1.9645], [-1.9919, 1.15]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-1.9919, 1.15], [-2.9458, 0.5676], [-2.3, 0.0]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-2.3, 0.0], [-2.835, -0.9813], [-1.9919, -1.15]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-1.9919, -1.15], [-1.9645, -2.2673], [-1.15, -1.9919]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-1.15, -1.9919], [-0.5676, -2.9458], [-0.0, -2.3]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-0.0, -2.3], [0.9813, -2.835], [1.15, -1.9919]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[1.15, -1.9919], [2.2673, -1.9645], [1.9919, -1.15]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[1.9919, -1.15], [2.9458, -0.5676], [2.3, -0.0]], y: [-0.5, 0.5], collide: 1}
  - id: spring_c
    shape: part
    pos: [-3.5, 0, 7.4174]
    friction: 0.1
    color: "#a39d90"
    pieces:
      - {kind: poly, points: [[3.5816, 4.5842], [3.8278, 4.8994], [3.6983, 4.9979], [3.444, 4.6542]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[3.444, 4.6542], [3.6983, 4.9979], [3.5662, 5.093], [3.3052, 4.7202]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[3.3052, 4.7202], [3.5662, 5.093], [3.4316, 5.1846], [3.1653, 4.7822]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[3.1653, 4.7822], [3.4316, 5.1846], [3.2947, 5.2727], [3.0244, 4.8401]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[3.0244, 4.8401], [3.2947, 5.2727], [3.1556, 5.3571], [2.8827, 4.8938]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[2.8827, 4.8938], [3.1556, 5.3571], [3.0143, 5.4379], [2.7403, 4.9435]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[2.7403, 4.9435], [3.0143, 5.4379], [2.8709, 5.5149], [2.5972, 4.9892]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[2.5972, 4.9892], [2.8709, 5.5149], [2.7255, 5.5882], [2.4536, 5.0307]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[2.4536, 5.0307], [2.7255, 5.5882], [2.5783, 5.6576], [2.3097, 5.0681]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[2.3097, 5.0681], [2.5783, 5.6576], [2.4293, 5.7232], [2.1655, 5.1015]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[2.1655, 5.1015], [2.4293, 5.7232], [2.2787, 5.7848], [2.0211, 5.1308]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[2.0211, 5.1308], [2.2787, 5.7848], [2.1265, 5.8425], [1.8767, 5.1561]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[1.8767, 5.1561], [2.1265, 5.8425], [1.9728, 5.8961], [1.7411, 5.2035]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[1.7411, 5.2035], [1.9728, 5.8961], [1.8178, 5.9458], [1.6043, 5.2473]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[1.6043, 5.2473], [1.8178, 5.9458], [1.6615, 5.9913], [1.4663, 5.2875]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[1.4663, 5.2875], [1.6615, 5.9913], [1.5041, 6.0327], [1.3274, 5.324]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[1.3274, 5.324], [1.5041, 6.0327], [1.3457, 6.07], [1.1876, 5.357]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[1.1876, 5.357], [1.3457, 6.07], [1.1863, 6.1032], [1.047, 5.3862]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[1.047, 5.3862], [1.1863, 6.1032], [1.0262, 6.1322], [0.9056, 5.4118]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[0.9056, 5.4118], [1.0262, 6.1322], [0.8653, 6.1569], [0.7636, 5.4336]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[0.7636, 5.4336], [0.8653, 6.1569], [0.7038, 6.1775], [0.6211, 5.4518]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[0.6211, 5.4518], [0.7038, 6.1775], [0.5419, 6.1938], [0.4782, 5.4661]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[0.4782, 5.4661], [0.5419, 6.1938], [0.3796, 6.2058], [0.335, 5.4768]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[0.335, 5.4768], [0.3796, 6.2058], [0.217, 6.2136], [0.1915, 5.4837]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[0.1915, 5.4837], [0.217, 6.2136], [0.0543, 6.2172], [0.0479, 5.4868]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[0.0479, 5.4868], [0.0543, 6.2172], [-0.1085, 6.2165], [-0.0958, 5.4862]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-0.0958, 5.4862], [-0.1085, 6.2165], [-0.2712, 6.2115], [-0.2393, 5.4818]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-0.2393, 5.4818], [-0.2712, 6.2115], [-0.4337, 6.2023], [-0.3828, 5.4737]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-0.3828, 5.4737], [-0.4337, 6.2023], [-0.5959, 6.1888], [-0.5259, 5.4618]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-0.5259, 5.4618], [-0.5959, 6.1888], [-0.7577, 6.1711], [-0.6687, 5.4461]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-0.6687, 5.4461], [-0.7577, 6.1711], [-0.919, 6.1491], [-0.811, 5.4268]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-0.811, 5.4268], [-0.919, 6.1491], [-1.0796, 6.123], [-0.9528, 5.4037]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-0.9528, 5.4037], [-1.0796, 6.123], [-1.2396, 6.0926], [-1.0939, 5.3769]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-1.0939, 5.3769], [-1.2396, 6.0926], [-1.3986, 6.0581], [-1.2343, 5.3464]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-1.2343, 5.3464], [-1.3986, 6.0581], [-1.5567, 6.0194], [-1.3738, 5.3123]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-1.3738, 5.3123], [-1.5567, 6.0194], [-1.7138, 5.9766], [-1.5124, 5.2745]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-1.5124, 5.2745], [-1.7138, 5.9766], [-1.8696, 5.9297], [-1.65, 5.2331]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-1.65, 5.2331], [-1.8696, 5.9297], [-2.0242, 5.8787], [-1.7864, 5.1881]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-1.7864, 5.1881], [-2.0242, 5.8787], [-2.1774, 5.8237], [-1.9216, 5.1395]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-1.9216, 5.1395], [-2.1774, 5.8237], [-2.3291, 5.7647], [-2.0555, 5.0875]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-2.0555, 5.0875], [-2.3291, 5.7647], [-2.4792, 5.7017], [-2.1879, 5.0319]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-2.1879, 5.0319], [-2.4792, 5.7017], [-2.6276, 5.6349], [-2.3189, 4.9729]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-2.3189, 4.9729], [-2.6276, 5.6349], [-2.7742, 5.5642], [-2.4667, 4.9475]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-2.4667, 4.9475], [-2.7742, 5.5642], [-2.9189, 5.4897], [-2.6148, 4.9177]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-2.6148, 4.9177], [-2.9189, 5.4897], [-3.0616, 5.4114], [-2.763, 4.8835]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-2.763, 4.8835], [-3.0616, 5.4114], [-3.2022, 5.3294], [-2.9111, 4.8449]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-2.9111, 4.8449], [-3.2022, 5.3294], [-3.3406, 5.2437], [-3.0591, 4.8019]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-3.0591, 4.8019], [-3.3406, 5.2437], [-3.4767, 5.1545], [-3.2069, 4.7544]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-3.2069, 4.7544], [-3.4767, 5.1545], [-3.6105, 5.0617], [-3.3542, 4.7024]], y: [-0.5, 0.5], collide: 1}
      - {kind: poly, points: [[-3.3542, 4.7024], [-3.6105, 5.0617], [-3.7417, 4.9655], [-3.501, 4.646]], y: [-0.5, 0.5], collide: 1}
      - {kind: rod, from: [-3.5, 0, 7.4174], to: [-0.2712, 0, 6.2115], radius: 0.25}   # C's leaf
      - {kind: disc, center: [-3.5, 7.4174], radius: 0.5, y: [-0.6, 0.6], color: "#8f8a80"}
  - id: frame
    shape: frame
    color: "#8f8a80"
    rods:
      - {from: [-3.5, 0.6, 7.4174], to: [-3.5, 2.0, 7.4174], radius: 0.4}
      - {from: [0, 5.0, 0], to: [0, 6.2, 0], radius: 0.6}
joints:
  - {id: j_d, type: hinge, body: wheel_d, axis: [0, -1, 0], damping: 0.0002}   # positive: against the clock, as drawn
  - {id: j_b, type: hinge, body: catch_b, axis: [0, -1, 0], damping: 0.0002, range: [0, 0.48], stiffness: 0.003, springref: -0.1}   # out on its stop; + presses the point in
  - {id: j_a, type: hinge, body: ratchet_a, axis: [0, -1, 0], damping: 0.001, frictionloss: 0.003}
  - {id: j_c, type: hinge, body: spring_c, axis: [0, -1, 0], damping: 0.002, range: [0, 0.3], stiffness: 0.5, springref: -0.2}   # the strong spring, preloaded onto its stop
contact: {solref: [0.002, 1.0], solimp: [0.95, 0.99, 0.0005], margin: 0}
driver: {joint: j_d, kind: velocity, rpm: 12, kv: 2, max_torque: 20}
checks:
  - {type: ratio, out: j_a, in: j_d, expect: 0.0833, tol: 0.001, settle_s: 5.5, window_s: 15.0}   # one tooth a turn
  - {type: still, joint: j_a, max: 0.005, settle_s: 4.5, window_s: 2.0}   # at rest while B is out
  - {type: clicks, joint: j_b, lift: 0.3, min: 4, settle_s: 0.5, window_s: 23.0}   # B pressed in once a turn
  - {type: penetration, max: 0.001, settle_s: 0.5}
camera: {target: [0, 0, 1.5], position: [0, -40, 6], fov: 34}
display:
  output: j_a
  labels: {j_d: "D (driver) with the bent spring B", j_a: "Ratchet A", j_c: "Strong spring C", j_b: "Bent spring B"}
  proof: {label: "C's shoe out of contact", sub: "B is never pressed in: A never moves"}

