# No. 196 (Brown 1868): "The pinion, B, rotates about a fixed axis and gives an irregular vibratory motion to the arm carrying the wheel, A."
#
# Model (cm): B is a 10-tooth pinion (module 0.6, pitch radius 3) on a fixed shaft at the origin. A is an irregular toothed wheel of 20 teeth at the same
# pitch 1.885: its pitch curve r = 5.828 (1 + 0.15 cos phi + 0.16 cos 2 phi), two unequal lobes as in the plate, the teeth straight-flanked (20 deg) at equal
# arc pitch, each square to the curve. A turns on a pin at the end of an arm 17 long whose other end is pivoted on the standard to the right; A rests
# on B by its own and the arm's weight, so as A is turned its radius at the contact changes and the arm rises and falls (-9.1 to
# 0.6 deg in a turn of A), an irregular vibration. Only the pinion is driven (20 rpm). Over a whole turn of A the pinion makes 2
# turns (ratio -10/20), but the speed of A varies through the turn (-0.617 to -0.382 of the pinion's in twelfths of a turn, from the rolling
# kinematics). A weight behind A balances it on its pin. Generator: opencode-runs/batch11/gen196.py.
number: 196
slug: irregular-wheel-arm
name: An irregular wheel on a vibrating arm
brown: "The pinion, B, rotates about a fixed axis and gives an irregular vibratory motion to the arm carrying the wheel, A."
units: cm
sim:
  timestep: 0.0002
  integrator: implicitfast
  iterations: 100
  solver: CG
  multiccd: true
  duration_s: 14.0
