# No. 35, Variable rotary motion produced by uniform rotary motion (Brown 1868).
#
# "Variable rotary motion produced by uniform rotary motion. The small spur-pinion works in a slot
#  cut in the bar, which turns loosely upon the shaft of the elliptical gear. The bearing of the
#  pinion-shaft has applied to it a spring, which keeps it engaged; the slot in the bar is to allow
#  for the variation of length of radius of the elliptical gear."
#
# Laid out as in the plate (1 unit = 1 cm; the drawing plane is x-z, depth is y): an elliptical
# gear (semi-axes 12 and 8, 40 teeth at equal arc pitch 1.587) turns on a shaft through its CENTRE.
# A bar hangs loosely on that shaft and stands up in front of the gear; in the bar's slot slides
# the pinion's bearing (a carriage), and in that bearing turns a 12-tooth pinion (pitch radius
# 3.03), pressed down onto the gear by a spring (200 N/m, 2 N preload) and its own weight. Teeth
# straight-flanked (20 deg), each its own convex piece (generator: opencode-runs/batch7/gen035.py).
#
# Fully physical. Only the pinion is motor-driven, at a uniform 30 rpm in its bearing. The gear
# turns by tooth contact alone at r_p/R of the pinion's speed, R the gear's radius under the
# pinion: from 3.03/12 = 0.25 (major vertex) to 3.03/8 = 0.38 (minor vertex), 12/40 = 0.3 on the
# mean, while the carriage rides 4 cm up and down the slot. The bar's own centring spring (a light
# 5 N·m/rad on its loose bearing) keeps it standing; it rocks a little with the tooth load.
number: 35
slug: variable-rotary-motion-from-uniform
name: Variable rotary motion produced by uniform rotary motion
brown: "Variable rotary motion produced by uniform rotary motion. The small spur-pinion works in a slot cut in the bar, which turns loosely upon the shaft of the elliptical gear. The bearing of the pinion-shaft has applied to it a spring, which keeps it engaged; the slot in the bar is to allow for the variation of length of radius of the elliptical gear."
units: cm
sim:
  timestep: 0.0002
  integrator: implicitfast
  iterations: 100
  solver: CG
  multiccd: true
  duration_s: 10
  floor: false
