# No. 122 (Brown 1868): "The rotation of the two spur-gears, with crank-wrists attached, produces a variable alternating traverse of the horizontal bar."
#
# Model (cm): two equal spur-gears (24 teeth, module 0.8, pitch radius 9.600000000000001) in mesh, the upper turned clockwise (the one driven joint, 20 turns a minute), the lower driven by its teeth the other way. Each carries a crank-wrist 6.0 cm out
# (90 and 130 degrees from the top at the start). A rod from each wrist is pinned to an end of a link (12 cm long) whose middle is pinned to the horizontal bar, which slides to and fro in a guide.
# The bar's traverse is the two cranks' motions averaged through the link, and as the two wrists are out of step it is not a sine: it goes quickly one way and slowly the other, and the strokes differ.
# There is no gravity (a plan on the bench). Generator: opencode-runs/batch9/gen122.py.
number: 122
slug: two-spur-gears-crank-wrists
name: Two spur-gears with crank-wrists driving a bar unevenly
brown: "The rotation of the two spur-gears, with crank-wrists attached, produces a variable alternating traverse of the horizontal bar."
units: cm
sim:
  timestep: 0.0002
  integrator: implicitfast
  iterations: 100
  solver: PGS
  multiccd: true
  duration_s: 10.0
  gravity: 0
  floor: false
