# No. 119 (Brown 1868): "Reciprocating rectilinear motion of the bar carrying the oblong endless rack, produced by the uniform rotary motion of the pinion working alternately above and below the rack. The shaft of the pinion moves up and down in, and is guided by, the slotted bar."
#
# Model (cm): the oblong endless rack is a frame with inside teeth: a run of 4 teeth along the top and the bottom (module 0.8, pitch 2.5133) joined by round ends of 14 teeth each (pitch radius 11.2), on a bar that
# slides in x. The pinion (16 teeth, pitch radius 6.4), the one driven joint, is turned uniformly (12 turns a minute), and its shaft is carried in a slotted bar so that it is free to go up and down, 4.8 cm either way, but not along.
# On the top run the pinion drives the frame 6.4 cm to the radian one way (to the right), then goes round the end's teeth to the bottom run and drives it back; the frame goes to and fro about 19.6531 cm.
# There is no gravity (the plan is flat on the bench) and the shaft slides in oil, so nothing but the teeth sets where it is. Generator: opencode-runs/batch9/gen119.py.
number: 119
slug: oblong-rack-pinion
name: A pinion working above and below an oblong endless rack
brown: "Reciprocating rectilinear motion of the bar carrying the oblong endless rack, produced by the uniform rotary motion of the pinion working alternately above and below the rack. The shaft of the pinion moves up and down in, and is guided by, the slotted bar."
units: cm
sim:
  timestep: 0.0002
  integrator: implicitfast
  iterations: 100
  solver: PGS
  multiccd: true
  duration_s: 12
  gravity: 0
  floor: false
