# No. 86 (Brown 1868): "A method of working a reciprocating pump by rotary motion. A rope, carrying the
# pump-rod, is attached to the wheel, A, which runs loosely upon the shaft. The shaft carries a cam, C, and has
# a continuous rotary motion. At every revolution the cam seizes the hooked catch, B, attached to the wheel, and
# drags it round, together with the wheel, and raises the rope until, on the extremity of the catch striking the
# stationary stop above, the catch is released, and the wheel is returned by the weight of the pump-bucket."
#
# Model (cm): the shaft turns clockwise, the one driven joint, 10 turns a minute; its cam C is a single
# tooth. The wheel A (8 cm) runs loose on the shaft and rests against a stop (its joint's range) under the pull
# of the rope, which is tied to its rim and runs down from its left side to the pump-rod and bucket (0.5 kg; the
# water's drag on the bucket is the slide's damping). The catch B is pivoted on A ahead of its hook and held in by
# a spring (its joint's) against a stop; the cam's tooth comes up under the hook and drags A round, which winds
# the rope on A's rim and raises the bucket 8 cm a radian. After about 74 deg the shoe on the
# catch's extremity (in front, behind the hook) runs over the stationary stop above the shaft: the stop presses it
# out, the catch turns on its pivot (its damping holds it out a moment) and its hook swings out clear of the tooth, and the bucket's weight returns A to its rest. The cam comes round and
# seizes the hook again at every revolution. Generator: opencode-runs/batch8/gen086.py.
number: 86
slug: pump-wheel-cam-catch
name: A pump worked by a cam, a hooked catch and a stop
brown: "A method of working a reciprocating pump by rotary motion. A rope, carrying the pump-rod, is attached to the wheel, A, which runs loosely upon the shaft. The shaft carries a cam, C, and has a continuous rotary motion. At every revolution the cam seizes the hooked catch, B, attached to the wheel, and drags it round, together with the wheel, and raises the rope until, on the extremity of the catch striking the stationary stop above, the catch is released, and the wheel is returned by the weight of the pump-bucket."
units: cm
sim:
  timestep: 0.0002
  integrator: implicitfast
  iterations: 100
  solver: PGS
  multiccd: true
  duration_s: 20.0
  floor: false
