# No. 170 (Brown 1868): "Another form of steam engine governor. Instead of the arms being connected with a slide working on a spindle, they cross each other and are elongated upward beyond the top thereof and connected with the valve-rod by two short links."
#
# Model (cm, gravity on): the spindle is the one driven joint (100 turns a minute; the engine that turns it is not drawn). Two arms (14 cm, a 2.0 cm ball on each) are pivoted at the top of the spindle on opposite sides, so that they cross; each is carried 7 cm up beyond its pivot,
# and a short link (7 cm, pinned at each end) joins that upper end to the valve-rod, which slides on the spindle above. As the balls fly out the upper ends close in and the valve-rod comes down. The balls (0.4 kg each) fly out until the pull of the spin is balanced. Generator: opencode-runs/batch11/gen170.py.
number: 170
slug: crossed-arm-governor-valve-rod
name: A governor with crossed arms working the valve-rod
brown: "Another form of steam engine governor. Instead of the arms being connected with a slide working on a spindle, they cross each other and are elongated upward beyond the top thereof and connected with the valve-rod by two short links."
units: cm
sim:
  timestep: 0.0002
  integrator: implicitfast
  iterations: 100
  solver: PGS
  multiccd: true
  duration_s: 9.0
  floor: false
bodies:
  - id: shaft
    shape: part
    pos: [0, 0, 0]
    mass: 0.4
    color: "#e4d9bf"
    pieces:
      - {kind: rod, from: [0, 0, 17.2], to: [0, 0, 50.0], radius: 0.8, collide: 0}
      - {kind: rod, from: [0, 0, 33.0], to: [0, 0, 35.4], radius: 1.6, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [-1.5, 0, 34.0], to: [1.5, 0, 34.0], radius: 0.5, collide: 0, color: "#8f8a80"}
  - id: sleeve
    shape: part
    pos: [0, 0, 46.5912]
    mount: shaft
    mass: 0.01
    color: "#b8ad97"
    pieces:
      - {kind: rod, from: [0, 0, 45.3912], to: [0, 0, 47.7912], radius: 1.4, collide: 0}
      - {kind: rod, from: [0, 0, 47.7912], to: [0, 0, 56.5912], radius: 0.6, collide: 0, color: "#8f8a80"}   # the valve-rod
      - {kind: rod, from: [-1.0, 0, 46.5912], to: [1.0, 0, 46.5912], radius: 0.5, collide: 0, color: "#8f8a80"}
  - id: arm_r
    shape: part
    pos: [-1.2, 0, 34.0]
    mount: shaft
    mass: 0.4
    color: "#a89a7e"
    pieces:
      - {kind: rod, from: [-4.1583, 0.5, 40.3442], to: [4.7167, 0.5, 21.3117], radius: 0.35, collide: 0, color: "#a89a7e"}
      - {kind: rod, from: [4.7167, -1.3, 21.3117], to: [4.7167, 1.3, 21.3117], radius: 2.0, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [-1.2, -1.0, 34.0], to: [-1.2, 1.0, 34.0], radius: 0.7, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [-4.1583, -1.6, 40.3442], to: [-4.1583, 0.5, 40.3442], radius: 0.5, collide: 0, color: "#8f8a80"}
  - id: arm_l
    shape: part
    pos: [1.2, 0, 34.0]
    mount: shaft
    mass: 0.4
    color: "#a89a7e"
    pieces:
      - {kind: rod, from: [4.1583, -0.5, 40.3442], to: [-4.7167, -0.5, 21.3117], radius: 0.35, collide: 0, color: "#a89a7e"}
      - {kind: rod, from: [-4.7167, -1.3, 21.3117], to: [-4.7167, 1.3, 21.3117], radius: 2.0, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [1.2, -1.0, 34.0], to: [1.2, 1.0, 34.0], radius: 0.7, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [4.1583, -1.6, 40.3442], to: [4.1583, -0.5, 40.3442], radius: 0.5, collide: 0, color: "#8f8a80"}
  - id: link_r
    shape: part
    pos: [-1.0, 0, 46.5912]
    mount: sleeve
    mass: 0.03
    color: "#b8ad97"
    pieces:
      - {kind: rod, from: [-1.0, -1.4, 46.5912], to: [-4.1583, -1.4, 40.3442], radius: 0.3, collide: 0, color: "#b8ad97"}
      - {kind: rod, from: [-1.0, -1.7, 46.5912], to: [-1.0, -1.1, 46.5912], radius: 0.5, collide: 0, color: "#8f8a80"}
  - id: link_l
    shape: part
    pos: [1.0, 0, 46.5912]
    mount: sleeve
    mass: 0.03
    color: "#b8ad97"
    pieces:
      - {kind: rod, from: [1.0, -1.4, 46.5912], to: [4.1583, -1.4, 40.3442], radius: 0.3, collide: 0, color: "#b8ad97"}
      - {kind: rod, from: [1.0, -1.7, 46.5912], to: [1.0, -1.1, 46.5912], radius: 0.5, collide: 0, color: "#8f8a80"}
  - id: frame
    shape: part
    pos: [0, 0, 0]
    fixed: true
    color: "#cfc6b4"
    pieces:
      - {kind: poly, points: [[-9.0, 12.6], [9.0, 12.6], [9.0, 14.0], [-9.0, 14.0]], y: [-4, 4], collide: 0, color: "#b9b09c"}
      - {kind: rod, from: [0, 0, 14.0], to: [0, 0, 19.2], radius: 1.6, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [0, 2.4, 14.0], to: [0, 2.4, 56.0], radius: 0.7, collide: 0}