bodies:
  - id: gear
    shape: part
    pos: [0, 0, 0]
    density: 7800
    friction: 0.1
    color: "#e8dec6"
    pieces:
      - {kind: disc, center: [0, 0], radius: 1.5, y: [-1.0, 1.0], collide: 0}   # hub
      - {kind: poly, points: [[11.4771, 0.0], [11.4117, 0.7921], [11.2192, 1.567], [10.9096, 2.3098], [10.4967, 3.0094], [9.9961, 3.6588], [9.4224, 4.2542], [8.7887, 4.7946], [8.1062, 5.2805], [7.384, 5.7132], [6.6295, 6.0944], [5.8491, 6.426], [5.0476, 6.7096], [4.2295, 6.9469], [3.3982, 7.1393], [2.557, 7.2877], [1.7086, 7.3931], [0.8554, 7.4561], [0.0, 7.4771], [-0.8554, 7.4561], [-1.7086, 7.3931], [-2.557, 7.2877], [-3.3982, 7.1393], [-4.2295, 6.9469], [-5.0476, 6.7096], [-5.8491, 6.426], [-6.6295, 6.0944], [-7.384, 5.7132], [-8.1062, 5.2805], [-8.7887, 4.7946], [-9.4224, 4.2542], [-9.9961, 3.6588], [-10.4967, 3.0094], [-10.9096, 2.3098], [-11.2192, 1.567], [-11.4117, 0.7921], [-11.4771, 0.0], [-11.4117, -0.7921], [-11.2192, -1.567], [-10.9096, -2.3098], [-10.4967, -3.0094], [-9.9961, -3.6588], [-9.4224, -4.2542], [-8.7887, -4.7946], [-8.1062, -5.2805], [-7.384, -5.7132], [-6.6295, -6.0944], [-5.8491, -6.426], [-5.0476, -6.7096], [-4.2295, -6.9469], [-3.3982, -7.1393], [-2.557, -7.2877], [-1.7086, -7.3931], [-0.8554, -7.4561], [-0.0, -7.4771], [0.8554, -7.4561], [1.7086, -7.3931], [2.557, -7.2877], [3.3982, -7.1393], [4.2295, -6.9469], [5.0476, -6.7096], [5.8491, -6.426], [6.6295, -6.0944], [7.384, -5.7132], [8.1062, -5.2805], [8.7887, -4.7946], [9.4224, -4.2542], [9.9961, -3.6588], [10.4967, -3.0094], [10.9096, -2.3098], [11.2192, -1.567], [11.4117, -0.7921]], y: [-0.6, 0.6], collide: 0}   # the plate, inside the root curve
      - {kind: poly, points: [[-0.1985, 7.4053], [-1.3343, 7.3551], [-0.9896, 8.4503], [-0.6384, 8.4658]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-1.729, 7.3203], [-2.8558, 7.1688], [-2.6105, 8.2903], [-2.262, 8.3372]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-3.2434, 7.0988], [-4.3511, 6.8426], [-4.2117, 7.9822], [-3.8691, 8.0614]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-4.7261, 6.737], [-5.8024, 6.3705], [-5.7784, 7.5183], [-5.4456, 7.6316]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-6.1579, 6.2286], [-7.1863, 5.7437], [-7.2912, 6.887], [-6.9732, 7.037]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-7.5139, 5.5656], [-8.471, 4.952], [-8.7227, 6.0721], [-8.4267, 6.2619]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-8.7593, 4.7389], [-9.6107, 3.9855], [-10.0316, 5.0536], [-9.7683, 5.2866]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-9.8458, 3.7418], [-10.5404, 2.8418], [-11.1546, 3.8118], [-10.9398, 4.0902]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-10.7071, 2.5762], [-11.1751, 1.54], [-11.9967, 2.3419], [-11.852, 2.6624]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-11.2612, 1.2638], [-11.4287, 0.1393], [-12.438, 0.6866], [-12.3862, 1.0344]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-11.4287, -0.1393], [-11.2612, -1.2638], [-12.3862, -1.0344], [-12.438, -0.6866]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-11.1751, -1.54], [-10.7071, -2.5762], [-11.852, -2.6624], [-11.9967, -2.3419]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-10.5404, -2.8418], [-9.8458, -3.7418], [-10.9398, -4.0902], [-11.1546, -3.8118]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-9.6107, -3.9855], [-8.7593, -4.7389], [-9.7683, -5.2866], [-10.0316, -5.0536]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-8.471, -4.952], [-7.5139, -5.5656], [-8.4267, -6.2619], [-8.7227, -6.0721]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-7.1863, -5.7437], [-6.1579, -6.2286], [-6.9732, -7.037], [-7.2912, -6.887]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-5.8024, -6.3705], [-4.7261, -6.737], [-5.4456, -7.6316], [-5.7784, -7.5183]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-4.3511, -6.8426], [-3.2434, -7.0988], [-3.8691, -8.0614], [-4.2117, -7.9822]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-2.8558, -7.1688], [-1.729, -7.3203], [-2.262, -8.3372], [-2.6105, -8.2903]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-1.3343, -7.3551], [-0.1985, -7.4053], [-0.6384, -8.4658], [-0.9896, -8.4503]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[0.1985, -7.4053], [1.3343, -7.3551], [0.9896, -8.4503], [0.6384, -8.4658]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[1.729, -7.3203], [2.8558, -7.1688], [2.6105, -8.2903], [2.262, -8.3372]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[3.2434, -7.0988], [4.3511, -6.8426], [4.2117, -7.9822], [3.8691, -8.0614]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[4.7261, -6.737], [5.8024, -6.3705], [5.7784, -7.5183], [5.4456, -7.6316]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[6.1579, -6.2286], [7.1863, -5.7437], [7.2912, -6.887], [6.9732, -7.037]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[7.5139, -5.5656], [8.471, -4.952], [8.7227, -6.0721], [8.4267, -6.2619]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[8.7593, -4.7389], [9.6107, -3.9855], [10.0316, -5.0536], [9.7683, -5.2866]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[9.8458, -3.7418], [10.5404, -2.8418], [11.1546, -3.8118], [10.9398, -4.0902]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[10.7071, -2.5762], [11.1751, -1.54], [11.9967, -2.3419], [11.852, -2.6624]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[11.2612, -1.2638], [11.4287, -0.1393], [12.438, -0.6866], [12.3862, -1.0344]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[11.4287, 0.1393], [11.2612, 1.2638], [12.3862, 1.0344], [12.438, 0.6866]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[11.1751, 1.54], [10.7071, 2.5762], [11.852, 2.6624], [11.9967, 2.3419]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[10.5404, 2.8418], [9.8458, 3.7418], [10.9398, 4.0902], [11.1546, 3.8118]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[9.6107, 3.9855], [8.7593, 4.7389], [9.7683, 5.2866], [10.0316, 5.0536]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[8.471, 4.952], [7.5139, 5.5656], [8.4267, 6.2619], [8.7227, 6.0721]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[7.1863, 5.7437], [6.1579, 6.2286], [6.9732, 7.037], [7.2912, 6.887]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[5.8024, 6.3705], [4.7261, 6.737], [5.4456, 7.6316], [5.7784, 7.5183]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[4.3511, 6.8426], [3.2434, 7.0988], [3.8691, 8.0614], [4.2117, 7.9822]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[2.8558, 7.1688], [1.729, 7.3203], [2.262, 8.3372], [2.6105, 8.2903]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[1.3343, 7.3551], [0.1985, 7.4053], [0.6384, 8.4658], [0.9896, 8.4503]], y: [-0.6, 0.6], collide: 1}
  - id: bar
    shape: part
    pos: [0, 0, 0]
    density: 2700
    color: "#a39d90"
    pieces:
      - {kind: disc, center: [0, 0], radius: 1.8, inner: 0.6, y: [-2.4, -1.6], collide: 0}       # its eye on the gear's shaft
      - {kind: poly, points: [[-0.6, 1.5], [0.6, 1.5], [0.6, 8.8], [-0.6, 8.8]], y: [-2.4, -1.6], collide: 0}
      - {kind: poly, points: [[-1.6, 8.8], [-0.7, 8.8], [-0.7, 17.5], [-1.6, 17.5]], y: [-2.4, -1.6], collide: 0}   # the slot's two cheeks
      - {kind: poly, points: [[0.7, 8.8], [1.6, 8.8], [1.6, 17.5], [0.7, 17.5]], y: [-2.4, -1.6], collide: 0}
      - {kind: poly, points: [[-1.6, 17.5], [1.6, 17.5], [1.6, 18.3], [-1.6, 18.3]], y: [-2.4, -1.6], collide: 0}
  - id: carriage
    shape: part
    mount: bar
    pos: [0, 0, 11.0301]
    density: 2700
    color: "#8f8a80"
    pieces:
      - {kind: poly, points: [[-0.68, 10.3], [0.68, 10.3], [0.68, 11.76], [-0.68, 11.76]], y: [-2.6, -1.4], collide: 0}   # the bearing block in the slot
  - id: pinion
    shape: part
    mount: carriage
    pos: [0, 0, 11.0301]
    density: 7800
    friction: 0.1
    color: "#e4d9bf"
    pieces:
      - {kind: disc, center: [0, 11.0301], radius: 2.3, y: [-0.6, 0.6], collide: 0}
      - {kind: rod, from: [0, -3.2, 11.0301], to: [0, 0.6, 11.0301], radius: 0.4, collide: 0}   # its shaft through the bearing
      - {kind: poly, points: [[-0.5685, 8.6029], [0.5685, 8.6029], [0.1758, 7.524], [-0.1758, 7.524]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[0.7213, 8.6438], [1.7059, 9.2123], [1.9053, 8.0817], [1.6008, 7.9059]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[1.8178, 9.3242], [2.3862, 10.3088], [3.1242, 9.4293], [2.9484, 9.1248]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[2.4272, 10.4616], [2.4272, 11.5985], [3.506, 11.2059], [3.506, 10.8543]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[2.3862, 11.7514], [1.8178, 12.736], [2.9484, 12.9353], [3.1242, 12.6308]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[1.7059, 12.8478], [0.7213, 13.4163], [1.6008, 14.1543], [1.9053, 13.9785]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[0.5685, 13.4573], [-0.5685, 13.4573], [-0.1758, 14.5361], [0.1758, 14.5361]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-0.7213, 13.4163], [-1.7059, 12.8478], [-1.9053, 13.9785], [-1.6008, 14.1543]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-1.8178, 12.736], [-2.3862, 11.7514], [-3.1242, 12.6308], [-2.9484, 12.9353]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-2.4272, 11.5985], [-2.4272, 10.4616], [-3.506, 10.8543], [-3.506, 11.2059]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-2.3862, 10.3088], [-1.8178, 9.3242], [-2.9484, 9.1248], [-3.1242, 9.4293]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-1.7059, 9.2123], [-0.7213, 8.6438], [-1.6008, 7.9059], [-1.9053, 8.0817]], y: [-0.6, 0.6], collide: 2}
  - {id: stubs, shape: frame, rods: [{from: [0, -3.0, 0], to: [0, 2.6, 0], radius: 0.55}], color: "#8f8a80"}
