# No. 390 (Brown 1868): "Device for converting oscillating into rotary motion."
#
# Model (cm, front view as Brown draws it): the semicircular piece A (rim radius 20) hangs from the lever on the fulcrum a and is rocked to
# and fro (the one driven joint, a velocity servo of its own swing, +-0.3 rad at 0.4 Hz). Two bands are made fast at A's tips, each lying
# in a groove on A's rim: band C runs open round pulley C, band D crossed round pulley D (its two ends in planes 2.4 cm apart, so the
# strands pass each other). The pulleys (5.8 cm) turn loose on the fly-wheel shaft 30 cm below; each carries a sprung pawl on a pin that
# engages a ratchet wheel fast on the shaft, both set the same way. A's swing turns the pulleys opposite ways; whichever turns forwards drives
# the shaft through its pawl while the other's pawl clicks back over its teeth, so the fly-wheel B turns continuously one way. The bands drive
# the pulleys by contact and friction only; all the pawl work is real contact. Generator: opencode-runs/batch13/gen390.py.
number: 390
slug: oscillating-to-rotary-bands
name: Device for converting oscillating into rotary motion
brown: "Device for converting oscillating into rotary motion. The semicircular piece, A, is attached to a lever which works on a fulcrum, a, and it has attached to it the ends of two bands, C and D, which run around two pulleys, loose on the shaft of the flywheel, B. Band, C, is open, and band, D, crossed. The pulleys have attached to them pawls which engage with two ratchet-wheels fast on the fly-wheel shaft. One pawl acts on its ratchet-wheel when the piece, A, turns one way, and the other when the said piece turns the other way, and thus a continuous rotary motion of the shaft is obtained."
units: cm
sim: {timestep: 0.0001, integrator: implicitfast, iterations: 60, duration_s: 10, floor: false}
bodies:
  - {id: rocker, shape: assembly, pos: [0, 0, 0], mass: 3, color: "#d8ccb0"}
  - id: rocker_web
    shape: part
    pos: [0, 0, 0]
    mount: rocker
    fixed: true
    color: "#d8ccb0"
    pieces:
      - {kind: poly, points: [[-34, 0.2], [34, 0.2], [34, 2.0], [-34, 2.0]], y: [-1.2, 1.2]}
      - {kind: band, center: [0, 0], r: [17.4, 19.95], a: [3.1416, 6.2832], y: [-4.2, 3.4], slices: 24}
      - {kind: poly, points: [[-20, -0.2], [-17.4, -0.2], [-17.4, 0.4], [-20, 0.4]], y: [-4.2, 3.4]}
      - {kind: poly, points: [[17.4, -0.2], [20, -0.2], [20, 0.4], [17.4, 0.4]], y: [-4.2, 3.4]}
      - {kind: disc, center: [0, 0], radius: 2.2, inner: 0.8, y: [-1.6, 1.6], color: "#b8ad97"}
  - id: fly
    shape: part
    pos: [0, 0, -30]
    density: 7800
    friction: 0.15
    color: "#e2d8bf"
    pieces:
      - {kind: rod, from: [0, -6.4, -30], to: [0, 11.6, -30], radius: 0.5, color: "#8f8a80"}
      - {kind: wheel, center: [0, -30], teeth: 32, tooth: [[3.1995, 0], [2.7373, -0.02], [2.7373, -0.16634954084936207]], phase: 0, root: 2.844, rim: 0.9954, hub: 0.711, spokes: 0, y: [-5.6, -4.8], collide: 2}
      - {kind: wheel, center: [0, -30], teeth: 32, tooth: [[3.1995, 0], [2.7373, -0.02], [2.7373, -0.16634954084936207]], phase: 0, root: 2.844, rim: 0.9954, hub: 0.711, spokes: 0, y: [4.2, 5.0], collide: 2}
      - {kind: disc, center: [0, -30], radius: 2.844, inner: 0.5, y: [-4.8, -3.95]}
      - {kind: disc, center: [0, -30], radius: 2.844, inner: 0.5, y: [3.45, 4.2]}
      - {kind: band, center: [0, -30], r: [13.5, 16.0], a: [0, 6.2832], y: [7.5, 9.5], slices: 48, color: "#d9cfb6"}
      - {kind: disc, center: [0, -30], radius: 2.2, inner: 0.5, y: [7.3, 9.7], color: "#d9cfb6"}
      - {kind: rod, from: [2.0, 8.5, -30.0], to: [13.5, 8.5, -30.0], radius: 0.7, color: "#d9cfb6"}
      - {kind: rod, from: [0.0, 8.5, -28.0], to: [0.0, 8.5, -16.5], radius: 0.7, color: "#d9cfb6"}
      - {kind: rod, from: [-2.0, 8.5, -30.0], to: [-13.5, 8.5, -30.0], radius: 0.7, color: "#d9cfb6"}
      - {kind: rod, from: [-0.0, 8.5, -32.0], to: [-0.0, 8.5, -43.5], radius: 0.7, color: "#d9cfb6"}
  - {id: pul_c, shape: assembly, pos: [0, 0, -30], color: "#e6dcc6"}
  - id: pawl_c
    shape: part
    pos: [4.1921, 0, -28.4221]
    mount: pul_c
    density: 7800
    friction: 0.15
    color: "#a39d90"
    pieces:
      - {kind: poly, points: [[4.2889, -28.5058], [3.0776, -29.9047], [2.8841, -29.7371], [4.0954, -28.3383]], y: [-5.54, -4.86], collide: 1}
      - {kind: disc, center: [4.1921, -28.4221], radius: 0.35, y: [-5.54, -4.86]}
      - {kind: rod, from: [4.1921, -4.86, -28.4221], to: [4.1921, -3.9, -28.4221], radius: 0.22, color: "#6f6a60"}
  - {id: pul_d, shape: assembly, pos: [0, 0, -30], color: "#e6dcc6"}
  - id: pawl_d
    shape: part
    pos: [4.1921, 0, -28.4221]
    mount: pul_d
    density: 7800
    friction: 0.15
    color: "#a39d90"
    pieces:
      - {kind: poly, points: [[4.2889, -28.5058], [3.0776, -29.9047], [2.8841, -29.7371], [4.0954, -28.3383]], y: [4.26, 4.94], collide: 1}
      - {kind: disc, center: [4.1921, -28.4221], radius: 0.35, y: [4.26, 4.94]}
      - {kind: rod, from: [4.1921, 3.4, -28.4221], to: [4.1921, 4.26, -28.4221], radius: 0.22, color: "#6f6a60"}
  - id: frame
    shape: part
    pos: [0, 0, 0]
    fixed: true
    color: "#cdc0a4"
    pieces:
      - {kind: disc, center: [0, 0], radius: 0.8, y: [-2.2, 5.0], color: "#8f8a80"}
      - {kind: poly, points: [[-1.2, -30], [1.2, -30], [1.8, -47], [-1.8, -47]], y: [10.4, 11.4]}
      - {kind: disc, center: [0, -30], radius: 1.3, y: [10.4, 11.4]}
      - {kind: poly, points: [[-6, -48], [6, -48], [6, -47], [-6, -47]], y: [8, 14], color: "#b9b09c"}
