# No. 128 (Brown 1868): "A continuous rotary motion of the shaft carrying the three wipers produces a reciprocating rectilinear motion of the rectangular frame. The shaft must revolve in the direction of the arrow for the parts to be in the position represented."
#
# Model (cm): the shaft turns clockwise at 12.0 rpm, the one driven joint; its three wipers (arms 6.0 cm long with rollers of 1.4 cm radius) are 120 degrees apart. Round them the rectangular frame
# slides to and fro on its lugs in two guides. A block on the bottom of the frame (face -2.8 cm left of the shaft, top -2.0) takes the roller going left across the bottom and is pushed to the left by it;
# a block hanging from the top (face 9.0 cm to the right, bottom 1.0) takes the roller going right across the top and is pushed back. So the frame makes three strokes to a turn of the shaft. Generator: opencode-runs/batch10/gen128.py.
number: 128
slug: three-wipers
name: Three wipers working a rectangular frame
brown: "A continuous rotary motion of the shaft carrying the three wipers produces a reciprocating rectilinear motion of the rectangular frame."
units: cm
sim:
  timestep: 0.0002
  integrator: implicitfast
  iterations: 100
  solver: PGS
  multiccd: true
  duration_s: 10
  floor: false
bodies:
  - id: wipers
    shape: part
    pos: [0, 0, 0]
    density: 7800
    friction: 0.05
    color: "#d9cfb6"
    pieces:
      - {kind: disc, center: [0, 0], radius: 2.0, inner: 0.0, y: [-0.8, 0.8]}
      - {kind: poly, points: [[-0.7, 0.0], [-0.55, 6.0], [0.55, 6.0], [0.7, -0.0]], y: [-0.3, 0.3]}   # an arm
      - {kind: rod, from: [0.0, -0.8, 6.0], to: [0.0, 0.8, 6.0], radius: 1.4, collide: 1, capsule: true, color: "#8f8a80"}   # a roller
      - {kind: poly, points: [[0.35, 0.6062], [5.4712, -2.5237], [4.9212, -3.4763], [-0.35, -0.6062]], y: [-0.3, 0.3]}   # an arm
      - {kind: rod, from: [5.1962, -0.8, -3.0], to: [5.1962, 0.8, -3.0], radius: 1.4, collide: 1, capsule: true, color: "#8f8a80"}   # a roller
      - {kind: poly, points: [[0.35, -0.6062], [-4.9212, -3.4763], [-5.4712, -2.5237], [-0.35, 0.6062]], y: [-0.3, 0.3]}   # an arm
      - {kind: rod, from: [-5.1962, -0.8, -3.0], to: [-5.1962, 0.8, -3.0], radius: 1.4, collide: 1, capsule: true, color: "#8f8a80"}   # a roller
  - id: frame
    shape: part
    pos: [0, 0, 0]
    density: 2000
    friction: 0.05
    color: "#b8ad97"
    pieces:
      - {kind: poly, points: [[-17.1, -9.6], [10.9, -9.6], [10.9, -8.6], [-17.1, -8.6]], y: [-0.8, 0.8]}
      - {kind: poly, points: [[-17.1, 8.6], [10.9, 8.6], [10.9, 9.6], [-17.1, 9.6]], y: [-0.8, 0.8]}
      - {kind: poly, points: [[-17.1, -8.6], [-16.1, -8.6], [-16.1, 8.6], [-17.1, 8.6]], y: [-0.8, 0.8]}
      - {kind: poly, points: [[9.9, -8.6], [10.9, -8.6], [10.9, 8.6], [9.9, 8.6]], y: [-0.8, 0.8]}
      - {kind: poly, points: [[-16.1, -8.6], [-5.9, -8.6], [-5.9, -2.0], [-16.1, -2.0]], y: [-0.8, 0.8], collide: 2, color: "#a89a7e"}
      - {kind: poly, points: [[5.9, 1.0], [9.9, 1.0], [9.9, 8.6], [5.9, 8.6]], y: [-0.8, 0.8], collide: 2, color: "#a89a7e"}
      - {kind: poly, points: [[-20.6, -0.5], [-17.1, -0.5], [-17.1, 0.5], [-20.6, 0.5]], y: [-0.5, 0.5]}
      - {kind: poly, points: [[10.9, -0.5], [14.4, -0.5], [14.4, 0.5], [10.9, 0.5]], y: [-0.5, 0.5]}
  - id: bench
    shape: part
    pos: [0, 0, 0]
    fixed: true
    color: "#cfc6b4"
    pieces:
      - {kind: rod, from: [0, -1.4, 0], to: [0, 2.6, 0], radius: 0.6, color: "#8f8a80"}   # the shaft
      - {kind: poly, points: [[-18.5, -2.2], [-16.0, -2.2], [-16.0, -0.5], [-18.5, -0.5]], y: [-1.2, 1.2], collide: 0, color: "#b9b09c"}
      - {kind: poly, points: [[-18.5, 0.5], [-16.0, 0.5], [-16.0, 2.2], [-18.5, 2.2]], y: [-1.2, 1.2], collide: 0, color: "#b9b09c"}
      - {kind: poly, points: [[16.0, -2.2], [18.5, -2.2], [18.5, -0.5], [16.0, -0.5]], y: [-1.2, 1.2], collide: 0, color: "#b9b09c"}
      - {kind: poly, points: [[16.0, 0.5], [18.5, 0.5], [18.5, 2.2], [16.0, 2.2]], y: [-1.2, 1.2], collide: 0, color: "#b9b09c"}
joints:
  - {id: j_s, type: hinge, body: wipers, axis: [0, 1, 0], damping: 0.002}   # the one driven joint; + : clockwise
  - {id: j_f, type: slide, body: frame, axis: [1, 0, 0], damping: 3.0}   # + : to the right
contact: {solref: [0.002, 1.0], solimp: [0.95, 0.99, 0.0005], margin: 0}
driver: {joint: j_s, kind: velocity, rpm: 12.0, kv: 5, max_torque: 20}
checks:
  - {type: advance, joint: j_s, beat: j_f, expect: 1.0472, tol: 0.02, settle_s: 1.0, window_s: 9}   # three to-and-fro strokes to a turn: the frame passes mid-stroke six times, a sixth of a turn between
  - {type: position, joint: j_f, min: -2.4, max: 2.4, settle_s: 1.0, window_s: 8}
camera: {target: [0, 0, 0], position: [0, -78.0, 0], fov: 34}
display:
  output: j_f
  labels: {j_s: "Shaft with wipers (driver)", j_f: "Frame"}
  proof: {label: "Wipers not touching the frame", sub: "the shaft turns but the frame stands"}

