# No. 113 (Brown 1868): "Circular into rectilinear motion, or vice versa, by means of rack and pinion."
#
# Model (cm): a pinion of 16 teeth (module 0.8, pitch radius 6.4, No. 34's straight-flanked teeth) turns on its shaft, the one driven joint, swung to and fro by the hand
# 1.6 rad each way (0.25 swings a second). Above it the rack (17 teeth, pitch 2.5133) is a bar that slides in a line; two rollers (the pins on the back plate, 0.05 cm clear)
# hold its back down against the pinion's push. The rack goes as the pinion's pitch circle, 6.4 cm to the radian, to the right as the pinion turns clockwise, about 10.2 cm each way,
# and the pinion goes where the rack pushes it, as the legend says "or vice versa". Generator: opencode-runs/batch9/gen113.py.
number: 113
slug: rack-and-pinion
name: A pinion and rack changing circular into straight motion
brown: "Circular into rectilinear motion, or vice versa, by means of rack and pinion."
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: [[-0.2646, 5.6571], [-1.9204, 5.3277], [-1.7002, 6.7582], [-1.0154, 6.8944]], y: [-0.8, 0.8], collide: 1}
      - {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}
      - {kind: poly, points: [[-1.9204, -5.3277], [-0.2646, -5.6571], [-1.0154, -6.8944], [-1.7002, -6.7582]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[0.2646, -5.6571], [1.9204, -5.3277], [1.7002, -6.7582], [1.0154, -6.8944]], y: [-0.8, 0.8], collide: 1}
      - {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}
      - {kind: poly, points: [[1.9204, 5.3277], [0.2646, 5.6571], [1.0154, 6.8944], [1.7002, 6.7582]], y: [-0.8, 0.8], collide: 1}
  - id: rack
    shape: part
    pos: [0, 0, 7.65]
    density: 7800
    friction: 0.1
    color: "#b8ad97"
    pieces:
      - {kind: poly, points: [[-21.3628, 7.2], [21.3628, 7.2], [21.3628, 8.1], [-21.3628, 8.1]], y: [-0.8, 0.8], collide: 2}   # the bar
      - {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: [[6.7209, 7.2], [8.3588, 7.2], [7.922, 6.0], [7.1576, 6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[9.2341, 7.2], [10.8721, 7.2], [10.4353, 6.0], [9.6709, 6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[11.7474, 7.2], [13.3853, 7.2], [12.9486, 6.0], [12.1842, 6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[14.2607, 7.2], [15.8986, 7.2], [15.4618, 6.0], [14.6974, 6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[16.774, 7.2], [18.4119, 7.2], [17.9751, 6.0], [17.2107, 6.0]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[19.2872, 7.2], [20.9252, 7.2], [20.4884, 6.0], [19.724, 6.0]], y: [-0.8, 0.8], collide: 2}
  - id: frame
    shape: part
    pos: [0, 0, 0]
    fixed: true
    color: "#cfc6b4"
    pieces:
      - {kind: rod, from: [0, -1.4, 0], to: [0, 2.2, 0], radius: 0.6, color: "#8f8a80"}   # the pinion's shaft
      - {kind: poly, points: [[-24, -9.9], [24, -9.9], [24, 11.55], [-24, 11.55]], y: [1.6, 2.4], collide: 0}   # the plate behind
      - {kind: poly, points: [[-26, -10.9], [26, -10.9], [26, -9.9], [-26, -9.9]], y: [-3, 3], color: "#b9b09c", collide: 0}   # the bench
      - {kind: disc, center: [-9.0, 9.15], radius: 1.0, inner: 0.0, y: [-0.8, 0.8], collide: 2}   # the rollers on the back plate
      - {kind: disc, center: [9.0, 9.15], radius: 1.0, inner: 0.0, y: [-0.8, 0.8], collide: 2}
      - {kind: rod, from: [-9.0, -0.95, 9.15], to: [-9.0, 1.8, 9.15], radius: 0.28, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [9.0, -0.95, 9.15], to: [9.0, 1.8, 9.15], radius: 0.28, collide: 0, color: "#8f8a80"}
joints:
  - {id: j_p, type: hinge, body: pinion, axis: [0, 1, 0], damping: 0.002}   # the one driven joint; + : clockwise
  - {id: j_r, type: slide, body: rack, axis: [1, 0, 0], damping: 0.05}   # + : 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: 0, swing: {amplitude: 1.6, hz: 0.25}, kv: 5.0, max_torque: 20}
checks:
  - {type: follow, out: j_r, in: j_p, expect: 0.064, tol: 0.0019, min_r2: 0.995, settle_s: 0.5, window_s: 3.0}   # the rack goes as the pinion's pitch circle
  - {type: follow, out: j_r, in: j_p, expect: 0.064, tol: 0.0019, min_r2: 0.995, settle_s: 4.5, window_s: 3.0}
  - {type: position, joint: j_r, min: -11.04, max: 11.04, settle_s: 0.0, window_s: 9}
camera: {target: [0, 0, 1.5], position: [0, -70.0, 1.5], fov: 34}
display:
  output: j_r
  labels: {j_p: "Pinion (driver)", j_r: "Rack"}
  proof: {label: "Teeth out of contact", sub: "the pinion turns but the rack stands"}

