# No. 370 (Brown 1868): "Motion for polishing mirrors, the rubbing of which should be varied as much as practicable. The handle turns the crank to which the long bar and attached ratchet-wheel are connected. The mirror is secured rigidly to the ratchet-wheel. The long bar, which is guided by pins in the lower rail, has both a longitudinal and an oscillating movement, and the ratchet-wheel is caused to rotate intermittently by a click operated by an eccentric on the crank-shaft, and hence the mirror has a compound movement."
#
# Reading of the figure (cm, no gravity: the machine lies flat on the polishing bed, seen from above as Brown draws it): the handle turns
# a crank (4 cm) on the upper rail; the long bar hangs from its pin and passes between guide pins in the lower rail, 40 cm
# below the shaft, so it both slides and swings. The ratchet-wheel (24 teeth) turns on an axle in the bar, 26 cm from the crank-pin,
# with the mirror fast to it. An eccentric on the crank-shaft, set 26 degrees ahead of the pin, works a rod down to the click lever,
# which rocks on the wheel's axle and carries the click; a second, sprung detent on the bar keeps the wheel from running back. So each
# turn of the crank sweeps the mirror up and down and side to side and steps it round by a tooth or so. The one driven joint is the crank,
# 15 rev/min; the clicks are sprung against the teeth. Generator: opencode-runs/batch12/gen370.py.
number: 370
slug: mirror-polishing-motion
name: Motion for polishing mirrors
brown: "Motion for polishing mirrors, the rubbing of which should be varied as much as practicable. The handle turns the crank to which the long bar and attached ratchet-wheel are connected. The mirror is secured rigidly to the ratchet-wheel. The long bar, which is guided by pins in the lower rail, has both a longitudinal and an oscillating movement, and the ratchet-wheel is caused to rotate intermittently by a click operated by an eccentric on the crank-shaft, and hence the mirror has a compound movement."
units: cm
sim: {timestep: 0.0002, integrator: implicitfast, iterations: 80, solver: PGS, multiccd: true, duration_s: 13.5, floor: false, gravity: 0}
bodies:
  - id: crank
    shape: part
    pos: [0, 0, 0]
    density: 7800
    color: "#8f8a80"
    pieces:
      - {kind: disc, center: [0, 0], radius: 5.4, y: [2.0, 2.8], collide: 0, color: "#a39a88"}
      - {kind: rod, from: [0, 2.0, 0], to: [0, 8.0, 0], radius: 0.8, collide: 0}
      - {kind: rod, from: [0.0, -0.6, -4.0], to: [0.0, 2.0, -4.0], radius: 0.45, collide: 0}
      - {kind: disc, center: [1.7535, -3.5952], radius: 2.2, y: [-4.0, -3.0], collide: 0, color: "#b8ad97"}
      - {kind: rod, from: [1.7535, -3.0, -3.5952], to: [1.7535, 2.0, -3.5952], radius: 0.5, collide: 0}
      - {kind: rod, from: [0, 2.4, 0], to: [-6.0, 2.4, 6.0], radius: 0.5, collide: 0}
      - {kind: rod, from: [-6.0, 2.4, 6.0], to: [-6.0, -2.5, 6.0], radius: 0.6, collide: 0, color: "#a88a5c"}
  - id: guide
    shape: part
    pos: [0.0, 0, -40.0]
    mass: 0.05
    color: "#5f5a52"
    pieces:
      - {kind: rod, from: [-1.25, -1.2, -40.0], to: [-1.25, 4.0, -40.0], radius: 0.4, collide: 0}
      - {kind: rod, from: [1.25, -1.2, -40.0], to: [1.25, 4.0, -40.0], radius: 0.4, collide: 0}
  - id: bar
    shape: part
    pos: [0.0, 0, -4.0]
    mount: guide
    density: 2000
    color: "#e4d9bf"
    pieces:
      - {kind: poly, points: [[-0.85, -52.0], [0.85, -52.0], [0.85, -2.8], [-0.85, -2.8]], y: [-0.5, 0.5], collide: 0}
      - {kind: rod, from: [0.0, -2.6, -30.0], to: [0.0, 1.6, -30.0], radius: 0.5, collide: 0, color: "#5f5a52"}
      - {kind: rod, from: [-8.4677, -2.8, -30.7408], to: [-8.4677, 0.5, -30.7408], radius: 0.25, collide: 0, color: "#5f5a52"}
      - {kind: rod, from: [-8.4677, 0.0, -30.7408], to: [-0.85, 0.0, -30.7408], radius: 0.3, collide: 0}
  - id: wheel
    shape: part
    pos: [0.0, 0, -30.0]
    mount: bar
    density: 2000
    friction: 0.2
    color: "#c9a95c"
    pieces:
      - {kind: disc, center: [0.0, -30.0], radius: 4.5, y: [-2.0, -1.0], collide: 0}
      - {kind: poly, points: [[4.3572, -29.3876], [6.1397, -29.1371], [4.6025, -28.0463], [4.0502, -28.2808]], y: [-2.0, -1.0], collide: 1}
      - {kind: poly, points: [[4.0502, -28.2808], [5.7071, -27.5775], [3.9401, -26.9217], [3.4672, -27.2911]], y: [-2.0, -1.0], collide: 1}
      - {kind: poly, points: [[3.4672, -27.2911], [4.8857, -26.1829], [3.0091, -26.0068], [2.648, -26.486]], y: [-2.0, -1.0], collide: 1}
      - {kind: poly, points: [[2.648, -26.486], [3.7313, -25.0485], [1.873, -25.3641], [1.6483, -25.9204]], y: [-2.0, -1.0], collide: 1}
      - {kind: poly, points: [[1.6483, -25.9204], [2.3226, -24.2515], [0.6093, -25.0373], [0.5362, -25.6328]], y: [-2.0, -1.0], collide: 1}
      - {kind: poly, points: [[0.5362, -25.6328], [0.7556, -23.8462], [-0.6959, -25.0487], [-0.6124, -25.6428]], y: [-2.0, -1.0], collide: 1}
      - {kind: poly, points: [[-0.6124, -25.6428], [-0.8629, -23.8603], [-1.9537, -25.3975], [-1.7192, -25.9498]], y: [-2.0, -1.0], collide: 1}
      - {kind: poly, points: [[-1.7192, -25.9498], [-2.4225, -24.2929], [-3.0783, -26.0599], [-2.7089, -26.5328]], y: [-2.0, -1.0], collide: 1}
      - {kind: poly, points: [[-2.7089, -26.5328], [-3.8171, -25.1143], [-3.9932, -26.9909], [-3.514, -27.352]], y: [-2.0, -1.0], collide: 1}
      - {kind: poly, points: [[-3.514, -27.352], [-4.9515, -26.2687], [-4.6359, -28.127], [-4.0796, -28.3517]], y: [-2.0, -1.0], collide: 1}
      - {kind: poly, points: [[-4.0796, -28.3517], [-5.7485, -27.6774], [-4.9627, -29.3907], [-4.3672, -29.4638]], y: [-2.0, -1.0], collide: 1}
      - {kind: poly, points: [[-4.3672, -29.4638], [-6.1538, -29.2444], [-4.9513, -30.6959], [-4.3572, -30.6124]], y: [-2.0, -1.0], collide: 1}
      - {kind: poly, points: [[-4.3572, -30.6124], [-6.1397, -30.8629], [-4.6025, -31.9537], [-4.0502, -31.7192]], y: [-2.0, -1.0], collide: 1}
      - {kind: poly, points: [[-4.0502, -31.7192], [-5.7071, -32.4225], [-3.9401, -33.0783], [-3.4672, -32.7089]], y: [-2.0, -1.0], collide: 1}
      - {kind: poly, points: [[-3.4672, -32.7089], [-4.8857, -33.8171], [-3.0091, -33.9932], [-2.648, -33.514]], y: [-2.0, -1.0], collide: 1}
      - {kind: poly, points: [[-2.648, -33.514], [-3.7313, -34.9515], [-1.873, -34.6359], [-1.6483, -34.0796]], y: [-2.0, -1.0], collide: 1}
      - {kind: poly, points: [[-1.6483, -34.0796], [-2.3226, -35.7485], [-0.6093, -34.9627], [-0.5362, -34.3672]], y: [-2.0, -1.0], collide: 1}
      - {kind: poly, points: [[-0.5362, -34.3672], [-0.7556, -36.1538], [0.6959, -34.9513], [0.6124, -34.3572]], y: [-2.0, -1.0], collide: 1}
      - {kind: poly, points: [[0.6124, -34.3572], [0.8629, -36.1397], [1.9537, -34.6025], [1.7192, -34.0502]], y: [-2.0, -1.0], collide: 1}
      - {kind: poly, points: [[1.7192, -34.0502], [2.4225, -35.7071], [3.0783, -33.9401], [2.7089, -33.4672]], y: [-2.0, -1.0], collide: 1}
      - {kind: poly, points: [[2.7089, -33.4672], [3.8171, -34.8857], [3.9932, -33.0091], [3.514, -32.648]], y: [-2.0, -1.0], collide: 1}
      - {kind: poly, points: [[3.514, -32.648], [4.9515, -33.7313], [4.6359, -31.873], [4.0796, -31.6483]], y: [-2.0, -1.0], collide: 1}
      - {kind: poly, points: [[4.0796, -31.6483], [5.7485, -32.3226], [4.9627, -30.6093], [4.3672, -30.5362]], y: [-2.0, -1.0], collide: 1}
      - {kind: poly, points: [[4.3672, -30.5362], [6.1538, -30.7556], [4.9513, -29.3041], [4.3572, -29.3876]], y: [-2.0, -1.0], collide: 1}
      - {kind: poly, points: [[-8.0, -38.0], [8.0, -38.0], [8.0, -22.0], [-8.0, -22.0]], y: [1.0, 1.6], collide: 0, color: "#b8c4c8"}
  - id: lever
    shape: part
    pos: [0.0, 0, -30.0]
    mount: bar
    mass: 0.04
    color: "#8f8a80"
    pieces:
      - {kind: rod, from: [0.0, -2.6, -30.0], to: [7.3, -2.6, -30.0], radius: 0.35, collide: 0}
      - {kind: rod, from: [0.0, -2.6, -30.0], to: [7.9874, -2.6, -32.9072], radius: 0.35, collide: 0}
      - {kind: rod, from: [7.3, -3.6, -30.0], to: [7.3, -2.4, -30.0], radius: 0.6, collide: 0}
  - id: click
    shape: part
    pos: [7.9874, 0, -32.9072]
    mount: lever
    mass: 0.01
    friction: 0.1
    color: "#b03a2e"
    pieces:
      - {kind: rod, from: [7.9874, -2.6, -32.9072], to: [5.4691, -2.6, -29.5215], radius: 0.22, collide: 0}
      - {kind: rod, from: [5.4691, -2.6, -29.5215], to: [5.4691, -0.9, -29.5215], radius: 0.2, capsule: true, collide: 2}
  - id: detent
    shape: part
    pos: [-8.4677, 0, -30.7408]
    mount: bar
    mass: 0.01
    friction: 0.1
    color: "#b03a2e"
    pieces:
      - {kind: rod, from: [-8.4677, -2.6, -30.7408], to: [-5.1009, -2.6, -32.945], radius: 0.22, collide: 0}
      - {kind: rod, from: [-5.1009, -2.6, -32.945], to: [-5.1009, -0.9, -32.945], radius: 0.2, capsule: true, collide: 2}
  - id: rod
    shape: part
    pos: [1.7535, 0, -3.5952]
    mount: crank
    mass: 0.05
    color: "#a39a88"
    pieces:
      - {kind: rod, from: [1.7535, -3.5, -3.5952], to: [7.3, -3.5, -30.0], radius: 0.4, collide: 0}
      - {kind: disc, center: [1.7535, -3.5952], radius: 2.0, y: [-3.9, -3.1], collide: 0}
  - id: frame
    shape: part
    pos: [0, 0, 0]
    fixed: true
    color: "#cfc6b4"
    pieces:
      - {kind: poly, points: [[-22, -11.5], [22, -11.5], [22, -5.5], [-22, -5.5]], y: [3.2, 5.0], collide: 0, color: "#b9b09c"}
      - {kind: poly, points: [[-24, -42.5], [24, -42.5], [24, -38.5], [-24, -38.5]], y: [3.2, 5.0], collide: 0, color: "#b9b09c"}
      - {kind: poly, points: [[-5, -5.5], [5, -5.5], [5, 3], [-5, 3]], y: [7.0, 8.4], collide: 0}
      - {kind: disc, center: [-19, -40.5], radius: 0.7, y: [3.0, 3.2], collide: 0, color: "#5f5a52"}
      - {kind: disc, center: [-10, -40.5], radius: 0.7, y: [3.0, 3.2], collide: 0, color: "#5f5a52"}
      - {kind: disc, center: [10, -40.5], radius: 0.7, y: [3.0, 3.2], collide: 0, color: "#5f5a52"}
      - {kind: disc, center: [19, -40.5], radius: 0.7, y: [3.0, 3.2], collide: 0, color: "#5f5a52"}