joints:
  - {id: j_gear, type: hinge, body: gear, axis: [0, 1, 0], damping: 0.02}
  - {id: j_bar, type: hinge, body: bar, axis: [0, 1, 0], damping: 0.01, stiffness: 5}
  - {id: j_slide, type: slide, body: carriage, axis: [0, 0, 1], damping: 1, stiffness: 200, springref: -1, range: [-1.5, 5.5]}
  - {id: j_pinion, type: hinge, body: pinion, axis: [0, 1, 0], damping: 0.001}
contact: {solref: [0.002, 1.0], solimp: [0.95, 0.99, 0.0005], margin: 0}
driver: {joint: j_pinion, kind: velocity, rpm: 30, kv: 4, max_torque: 6}
checks:
  - {type: ratio, out: j_gear, in: j_pinion, expect: -0.3, tol: 0.006, settle_s: 1, window_s: 6.67}
  - {type: ratio_range, out: j_gear, in: j_pinion, min: -0.42, max: -0.18, min_swing: 0.09, settle_s: 1, window_s: 6.67}
  - {type: penetration, max: 0.001, settle_s: 0.5}
camera: {target: [0, 0, -0.5], position: [0, -98, 0.5], fov: 34}
display:
  output: j_gear
  labels: {j_pinion: "Pinion (driver, uniform)", j_gear: "Elliptical gear (varying)"}
  proof: {label: "Teeth out of contact", sub: "the pinion turns alone: the elliptical gear stands still"}