joints:
  - {id: j_a, type: hinge, body: rocker, axis: [0, 1, 0], damping: 0.05}   # the lever and A: the one driven joint
  - {id: j_f, type: hinge, body: fly, axis: [0, 1, 0], damping: 0.02}     # the fly-wheel shaft with its two ratchets: the work
  - {id: j_pc, type: hinge, body: pul_c, axis: [0, 1, 0], damping: 0.002}
  - {id: j_pd, type: hinge, body: pul_d, axis: [0, 1, 0], damping: 0.002}
  - {id: j_kc, type: hinge, body: pawl_c, axis: [0, -1, 0], damping: 0.0002, range: [-0.04, 0.28], stiffness: 0.004, springref: -0.35}
  - {id: j_kd, type: hinge, body: pawl_d, axis: [0, -1, 0], damping: 0.0002, range: [-0.04, 0.28], stiffness: 0.004, springref: -0.35}
wheels:
  # A's rim, grooved for each band; each groove is two quarter arcs (the band's two ends) that together make A's half circle
  - {id: a_c1, body: rocker, pos: [0, -3.2, 0], radius: 20, width: 1.4, groove: 0.8, flange: 0, arc: [3.1416, 4.7124], mass: 0.2, color: "#d8ccb0"}
  - {id: a_c2, body: rocker, pos: [0, -3.2, 0], radius: 20, width: 1.4, groove: 0.8, flange: 0, arc: [4.7124, 6.2832], mass: 0.2, color: "#d8ccb0"}
  - {id: a_d1, body: rocker, pos: [0, 0.2, 0], radius: 20, width: 1.4, groove: 0.8, flange: 0, arc: [3.1416, 4.7124], mass: 0.2, color: "#d8ccb0"}
  - {id: a_d2, body: rocker, pos: [0, 2.6, 0], radius: 20, width: 1.4, groove: 0.8, flange: 0, arc: [4.7124, 6.2832], mass: 0.2, color: "#d8ccb0"}
  - {id: w_c, body: pul_c, pos: [0, -3.2, 0], radius: 5.8, width: 1.4, groove: 0.6, flange: 0.5, mass: 0.3, spokes: 0, hub: 1.2, web: true, color: "#e6dcc6"}
  - {id: w_d, body: pul_d, pos: [0, 1.4000000000000001, 0], radius: 5.8, width: 4, flange: 0.5, mass: 0.4, spokes: 0, hub: 1.2, web: true, color: "#efe6d2"}