pins:
  - {id: p_pin, a: bar, b: crank, at: [0.0, 0, -4.0]}     # the bar hangs from the crank-pin
  - {id: p_rod, a: rod, b: lever, at: [7.3, -3.0, -30.0]}   # the eccentric rod takes the click lever
joints:
  - {id: j_c, type: hinge, body: crank, axis: [0, -1, 0], damping: 0.002}   # the one driven joint: the handle and crank; + : anticlockwise as drawn
  - {id: j_g, type: hinge, body: guide, axis: [0, -1, 0], damping: 0.0005}   # the guide pins, rocking as the bar swings
  - {id: j_b, type: slide, body: bar, axis: [0, 0, 1], range: [-1.5, 9.5], damping: 0.005}   # the bar, endwise between the pins
  - {id: j_w, type: hinge, body: wheel, axis: [0, -1, 0], damping: 0.001, frictionloss: 0.02}   # the ratchet-wheel and mirror
  - {id: j_l, type: hinge, body: lever, axis: [0, -1, 0], damping: 0.0005}
  - {id: j_k, type: hinge, body: click, axis: [0, -1, 0], range: [-0.5, 0.5], stiffness: 0.03, springref: 0.150, damping: 0.0002}   # the click, sprung to the teeth
  - {id: j_d, type: hinge, body: detent, axis: [0, -1, 0], range: [-0.5, 0.5], stiffness: 0.03, springref: 0.150, damping: 0.0002}   # the detent
  - {id: j_e, type: hinge, body: rod, axis: [0, -1, 0], damping: 0.0005}   # the eccentric rod on its eccentric
contact: {solref: [0.002, 1.0], solimp: [0.95, 0.99, 0.0005], margin: 0}
driver: {joint: j_c, kind: velocity, rpm: 15, kv: 2, max_torque: 5}
checks:
  - {type: ratio, out: j_w, in: j_c, expect: 0.04167, tol: 0.06, settle_s: 1.0, window_s: 12}
  - {type: monotonic, joint: j_w, direction: 1, max_back: 0.05, settle_s: 1.0, window_s: 12}
  - {type: amplitude, joint: j_g, min: 0.09, max: 0.106, sustain: 0.95, settle_s: 1.0, window_s: 12}   # the bar swings on the guide pins (theory asin(4/40) = 0.1002)
  - {type: penetration, max: 0.001, settle_s: 0.5}
camera: {target: [0, 0, -39.0], position: [0, -172.0, -39.0], fov: 34}
display:
  output: j_w
  labels: {j_c: "Handle and crank (driver)", j_b: "Long bar (endwise)", j_g: "Long bar (swing)", j_w: "Ratchet-wheel and mirror"}