bodies:
  - id: gear_1
    shape: part
    pos: [0.0, 0, 9.6]
    density: 7800
    friction: 0.1
    color: "#d9cfb6"
    pieces:
      - {kind: disc, center: [0.0, 9.6], radius: 8.75, inner: 7.7, y: [-0.6, 0.6]}
      - {kind: disc, center: [0.0, 9.6], radius: 1.5, inner: 0.7, y: [-0.6, 0.6]}
      - {kind: poly, points: [[1.4409, 9.6794], [7.4595, 11.5411], [7.2527, 12.2099], [1.234, 10.3481]], y: [-0.5, 0.5]}
      - {kind: poly, points: [[0.6517, 10.8875], [2.0487, 17.0307], [1.3661, 17.1859], [-0.0309, 11.0428]], y: [-0.5, 0.5]}
      - {kind: poly, points: [[-0.7892, 10.8082], [-5.4108, 15.0896], [-5.8865, 14.5761], [-1.2649, 10.2947]], y: [-0.5, 0.5]}
      - {kind: poly, points: [[-1.4409, 9.5206], [-7.4595, 7.6589], [-7.2527, 6.9901], [-1.234, 8.8519]], y: [-0.5, 0.5]}
      - {kind: poly, points: [[-0.6517, 8.3125], [-2.0487, 2.1693], [-1.3661, 2.0141], [0.0309, 8.1572]], y: [-0.5, 0.5]}
      - {kind: poly, points: [[0.7892, 8.3918], [5.4108, 4.1104], [5.8865, 4.6239], [1.2649, 8.9053]], y: [-0.5, 0.5]}
      - {kind: poly, points: [[0.8441, 18.4], [-0.8441, 18.4], [-0.3491, 19.76], [0.3491, 19.76]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-1.4623, 18.3186], [-3.0929, 17.8817], [-2.9668, 19.3235], [-2.2924, 19.5042]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-3.669, 17.6431], [-5.131, 16.799], [-5.3823, 18.2243], [-4.7777, 18.5734]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-5.6257, 16.4194], [-6.8194, 15.2257], [-7.4311, 16.5374], [-6.9374, 17.0311]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-7.199, 14.731], [-8.0431, 13.269], [-8.9734, 14.3777], [-8.6243, 14.9823]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-8.2817, 12.6929], [-8.7186, 11.0623], [-9.9042, 11.8924], [-9.7235, 12.5668]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-8.8, 10.4441], [-8.8, 8.7559], [-10.16, 9.2509], [-10.16, 9.9491]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-8.7186, 8.1377], [-8.2817, 6.5071], [-9.7235, 6.6332], [-9.9042, 7.3076]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-8.0431, 5.931], [-7.199, 4.469], [-8.6243, 4.2177], [-8.9734, 4.8223]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-6.8194, 3.9743], [-5.6257, 2.7806], [-6.9374, 2.1689], [-7.4311, 2.6626]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-5.131, 2.401], [-3.669, 1.5569], [-4.7777, 0.6266], [-5.3823, 0.9757]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-3.0929, 1.3183], [-1.4623, 0.8814], [-2.2924, -0.3042], [-2.9668, -0.1235]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-0.8441, 0.8], [0.8441, 0.8], [0.3491, -0.56], [-0.3491, -0.56]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[1.4623, 0.8814], [3.0929, 1.3183], [2.9668, -0.1235], [2.2924, -0.3042]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[3.669, 1.5569], [5.131, 2.401], [5.3823, 0.9757], [4.7777, 0.6266]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[5.6257, 2.7806], [6.8194, 3.9743], [7.4311, 2.6626], [6.9374, 2.1689]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[7.199, 4.469], [8.0431, 5.931], [8.9734, 4.8223], [8.6243, 4.2177]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[8.2817, 6.5071], [8.7186, 8.1377], [9.9042, 7.3076], [9.7235, 6.6332]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[8.8, 8.7559], [8.8, 10.4441], [10.16, 9.9491], [10.16, 9.2509]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[8.7186, 11.0623], [8.2817, 12.6929], [9.7235, 12.5668], [9.9042, 11.8924]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[8.0431, 13.269], [7.199, 14.731], [8.6243, 14.9823], [8.9734, 14.3777]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[6.8194, 15.2257], [5.6257, 16.4194], [6.9374, 17.0311], [7.4311, 16.5374]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[5.131, 16.799], [3.669, 17.6431], [4.7777, 18.5734], [5.3823, 18.2243]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[3.0929, 17.8817], [1.4623, 18.3186], [2.2924, 19.5042], [2.9668, 19.3235]], y: [-0.6, 0.6], collide: 1}
      - {kind: rod, from: [6.0, -1.6, 9.6], to: [6.0, -0.5, 9.6], radius: 0.4, collide: 0, color: "#8f8a80"}   # the crank-wrist
  - id: gear_2
    shape: part
    pos: [0.0, 0, -9.6]
    density: 7800
    friction: 0.1
    color: "#d0c6ac"
    pieces:
      - {kind: disc, center: [0.0, -9.6], radius: 8.75, inner: 7.7, y: [-0.6, 0.6]}
      - {kind: disc, center: [0.0, -9.6], radius: 1.5, inner: 0.7, y: [-0.6, 0.6]}
      - {kind: poly, points: [[1.4409, -9.5206], [7.4595, -7.6589], [7.2527, -6.9901], [1.234, -8.8519]], y: [-0.5, 0.5]}
      - {kind: poly, points: [[0.6517, -8.3125], [2.0487, -2.1693], [1.3661, -2.0141], [-0.0309, -8.1572]], y: [-0.5, 0.5]}
      - {kind: poly, points: [[-0.7892, -8.3918], [-5.4108, -4.1104], [-5.8865, -4.6239], [-1.2649, -8.9053]], y: [-0.5, 0.5]}
      - {kind: poly, points: [[-1.4409, -9.6794], [-7.4595, -11.5411], [-7.2527, -12.2099], [-1.234, -10.3481]], y: [-0.5, 0.5]}
      - {kind: poly, points: [[-0.6517, -10.8875], [-2.0487, -17.0307], [-1.3661, -17.1859], [0.0309, -11.0428]], y: [-0.5, 0.5]}
      - {kind: poly, points: [[0.7892, -10.8082], [5.4108, -15.0896], [5.8865, -14.5761], [1.2649, -10.2947]], y: [-0.5, 0.5]}
      - {kind: poly, points: [[-0.3118, -0.7651], [-1.9855, -0.9855], [-1.6723, 0.4275], [-0.98, 0.5186]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-2.5878, -1.1468], [-4.1475, -1.7929], [-4.2106, -0.347], [-3.5655, -0.0798]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-4.6874, -2.1046], [-6.0268, -3.1323], [-6.462, -1.752], [-5.9081, -1.327]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-6.4677, -3.5732], [-7.4954, -4.9126], [-8.273, -3.6919], [-7.848, -3.138]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-7.8071, -5.4525], [-8.4532, -7.0122], [-9.5202, -6.0345], [-9.253, -5.3894]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-8.6145, -7.6145], [-8.8349, -9.2882], [-10.1186, -8.62], [-10.0275, -7.9277]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-8.8349, -9.9118], [-8.6145, -11.5855], [-10.0275, -11.2723], [-10.1186, -10.58]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-8.4532, -12.1878], [-7.8071, -13.7475], [-9.253, -13.8106], [-9.5202, -13.1655]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-7.4954, -14.2874], [-6.4677, -15.6268], [-7.848, -16.062], [-8.273, -15.5081]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-6.0268, -16.0677], [-4.6874, -17.0954], [-5.9081, -17.873], [-6.462, -17.448]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-4.1475, -17.4071], [-2.5878, -18.0532], [-3.5655, -19.1202], [-4.2106, -18.853]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-1.9855, -18.2145], [-0.3118, -18.4349], [-0.98, -19.7186], [-1.6723, -19.6275]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[0.3118, -18.4349], [1.9855, -18.2145], [1.6723, -19.6275], [0.98, -19.7186]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[2.5878, -18.0532], [4.1475, -17.4071], [4.2106, -18.853], [3.5655, -19.1202]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[4.6874, -17.0954], [6.0268, -16.0677], [6.462, -17.448], [5.9081, -17.873]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[6.4677, -15.6268], [7.4954, -14.2874], [8.273, -15.5081], [7.848, -16.062]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[7.8071, -13.7475], [8.4532, -12.1878], [9.5202, -13.1655], [9.253, -13.8106]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[8.6145, -11.5855], [8.8349, -9.9118], [10.1186, -10.58], [10.0275, -11.2723]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[8.8349, -9.2882], [8.6145, -7.6145], [10.0275, -7.9277], [10.1186, -8.62]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[8.4532, -7.0122], [7.8071, -5.4525], [9.253, -5.3894], [9.5202, -6.0345]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[7.4954, -4.9126], [6.4677, -3.5732], [7.848, -3.138], [8.273, -3.6919]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[6.0268, -3.1323], [4.6874, -2.1046], [5.9081, -1.327], [6.462, -1.752]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[4.1475, -1.7929], [2.5878, -1.1468], [3.5655, -0.0798], [4.2106, -0.347]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[1.9855, -0.9855], [0.3118, -0.7651], [0.98, 0.5186], [1.6723, 0.4275]], y: [-0.6, 0.6], collide: 2}
      - {kind: rod, from: [4.5963, -1.6, -13.4567], to: [4.5963, -0.5, -13.4567], radius: 0.4, collide: 0, color: "#8f8a80"}   # the crank-wrist
  - id: rod_1
    shape: part
    pos: [6.0, 0, 9.6]
    mount: gear_1
    mass: 0.2
    color: "#b8ad97"
    pieces:
      - {kind: disc, center: [6.0, 9.6], radius: 0.8, inner: 0.3, y: [-1.5, -0.9]}
      - {kind: poly, points: [[6.0883, 10.0413], [24.0883, 6.4413], [23.9117, 5.5587], [5.9117, 9.1587]], y: [-1.5, -0.9]}
      - {kind: disc, center: [24.0, 6.0], radius: 0.7, inner: 0.3, y: [-1.5, -0.9]}
  - id: rod_2
    shape: part
    pos: [4.5963, 0, -13.4567]
    mount: gear_2
    mass: 0.2
    color: "#b8ad97"
    pieces:
      - {kind: disc, center: [4.5963, -13.4567], radius: 0.8, inner: 0.3, y: [-1.5, -0.9]}
      - {kind: poly, points: [[4.4348, -13.0367], [23.8386, -5.5799], [24.1614, -6.4201], [4.7577, -13.8768]], y: [-1.5, -0.9]}
      - {kind: disc, center: [24.0, -6.0], radius: 0.7, inner: 0.3, y: [-1.5, -0.9]}
  - id: bar_x
    shape: part
    pos: [24.0, 0, 0]
    mass: 0.5
    color: "#9a8c74"
    pieces:
      - {kind: poly, points: [[25.0, -0.5], [44.0, -0.5], [44.0, 0.5], [25.0, 0.5]], y: [-2.2, -1.6]}   # the horizontal bar
      - {kind: disc, center: [24.0, 0], radius: 1.1, inner: 0.3, y: [-2.2, -1.6]}   # its eye, where the link is pinned
  - id: link
    shape: part
    pos: [24.0, 0, 0]
    mount: bar_x
    mass: 0.3
    color: "#a89d89"
    pieces:
      - {kind: poly, points: [[23.5, -6.0], [24.5, -6.0], [24.5, 6.0], [23.5, 6.0]], y: [-1.6, -1.0]}   # the link
      - {kind: rod, from: [24.0, -2.3, 0], to: [24.0, -1.0, 0], radius: 0.3, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [24.0, -1.7, 6.0], to: [24.0, -0.8, 6.0], radius: 0.3, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [24.0, -1.7, -6.0], to: [24.0, -0.8, -6.0], radius: 0.3, collide: 0, color: "#8f8a80"}
  - id: frame
    shape: part
    pos: [0, 0, 0]
    fixed: true
    color: "#cfc6b4"
    pieces:
      - {kind: rod, from: [0.0, 0.6, 9.600000000000001], to: [0.0, 2.0, 9.600000000000001], radius: 0.6, color: "#8f8a80"}
      - {kind: rod, from: [0.0, 0.6, -9.600000000000001], to: [0.0, 2.0, -9.600000000000001], radius: 0.6, color: "#8f8a80"}
      - {kind: poly, points: [[-1.0, -10.600000000000001], [1.0, -10.600000000000001], [1.0, 10.600000000000001], [-1.0, 10.600000000000001]], y: [1.4, 2.2]}   # the standard of the two shafts
      - {kind: poly, points: [[30.0, -1.7], [48.0, -1.7], [48.0, -1.0], [30.0, -1.0]], y: [-2.5, -1.3]}   # the guide
      - {kind: poly, points: [[30.0, 1.0], [48.0, 1.0], [48.0, 1.7], [30.0, 1.7]], y: [-2.5, -1.3]}
