# No. 114 (Brown 1868): "Uniform circular motion into reciprocating rectilinear motion, by means of mutilated pinion, which drives alternately the top and bottom rack."
#
# Model (cm): a mutilated pinion (16 tooth spaces, module 0.8, pitch radius 6.4, No. 34's straight-flanked teeth) has teeth on 6 of them and is cut down to its root circle round the
# rest; it turns continuously, the one driven joint, 30 turns a minute, on a fixed shaft. It stands inside an oval frame whose top and bottom bars carry racks facing in, and the frame
# slides to and fro on its ways. While the teeth pass the top rack they draw the frame to the right, about 17 cm (the teeth and their entry and exit run a pitch or so past 15.1 cm); they quit it, the frame stands (a drag on its slide stops it, as the
# builders' friction would), and half a turn on they take the bottom rack and draw the frame back to the left. Generator: opencode-runs/batch9/gen114.py.
number: 114
slug: mutilated-pinion-two-racks
name: A mutilated pinion driving the top and bottom rack in turn
brown: "Uniform circular motion into reciprocating rectilinear motion, by means of mutilated pinion, which drives alternately the top and bottom rack."
units: cm
sim:
  timestep: 0.0002
  integrator: implicitfast
  iterations: 100
  solver: PGS
  multiccd: true
  duration_s: 10
  floor: false