bodies:
  - id: arm
    shape: part
    pos: [17.0, 0, 7.9572]
    density: 2700
    color: "#8f8a80"
    pieces:
      - {kind: poly, points: [[0.0, 7.4572], [17.0, 7.4572], [17.0, 8.4572], [0.0, 8.4572]], y: [-1.6, -1.0], collide: 0}   # the arm, in front of A
      - {kind: disc, center: [0.0, 7.9572], radius: 0.9, y: [-1.6, -1.0], collide: 0}   # its eye on A's pin
      - {kind: disc, center: [17.0, 7.9572], radius: 1.1, y: [-1.6, -1.0], collide: 0}   # its eye on the pivot
      - {kind: disc, center: [0.0, 7.9572], radius: 0.45, y: [-1.6, 1.2], collide: 0, color: "#6f6a60"}   # A's pin
  - id: wheel
    shape: part
    mount: arm
    pos: [0.0, 0, 7.9572]
    density: 7800
    friction: 0.1
    color: "#c9b88f"
    pieces:
      - {kind: poly, points: [[0.0, 7.9572], [-5.9267, 11.3675], [-6.1664, 10.8739]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-6.1664, 10.8739], [-6.3381, 10.3427]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-6.3381, 10.3427], [-6.4333, 9.8039]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-6.4333, 9.8039], [-6.4552, 9.249]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-6.4552, 9.249], [-6.4049, 8.7086]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-6.4049, 8.7086], [-6.2844, 8.1735]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-6.2844, 8.1735], [-6.104, 7.6716]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-6.104, 7.6716], [-5.8644, 7.1921]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-5.8644, 7.1921], [-5.5769, 6.7502]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-5.5769, 6.7502], [-5.2568, 6.3563]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-5.2568, 6.3563], [-4.9014, 5.9974]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-4.9014, 5.9974], [-4.5318, 5.6859]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-4.5318, 5.6859], [-4.142, 5.408]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-4.142, 5.408], [-3.752, 5.1702]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-3.752, 5.1702], [-3.3523, 4.9591]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-3.3523, 4.9591], [-2.9603, 4.7771]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-2.9603, 4.7771], [-2.5635, 4.6125]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-2.5635, 4.6125], [-2.1699, 4.4642]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-2.1699, 4.4642], [-1.7863, 4.3308]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-1.7863, 4.3308], [-1.3981, 4.2053]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-1.3981, 4.2053], [-1.0183, 4.0913]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-1.0183, 4.0913], [-0.6315, 3.9856]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-0.6315, 3.9856], [-0.2501, 3.8941]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-0.2501, 3.8941], [0.1414, 3.8166]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [0.1414, 3.8166], [0.53, 3.7598]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [0.53, 3.7598], [0.9302, 3.7261]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [0.9302, 3.7261], [1.3341, 3.7215]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [1.3341, 3.7215], [1.7322, 3.7497]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [1.7322, 3.7497], [2.1354, 3.8158]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [2.1354, 3.8158], [2.5248, 3.9204]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [2.5248, 3.9204], [2.9088, 4.0694]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [2.9088, 4.0694], [3.2676, 4.2581]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [3.2676, 4.2581], [3.6078, 4.4927]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [3.6078, 4.4927], [3.9111, 4.7627]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [3.9111, 4.7627], [4.1826, 5.0745]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [4.1826, 5.0745], [4.4114, 5.4189]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [4.4114, 5.4189], [4.5906, 5.7832]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [4.5906, 5.7832], [4.724, 6.1746]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [4.724, 6.1746], [4.8053, 6.5724]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [4.8053, 6.5724], [4.8375, 6.9844]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [4.8375, 6.9844], [4.8207, 7.3895]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [4.8207, 7.3895], [4.7569, 7.7963]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [4.7569, 7.7963], [4.6521, 8.1856]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [4.6521, 8.1856], [4.5071, 8.5676]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [4.5071, 8.5676], [4.3285, 8.9325]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [4.3285, 8.9325], [4.1255, 9.2733]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [4.1255, 9.2733], [3.8959, 9.6027]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [3.8959, 9.6027], [3.652, 9.9106]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [3.652, 9.9106], [3.3889, 10.2107]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [3.3889, 10.2107], [3.1188, 10.4951]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [3.1188, 10.4951], [2.8337, 10.777]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [2.8337, 10.777], [2.5449, 11.0489]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [2.5449, 11.0489], [2.2419, 11.3223]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [2.2419, 11.3223], [1.9287, 11.5925]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [1.9287, 11.5925], [1.6089, 11.8544]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [1.6089, 11.8544], [1.2677, 12.1156]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [1.2677, 12.1156], [0.9137, 12.3639]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [0.9137, 12.3639], [0.5306, 12.6042]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [0.5306, 12.6042], [0.1292, 12.8227]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [0.1292, 12.8227], [-0.3068, 13.0209]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-0.3068, 13.0209], [-0.7619, 13.1846]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-0.7619, 13.1846], [-1.2509, 13.3121]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-1.2509, 13.3121], [-1.7617, 13.3925]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-1.7617, 13.3925], [-2.2791, 13.4185]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-2.2791, 13.4185], [-2.8142, 13.3852]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-2.8142, 13.3852], [-3.339, 13.2893]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-3.339, 13.2893], [-3.8623, 13.1248]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-3.8623, 13.1248], [-4.355, 12.897]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-4.355, 12.897], [-4.8239, 12.5995]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-4.8239, 12.5995], [-5.2421, 12.2465]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-5.2421, 12.2465], [-5.6152, 11.8313]], y: [-0.3, 0.3], collide: 0}
      - {kind: poly, points: [[0.0, 7.9572], [-5.6152, 11.8313], [-5.9267, 11.3675]], y: [-0.3, 0.3], collide: 0}
      - {kind: disc, center: [2.0789, 6.758], radius: 1.6, y: [0.65, 4.4688], collide: 0, color: "#6f6a60"}   # the balance weight, behind
      - {kind: poly, points: [[-0.1695, 3.7671], [1.0959, 3.6076], [0.4727, 2.3942], [0.1331, 2.437]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[1.4835, 3.6012], [2.7333, 3.8555], [2.5317, 2.5065], [2.1963, 2.4382]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[3.0315, 3.9745], [4.0654, 4.7213], [4.4377, 3.409], [4.1602, 3.2086]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[4.2617, 4.9449], [4.8445, 6.0793], [5.7714, 5.0786], [5.615, 4.7741]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[4.9112, 6.368], [4.9244, 7.6434], [6.2013, 7.1635], [6.1977, 6.8212]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[4.8486, 7.9642], [4.3531, 9.1394], [5.7154, 9.2075], [5.8484, 8.892]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[4.1225, 9.4727], [3.3043, 10.4512], [4.5869, 10.9155], [4.8065, 10.6528]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[2.9322, 10.8081], [1.9859, 11.6631], [3.1913, 12.3014], [3.4454, 12.0719]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[1.5896, 11.9973], [0.5387, 12.72], [1.6494, 13.5117], [1.9315, 13.3178]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[0.1561, 12.9362], [-1.0387, 13.3824], [-0.1532, 14.42], [0.1675, 14.3002]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-1.4208, 13.4677], [-2.6951, 13.521], [-2.1754, 14.7821], [-1.8334, 14.7678]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-3.0581, 13.4763], [-4.2714, 13.0831], [-4.2227, 14.4463], [-3.8971, 14.5518]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-4.5811, 12.9159], [-5.5609, 12.0994], [-6.023, 13.3828], [-5.76, 13.602]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-5.7733, 11.8381], [-6.366, 10.7088], [-7.2842, 11.7175], [-7.1251, 12.0206]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-6.4624, 10.3769], [-6.5773, 9.1067], [-7.8118, 9.6868], [-7.781, 10.0278]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-6.5389, 8.7531], [-6.1779, 7.5299], [-7.5393, 7.6146], [-7.6362, 7.9429]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-6.0086, 7.2011], [-5.2519, 6.1744], [-6.5605, 5.7894], [-6.7636, 6.065]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-4.9628, 5.899], [-3.9331, 5.1464], [-5.0661, 4.3869], [-5.3425, 4.5889]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-3.5347, 4.9382], [-2.364, 4.4321], [-3.3008, 3.4407], [-3.615, 3.5765]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-1.8659, 4.262], [-0.6448, 3.8936], [-1.4616, 2.8012], [-1.7894, 2.9001]], y: [-0.6, 0.6], collide: 1}
  - id: pinion
    shape: part
    pos: [0, 0, 0]
    density: 7800
    friction: 0.1
    color: "#b9ac90"
    pieces:
      - {kind: disc, center: [0, 0], radius: 2.2337, y: [-0.3, 0.3], collide: 0}
      - {kind: disc, center: [0, 0], radius: 0.8, y: [-0.9, 0.9], collide: 0, color: "#8f8a80"}   # the hub
      - {kind: poly, points: [[0.1966, 2.3629], [-1.056, 2.1229], [-0.839, 3.4696], [-0.5028, 3.534]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-1.2298, 2.0272], [-2.1022, 1.0968], [-2.7182, 2.3138], [-2.484, 2.5635]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-2.1865, 0.9171], [-2.3454, -0.3483], [-3.559, 0.2742], [-3.5164, 0.6139]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-2.308, -0.5432], [-1.6927, -1.6604], [-3.0405, -1.8701], [-3.2057, -1.5703]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-1.5479, -1.7961], [-0.3935, -2.3382], [-1.3606, -3.3001], [-1.6705, -3.1546]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-0.1966, -2.3629], [1.056, -2.1229], [0.839, -3.4696], [0.5028, -3.534]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[1.2298, -2.0272], [2.1022, -1.0968], [2.7182, -2.3138], [2.484, -2.5635]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[2.1865, -0.9171], [2.3454, 0.3483], [3.559, -0.2742], [3.5164, -0.6139]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[2.308, 0.5432], [1.6927, 1.6604], [3.0405, 1.8701], [3.2057, 1.5703]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[1.5479, 1.7961], [0.3935, 2.3382], [1.3606, 3.3001], [1.6705, 3.1546]], y: [-0.6, 0.6], collide: 2}
  - id: frame
    shape: part
    pos: [0, 0, 0]
    fixed: true
    density: 7800
    color: "#cfc6b4"
    pieces:
      - {kind: disc, center: [0, 0], radius: 0.5, y: [0.9, 3.0], collide: 0, color: "#6f6a60"}   # B's fixed shaft
      - {kind: disc, center: [17.0, 7.9572], radius: 0.5, y: [-1.0, 3.0], collide: 0, color: "#6f6a60"}   # the arm's pivot pin
      - {kind: poly, points: [[15.4, 1.9572], [18.6, 1.9572], [18.0, 7.9572], [16.0, 7.9572]], y: [1.2, 3.0], collide: 0}   # its standard
      - {kind: poly, points: [[11.0, 0.4572], [23.0, 0.4572], [23.0, 1.9572], [11.0, 1.9572]], y: [-2.0, 3.0], collide: 0, color: "#9c9282"}   # the bench