bodies:
  - id: carrier
    shape: part
    pos: [0, 0, 4.8]
    mass: 0.05
    friction: 0.1
    color: "#8f8a80"
    pieces:
      - {kind: rod, from: [0, -1.4, 4.8], to: [0, 2.2, 4.8], radius: 0.6, collide: 0, color: "#8f8a80"}   # the shaft
  - id: pinion
    shape: part
    pos: [0, 0, 4.8]
    mount: carrier
    density: 7800
    friction: 0.1
    color: "#d9cfb6"
    pieces:
      - {kind: disc, center: [0, 4.8], radius: 5.55, inner: 0.6, y: [-0.8, 0.8]}
      - {kind: poly, points: [[0.8441, 10.4], [-0.8441, 10.4], [-0.3491, 11.76], [0.3491, 11.76]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-1.3632, 10.2967], [-2.9229, 9.6507], [-2.986, 11.0966], [-2.341, 11.3638]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-3.3629, 9.3567], [-4.5567, 8.1629], [-5.1683, 9.4746], [-4.6746, 9.9683]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-4.8507, 7.7229], [-5.4967, 6.1632], [-6.5638, 7.141], [-6.2966, 7.786]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-5.6, 5.6441], [-5.6, 3.9559], [-6.96, 4.4509], [-6.96, 5.1491]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-5.4967, 3.4368], [-4.8507, 1.8771], [-6.2966, 1.814], [-6.5638, 2.459]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-4.5567, 1.4371], [-3.3629, 0.2433], [-4.6746, -0.3683], [-5.1683, 0.1254]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-2.9229, -0.0507], [-1.3632, -0.6967], [-2.341, -1.7638], [-2.986, -1.4966]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-0.8441, -0.8], [0.8441, -0.8], [0.3491, -2.16], [-0.3491, -2.16]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[1.3632, -0.6967], [2.9229, -0.0507], [2.986, -1.4966], [2.341, -1.7638]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[3.3629, 0.2433], [4.5567, 1.4371], [5.1683, 0.1254], [4.6746, -0.3683]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[4.8507, 1.8771], [5.4967, 3.4368], [6.5638, 2.459], [6.2966, 1.814]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[5.6, 3.9559], [5.6, 5.6441], [6.96, 5.1491], [6.96, 4.4509]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[5.4967, 6.1632], [4.8507, 7.7229], [6.2966, 7.786], [6.5638, 7.141]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[4.5567, 8.1629], [3.3629, 9.3567], [4.6746, 9.9683], [5.1683, 9.4746]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[2.9229, 9.6507], [1.3632, 10.2967], [2.341, 11.3638], [2.986, 11.0966]], y: [-0.8, 0.8], collide: 1}
  - id: oblong
    shape: part
    pos: [0, 0, 0]
    mass: 0.4
    friction: 0.1
    color: "#b8ad97"
    pieces:
      - {kind: poly, points: [[-9.6154, 12.0], [-7.9775, 12.0], [-8.4143, 10.8], [-9.1787, 10.8]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-7.1021, 12.0], [-5.4642, 12.0], [-5.901, 10.8], [-6.6654, 10.8]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-4.5889, 12.0], [-2.9509, 12.0], [-3.3877, 10.8], [-4.1521, 10.8]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-2.0756, 12.0], [-0.4377, 12.0], [-0.8744, 10.8], [-1.6388, 10.8]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-9.6154, -12.0], [-7.9775, -12.0], [-8.4143, -10.8], [-9.1787, -10.8]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-7.1021, -12.0], [-5.4642, -12.0], [-5.901, -10.8], [-6.6654, -10.8]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-4.5889, -12.0], [-2.9509, -12.0], [-3.3877, -10.8], [-4.1521, -10.8]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-2.0756, -12.0], [-0.4377, -12.0], [-0.8744, -10.8], [-1.6388, -10.8]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[0.5298, 12.0162], [2.1574, 11.8329], [1.589, 10.6893], [0.8294, 10.7749]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[3.1903, 11.5971], [4.7364, 11.0561], [3.9278, 10.0677], [3.2063, 10.3202]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[5.6909, 10.5964], [7.0778, 9.725], [6.0696, 8.9413], [5.4223, 9.348]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[7.9062, 9.0644], [9.0644, 7.9062], [7.907, 7.3665], [7.3665, 7.907]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[9.725, 7.0778], [10.5964, 5.6909], [9.348, 5.4223], [8.9413, 6.0696]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[11.0561, 4.7364], [11.5971, 3.1903], [10.3202, 3.2063], [10.0677, 3.9278]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[11.8329, 2.1574], [12.0162, 0.5298], [10.7749, 0.8294], [10.6893, 1.589]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[12.0162, -0.5298], [11.8329, -2.1574], [10.6893, -1.589], [10.7749, -0.8294]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[11.5971, -3.1903], [11.0561, -4.7364], [10.0677, -3.9278], [10.3202, -3.2063]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[10.5964, -5.6909], [9.725, -7.0778], [8.9413, -6.0696], [9.348, -5.4223]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[9.0644, -7.9062], [7.9062, -9.0644], [7.3665, -7.907], [7.907, -7.3665]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[7.0778, -9.725], [5.6909, -10.5964], [5.4223, -9.348], [6.0696, -8.9413]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[4.7364, -11.0561], [3.1903, -11.5971], [3.2063, -10.3202], [3.9278, -10.0677]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[2.1574, -11.8329], [0.5298, -12.0162], [0.8294, -10.7749], [1.589, -10.6893]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-10.5829, 12.0162], [-12.2105, 11.8329], [-11.6421, 10.6893], [-10.8825, 10.7749]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-13.2434, 11.5971], [-14.7895, 11.0561], [-13.9809, 10.0677], [-13.2594, 10.3202]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-15.744, 10.5964], [-17.1309, 9.725], [-16.1227, 8.9413], [-15.4754, 9.348]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-17.9593, 9.0644], [-19.1175, 7.9062], [-17.9601, 7.3665], [-17.4196, 7.907]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-19.7781, 7.0778], [-20.6495, 5.6909], [-19.4011, 5.4223], [-18.9944, 6.0696]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-21.1092, 4.7364], [-21.6502, 3.1903], [-20.3733, 3.2063], [-20.1208, 3.9278]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-21.8859, 2.1574], [-22.0693, 0.5298], [-20.828, 0.8294], [-20.7424, 1.589]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-22.0693, -0.5298], [-21.8859, -2.1574], [-20.7424, -1.589], [-20.828, -0.8294]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-21.6502, -3.1903], [-21.1092, -4.7364], [-20.1208, -3.9278], [-20.3733, -3.2063]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-20.6495, -5.6909], [-19.7781, -7.0778], [-18.9944, -6.0696], [-19.4011, -5.4223]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-19.1175, -7.9062], [-17.9593, -9.0644], [-17.4196, -7.907], [-17.9601, -7.3665]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-17.1309, -9.725], [-15.744, -10.5964], [-15.4754, -9.348], [-16.1227, -8.9413]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-14.7895, -11.0561], [-13.2434, -11.5971], [-13.2594, -10.3202], [-13.9809, -10.0677]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-12.2105, -11.8329], [-10.5829, -12.0162], [-10.8825, -10.7749], [-11.6421, -10.6893]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-10.0531, 12.1], [0.0, 12.1], [0.0, 13.0], [-10.0531, 13.0]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[-10.0531, -12.1], [0.0, -12.1], [0.0, -13.0], [-10.0531, -13.0]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[0.0, 12.1], [0.0, 13.0], [2.8928, 12.6741], [2.6925, 11.7966]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[2.6925, 11.7966], [2.8928, 12.6741], [5.6405, 11.7126], [5.25, 10.9017]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[5.25, 10.9017], [5.6405, 11.7126], [8.1054, 10.1638], [7.5442, 9.4602]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[7.5442, 9.4602], [8.1054, 10.1638], [10.1638, 8.1054], [9.4602, 7.5442]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[9.4602, 7.5442], [10.1638, 8.1054], [11.7126, 5.6405], [10.9017, 5.25]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[10.9017, 5.25], [11.7126, 5.6405], [12.6741, 2.8928], [11.7966, 2.6925]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[11.7966, 2.6925], [12.6741, 2.8928], [13.0, 0.0], [12.1, 0.0]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[12.1, 0.0], [13.0, 0.0], [12.6741, -2.8928], [11.7966, -2.6925]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[11.7966, -2.6925], [12.6741, -2.8928], [11.7126, -5.6405], [10.9017, -5.25]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[10.9017, -5.25], [11.7126, -5.6405], [10.1638, -8.1054], [9.4602, -7.5442]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[9.4602, -7.5442], [10.1638, -8.1054], [8.1054, -10.1638], [7.5442, -9.4602]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[7.5442, -9.4602], [8.1054, -10.1638], [5.6405, -11.7126], [5.25, -10.9017]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[5.25, -10.9017], [5.6405, -11.7126], [2.8928, -12.6741], [2.6925, -11.7966]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[2.6925, -11.7966], [2.8928, -12.6741], [0.0, -13.0], [0.0, -12.1]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[-10.0531, 12.1], [-10.0531, 13.0], [-12.9459, 12.6741], [-12.7456, 11.7966]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[-12.7456, 11.7966], [-12.9459, 12.6741], [-15.6936, 11.7126], [-15.3031, 10.9017]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[-15.3031, 10.9017], [-15.6936, 11.7126], [-18.1585, 10.1638], [-17.5973, 9.4602]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[-17.5973, 9.4602], [-18.1585, 10.1638], [-20.2169, 8.1054], [-19.5133, 7.5442]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[-19.5133, 7.5442], [-20.2169, 8.1054], [-21.7657, 5.6405], [-20.9548, 5.25]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[-20.9548, 5.25], [-21.7657, 5.6405], [-22.7272, 2.8928], [-21.8497, 2.6925]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[-21.8497, 2.6925], [-22.7272, 2.8928], [-23.0531, 0.0], [-22.1531, 0.0]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[-22.1531, 0.0], [-23.0531, 0.0], [-22.7272, -2.8928], [-21.8497, -2.6925]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[-21.8497, -2.6925], [-22.7272, -2.8928], [-21.7657, -5.6405], [-20.9548, -5.25]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[-20.9548, -5.25], [-21.7657, -5.6405], [-20.2169, -8.1054], [-19.5133, -7.5442]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[-19.5133, -7.5442], [-20.2169, -8.1054], [-18.1585, -10.1638], [-17.5973, -9.4602]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[-17.5973, -9.4602], [-18.1585, -10.1638], [-15.6936, -11.7126], [-15.3031, -10.9017]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[-15.3031, -10.9017], [-15.6936, -11.7126], [-12.9459, -12.6741], [-12.7456, -11.7966]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[-12.7456, -11.7966], [-12.9459, -12.6741], [-10.0531, -13.0], [-10.0531, -12.1]], y: [-0.8, 0.8], collide: 0}
  - id: frame
    shape: part
    pos: [0, 0, 0]
    fixed: true
    color: "#cfc6b4"
    pieces:
      - {kind: poly, points: [[-1.6, -16.0], [-1.0, -16.0], [-1.0, 15.0], [-1.6, 15.0]], y: [1.4, 2.4], collide: 0}   # the slotted bar, behind: the pinion's shaft runs in its slot
      - {kind: poly, points: [[1.0, -16.0], [1.6, -16.0], [1.6, 15.0], [1.0, 15.0]], y: [1.4, 2.4], collide: 0}
      - {kind: poly, points: [[-1.6, 15.0], [1.6, 15.0], [1.6, 16.0], [-1.6, 16.0]], y: [1.4, 2.4], collide: 0}
      - {kind: poly, points: [[-1.6, -16.0], [1.6, -16.0], [1.6, -15.0], [-1.6, -15.0]], y: [1.4, 2.4], collide: 0}
      - {kind: poly, points: [[-30, -17.0], [30, -17.0], [30, -16.0], [-30, -16.0]], y: [-3, 3], color: "#b9b09c", collide: 0}   # the bench