joints:
  - {id: j_1, type: hinge, body: gear_1, axis: [0, 1, 0], damping: 0.002}   # the one driven joint; + : clockwise
  - {id: j_2, type: hinge, body: gear_2, axis: [0, 1, 0], damping: 0.002}
  - {id: j_r1, type: hinge, body: rod_1, axis: [0, 1, 0], damping: 0.001}
  - {id: j_r2, type: hinge, body: rod_2, axis: [0, 1, 0], damping: 0.001}
  - {id: j_x, type: slide, body: bar_x, axis: [1, 0, 0], damping: 0.05}   # the horizontal bar; + : to the right
  - {id: j_l, type: hinge, body: link, axis: [0, 1, 0], damping: 0.001}   # the link on the bar
pins:
  - {id: pin_1, a: rod_1, b: link, at: [24.0, 0, 6.0]}
  - {id: pin_2, a: rod_2, b: link, at: [24.0, 0, -6.0]}
contact: {solref: [0.002, 1.0], solimp: [0.95, 0.99, 0.0005], margin: 0}
driver: {joint: j_1, kind: velocity, rpm: 20.0, kv: 1.0, max_torque: 20.0}
checks:
  - {type: follow, out: j_x, in: j_1, expect: -0.05169, tol: 0.0026, min_r2: 0.98, settle_s: 3.6333, window_s: 0.3333}   # (second turn) the gears at 70-110 degrees: the bar goes fast to the left
  - {type: follow, out: j_x, in: j_1, expect: -0.04378, tol: 0.0022, min_r2: 0.98, settle_s: 4.1333, window_s: 0.3333}   # 130-170: slower
  - {type: follow, out: j_x, in: j_1, expect: 0.02877, tol: 0.0015, min_r2: 0.95, settle_s: 4.9667, window_s: 0.3333}   # 230-270: coming back, slower still
  - {type: follow, out: j_x, in: j_1, expect: 0.06029, tol: 0.003, min_r2: 0.95, settle_s: 5.55, window_s: 0.3333}   # 300-340: and twice as fast again
  - {type: position, joint: j_x, min: -11.0, max: 1.1, settle_s: 0.0, window_s: 9}   # the stroke: about 11.5 cm
camera: {target: [14.0, 0, 0], position: [14.0, -95.0, 0], fov: 34}
display:
  output: j_x
  labels: {j_1: "Upper gear (driver)", j_2: "Lower gear", j_x: "Horizontal bar"}
  proof: {label: "Gear teeth out of contact", sub: "the upper gear turns but the lower and the bar stand"}