bodies:
  - id: shaft
    shape: part
    pos: [0, 0, 0]
    mass: 1.0
    friction: 0.1
    color: "#d9cfb6"
    pieces:
      - {kind: disc, center: [0, 0], radius: 1.4, inner: 0.5, y: [-1.3, -0.1]}
      - {kind: poly, points: [[0.1536, -1.066], [0.8536, -2.2785], [1.5464, -1.8785], [0.8464, -0.666]], y: [-1.2, -0.2], collide: 1}   # the cam C
      - {kind: rod, from: [1.2, -0.8, -2.0785], to: [1.2, -0.6, -2.0785], radius: 0.4, collide: 1, capsule: true}
  - id: wheel_a
    shape: part
    pos: [0, 0, 0]
    mass: 0.4
    color: "#cdbf9f"
    pieces:
      - {kind: disc, center: [0, 0], radius: 8.0, inner: 0.6, y: [0.1, 0.9]}
      - {kind: disc, center: [0, 0], radius: 8.5, inner: 8.0, y: [0.9, 1.3]}   # the rope's groove: a flange
      - {kind: disc, center: [-3.6, 2.4], radius: 0.45, y: [-1.3, 0.1]}   # the catch's stud
  - id: catch_b
    shape: part
    pos: [-3.6, 0, 2.4]
    mount: wheel_a
    mass: 0.03
    friction: 0.1
    color: "#6b5a44"
    pieces:
      - {kind: poly, points: [[-3.9, 2.4], [-3.3000000000000003, 2.4], [-2.9, 0.0], [-3.5, 0.0]], y: [-1.2, -0.2], collide: 2}   # the arm down to the hook
      - {kind: poly, points: [[-3.4, -0.4], [-1.75, -0.4], [-1.75, 0.4], [-3.4, 0.4]], y: [-1.2, -0.2], collide: 2}   # the hook
      - {kind: poly, points: [[-3.15, 0.0], [-2.7779, -0.5905], [-4.0104, -0.8524], [-4.1, 0.0]], y: [-1.95, -1.3], collide: 2}   # its extremity, in front, which meets the stop
      - {kind: poly, points: [[-2.7779, -0.5905], [-2.3113, -1.029], [-3.7455, -1.6676], [-4.0104, -0.8524]], y: [-1.95, -1.3], collide: 2}   # its extremity, in front, which meets the stop
      - {kind: poly, points: [[-2.3113, -1.029], [-1.796, -1.3049], [-3.317, -2.4099], [-3.7455, -1.6676]], y: [-1.95, -1.3], collide: 2}   # its extremity, in front, which meets the stop
      - {kind: poly, points: [[-1.796, -1.3049], [-1.278, -1.4194], [-2.7434, -3.0469], [-3.317, -2.4099]], y: [-1.95, -1.3], collide: 2}   # its extremity, in front, which meets the stop
      - {kind: poly, points: [[-1.278, -1.4194], [-0.8, -1.3856], [-2.05, -3.5507], [-2.7434, -3.0469]], y: [-1.95, -1.3], collide: 2}   # its extremity, in front, which meets the stop
  - id: bucket
    shape: part
    pos: [-8.05, 0, -12.0]
    mass: 0.5
    color: "#9a8c74"
    pieces:
      - {kind: rod, from: [-8.05, 0.7, -12.0], to: [-8.05, 0.7, -20.0], radius: 0.35}   # the pump-rod
      - {kind: poly, points: [[-9.6, -22.0], [-6.5, -22.0], [-6.5, -20.0], [-9.6, -20.0]], y: [-0.9, 2.3]}   # the bucket
  - id: frame
    shape: part
    pos: [0, 0, 0]
    fixed: true
    color: "#cfc6b4"
    pieces:
      - {kind: rod, from: [0, -1.4, 0], to: [0, 2.8, 0], radius: 0.5, color: "#8f8a80"}   # the shaft's journal
      - {kind: poly, points: [[-1.6, -27.0], [1.6, -27.0], [1.0, 0], [-1.0, 0]], y: [1.8, 2.8]}   # its standard, behind
      - {kind: rod, from: [-1.9159, -1.65, 1.9727], to: [-1.9159, -1.6, 1.9727], radius: 0.3, collide: 1, capsule: true, color: "#8f8a80"}   # the stationary stop
      - {kind: poly, points: [[-2.2659, 1.9727], [-1.5659, 1.9727], [-1.5659, 12.0], [-2.2659, 12.0]], y: [-2.6, -2.0]}   # its hanger, in front
      - {kind: poly, points: [[-14, 12.0], [6, 12.0], [6, 13.0], [-14, 13.0]], y: [-3, 3], color: "#b9b09c"}   # the beam over
      - {kind: poly, points: [[-10.6, -27.0], [-5.5, -27.0], [-5.5, -16.0], [-10.6, -16.0]], y: [2.4, 3.0], color: "#a8b4b8"}   # the pump's barrel, behind
      - {kind: poly, points: [[-14, -28.0], [6, -28.0], [6, -27.0], [-14, -27.0]], y: [-3, 3], color: "#b9b09c"}
joints:
  - {id: j_s, type: hinge, body: shaft, axis: [0, 1, 0], damping: 0.002}   # the one driven joint; + : clockwise
  - {id: j_A, type: hinge, body: wheel_a, axis: [0, 1, 0], range: [0, 1.9], damping: 0.01}   # rests against its stop at 0
  - {id: j_c, type: hinge, body: catch_b, axis: [0, 1, 0], range: [0, 0.6], stiffness: 0.3, springref: -0.15, damping: 0.2}   # + : the hook out
  - {id: j_w, type: slide, body: bucket, axis: [0, 0, 1], damping: 20.0}   # + : up
ropes:
  - {id: rope, from: {body: wheel_a, at: [-1.3979, 0.6 , 7.9277]}, over: {center: [0, 0.6, 0], radius: 8.0, axis: y, side: [-17, 0.6, 10]}, to: {body: bucket, at: [-8.05, 0.6, -12.0]}, width: 0.5, thickness: 0.3}
contact: {solref: [0.002, 1.0], solimp: [0.95, 0.99, 0.0005], margin: 0}
driver: {joint: j_s, kind: velocity, rpm: 10.0, kv: 2.0, max_torque: 20}
checks:
  - {type: follow, out: j_w, in: j_s, expect: 0.08, tol: 0.0016, min_r2: 0.995, settle_s: 1.9, window_s: 0.9}   # the bucket rises with the cam: R a radian
  - {type: position, joint: j_w, min: -0.3, max: 11.9, settle_s: 0.5, window_s: 19}
  - {type: penetration, max: 0.001, settle_s: 0.5}
camera: {target: [-3, 0, -13], position: [-3, -105, -7], fov: 36}
display:
  output: j_w
  labels: {j_s: "Shaft with cam C (driver)", j_A: "Wheel A", j_c: "Catch B", j_w: "Pump-rod and bucket"}
  proof: {label: "Cam out of contact", sub: "the shaft turns but the wheel and the bucket stay at rest"}

