# No. 147 (Brown 1868): "Steam engine governor. On engine starting the spindle revolves and carries round the cross-head to which fans are attached, and on which are also fitted two friction-rollers which bear on two circular inclined planes attached securely to the center shaft, the cross-head being loose on the shaft. The cross-head is made heavy... As the speed of the center shaft increases, the resistance of the air to the wings tends to retard the rotation of the cross-head; the friction-rollers therefore run up the inclined planes and raise the cross-head, to the upper part of which is connected a lever operating upon the regulating-valve of the engine."
#
# Model (cm): the centre shaft (the one driven joint, 60 turns a minute) carries two circular inclined planes, each rising 4 cm over half a turn. The heavy cross-head (0.3 kg) is loose on the shaft:
# it can turn on it and slide up it, and carries two rollers that bear on the planes. The air's drag on its fans is a damping on the cross-head's turning
# (0.02 N m s) and the valve lever's pull a spring on its rise (70 N/m). Driven round by the planes against that drag, the cross-head lags, the rollers run up the planes
# and it rises until the spring and its weight balance the climb. Generator: opencode-runs/batch10/gen147.py.
number: 147
slug: steam-engine-governor
name: Steam engine governor
brown: "Steam engine governor. The operation is as follows: On engine starting the spindle revolves and carries round the cross-head to which fans are attached, and on which are also fitted two friction-rollers which bear on two circular inclined planes attached securely to the center shaft, the cross-head being loose on the shaft."
units: cm
sim:
  timestep: 0.0002
  integrator: implicitfast
  iterations: 100
  solver: CG
  multiccd: true
  duration_s: 9.0
  floor: false