cords:
  - id: band_c
    from: {body: rocker, at: [-20, -3.2, 0], wound: true}
    to: {body: rocker, at: [20, -3.2, 0], wound: true}
    over: [a_c1, w_c, a_c2]
    senses: [-1, -1, -1]
    links: 90
    segments: 9
    root_damping: 0.0001
    joint_armature: 0.000001
    thickness: 0.4
    density: 1400
    stiffness: 30000.0
    pretension: 20
    damping: 2.0
    friction: 0.6
    color: "#6f5a3c"
  - id: band_d
    from: {body: rocker, at: [-20, 0.2, 0], wound: true}
    to: {body: rocker, at: [20, 2.6, 0], wound: true}
    over: [a_d1, w_d, a_d2]
    senses: [-1, 1, -1]
    wraps: [{wheel: w_d, advance: 2.4, station: -1.2}]
    links: 86
    segments: 9
    root_damping: 0.0001
    joint_armature: 0.000001
    thickness: 0.4
    density: 1400
    stiffness: 30000.0
    pretension: 20
    damping: 2.0
    friction: 0.6
    color: "#6f5a3c"
contact: {solref: [0.0003, 1], solimp: [0.95, 0.99, 0.0005], margin: 0}
driver: {joint: j_a, kind: velocity, rpm: 0, swing: {amplitude: 0.3, hz: 0.4}, kv: 50, max_torque: 200}
checks:
  # each pulley follows A both ways, at A's rim over its own (20.2 / 6.0 on the bands' centre lines): C (open) the same way, D (crossed) the other
  # (the open band C, with the smaller wrap on its pulley, creeps on it by a few per cent a stroke: its r² is the lower)
  - {type: follow, out: j_pc, in: j_a, expect: 3.37, tol: 0.3, min_r2: 0.93, settle_s: 1, window_s: 8.5}
  - {type: follow, out: j_pd, in: j_a, expect: -3.37, tol: 0.2, settle_s: 1, window_s: 8.5}
  # the fly-wheel turns one way, both strokes, never running back
  - {type: turning, joint: j_f, direction: 1, min_mean: 1.6, min_fraction: 0.9, settle_s: 1, window_s: 8.5}
  - {type: monotonic, joint: j_f, direction: 1, max_back: 0.05, settle_s: 1, window_s: 8.5}
  - {type: clicks, joint: j_kc, lift: 0.1, min: 4, settle_s: 1, window_s: 8.5}
  - {type: clicks, joint: j_kd, lift: 0.1, min: 4, settle_s: 1, window_s: 8.5}
  - {type: penetration, max: 0.0025, settle_s: 0.5}
camera: {target: [0, 0, -29.5], position: [0, -160, -29.5], fov: 34}
display:
  output: j_f
  labels: {j_a: "Lever and A (rocked)", j_f: "Fly-wheel B", j_pc: "Pulley C (open band)", j_pd: "Pulley D (crossed band)", j_kc: "Pawl of C", j_kd: "Pawl of D"}
