# No. 149 (Brown 1868): "Uniform circular converted, by the cams acting upon the levers, into alternating rectilinear motions of the attached rods."
#
# Model (cm, gravity on): the shaft (the one driven joint, 12 turns a minute, clockwise in the view) carries two eccentric cams (4.5 cm radius, 2.0 cm throw), half a turn apart. A lever on each side, pivoted on its standard, rests its finger
# on its cam by its own weight (real contact) and, by a link pinned to a point 12 cm from its pivot, works a rod in vertical guides: the rods rise and fall 2.67 cm, one up while the other goes down. Generator: opencode-runs/batch10/gen149.py.
number: 149
slug: cams-levers-rods
name: Two cams working levers and rods in turn
brown: "Uniform circular converted, by the cams acting upon the levers, into alternating rectilinear motions of the attached rods."
units: cm
sim:
  timestep: 0.0002
  integrator: implicitfast
  iterations: 100
  solver: PGS
  multiccd: true
  duration_s: 12.0
  floor: false
bodies:
  - id: cam
    shape: part
    pos: [0, 0, 0]
    mass: 20.0
    friction: 0.03
    color: "#d9cfb6"
    pieces:
      - {kind: rod, from: [0, -2.4, 0], to: [0, 3.6, 0], radius: 1.2, color: "#8f8a80"}   # the shaft
      - {kind: poly, points: [[6.5, 0.0], [6.4829, 0.3922], [6.4316, 0.7814], [6.3467, 1.1647], [6.2286, 1.5391], [6.0784, 1.9018], [5.8971, 2.25], [5.6862, 2.5811], [5.4472, 2.8925], [5.182, 3.182], [4.8925, 3.4472], [4.5811, 3.6862], [4.25, 3.8971], [3.9018, 4.0784], [3.5391, 4.2286], [3.1647, 4.3467], [2.7814, 4.4316], [2.3922, 4.4829], [2.0, 4.5], [1.6078, 4.4829], [1.2186, 4.4316], [0.8353, 4.3467], [0.4609, 4.2286], [0.0982, 4.0784], [-0.25, 3.8971], [-0.5811, 3.6862], [-0.8925, 3.4472], [-1.182, 3.182], [-1.4472, 2.8925], [-1.6862, 2.5811], [-1.8971, 2.25], [-2.0784, 1.9018], [-2.2286, 1.5391], [-2.3467, 1.1647], [-2.4316, 0.7814], [-2.4829, 0.3922], [-2.5, 0.0], [-2.4829, -0.3922], [-2.4316, -0.7814], [-2.3467, -1.1647], [-2.2286, -1.5391], [-2.0784, -1.9018], [-1.8971, -2.25], [-1.6862, -2.5811], [-1.4472, -2.8925], [-1.182, -3.182], [-0.8925, -3.4472], [-0.5811, -3.6862], [-0.25, -3.8971], [0.0982, -4.0784], [0.4609, -4.2286], [0.8353, -4.3467], [1.2186, -4.4316], [1.6078, -4.4829], [2.0, -4.5], [2.3922, -4.4829], [2.7814, -4.4316], [3.1647, -4.3467], [3.5391, -4.2286], [3.9018, -4.0784], [4.25, -3.8971], [4.5811, -3.6862], [4.8925, -3.4472], [5.182, -3.182], [5.4472, -2.8925], [5.6862, -2.5811], [5.8971, -2.25], [6.0784, -1.9018], [6.2286, -1.5391], [6.3467, -1.1647], [6.4316, -0.7814], [6.4829, -0.3922]], y: [-1.8, -0.4], collide: 1}
      - {kind: poly, points: [[2.5, 0.0], [2.4829, 0.3922], [2.4316, 0.7814], [2.3467, 1.1647], [2.2286, 1.5391], [2.0784, 1.9018], [1.8971, 2.25], [1.6862, 2.5811], [1.4472, 2.8925], [1.182, 3.182], [0.8925, 3.4472], [0.5811, 3.6862], [0.25, 3.8971], [-0.0982, 4.0784], [-0.4609, 4.2286], [-0.8353, 4.3467], [-1.2186, 4.4316], [-1.6078, 4.4829], [-2.0, 4.5], [-2.3922, 4.4829], [-2.7814, 4.4316], [-3.1647, 4.3467], [-3.5391, 4.2286], [-3.9018, 4.0784], [-4.25, 3.8971], [-4.5811, 3.6862], [-4.8925, 3.4472], [-5.182, 3.182], [-5.4472, 2.8925], [-5.6862, 2.5811], [-5.8971, 2.25], [-6.0784, 1.9018], [-6.2286, 1.5391], [-6.3467, 1.1647], [-6.4316, 0.7814], [-6.4829, 0.3922], [-6.5, 0.0], [-6.4829, -0.3922], [-6.4316, -0.7814], [-6.3467, -1.1647], [-6.2286, -1.5391], [-6.0784, -1.9018], [-5.8971, -2.25], [-5.6862, -2.5811], [-5.4472, -2.8925], [-5.182, -3.182], [-4.8925, -3.4472], [-4.5811, -3.6862], [-4.25, -3.8971], [-3.9018, -4.0784], [-3.5391, -4.2286], [-3.1647, -4.3467], [-2.7814, -4.4316], [-2.3922, -4.4829], [-2.0, -4.5], [-1.6078, -4.4829], [-1.2186, -4.4316], [-0.8353, -4.3467], [-0.4609, -4.2286], [-0.0982, -4.0784], [0.25, -3.8971], [0.5811, -3.6862], [0.8925, -3.4472], [1.182, -3.182], [1.4472, -2.8925], [1.6862, -2.5811], [1.8971, -2.25], [2.0784, -1.9018], [2.2286, -1.5391], [2.3467, -1.1647], [2.4316, -0.7814], [2.4829, -0.3922]], y: [0.4, 1.8], collide: 1}
  - id: lever_a
    shape: part
    pos: [-18.0, 0, 5.0]
    mass: 0.3
    friction: 0.03
    color: "#b8ad97"
    pieces:
      - {kind: poly, points: [[-19.5, 4.3], [0.0, 4.3], [0.0, 5.7], [-19.5, 5.7]], y: [-1.7, -0.5], collide: 0}
      - {kind: rod, from: [0.0, -1.2999999999999998, 5.0], to: [0.0, -0.9, 5.0], radius: 0.5, collide: 2, capsule: true, color: "#8f8a80"}   # the finger on the cam
  - id: link_a
    shape: part
    pos: [-6.0, 0, 5.0]
    mount: lever_a
    mass: 0.1
    color: "#c9bfa6"
    pieces:
      - {kind: poly, points: [[-6.35, 5.0], [-5.65, 5.0], [-5.65, 11.0], [-6.35, 11.0]], y: [-2.2, -1.7], collide: 0}
  - id: rod_a
    shape: part
    pos: [-6.0, 0, 11.0]
    mass: 0.15
    color: "#d2c8ae"
    pieces:
      - {kind: poly, points: [[-6.7, 11.0], [-5.3, 11.0], [-5.3, 24.0], [-6.7, 24.0]], y: [-2.7, -2.2], collide: 0}
      - {kind: poly, points: [[-7.6, 23.0], [-4.4, 23.0], [-4.4, 24.6], [-7.6, 24.6]], y: [-2.7, -2.2], collide: 0, color: "#a89a7e"}   # the rod's head
  - id: lever_b
    shape: part
    pos: [18.0, 0, 5.0]
    mass: 0.3
    friction: 0.03
    color: "#b8ad97"
    pieces:
      - {kind: poly, points: [[19.5, 4.3], [0.0, 4.3], [0.0, 5.7], [19.5, 5.7]], y: [0.5, 1.7], collide: 0}
      - {kind: rod, from: [0.0, 0.9, 5.0], to: [0.0, 1.2999999999999998, 5.0], radius: 0.5, collide: 2, capsule: true, color: "#8f8a80"}   # the finger on the cam
  - id: link_b
    shape: part
    pos: [6.0, 0, 5.0]
    mount: lever_b
    mass: 0.1
    color: "#c9bfa6"
    pieces:
      - {kind: poly, points: [[5.65, 5.0], [6.35, 5.0], [6.35, 11.0], [5.65, 11.0]], y: [0.0, 0.5], collide: 0}
  - id: rod_b
    shape: part
    pos: [6.0, 0, 11.0]
    mass: 0.15
    color: "#d2c8ae"
    pieces:
      - {kind: poly, points: [[5.3, 11.0], [6.7, 11.0], [6.7, 24.0], [5.3, 24.0]], y: [-0.5, 0.0], collide: 0}
      - {kind: poly, points: [[4.4, 23.0], [7.6, 23.0], [7.6, 24.6], [4.4, 24.6]], y: [-0.5, 0.0], collide: 0, color: "#a89a7e"}   # the rod's head
  - id: frame
    shape: part
    pos: [0, 0, 0]
    fixed: true
    color: "#cfc6b4"
    pieces:
      - {kind: poly, points: [[-1.8, -13], [1.8, -13], [1.4, 0], [-1.4, 0]], y: [2.2, 3.2]}   # the shaft's standard, behind
      - {kind: poly, points: [[-19.2, -13], [-16.8, -13], [-17.2, 5.0], [-18.8, 5.0]], y: [2.2, 3.2]}   # the lever's standard, behind
      - {kind: rod, from: [-18.0, -2.0, 5.0], to: [-18.0, 3.0, 5.0], radius: 0.7, color: "#8f8a80"}
      - {kind: poly, points: [[16.8, -13], [19.2, -13], [18.8, 5.0], [17.2, 5.0]], y: [2.2, 3.2]}   # the lever's standard, behind
      - {kind: rod, from: [18.0, -2.0, 5.0], to: [18.0, 3.0, 5.0], radius: 0.7, color: "#8f8a80"}
      - {kind: poly, points: [[-7.6, 13.5], [-6.8, 13.5], [-6.8, 14.5], [-7.6, 14.5]], y: [-2.9000000000000004, -1.8000000000000003], collide: 0}
      - {kind: poly, points: [[-5.2, 13.5], [-4.4, 13.5], [-4.4, 14.5], [-5.2, 14.5]], y: [-2.9000000000000004, -1.8000000000000003], collide: 0}
      - {kind: poly, points: [[-7.6, 19.5], [-6.8, 19.5], [-6.8, 20.5], [-7.6, 20.5]], y: [-2.9000000000000004, -1.8000000000000003], collide: 0}
      - {kind: poly, points: [[-5.2, 19.5], [-4.4, 19.5], [-4.4, 20.5], [-5.2, 20.5]], y: [-2.9000000000000004, -1.8000000000000003], collide: 0}
      - {kind: poly, points: [[4.4, 13.5], [5.2, 13.5], [5.2, 14.5], [4.4, 14.5]], y: [-0.7, 0.4], collide: 0}
      - {kind: poly, points: [[6.8, 13.5], [7.6, 13.5], [7.6, 14.5], [6.8, 14.5]], y: [-0.7, 0.4], collide: 0}
      - {kind: poly, points: [[4.4, 19.5], [5.2, 19.5], [5.2, 20.5], [4.4, 20.5]], y: [-0.7, 0.4], collide: 0}
      - {kind: poly, points: [[6.8, 19.5], [7.6, 19.5], [7.6, 20.5], [6.8, 20.5]], y: [-0.7, 0.4], collide: 0}
      - {kind: poly, points: [[-25.0, -14], [25.0, -14], [25.0, -13], [-25.0, -13]], y: [-3.5, 3.5], color: "#b9b09c"}