bodies:
  - id: shaft
    shape: part
    pos: [0, 0, 0]
    density: 7800
    friction: 0.1
    color: "#e4d9bf"
    pieces:
      - {kind: rod, from: [0, 0, -4.5], to: [0, 0, 14.2], radius: 1.0, collide: 0}   # the centre shaft
      - {kind: rod, from: [0, 0, -4.5], to: [0, 0, -3.0], radius: 2.6, collide: 0, color: "#8f8a80"}   # its collar
      - {kind: loft, a: [[1.6, 0.0, 3.2], [4.6, 0.0, 3.2], [4.6, 0.0, 4.0], [1.6, 0.0, 4.0]], b: [[1.5863, 0.2088, 3.0333], [4.5606, 0.6004, 3.0333], [4.5606, 0.6004, 3.8333], [1.5863, 0.2088, 3.8333]], collide: 2}
      - {kind: loft, a: [[1.5863, 0.2088, 3.0333], [4.5606, 0.6004, 3.0333], [4.5606, 0.6004, 3.8333], [1.5863, 0.2088, 3.8333]], b: [[1.5455, 0.4141, 2.8667], [4.4433, 1.1906, 2.8667], [4.4433, 1.1906, 3.6667], [1.5455, 0.4141, 3.6667]], collide: 2}
      - {kind: loft, a: [[1.5455, 0.4141, 2.8667], [4.4433, 1.1906, 2.8667], [4.4433, 1.1906, 3.6667], [1.5455, 0.4141, 3.6667]], b: [[1.4782, 0.6123, 2.7], [4.2498, 1.7603, 2.7], [4.2498, 1.7603, 3.5], [1.4782, 0.6123, 3.5]], collide: 2}
      - {kind: loft, a: [[1.4782, 0.6123, 2.7], [4.2498, 1.7603, 2.7], [4.2498, 1.7603, 3.5], [1.4782, 0.6123, 3.5]], b: [[1.3856, 0.8, 2.5333], [3.9837, 2.3, 2.5333], [3.9837, 2.3, 3.3333], [1.3856, 0.8, 3.3333]], collide: 2}
      - {kind: loft, a: [[1.3856, 0.8, 2.5333], [3.9837, 2.3, 2.5333], [3.9837, 2.3, 3.3333], [1.3856, 0.8, 3.3333]], b: [[1.2694, 0.974, 2.3667], [3.6494, 2.8003, 2.3667], [3.6494, 2.8003, 3.1667], [1.2694, 0.974, 3.1667]], collide: 2}
      - {kind: loft, a: [[1.2694, 0.974, 2.3667], [3.6494, 2.8003, 2.3667], [3.6494, 2.8003, 3.1667], [1.2694, 0.974, 3.1667]], b: [[1.1314, 1.1314, 2.2], [3.2527, 3.2527, 2.2], [3.2527, 3.2527, 3.0], [1.1314, 1.1314, 3.0]], collide: 2}
      - {kind: loft, a: [[1.1314, 1.1314, 2.2], [3.2527, 3.2527, 2.2], [3.2527, 3.2527, 3.0], [1.1314, 1.1314, 3.0]], b: [[0.974, 1.2694, 2.0333], [2.8003, 3.6494, 2.0333], [2.8003, 3.6494, 2.8333], [0.974, 1.2694, 2.8333]], collide: 2}
      - {kind: loft, a: [[0.974, 1.2694, 2.0333], [2.8003, 3.6494, 2.0333], [2.8003, 3.6494, 2.8333], [0.974, 1.2694, 2.8333]], b: [[0.8, 1.3856, 1.8667], [2.3, 3.9837, 1.8667], [2.3, 3.9837, 2.6667], [0.8, 1.3856, 2.6667]], collide: 2}
      - {kind: loft, a: [[0.8, 1.3856, 1.8667], [2.3, 3.9837, 1.8667], [2.3, 3.9837, 2.6667], [0.8, 1.3856, 2.6667]], b: [[0.6123, 1.4782, 1.7], [1.7603, 4.2498, 1.7], [1.7603, 4.2498, 2.5], [0.6123, 1.4782, 2.5]], collide: 2}
      - {kind: loft, a: [[0.6123, 1.4782, 1.7], [1.7603, 4.2498, 1.7], [1.7603, 4.2498, 2.5], [0.6123, 1.4782, 2.5]], b: [[0.4141, 1.5455, 1.5333], [1.1906, 4.4433, 1.5333], [1.1906, 4.4433, 2.3333], [0.4141, 1.5455, 2.3333]], collide: 2}
      - {kind: loft, a: [[0.4141, 1.5455, 1.5333], [1.1906, 4.4433, 1.5333], [1.1906, 4.4433, 2.3333], [0.4141, 1.5455, 2.3333]], b: [[0.2088, 1.5863, 1.3667], [0.6004, 4.5606, 1.3667], [0.6004, 4.5606, 2.1667], [0.2088, 1.5863, 2.1667]], collide: 2}
      - {kind: loft, a: [[0.2088, 1.5863, 1.3667], [0.6004, 4.5606, 1.3667], [0.6004, 4.5606, 2.1667], [0.2088, 1.5863, 2.1667]], b: [[0.0, 1.6, 1.2], [0.0, 4.6, 1.2], [0.0, 4.6, 2.0], [0.0, 1.6, 2.0]], collide: 2}
      - {kind: loft, a: [[0.0, 1.6, 1.2], [0.0, 4.6, 1.2], [0.0, 4.6, 2.0], [0.0, 1.6, 2.0]], b: [[-0.2088, 1.5863, 1.0333], [-0.6004, 4.5606, 1.0333], [-0.6004, 4.5606, 1.8333], [-0.2088, 1.5863, 1.8333]], collide: 2}
      - {kind: loft, a: [[-0.2088, 1.5863, 1.0333], [-0.6004, 4.5606, 1.0333], [-0.6004, 4.5606, 1.8333], [-0.2088, 1.5863, 1.8333]], b: [[-0.4141, 1.5455, 0.8667], [-1.1906, 4.4433, 0.8667], [-1.1906, 4.4433, 1.6667], [-0.4141, 1.5455, 1.6667]], collide: 2}
      - {kind: loft, a: [[-0.4141, 1.5455, 0.8667], [-1.1906, 4.4433, 0.8667], [-1.1906, 4.4433, 1.6667], [-0.4141, 1.5455, 1.6667]], b: [[-0.6123, 1.4782, 0.7], [-1.7603, 4.2498, 0.7], [-1.7603, 4.2498, 1.5], [-0.6123, 1.4782, 1.5]], collide: 2}
      - {kind: loft, a: [[-0.6123, 1.4782, 0.7], [-1.7603, 4.2498, 0.7], [-1.7603, 4.2498, 1.5], [-0.6123, 1.4782, 1.5]], b: [[-0.8, 1.3856, 0.5333], [-2.3, 3.9837, 0.5333], [-2.3, 3.9837, 1.3333], [-0.8, 1.3856, 1.3333]], collide: 2}
      - {kind: loft, a: [[-0.8, 1.3856, 0.5333], [-2.3, 3.9837, 0.5333], [-2.3, 3.9837, 1.3333], [-0.8, 1.3856, 1.3333]], b: [[-0.974, 1.2694, 0.3667], [-2.8003, 3.6494, 0.3667], [-2.8003, 3.6494, 1.1667], [-0.974, 1.2694, 1.1667]], collide: 2}
      - {kind: loft, a: [[-0.974, 1.2694, 0.3667], [-2.8003, 3.6494, 0.3667], [-2.8003, 3.6494, 1.1667], [-0.974, 1.2694, 1.1667]], b: [[-1.1314, 1.1314, 0.2], [-3.2527, 3.2527, 0.2], [-3.2527, 3.2527, 1.0], [-1.1314, 1.1314, 1.0]], collide: 2}
      - {kind: loft, a: [[-1.1314, 1.1314, 0.2], [-3.2527, 3.2527, 0.2], [-3.2527, 3.2527, 1.0], [-1.1314, 1.1314, 1.0]], b: [[-1.2694, 0.974, 0.0333], [-3.6494, 2.8003, 0.0333], [-3.6494, 2.8003, 0.8333], [-1.2694, 0.974, 0.8333]], collide: 2}
      - {kind: loft, a: [[-1.2694, 0.974, 0.0333], [-3.6494, 2.8003, 0.0333], [-3.6494, 2.8003, 0.8333], [-1.2694, 0.974, 0.8333]], b: [[-1.3856, 0.8, -0.1333], [-3.9837, 2.3, -0.1333], [-3.9837, 2.3, 0.6667], [-1.3856, 0.8, 0.6667]], collide: 2}
      - {kind: loft, a: [[-1.3856, 0.8, -0.1333], [-3.9837, 2.3, -0.1333], [-3.9837, 2.3, 0.6667], [-1.3856, 0.8, 0.6667]], b: [[-1.4782, 0.6123, -0.3], [-4.2498, 1.7603, -0.3], [-4.2498, 1.7603, 0.5], [-1.4782, 0.6123, 0.5]], collide: 2}
      - {kind: loft, a: [[-1.4782, 0.6123, -0.3], [-4.2498, 1.7603, -0.3], [-4.2498, 1.7603, 0.5], [-1.4782, 0.6123, 0.5]], b: [[-1.5455, 0.4141, -0.4667], [-4.4433, 1.1906, -0.4667], [-4.4433, 1.1906, 0.3333], [-1.5455, 0.4141, 0.3333]], collide: 2}
      - {kind: loft, a: [[-1.5455, 0.4141, -0.4667], [-4.4433, 1.1906, -0.4667], [-4.4433, 1.1906, 0.3333], [-1.5455, 0.4141, 0.3333]], b: [[-1.5863, 0.2088, -0.6333], [-4.5606, 0.6004, -0.6333], [-4.5606, 0.6004, 0.1667], [-1.5863, 0.2088, 0.1667]], collide: 2}
      - {kind: loft, a: [[-1.5863, 0.2088, -0.6333], [-4.5606, 0.6004, -0.6333], [-4.5606, 0.6004, 0.1667], [-1.5863, 0.2088, 0.1667]], b: [[-1.6, 0.0, 3.2], [-4.6, 0.0, 3.2], [-4.6, 0.0, 4.0], [-1.6, 0.0, 4.0]], collide: 2}
      - {kind: loft, a: [[-1.6, 0.0, 3.2], [-4.6, 0.0, 3.2], [-4.6, 0.0, 4.0], [-1.6, 0.0, 4.0]], b: [[-1.5863, -0.2088, 3.0333], [-4.5606, -0.6004, 3.0333], [-4.5606, -0.6004, 3.8333], [-1.5863, -0.2088, 3.8333]], collide: 2}
      - {kind: loft, a: [[-1.5863, -0.2088, 3.0333], [-4.5606, -0.6004, 3.0333], [-4.5606, -0.6004, 3.8333], [-1.5863, -0.2088, 3.8333]], b: [[-1.5455, -0.4141, 2.8667], [-4.4433, -1.1906, 2.8667], [-4.4433, -1.1906, 3.6667], [-1.5455, -0.4141, 3.6667]], collide: 2}
      - {kind: loft, a: [[-1.5455, -0.4141, 2.8667], [-4.4433, -1.1906, 2.8667], [-4.4433, -1.1906, 3.6667], [-1.5455, -0.4141, 3.6667]], b: [[-1.4782, -0.6123, 2.7], [-4.2498, -1.7603, 2.7], [-4.2498, -1.7603, 3.5], [-1.4782, -0.6123, 3.5]], collide: 2}
      - {kind: loft, a: [[-1.4782, -0.6123, 2.7], [-4.2498, -1.7603, 2.7], [-4.2498, -1.7603, 3.5], [-1.4782, -0.6123, 3.5]], b: [[-1.3856, -0.8, 2.5333], [-3.9837, -2.3, 2.5333], [-3.9837, -2.3, 3.3333], [-1.3856, -0.8, 3.3333]], collide: 2}
      - {kind: loft, a: [[-1.3856, -0.8, 2.5333], [-3.9837, -2.3, 2.5333], [-3.9837, -2.3, 3.3333], [-1.3856, -0.8, 3.3333]], b: [[-1.2694, -0.974, 2.3667], [-3.6494, -2.8003, 2.3667], [-3.6494, -2.8003, 3.1667], [-1.2694, -0.974, 3.1667]], collide: 2}
      - {kind: loft, a: [[-1.2694, -0.974, 2.3667], [-3.6494, -2.8003, 2.3667], [-3.6494, -2.8003, 3.1667], [-1.2694, -0.974, 3.1667]], b: [[-1.1314, -1.1314, 2.2], [-3.2527, -3.2527, 2.2], [-3.2527, -3.2527, 3.0], [-1.1314, -1.1314, 3.0]], collide: 2}
      - {kind: loft, a: [[-1.1314, -1.1314, 2.2], [-3.2527, -3.2527, 2.2], [-3.2527, -3.2527, 3.0], [-1.1314, -1.1314, 3.0]], b: [[-0.974, -1.2694, 2.0333], [-2.8003, -3.6494, 2.0333], [-2.8003, -3.6494, 2.8333], [-0.974, -1.2694, 2.8333]], collide: 2}
      - {kind: loft, a: [[-0.974, -1.2694, 2.0333], [-2.8003, -3.6494, 2.0333], [-2.8003, -3.6494, 2.8333], [-0.974, -1.2694, 2.8333]], b: [[-0.8, -1.3856, 1.8667], [-2.3, -3.9837, 1.8667], [-2.3, -3.9837, 2.6667], [-0.8, -1.3856, 2.6667]], collide: 2}
      - {kind: loft, a: [[-0.8, -1.3856, 1.8667], [-2.3, -3.9837, 1.8667], [-2.3, -3.9837, 2.6667], [-0.8, -1.3856, 2.6667]], b: [[-0.6123, -1.4782, 1.7], [-1.7603, -4.2498, 1.7], [-1.7603, -4.2498, 2.5], [-0.6123, -1.4782, 2.5]], collide: 2}
      - {kind: loft, a: [[-0.6123, -1.4782, 1.7], [-1.7603, -4.2498, 1.7], [-1.7603, -4.2498, 2.5], [-0.6123, -1.4782, 2.5]], b: [[-0.4141, -1.5455, 1.5333], [-1.1906, -4.4433, 1.5333], [-1.1906, -4.4433, 2.3333], [-0.4141, -1.5455, 2.3333]], collide: 2}
      - {kind: loft, a: [[-0.4141, -1.5455, 1.5333], [-1.1906, -4.4433, 1.5333], [-1.1906, -4.4433, 2.3333], [-0.4141, -1.5455, 2.3333]], b: [[-0.2088, -1.5863, 1.3667], [-0.6004, -4.5606, 1.3667], [-0.6004, -4.5606, 2.1667], [-0.2088, -1.5863, 2.1667]], collide: 2}
      - {kind: loft, a: [[-0.2088, -1.5863, 1.3667], [-0.6004, -4.5606, 1.3667], [-0.6004, -4.5606, 2.1667], [-0.2088, -1.5863, 2.1667]], b: [[-0.0, -1.6, 1.2], [-0.0, -4.6, 1.2], [-0.0, -4.6, 2.0], [-0.0, -1.6, 2.0]], collide: 2}
      - {kind: loft, a: [[-0.0, -1.6, 1.2], [-0.0, -4.6, 1.2], [-0.0, -4.6, 2.0], [-0.0, -1.6, 2.0]], b: [[0.2088, -1.5863, 1.0333], [0.6004, -4.5606, 1.0333], [0.6004, -4.5606, 1.8333], [0.2088, -1.5863, 1.8333]], collide: 2}
      - {kind: loft, a: [[0.2088, -1.5863, 1.0333], [0.6004, -4.5606, 1.0333], [0.6004, -4.5606, 1.8333], [0.2088, -1.5863, 1.8333]], b: [[0.4141, -1.5455, 0.8667], [1.1906, -4.4433, 0.8667], [1.1906, -4.4433, 1.6667], [0.4141, -1.5455, 1.6667]], collide: 2}
      - {kind: loft, a: [[0.4141, -1.5455, 0.8667], [1.1906, -4.4433, 0.8667], [1.1906, -4.4433, 1.6667], [0.4141, -1.5455, 1.6667]], b: [[0.6123, -1.4782, 0.7], [1.7603, -4.2498, 0.7], [1.7603, -4.2498, 1.5], [0.6123, -1.4782, 1.5]], collide: 2}
      - {kind: loft, a: [[0.6123, -1.4782, 0.7], [1.7603, -4.2498, 0.7], [1.7603, -4.2498, 1.5], [0.6123, -1.4782, 1.5]], b: [[0.8, -1.3856, 0.5333], [2.3, -3.9837, 0.5333], [2.3, -3.9837, 1.3333], [0.8, -1.3856, 1.3333]], collide: 2}
      - {kind: loft, a: [[0.8, -1.3856, 0.5333], [2.3, -3.9837, 0.5333], [2.3, -3.9837, 1.3333], [0.8, -1.3856, 1.3333]], b: [[0.974, -1.2694, 0.3667], [2.8003, -3.6494, 0.3667], [2.8003, -3.6494, 1.1667], [0.974, -1.2694, 1.1667]], collide: 2}
      - {kind: loft, a: [[0.974, -1.2694, 0.3667], [2.8003, -3.6494, 0.3667], [2.8003, -3.6494, 1.1667], [0.974, -1.2694, 1.1667]], b: [[1.1314, -1.1314, 0.2], [3.2527, -3.2527, 0.2], [3.2527, -3.2527, 1.0], [1.1314, -1.1314, 1.0]], collide: 2}
      - {kind: loft, a: [[1.1314, -1.1314, 0.2], [3.2527, -3.2527, 0.2], [3.2527, -3.2527, 1.0], [1.1314, -1.1314, 1.0]], b: [[1.2694, -0.974, 0.0333], [3.6494, -2.8003, 0.0333], [3.6494, -2.8003, 0.8333], [1.2694, -0.974, 0.8333]], collide: 2}
      - {kind: loft, a: [[1.2694, -0.974, 0.0333], [3.6494, -2.8003, 0.0333], [3.6494, -2.8003, 0.8333], [1.2694, -0.974, 0.8333]], b: [[1.3856, -0.8, -0.1333], [3.9837, -2.3, -0.1333], [3.9837, -2.3, 0.6667], [1.3856, -0.8, 0.6667]], collide: 2}
      - {kind: loft, a: [[1.3856, -0.8, -0.1333], [3.9837, -2.3, -0.1333], [3.9837, -2.3, 0.6667], [1.3856, -0.8, 0.6667]], b: [[1.4782, -0.6123, -0.3], [4.2498, -1.7603, -0.3], [4.2498, -1.7603, 0.5], [1.4782, -0.6123, 0.5]], collide: 2}
      - {kind: loft, a: [[1.4782, -0.6123, -0.3], [4.2498, -1.7603, -0.3], [4.2498, -1.7603, 0.5], [1.4782, -0.6123, 0.5]], b: [[1.5455, -0.4141, -0.4667], [4.4433, -1.1906, -0.4667], [4.4433, -1.1906, 0.3333], [1.5455, -0.4141, 0.3333]], collide: 2}
      - {kind: loft, a: [[1.5455, -0.4141, -0.4667], [4.4433, -1.1906, -0.4667], [4.4433, -1.1906, 0.3333], [1.5455, -0.4141, 0.3333]], b: [[1.5863, -0.2088, -0.6333], [4.5606, -0.6004, -0.6333], [4.5606, -0.6004, 0.1667], [1.5863, -0.2088, 0.1667]], collide: 2}
      - {kind: loft, a: [[1.5863, -0.2088, -0.6333], [4.5606, -0.6004, -0.6333], [4.5606, -0.6004, 0.1667], [1.5863, -0.2088, 0.1667]], b: [[1.6, -0.0, 3.2], [4.6, -0.0, 3.2], [4.6, -0.0, 4.0], [1.6, -0.0, 4.0]], collide: 2}
  - id: spin
    shape: part
    pos: [0, 0, 0]
    mass: 0.05
    color: "#b8ad97"
    pieces:
      - {kind: rod, from: [0, 0, 9.4], to: [0, 0, 12.6], radius: 1.7, collide: 0}   # the sleeve the cross-head turns on
  - id: head
    shape: part
    pos: [0, 0, 0]
    mount: spin
    mass: 0.3
    friction: 0.05
    color: "#b8ad97"
    pieces:
      - {kind: rod, from: [-4.6, 0, 11.0], to: [4.6, 0, 11.0], radius: 0.7, collide: 0, color: "#a89a7e"}   # the cross-head's bar (turned to the planes' angle)
      - {kind: rod, from: [-1.9775, 0.2989, 0.691], to: [-4.5483, 0.6874, 0.691], radius: 0.5, collide: 1, capsule: true, color: "#8f8a80"}
      - {kind: rod, from: [1.9775, -0.2989, 0.691], to: [4.5483, -0.6874, 0.691], radius: 0.5, collide: 1, capsule: true, color: "#8f8a80"}
      - {kind: rod, from: [-4.5483, 0.6874, 0.691], to: [-4.5483, 0.6874, 11.0], radius: 0.35, collide: 0, color: "#a89a7e"}
      - {kind: rod, from: [4.5483, -0.6874, 0.691], to: [4.5483, -0.6874, 11.0], radius: 0.35, collide: 0, color: "#a89a7e"}
      - {kind: poly, points: [[4.6, 9.6], [9.0, 10.8], [9.0, 12.6], [4.6, 11.4]], y: [-2.6, 2.6], collide: 0, color: "#cdbf9f"}   # a fan, pitched
      - {kind: poly, points: [[-4.6, 11.4], [-9.0, 12.6], [-9.0, 10.8], [-4.6, 9.6]], y: [-2.6, 2.6], collide: 0, color: "#cdbf9f"}   # and the other
