# No. 131 (Brown 1868): "On rotating the disk carrying the crank-pin working in the slotted arm, reciprocating rectilinear motion is imparted to the rack at the bottom by the vibration of the toothed sector."
#
# Model (cm, no gravity: a plan): a disk of 13.0 cm radius turns on a shaft 18.0 cm above the pivot of an arm (the one driven joint, 12 rpm). A crank-pin 9.0 cm from the disk's centre works in a slot in the arm (7.3 to 28.5 cm from the pivot);
# the arm swings asin(9.0/18.0) = 0.524 rad each way and carries a toothed sector (module 0.8, pitch radius 7.2, straight-flanked 20-degree teeth as No. 34) on its pivot, which works a rack along the bottom: 3.8 cm either side of the middle (7.2 cm to the radian).
# Clockwise swing of the arm drives the rack left. Generator: opencode-runs/batch10/gen131.py.
number: 131
slug: slotted-arm-sector-rack
name: A crank-pin in a slotted arm driving a sector and rack
brown: "On rotating the disk carrying the crank-pin working in the slotted arm, reciprocating rectilinear motion is imparted to the rack at the bottom by the vibration of the toothed sector."
units: cm
sim:
  timestep: 0.0002
  integrator: implicitfast
  iterations: 100
  solver: PGS
  multiccd: true
  duration_s: 12.0
  floor: false
  gravity: 0
bodies:
  - id: disk
    shape: part
    pos: [0, 0, 18.0]
    mass: 1.5
    friction: 0.1
    color: "#d9cfb6"
    pieces:
      - {kind: disc, center: [0, 0], radius: 13.0, inner: 1.6, y: [0.4, 1.9], collide: 0}
      - {kind: rod, from: [0, -0.8, 9.0], to: [0, 0.8, 9.0], radius: 1.0, collide: 2, capsule: true, color: "#8f8a80"}   # the crank-pin (hatched in the plate)
      - {kind: rod, from: [0, -0.1, 18.0], to: [0, 2.6, 18.0], radius: 0.9, collide: 0, color: "#8f8a80"}
  - id: arm
    shape: part
    pos: [0, 0, 0]
    mass: 0.6
    friction: 0.1
    color: "#b8ad97"
    pieces:
      - {kind: poly, points: [[-2.5, 7.3], [-1.2, 7.3], [-1.2, 28.5], [-2.5, 28.5]], y: [-1.4, -0.2], collide: 1}
      - {kind: poly, points: [[1.2, 7.3], [2.5, 7.3], [2.5, 28.5], [1.2, 28.5]], y: [-1.4, -0.2], collide: 1}
      - {kind: poly, points: [[-2.5, 28.5], [2.5, 28.5], [2.5, 29.8], [-2.5, 29.8]], y: [-1.4, -0.2], collide: 0}
      - {kind: poly, points: [[-2.5, 6.0], [2.5, 6.0], [2.5, 7.3], [-2.5, 7.3]], y: [-1.4, -0.2], collide: 0}
      - {kind: poly, points: [[-2.2, 0.0], [2.2, 0.0], [2.2, 6.0], [-2.2, 6.0]], y: [-1.4, -0.2], collide: 0}
      - {kind: disc, center: [0, 0], radius: 2.6, inner: 0.9, y: [-1.7, 0.0], collide: 0}
      - {kind: poly, points: [[0, 0], [-6.2535, -1.1027], [-5.967, -2.1718], [-5.4993, -3.175], [-4.8644, -4.0817], [-4.0817, -4.8644], [-3.175, -5.4993], [-2.1718, -5.967], [-1.1027, -6.2535], [0.0, -6.35], [1.1027, -6.2535], [2.1718, -5.967], [3.175, -5.4993], [4.0817, -4.8644], [4.8644, -4.0817], [5.4993, -3.175], [5.967, -2.1718], [6.2535, -1.1027]], y: [-1.4, -0.2], collide: 0}
      - {kind: poly, points: [[-6.4493, -0.2801], [-6.1562, -1.9426], [-7.5815, -1.6913], [-7.7027, -1.0037]], y: [-1.4, -0.2], collide: 1}
      - {kind: poly, points: [[-5.9646, -2.469], [-5.1205, -3.931], [-6.5458, -4.1823], [-6.8949, -3.5777]], y: [-1.4, -0.2], collide: 1}
      - {kind: poly, points: [[-4.7605, -4.3601], [-3.4672, -5.4453], [-4.7206, -6.1689], [-5.2555, -5.7201]], y: [-1.4, -0.2], collide: 1}
      - {kind: poly, points: [[-2.9821, -5.7253], [-1.3957, -6.3027], [-2.326, -7.4114], [-2.9821, -7.1726]], y: [-1.4, -0.2], collide: 1}
      - {kind: poly, points: [[-0.8441, -6.4], [0.8441, -6.4], [0.3491, -7.76], [-0.3491, -7.76]], y: [-1.4, -0.2], collide: 1}
      - {kind: poly, points: [[1.3957, -6.3027], [2.9821, -5.7253], [2.9821, -7.1726], [2.326, -7.4114]], y: [-1.4, -0.2], collide: 1}
      - {kind: poly, points: [[3.4672, -5.4453], [4.7605, -4.3601], [5.2555, -5.7201], [4.7206, -6.1689]], y: [-1.4, -0.2], collide: 1}
      - {kind: poly, points: [[5.1205, -3.931], [5.9646, -2.469], [6.8949, -3.5777], [6.5458, -4.1823]], y: [-1.4, -0.2], collide: 1}
      - {kind: poly, points: [[6.1562, -1.9426], [6.4493, -0.2801], [7.7027, -1.0037], [7.5815, -1.6913]], y: [-1.4, -0.2], collide: 1}
  - id: rack
    shape: part
    pos: [0, 0, 0]
    mass: 0.4
    friction: 0.1
    color: "#b8ad97"
    pieces:
      - {kind: poly, points: [[-12.5664, -9.0], [12.5664, -9.0], [12.5664, -8.0], [-12.5664, -8.0]], y: [-1.4, -0.2], collide: 0}   # the bar behind the teeth
      - {kind: rod, from: [-16.5664, -0.8, -8.5], to: [16.5664, -0.8, -8.5], radius: 0.5, collide: 0, color: "#a89a7e"}   # the rack's rod, running in bearings
      - {kind: poly, points: [[-12.1287, -8.0], [-10.4908, -8.0], [-10.9275, -6.8], [-11.6919, -6.8]], y: [-1.4, -0.2], collide: 2}
      - {kind: poly, points: [[-9.6154, -8.0], [-7.9775, -8.0], [-8.4143, -6.8], [-9.1787, -6.8]], y: [-1.4, -0.2], collide: 2}
      - {kind: poly, points: [[-7.1021, -8.0], [-5.4642, -8.0], [-5.901, -6.8], [-6.6654, -6.8]], y: [-1.4, -0.2], collide: 2}
      - {kind: poly, points: [[-4.5889, -8.0], [-2.9509, -8.0], [-3.3877, -6.8], [-4.1521, -6.8]], y: [-1.4, -0.2], collide: 2}
      - {kind: poly, points: [[-2.0756, -8.0], [-0.4377, -8.0], [-0.8744, -6.8], [-1.6388, -6.8]], y: [-1.4, -0.2], collide: 2}
      - {kind: poly, points: [[0.4377, -8.0], [2.0756, -8.0], [1.6388, -6.8], [0.8744, -6.8]], y: [-1.4, -0.2], collide: 2}
      - {kind: poly, points: [[2.9509, -8.0], [4.5889, -8.0], [4.1521, -6.8], [3.3877, -6.8]], y: [-1.4, -0.2], collide: 2}
      - {kind: poly, points: [[5.4642, -8.0], [7.1021, -8.0], [6.6654, -6.8], [5.901, -6.8]], y: [-1.4, -0.2], collide: 2}
      - {kind: poly, points: [[7.9775, -8.0], [9.6154, -8.0], [9.1787, -6.8], [8.4143, -6.8]], y: [-1.4, -0.2], collide: 2}
      - {kind: poly, points: [[10.4908, -8.0], [12.1287, -8.0], [11.6919, -6.8], [10.9275, -6.8]], y: [-1.4, -0.2], collide: 2}
  - id: frame
    shape: part
    pos: [0, 0, 0]
    fixed: true
    color: "#cfc6b4"
    pieces:
      - {kind: rod, from: [0, -1.9, 0], to: [0, 2.6, 0], radius: 1.1, collide: 0, color: "#8f8a80"}   # the arm's pivot
      - {kind: poly, points: [[-1.8, -14.0], [1.8, -14.0], [1.4, 0], [-1.4, 0]], y: [2.0, 3.2], collide: 0}   # its standard behind
      - {kind: poly, points: [[-19.5664, -15.0], [19.5664, -15.0], [19.5664, -14.0], [-19.5664, -14.0]], y: [-3, 3], color: "#b9b09c", collide: 0}   # the bench
      - {kind: poly, points: [[-18.5664, -11.2], [-16.1664, -11.2], [-16.1664, -5.8], [-18.5664, -5.8]], y: [-1.6, 0.2], collide: 0}   # the rack's bearings, either end
      - {kind: poly, points: [[16.1664, -11.2], [18.5664, -11.2], [18.5664, -5.8], [16.1664, -5.8]], y: [-1.6, 0.2], collide: 0}