joints:
  - {id: j_p, type: hinge, body: pinion, axis: [0, 1, 0], damping: 0.002}   # the one driven joint; + : clockwise
  - {id: j_z, type: slide, body: carrier, axis: [0, 0, 1], range: [-10.2, 0.6], damping: 5.0}   # the shaft in the slotted bar; + : up
  - {id: j_f, type: slide, body: oblong, axis: [1, 0, 0], range: [-15.8531, 21.853099999999998], damping: 0.05}   # the bar carrying the rack; + : to the right
contact: {solref: [0.002, 1.0], solimp: [0.95, 0.99, 0.0005], margin: 0}
driver: {joint: j_p, kind: velocity, rpm: 12.0, kv: 5.0, max_torque: 20.0}
checks:
  - {type: follow, out: j_f, in: j_p, expect: 0.064, tol: 0.0032, min_r2: 0.99, settle_s: 0.3, window_s: 0.8}   # on the top run
  - {type: follow, out: j_f, in: j_p, expect: -0.064, tol: 0.0032, min_r2: 0.99, settle_s: 3.3, window_s: 1.0}   # on the bottom run: the other way
  - {type: position, joint: j_f, min: -5.6, max: 15.6531, settle_s: 0.0, window_s: 11}   # the bar goes to and fro about 19.6531 cm and comes no further
camera: {target: [7.4265, 0, -1], position: [7.4265, -110.0, -1], fov: 34}
display:
  output: j_f
  labels: {j_p: "Pinion (driver)", j_f: "Oblong rack bar", j_z: "Pinion shaft in slot"}
  proof: {label: "Teeth out of contact", sub: "the pinion turns but the rack bar stands"}