joints:
  - {id: j_s, type: hinge, body: shaft, axis: [0, 0, 1], damping: 0.002}   # the one driven joint: the centre shaft; + : counter-clockwise from above
  - {id: j_h, type: hinge, body: spin, axis: [0, 0, 1], damping: 0.02}   # the cross-head loose on the shaft, held back by the air on its fans
  - {id: j_z, type: slide, body: head, axis: [0, 0, 1], range: [-0.05, 3.4], stiffness: 70.0, springref: 0, damping: 0.3}   # its rise, against the valve lever's spring
driver: {joint: j_s, kind: velocity, rpm: 60, kv: 0.3, max_torque: 3}
checks:
  - {type: position, joint: j_z, min: 0.9, max: 1.7, settle_s: 1.0, window_s: 7.5}   # the cross-head stands up the planes
  - {type: ratio, out: j_h, in: j_s, expect: 1.0, tol: 0.03, settle_s: 3.0, window_s: 5.0}   # and turns with the shaft
camera: {target: [0, 0, 4.6], position: [0, -50, 14], fov: 34}
display:
  output: j_z
  labels: {j_s: "Centre shaft (driver)", j_z: "Cross-head rise"}
  proof: {label: "Rollers out of contact", sub: "the shaft turns but the cross-head does not rise"}