joints:
  - {id: j_d, type: hinge, body: disk, axis: [0, 1, 0], damping: 0.002}   # the one driven joint; + : clockwise
  - {id: j_arm, type: hinge, body: arm, axis: [0, 1, 0], damping: 0.01}   # + : clockwise, the sector's teeth moving left
  - {id: j_x, type: slide, body: rack, axis: [1, 0, 0], damping: 0.05}   # + : right
contact: {solref: [0.002, 1.0], solimp: [0.95, 0.99, 0.0005], margin: 0}
driver: {joint: j_d, kind: velocity, rpm: 12.0, kv: 20.0, max_torque: 30}
checks:
  - {type: follow, out: j_x, in: j_arm, expect: -0.072, tol: 0.0036, min_r2: 0.995, settle_s: 1.0, window_s: 8.0}   # the rack runs left as the sector turns clockwise
  - {type: amplitude, joint: j_arm, min: 0.4869, max: 0.5498, settle_s: 1, window_s: 10}   # the arm's swing: asin(pin radius over the shafts' distance)
  - {type: position, joint: j_x, min: -4.3699, max: 4.3699, settle_s: 0.0, window_s: 12}
camera: {target: [0, 0, 12.0], position: [0, -150.0, 12.0], fov: 34}
display:
  output: j_x
  labels: {j_d: "Disk (driver)", j_arm: "Slotted arm and sector", j_x: "Rack"}
  proof: {label: "Teeth out of contact", sub: "the arm swings but the rack stands"}

