# No. 220 (Brown 1868): "The two crank-shafts are parallel in direction, but not in line with each other. The revolution of either will communicate motion to the other with
# a varying velocity, for the wrist of one crank working in the slot of the other is continually changing its distance from the shaft of the latter."
#
# Model (cm; drawing plane x-z, the shafts along y): the driving crank's shaft at the origin, its wrist 4 out (radius 0.45); the slotted crank's shaft 1.5 to the right,
# its arm slotted from 1.5 to 6.4 out (clearance 0.04). The wrist works in the slot, its distance from the slotted crank's shaft running from 2.5 to 5.5,
# so the slotted crank turns 0.727 to 1.600 times as fast as the driver (4/(4+1.5) to 4/(4-1.5); kinematics), once a turn on the mean.
# Gravity is on (the shafts are level) The slotted crank carries a counterweight, so it balances on its shaft. Only the driving crank is driven (10 rpm). Generator: opencode-runs/batch11/gen220.py.
number: 220
slug: offset-crank-shafts-slot
name: Two offset crank-shafts, the wrist of one in the slot of the other
brown: "The two crank-shafts are parallel in direction, but not in line with each other. The revolution of either will communicate motion to the other with a varying velocity, for the wrist of one crank working in the slot of the other is continually changing its distance from the shaft of the latter."
units: cm
sim:
  timestep: 0.0002
  integrator: implicitfast
  iterations: 100
  solver: CG
  multiccd: true
  duration_s: 13.0
bodies:
  - id: crankA
    shape: part
    pos: [0, 0, 0]
    density: 2700
    friction: 0.1
    color: "#b8ad97"
    pieces:
      - {kind: poly, points: [[-1.2, 0.0], [-1.1591, -0.3106], [-1.0392, -0.6], [-0.8485, -0.8485], [-0.6, -1.0392], [-0.3106, -1.1591], [-0.0, -1.2], [4.0, -0.8], [4.2071, -0.7727], [4.4, -0.6928], [4.5657, -0.5657], [4.6928, -0.4], [4.7727, -0.2071], [4.8, 0.0], [4.7727, 0.2071], [4.6928, 0.4], [4.5657, 0.5657], [4.4, 0.6928], [4.2071, 0.7727], [4.0, 0.8], [0.0, 1.2], [-0.3106, 1.1591], [-0.6, 1.0392], [-0.8485, 0.8485], [-1.0392, 0.6], [-1.1591, 0.3106]], y: [0.8, 1.4], collide: 0}   # the driving crank
      - {kind: disc, center: [4.0, 0], radius: 0.45, y: [-0.6, 1.4], collide: 1, color: "#6f6a60"}   # its wrist, in the slot
      - {kind: disc, center: [0, 0], radius: 0.6, y: [0.8, 4.0], collide: 0, color: "#8f8a80"}   # its shaft, behind
  - id: crankB
    shape: part
    pos: [1.5, 0, 0]
    density: 2700
    friction: 0.1
    color: "#d0c3a2"
    pieces:
      - {kind: poly, points: [[3.0, 0.49], [4.225, 0.49], [4.225, 1.49], [3.0, 1.49]], y: [-0.4, 0.4], collide: 2}
      - {kind: poly, points: [[3.0, -0.49], [3.0, -1.49], [4.225, -1.49], [4.225, -0.49]], y: [-0.4, 0.4], collide: 2}
      - {kind: poly, points: [[4.225, 0.49], [5.45, 0.49], [5.45, 1.49], [4.225, 1.49]], y: [-0.4, 0.4], collide: 2}
      - {kind: poly, points: [[4.225, -0.49], [4.225, -1.49], [5.45, -1.49], [5.45, -0.49]], y: [-0.4, 0.4], collide: 2}
      - {kind: poly, points: [[5.45, 0.49], [6.675, 0.49], [6.675, 1.49], [5.45, 1.49]], y: [-0.4, 0.4], collide: 2}
      - {kind: poly, points: [[5.45, -0.49], [5.45, -1.49], [6.675, -1.49], [6.675, -0.49]], y: [-0.4, 0.4], collide: 2}
      - {kind: poly, points: [[6.675, 0.49], [7.9, 0.49], [7.9, 1.49], [6.675, 1.49]], y: [-0.4, 0.4], collide: 2}
      - {kind: poly, points: [[6.675, -0.49], [6.675, -1.49], [7.9, -1.49], [7.9, -0.49]], y: [-0.4, 0.4], collide: 2}
      - {kind: poly, points: [[0.2, 0.0], [0.2443, -0.3365], [0.3742, -0.65], [0.5808, -0.9192], [0.85, -1.1258], [1.1635, -1.2557], [2.8, -1.49], [2.8, 1.49], [1.1635, 1.2557], [0.85, 1.1258], [0.5808, 0.9192], [0.3742, 0.65], [0.2443, 0.3365]], y: [-0.4, 0.4], collide: 0}   # the boss and the web to the slot
      - {kind: poly, points: [[2.8, -1.49], [7.9, -1.49], [9.241, -0.6705], [9.241, 0.6705], [7.9, 1.49], [2.8, 1.49], [2.8, 0.49], [7.9, 0.49], [7.9, -0.49], [2.8, -0.49]], y: [-0.42, -0.4], collide: 0}   # the slotted arm's face
      - {kind: disc, center: [-1.1, 0], radius: 1.6, y: [-1.2, 0.4], collide: 0}   # the counterweight
      - {kind: disc, center: [1.5, 0], radius: 0.6, y: [-4.0, 0.4], collide: 0, color: "#8f8a80"}   # its shaft, in front
  - id: frame
    shape: part
    pos: [0, 0, 0]
    fixed: true
    density: 7800
    color: "#cfc6b4"
    pieces:
      - {kind: poly, points: [[-1.0, -0.8], [1.0, -0.8], [1.3, -5.0], [-1.3, -5.0]], y: [3.0, 3.8], collide: 0}   # the driving shaft's standard, behind
      - {kind: disc, center: [0, 0], radius: 1.1, y: [3.0, 3.8], collide: 0}
      - {kind: poly, points: [[0.5, -0.8], [2.5, -0.8], [2.8, -5.0], [0.2, -5.0]], y: [-3.8, -3.0], collide: 0}   # the slotted crank's standard, in front
      - {kind: disc, center: [1.5, 0], radius: 1.1, y: [-3.8, -3.0], collide: 0}
joints:
  - {id: j_a, type: hinge, body: crankA, axis: [0, -1, 0], damping: 0.01}   # the one driven joint; +: counter-clockwise
  - {id: j_b, type: hinge, body: crankB, axis: [0, -1, 0], damping: 0.002, frictionloss: 0.002}
contact: {solref: [0.002, 1.0], solimp: [0.95, 0.99, 0.0005], margin: 0}
driver: {joint: j_a, kind: velocity, rpm: 10, kv: 20, max_torque: 40}
checks:
  - {type: ratio, out: j_b, in: j_a, expect: 1.0, tol: 0.02, settle_s: 0.5, window_s: 12}   # once a turn on the mean
  - {type: ratio_range, out: j_b, in: j_a, min: 0.655, max: 1.728, min_swing: 0.524, settle_s: 0.5, window_s: 12, slices: 48}   # 0.727..1.600 (kinematics)
  - {type: penetration, max: 0.001, settle_s: 0.5}
camera: {target: [1.6, 0, -0.5], position: [5.0, -40.0, 6.0], fov: 34}
display:
  output: j_b
  labels: {j_a: "Driving crank", j_b: "Slotted crank"}
  proof: {label: "Wrist out of the slot", sub: "the driver turns alone"}