joints:
  - {id: j_s, type: hinge, body: shaft, axis: [0, 0, 1], damping: 0.002}   # the one driven joint: the spindle
  - {id: j_r, type: hinge, body: arm_r, axis: [0, -1, 0], damping: 0.004}   # the right arm; + : outward (the ball flies out)
  - {id: j_l, type: hinge, body: arm_l, axis: [0, 1, 0], damping: 0.004}   # the left arm; + : outward
  - {id: j_z, type: slide, body: sleeve, axis: [0, 0, 1], range: [-14, 6], stiffness: 0.0, springref: 0, damping: 0.05}   # the valve-rod (the slide): + up
  - {id: j_lr, type: hinge, body: link_r, axis: [0, 1, 0], damping: 0.0005}
  - {id: j_ll, type: hinge, body: link_l, axis: [0, 1, 0], damping: 0.0005}
pins:
  - {"id": "pin_r", "a": "link_r", "b": "arm_r", "at": [-4.1583, 0, 40.3442]}
  - {"id": "pin_l", "a": "link_l", "b": "arm_l", "at": [4.1583, 0, 40.3442]}
contact: {solref: [0.002, 1.0], solimp: [0.95, 0.99, 0.0005], margin: 0}
driver: {joint: j_s, kind: velocity, rpm: 100.0, kv: 1.0, max_torque: 5}
checks:
  - {type: follow, out: j_z, in: j_r, expect: -0.0994, tol: 0.008, min_r2: 0.995, settle_s: 0.2, window_s: 0.2}   # the valve-rod falls as the links' geometry says (m per radian of arm) as the balls fly out
  - {type: position, joint: j_r, min: 0.40, max: 0.52, settle_s: 4.0, window_s: 5.0}   # the balls stand out about 51 degrees from the spindle
  - {type: ratio, out: j_l, in: j_r, expect: 1.0, tol: 0.02, settle_s: 3.0, window_s: 5.0}   # both arms alike
  - {type: position, joint: j_z, min: -4.9, max: -3.5, settle_s: 4.0, window_s: 5.0}   # and the valve-rod stands down about 4 cm
  - {type: penetration, max: 0.0015, settle_s: 0.5}
camera: {target: [0.0, 0, 30.0], position: [0.0, -100.0, 30.0], fov: 34}
display:
  output: j_z
  labels: {j_s: "Spindle (driver)", j_r: "Right ball arm", j_l: "Left ball arm", j_z: "Valve-rod (slide)"}
  proof: {label: "Links unpinned", sub: "the balls fly out but the valve-rod does not fall"}