joints:
  - {id: j_pinion, type: hinge, body: pinion, axis: [0, -1, 0], damping: 0.001}   # the one driven joint; +: counter-clockwise
  - {id: j_arm, type: hinge, body: arm, axis: [0, -1, 0], damping: 0.05, range: [-0.6, 0.6]}   # +: counter-clockwise about the pivot (A's end falls)
  - {id: j_wheel, type: hinge, body: wheel, axis: [0, -1, 0], damping: 0.01}
contact: {solref: [0.002, 1.0], solimp: [0.95, 0.99, 0.0005], margin: 0}
driver: {joint: j_pinion, kind: velocity, rpm: 20.0, kv: 1.5, max_torque: 6}
checks:
  - {type: ratio, out: j_wheel, in: j_pinion, expect: -0.5000, tol: 0.0150, settle_s: 1.0, window_s: 6.000}   # a whole turn of A: -NB/NA
  - {type: ratio_range, out: j_wheel, in: j_pinion, min: -0.710, max: -0.324, min_swing: 0.118, settle_s: 1.0, window_s: 6.000, slices: 12}   # A's speed varies through the turn
  - {type: position, joint: j_arm, min: -0.188, max: 0.040, settle_s: 0.3, window_s: 13.5}
  - {type: amplitude, joint: j_arm, min: 0.0629, max: 0.1048, settle_s: 0.3, window_s: 13.5}
  - {type: penetration, max: 0.001, settle_s: 0.5}
camera: {target: [7.5, 0, 2.9786], position: [7.5, -80, 3.9786], fov: 34}
display:
  output: j_arm
  labels: {j_pinion: "Pinion B (driver)", j_wheel: "Irregular wheel A", j_arm: "Arm carrying A"}
  proof: {label: "Teeth out of contact", sub: "the pinion turns alone: A and its arm stand still"}

