# No. 93 (Brown 1868): "Crank motion, with the crank-wrist working in a slotted yoke, thereby dispensing with the
# oscillating connecting-rod or pitman."
#
# Model (cm): the crank-disc (6.5 cm, the one driven joint, 30 turns a minute, clockwise in the view) carries the
# crank-wrist 4 cm from its centre. The wrist works by real contact in the horizontal slot of a yoke (1.2 cm
# wide, 0.1 mm clearance a side) whose rod, above and below, slides up and down in fixed guides: the slot lets
# the wrist pass to and fro, and the yoke takes only its height, z = r cos t, 8 cm in all, exactly harmonic.
# Generator: opencode-runs/batch8/gen093.py.
number: 93
slug: crank-slotted-yoke
name: A crank-wrist working in a slotted yoke
brown: "Crank motion, with the crank-wrist working in a slotted yoke, thereby dispensing with the oscillating connecting-rod or pitman."
units: cm
sim:
  timestep: 0.0002
  integrator: implicitfast
  iterations: 100
  solver: PGS
  multiccd: true
  duration_s: 10
  floor: false
bodies:
  - id: crank
    shape: part
    pos: [0, 0, 0]
    mass: 1.5
    friction: 0.05
    color: "#d9cfb6"
    pieces:
      - {kind: rod, from: [0, 0.5, 0], to: [0, 3.0, 0], radius: 0.8, color: "#8f8a80"}   # the crank-shaft
      - {kind: disc, center: [0, 0], radius: 6.5, y: [0.0, 0.5]}   # the crank-disc, behind the yoke
      - {kind: rod, from: [0, 0.0, 4.0], to: [0, -1.3, 4.0], radius: 0.6, collide: 1, capsule: true, color: "#8f8a80"}   # the crank-wrist
  - id: yoke
    shape: part
    pos: [0, 0, 4.0]
    mass: 0.8
    friction: 0.05
    color: "#b8ad97"
    pieces:
      - {kind: poly, points: [[-5.6, 4.609999999999999], [5.6, 4.609999999999999], [5.6, 5.51], [-5.6, 5.51]], y: [-1.2, -0.1], collide: 2}   # the slot's upper face
      - {kind: poly, points: [[-5.6, 2.49], [5.6, 2.49], [5.6, 3.39], [-5.6, 3.39]], y: [-1.2, -0.1], collide: 2}   # its lower face
      - {kind: poly, points: [[-5.6, 5.06], [-6.0056, 4.9793], [-6.3495, 4.7495], [-6.5793, 4.4056], [-6.66, 4.0], [-6.5793, 3.5944], [-6.3495, 3.2505], [-6.0056, 3.0207], [-5.6, 2.94]], y: [-1.2, -0.1]}   # a round end
      - {kind: poly, points: [[5.6, 5.06], [6.0056, 4.9793], [6.3495, 4.7495], [6.5793, 4.4056], [6.66, 4.0], [6.5793, 3.5944], [6.3495, 3.2505], [6.0056, 3.0207], [5.6, 2.94]], y: [-1.2, -0.1]}   # a round end
      - {kind: rod, from: [0, -0.65, 5.51], to: [0, -0.65, 16.0], radius: 0.6}   # the rod above
      - {kind: rod, from: [0, -0.65, 2.49], to: [0, -0.65, -0.20000000000000018], radius: 0.6}   # and below, short of the shaft
  - id: frame
    shape: part
    pos: [0, 0, 0]
    fixed: true
    color: "#cfc6b4"
    pieces:
      - {kind: poly, points: [[-1.4, -12], [1.4, -12], [1.0, 0], [-1.0, 0]], y: [1.8, 2.8]}   # the shaft's standard, behind
      - {kind: poly, points: [[-1.8, 11.5], [-0.75, 11.5], [-0.75, 13.0], [-1.8, 13.0]], y: [-1.7, 0.4]}   # the guide above
      - {kind: poly, points: [[0.75, 11.5], [1.8, 11.5], [1.8, 13.0], [0.75, 13.0]], y: [-1.7, 0.4]}
      - {kind: poly, points: [[-9, 11.5], [9, 11.5], [9, 13.0], [-9, 13.0]], y: [1.0, 1.8]}   # its bracket, behind
      - {kind: poly, points: [[-9, -12], [-8, -12], [-8, 13.0], [-9, 13.0]], y: [1.0, 1.8]}   # the posts
      - {kind: poly, points: [[8, -12], [9, -12], [9, 13.0], [8, 13.0]], y: [1.0, 1.8]}
      - {kind: poly, points: [[-11, -13], [11, -13], [11, -12], [-11, -12]], y: [-3, 3], color: "#b9b09c"}
joints:
  - {id: j_s, type: hinge, body: crank, axis: [0, 1, 0], damping: 0.002}   # the one driven joint; + : clockwise
  - {id: j_z, type: slide, body: yoke, axis: [0, 0, 1], range: [-9.5, 0.5], damping: 3.0}   # the yoke in its guides (collars stop it 1.5 cm below its stroke); + : up
contact: {solref: [0.002, 1.0], solimp: [0.95, 0.99, 0.0005], margin: 0}
driver: {joint: j_s, kind: velocity, rpm: 30, kv: 20.0, max_torque: 20}
checks:
  - {type: follow, out: j_z, in: j_s, expect: -0.03995, tol: 0.0008, min_r2: 0.995, settle_s: 2.4722, window_s: 0.0556}   # mid-stroke: r a radian
  - {type: follow, out: j_z, in: j_s, expect: -0.02825, tol: 0.00057, min_r2: 0.995, settle_s: 2.2222, window_s: 0.0556}   # at 45 deg ...
  - {type: follow, out: j_z, in: j_s, expect: -0.02825, tol: 0.00057, min_r2: 0.995, settle_s: 2.7222, window_s: 0.0556}   # ... and 135 deg alike: harmonic, no obliquity
  - {type: position, joint: j_z, min: -8.05, max: 0.05, settle_s: 0.5, window_s: 9}   # the stroke: twice the throw
  - {type: penetration, max: 0.001, settle_s: 0.5}
camera: {target: [0, 0, 1], position: [0, -80, 6], fov: 34}
display:
  output: j_z
  labels: {j_s: "Crank (driver)", j_z: "Slotted yoke"}
  proof: {label: "Wrist out of contact", sub: "the crank turns but the yoke drops to its collars"}