bodies:
  - id: pinion
    shape: part
    pos: [0, 0, 0]
    density: 7800
    friction: 0.1
    color: "#d9cfb6"
    pieces:
      - {kind: disc, center: [0, 0], radius: 5.55, inner: 0.6, y: [-0.8, 0.8]}
      - {kind: poly, points: [[-2.4094, 5.1252], [-3.813, 4.1873], [-4.157, 5.5931], [-3.5765, 5.981]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-4.1873, 3.813], [-5.1252, 2.4094], [-5.981, 3.5765], [-5.5931, 4.157]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-5.3277, 1.9204], [-5.6571, 0.2646], [-6.8944, 1.0154], [-6.7582, 1.7002]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-5.6571, -0.2646], [-5.3277, -1.9204], [-6.7582, -1.7002], [-6.8944, -1.0154]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-5.1252, -2.4094], [-4.1873, -3.813], [-5.5931, -4.157], [-5.981, -3.5765]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-3.813, -4.1873], [-2.4094, -5.1252], [-3.5765, -5.981], [-4.157, -5.5931]], y: [-0.8, 0.8], collide: 1}
  - id: oval
    shape: part
    pos: [0, 0, 0]
    density: 2700
    friction: 0.1
    color: "#b8ad97"
    pieces:
      - {kind: poly, points: [[-23.8761, 7.2], [6.2832, 7.2], [6.2832, 8.2], [-23.8761, 8.2]], y: [-0.8, 0.8], collide: 2}   # the top bar
      - {kind: poly, points: [[-23.8761, -8.2], [6.2832, -8.2], [6.2832, -7.2], [-23.8761, -7.2]], y: [-0.8, 0.8], collide: 2}   # the bottom bar
      - {kind: poly, points: [[-23.4384, 7.2], [-21.8005, 7.2], [-22.2373, 6.0], [-23.0017, 6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-20.9252, 7.2], [-19.2872, 7.2], [-19.724, 6.0], [-20.4884, 6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-18.4119, 7.2], [-16.774, 7.2], [-17.2107, 6.0], [-17.9751, 6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-15.8986, 7.2], [-14.2607, 7.2], [-14.6974, 6.0], [-15.4618, 6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-13.3853, 7.2], [-11.7474, 7.2], [-12.1842, 6.0], [-12.9486, 6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-10.8721, 7.2], [-9.2341, 7.2], [-9.6709, 6.0], [-10.4353, 6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-8.3588, 7.2], [-6.7209, 7.2], [-7.1576, 6.0], [-7.922, 6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-5.8455, 7.2], [-4.2076, 7.2], [-4.6443, 6.0], [-5.4087, 6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-3.3322, 7.2], [-1.6943, 7.2], [-2.1311, 6.0], [-2.8955, 6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-0.819, 7.2], [0.819, 7.2], [0.3822, 6.0], [-0.3822, 6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[1.6943, 7.2], [3.3322, 7.2], [2.8955, 6.0], [2.1311, 6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[4.2076, 7.2], [5.8455, 7.2], [5.4087, 6.0], [4.6443, 6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-23.4384, -7.2], [-21.8005, -7.2], [-22.2373, -6.0], [-23.0017, -6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-20.9252, -7.2], [-19.2872, -7.2], [-19.724, -6.0], [-20.4884, -6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-18.4119, -7.2], [-16.774, -7.2], [-17.2107, -6.0], [-17.9751, -6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-15.8986, -7.2], [-14.2607, -7.2], [-14.6974, -6.0], [-15.4618, -6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-13.3853, -7.2], [-11.7474, -7.2], [-12.1842, -6.0], [-12.9486, -6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-10.8721, -7.2], [-9.2341, -7.2], [-9.6709, -6.0], [-10.4353, -6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-8.3588, -7.2], [-6.7209, -7.2], [-7.1576, -6.0], [-7.922, -6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-5.8455, -7.2], [-4.2076, -7.2], [-4.6443, -6.0], [-5.4087, -6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-3.3322, -7.2], [-1.6943, -7.2], [-2.1311, -6.0], [-2.8955, -6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-0.819, -7.2], [0.819, -7.2], [0.3822, -6.0], [-0.3822, -6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[1.6943, -7.2], [3.3322, -7.2], [2.8955, -6.0], [2.1311, -6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[4.2076, -7.2], [5.8455, -7.2], [5.4087, -6.0], [4.6443, -6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-23.8761, 7.3], [-23.8761, 8.2], [-27.0141, 7.5758], [-26.6697, 6.7443]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[-26.6697, 6.7443], [-27.0141, 7.5758], [-29.6744, 5.7983], [-29.038, 5.1619]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[-29.038, 5.1619], [-29.6744, 5.7983], [-31.4519, 3.138], [-30.6204, 2.7936]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[-30.6204, 2.7936], [-31.4519, 3.138], [-32.0761, 0.0], [-31.1761, 0.0]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[-31.1761, 0.0], [-32.0761, 0.0], [-31.4519, -3.138], [-30.6204, -2.7936]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[-30.6204, -2.7936], [-31.4519, -3.138], [-29.6744, -5.7983], [-29.038, -5.1619]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[-29.038, -5.1619], [-29.6744, -5.7983], [-27.0141, -7.5758], [-26.6697, -6.7443]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[-26.6697, -6.7443], [-27.0141, -7.5758], [-23.8761, -8.2], [-23.8761, -7.3]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[6.2832, 7.3], [6.2832, 8.2], [9.4212, 7.5758], [9.0768, 6.7443]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[9.0768, 6.7443], [9.4212, 7.5758], [12.0815, 5.7983], [11.4451, 5.1619]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[11.4451, 5.1619], [12.0815, 5.7983], [13.859, 3.138], [13.0275, 2.7936]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[13.0275, 2.7936], [13.859, 3.138], [14.4832, 0.0], [13.5832, 0.0]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[13.5832, 0.0], [14.4832, 0.0], [13.859, -3.138], [13.0275, -2.7936]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[13.0275, -2.7936], [13.859, -3.138], [12.0815, -5.7983], [11.4451, -5.1619]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[11.4451, -5.1619], [12.0815, -5.7983], [9.4212, -7.5758], [9.0768, -6.7443]], y: [-0.8, 0.8], collide: 0}
      - {kind: poly, points: [[9.0768, -6.7443], [9.4212, -7.5758], [6.2832, -8.2], [6.2832, -7.3]], y: [-0.8, 0.8], collide: 0}
  - id: frame
    shape: part
    pos: [0, 0, 0]
    fixed: true
    color: "#cfc6b4"
    pieces:
      - {kind: rod, from: [0, -1.4, 0], to: [0, 3.0, 0], radius: 0.6, color: "#8f8a80"}   # the pinion's shaft
      - {kind: poly, points: [[-1.4, -12.2], [1.4, -12.2], [1.0, 0], [-1.0, 0]], y: [2.0, 3.0], collide: 0}   # its standard, behind
      - {kind: poly, points: [[-40, -12.2], [42, -12.2], [42, -11.0], [-40, -11.0]], y: [-3, 3], color: "#b9b09c", collide: 0}   # the bench
      - {kind: poly, points: [[-38, -11.0], [-35, -11.0], [-35, -8.5], [-38, -8.5]], y: [-1.6, 1.6], collide: 0}   # the ways' posts
      - {kind: poly, points: [[37, -11.0], [40, -11.0], [40, -8.5], [37, -8.5]], y: [-1.6, 1.6], collide: 0}
      - {kind: poly, points: [[-38, -8.5], [40, -8.5], [40, -8.25], [-38, -8.25]], y: [-1.6, 1.6], collide: 0, color: "#a39a86"}   # the way the oval rides on
joints:
  - {id: j_p, type: hinge, body: pinion, axis: [0, 1, 0], damping: 0.002}   # the one driven joint; + : clockwise
  - {id: j_f, type: slide, body: oval, axis: [1, 0, 0], damping: 60.0}   # + : 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: 30.0, kv: 5.0, max_torque: 20}
checks:
  - {type: follow, out: j_f, in: j_p, expect: 0.064, tol: 0.0019, min_r2: 0.995, settle_s: 0.3, window_s: 0.5}   # the top rack goes as A's pitch circle
  - {type: follow, out: j_f, in: j_p, expect: -0.064, tol: 0.0019, min_r2: 0.995, settle_s: 1.25, window_s: 0.6}   # then the bottom rack, the other way
  - {type: position, joint: j_f, min: -0.5, max: 20.2, settle_s: 0.0, window_s: 9}
camera: {target: [1, 0, 0], position: [1, -80.0, 0], fov: 34}
display:
  output: j_f
  labels: {j_p: "Mutilated pinion (driver)", j_f: "Oval frame"}
  proof: {label: "Pinion's teeth out of contact", sub: "the pinion turns but the frame stands"}