joints:
  - {id: j_s, type: hinge, body: cam, axis: [0, 1, 0], damping: 0.002}   # the one driven joint; + : clockwise
  - {id: j_a1, type: hinge, body: lever_a, axis: [0, 1, 0], range: [-0.6, 0.6], damping: 0.002}   # the left lever; + : clockwise (its finger falls)
  - {id: j_k1, type: hinge, body: link_a, axis: [0, 1, 0], damping: 0.002}
  - {id: j_r1, type: slide, body: rod_a, axis: [0, 0, 1], damping: 0.05}   # the left rod; + : up
  - {id: j_a2, type: hinge, body: lever_b, axis: [0, -1, 0], range: [-0.6, 0.6], damping: 0.002}   # the right lever; + : its finger falls
  - {id: j_k2, type: hinge, body: link_b, axis: [0, 1, 0], damping: 0.002}
  - {id: j_r2, type: slide, body: rod_b, axis: [0, 0, 1], damping: 0.05}   # the right rod; + : up
pins:
  - {id: pin_a, a: link_a, b: rod_a, at: [-6.0, 0, 11.0]}
  - {id: pin_b, a: link_b, b: rod_b, at: [6.0, 0, 11.0]}
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: 100.0, max_torque: 100.0}
checks:
  - {type: follow, out: j_r1, in: j_s, expect: -0.0129, tol: 0.0008, min_r2: 0.99, settle_s: 9.5139, window_s: 0.9722}   # shaft turns -35..35 deg
  - {type: follow, out: j_r1, in: j_s, expect: 0.0127, tol: 0.0008, min_r2: 0.99, settle_s: 12.0139, window_s: 0.9722}   # shaft turns 145..215 deg
  - {type: follow, out: j_r1, in: j_s, expect: -0.0129, tol: 0.0008, min_r2: 0.99, settle_s: 14.5139, window_s: 0.9722}   # shaft turns -35..35 deg
  - {type: follow, out: j_r1, in: j_s, expect: 0.0127, tol: 0.0008, min_r2: 0.99, settle_s: 17.0139, window_s: 0.9722}   # shaft turns 145..215 deg
  - {type: follow, out: j_r2, in: j_s, expect: 0.0127, tol: 0.0008, min_r2: 0.99, settle_s: 9.5139, window_s: 0.9722}
  - {type: follow, out: j_r2, in: j_s, expect: -0.0129, tol: 0.0008, min_r2: 0.99, settle_s: 12.0139, window_s: 0.9722}
  - {type: position, joint: j_r1, min: -1.4852, max: 1.4823, settle_s: 1.0, window_s: 10.5}   # the rod's stroke
  - {type: position, joint: j_r2, min: -1.4852, max: 1.4823, settle_s: 1.0, window_s: 10.5}
  - {type: penetration, max: 0.001, settle_s: 0.5}
camera: {target: [0, 0, 2.0], position: [0, -82.0, 2.0], fov: 34}
display:
  output: j_r1
  labels: {j_s: "Cams (driver)", j_r1: "Left rod", j_r2: "Right rod"}
  proof: {label: "Cams out of contact", sub: "the shaft turns but the rods stand"}

