# No. 185 (Brown 1868): "Link-motion valve-gear of a locomotive. Two eccentrics are used for one valve, one for the forward and the other for the backward
#  movement of the engine. The extremities of the eccentric-rods are jointed to a curved slotted bar, or, as it is termed, a link, which can be raised or lowered
#  by an arrangement of levers terminating in a handle as shown. In the slot of the link is a slide and pin connected with an arrangement of levers terminating
#  at the valve-stem. ... Suppose the link raised so that the slide is in the middle, then the link will oscillate on the pin of the slide, and consequently the
#  valve will be at rest. If the link is moved so that the slide is at one of its extremities, the whole throw of the eccentric connected with that extremity
#  will be given to it ... The nearer the slide is to the middle of the slot the greater will be the expansion, and vice versa."
#
# Model (cm): the crank-shaft (the one driven joint, 30 rpm) carries two eccentrics of throw 3, the forward one set 110 deg and the backward one
# -110 deg from the crank (advance 20 deg). Their rods (45 long) are jointed to the ends of the link, a slot curved to radius 45 about the
# shaft, 14 between the pins. The link hangs by a saddle pin from a 15 cm hanger on the 14 cm lifting arm of the weigh-shaft, which carries the reversing
# handle. The die (r 0.8) on the end of the valve rod runs in the slot; the rod slides level in its guide to the slide valve in the steam chest (the plate's
# rocker between them is left out). The hand sets the handle by a joint spring: full forward gear (die 5 from the middle, toward the forward rod) at the
# start, mid gear at 6.5 s, full backward gear at 14.5 s.
# Expected valve travel (half-stroke) from the kinematic solution: forward 2.465, mid 1.477, backward 2.368 cm; a pure-lap estimate
# e|cos(90+adv)| = 1.026 in mid gear (the link "oscillating on the pin of the slide": the valve then moves only by the lap and lead).
# Generator: opencode-runs/batch11/gen185.py.
number: 185
slug: link-motion
name: Link-motion valve-gear of a locomotive
brown: "Link-motion valve-gear of a locomotive. Two eccentrics are used for one valve, one for the forward and the other for the backward movement of the engine. The extremities of the eccentric-rods are jointed to a curved slotted bar, or, as it is termed, a link, which can be raised or lowered by an arrangement of levers terminating in a handle as shown."
units: cm
sim:
  timestep: 0.0002
  integrator: implicitfast
  iterations: 100
  solver: CG
  multiccd: true
  duration_s: 22.9
  floor: false
bodies:
  - id: shaft
    shape: part
    pos: [0, 0, 0]
    density: 7800
    color: "#8f8a80"
    pieces:
      - {kind: disc, center: [0, 0], radius: 2.0, y: [-6, 3], collide: 0}   # the crank-shaft
      - {kind: disc, center: [-1.0261, 2.8191], radius: 5.2, y: [-2.6, -1.4], collide: 0}   # the forward eccentric
      - {kind: disc, center: [-1.0261, -2.8191], radius: 5.2, y: [1.4, 2.6], collide: 0}   # the backward eccentric
      - {kind: poly, points: [[0, -1.6], [9, -1.6], [9, 1.6], [0, 1.6]], y: [3.2, 4.4], collide: 0}   # the crank
  - id: rod_f
    shape: part
    mount: shaft
    pos: [-1.0261, 0, 2.8191]
    density: 2700
    color: "#d9ccae"
    pieces:
      - {kind: disc, center: [-1.0261, 2.8191], radius: 6.0, inner: 5.3, y: [-2.6, -1.4], collide: 0}   # its strap
      - {kind: rod, from: [-7.0251, -2.0, 2.7117], to: [-46.0188, -1.4, 2.0135], radius: 0.55, collide: 0}
  - id: link
    shape: part
    mount: rod_f
    pos: [-46.0188, 0, 2.0135]
    density: 2700
    friction: 0.05
    color: "#e8dec6"
    pieces:
      - {kind: band, center: [-1.1998, -2.018], r: [43.36, 44.16], a: [3.0384, 3.3778], slices: 24, y: [-0.6, 0.6], collide: 1}   # the slot's near cheek
      - {kind: band, center: [-1.1998, -2.018], r: [45.84, 46.64], a: [3.0384, 3.3778], slices: 24, y: [-0.6, 0.6], collide: 1}   # the far cheek
      - {kind: disc, center: [-45.9603, 2.6187], radius: 1.64, y: [-0.6, 0.6], collide: 0}   # the slot's closed end
      - {kind: disc, center: [-44.9505, -12.5477], radius: 1.64, y: [-0.6, 0.6], collide: 0}   # the slot's closed end
      - {kind: rod, from: [-47.3376, 0, -5.0898], to: [-48.5949, 0, -5.1735], radius: 0.5, collide: 0}   # the saddle bracket
      - {kind: rod, from: [-48.5949, -1.4, -5.1735], to: [-48.5949, 0.6, -5.1735], radius: 0.35, collide: 0}
      - {kind: rod, from: [-46.0188, -1.4, 2.0135], to: [-46.0188, 0.6, 2.0135], radius: 0.35, collide: 0}   # a rod pin
      - {kind: rod, from: [-45.0888, -1.4, -11.9556], to: [-45.0888, 0.6, -11.9556], radius: 0.35, collide: 0}   # a rod pin
  - id: rod_b
    shape: part
    mount: shaft
    pos: [-1.0261, 0, -2.8191]
    density: 2700
    color: "#d9ccae"
    pieces:
      - {kind: disc, center: [-1.0261, -2.8191], radius: 6.0, inner: 5.3, y: [1.4, 2.6], collide: 0}
      - {kind: rod, from: [-6.9011, 2.0, -4.0373], to: [-45.0888, 0.9, -11.9556], radius: 0.55, collide: 0}
  - id: arm
    shape: part
    pos: [-59.0, 0, 15.0]
    density: 2700
    color: "#8f8a80"
    pieces:
      - {kind: disc, center: [-59.0, 15.0], radius: 1.4, y: [-2.6, -1.4], collide: 0}   # the weigh-shaft
      - {kind: rod, from: [-59.0, -2.0, 15.0], to: [-46.0776, -2.0, 9.6137], radius: 0.6, collide: 0}   # the lifting arm
      - {kind: rod, from: [-59.0, -3.0, 15.0], to: [-65.3732, -3.0, 30.7601], radius: 0.6, collide: 0}   # the reversing handle
  - id: hanger
    shape: part
    mount: arm
    pos: [-46.0776, 0, 9.6137]
    density: 2700
    color: "#d9ccae"
    pieces:
      - {kind: rod, from: [-46.0776, -1.4, 9.6137], to: [-48.5949, -1.4, -5.1735], radius: 0.45, collide: 0}
  - id: valve
    shape: part
    pos: [-46.1545, 0, 0]
    density: 7800
    friction: 0.05
    color: "#e4d9bf"
    pieces:
      - {kind: disc, center: [-46.1545, 0], radius: 0.8, y: [-0.5, 0.5], collide: 2}   # the die in the slot
      - {kind: rod, from: [-46.1545, 0.9, 0], to: [-68.1545, 0.9, 0], radius: 0.45, collide: 0}   # the valve rod
      - {kind: poly, points: [[-73.1545, -1.4], [-68.1545, -1.4], [-68.1545, 1.4], [-73.1545, 1.4]], y: [-1.5, 1.5], collide: 0}   # the slide valve
  - id: chest
    shape: frame
    color: "#8f8a80"
    rods:
      - {from: [-81.1545, 2.6, -2.2], to: [-64.1545, 2.6, -2.2], radius: 0.5}   # the steam chest's face and cover, and the valve-rod guide
      - {from: [-81.1545, 2.6, 2.6], to: [-64.1545, 2.6, 2.6], radius: 0.5}
      - {from: [-54.1545, 2.6, -1.0], to: [-50.1545, 2.6, -1.0], radius: 0.35}
      - {from: [-59.0, 3.4, 15.0], to: [-59.0, 3.4, -22], radius: 0.8}   # the weigh-shaft's bracket
      - {from: [0, 5.5, 0], to: [0, 5.5, -22], radius: 1.2}   # the crank-shaft's bearing
pins:
  - {id: p_rod_b, a: rod_b, b: link, at: [-45.0888, 0, -11.9556]}   # the backward rod's pin in the link
  - {id: p_hanger, a: hanger, b: link, at: [-48.5949, 0, -5.1735]}   # the saddle pin
joints:
  - {id: j_shaft, type: hinge, body: shaft, axis: [0, -1, 0], damping: 0.001}   # the one driven joint; +: counter-clockwise
  - {id: j_rf, type: hinge, body: rod_f, axis: [0, -1, 0], damping: 0.002}
  - {id: j_link, type: hinge, body: link, axis: [0, -1, 0], damping: 0.002}
  - {id: j_rb, type: hinge, body: rod_b, axis: [0, -1, 0], damping: 0.002}
  - {id: j_arm, type: hinge, body: arm, axis: [0, -1, 0], damping: 3, stiffness: 300.0, springref: 0, range: [-0.9, 0.9]}   # the reversing handle, held where the hand sets it
  - {id: j_hanger, type: hinge, body: hanger, axis: [0, -1, 0], damping: 0.002}
  - {id: j_valve, type: slide, body: valve, axis: [1, 0, 0], damping: 0.3, range: [-8, 8]}
hand:
  - {t: 6.500000000000002, springref: {j_arm: 0.3586}}
  - {t: 14.500000000000004, springref: {j_arm: 0.7547}}
contact: {solref: [0.002, 1.0], solimp: [0.95, 0.99, 0.0005], margin: 0}
driver: {joint: j_shaft, kind: velocity, rpm: 30.0, kv: 3, max_torque: 12}   # kv x speed (9.4) under the cap; stiff enough that the crank keeps time through the gear changes
checks:
  - {type: amplitude, joint: j_valve, min: 0.0234, max: 0.0259, settle_s: 0.3, window_s: 6.0}   # full forward gear: valve half-travel 2.465 cm (kinematic)
  - {type: amplitude, joint: j_valve, min: 0.0126, max: 0.017, settle_s: 8.0, window_s: 6.0}   # mid gear: only lap and lead, 1.477 cm
  - {type: amplitude, joint: j_valve, min: 0.0225, max: 0.0249, settle_s: 16.0, window_s: 6.0}   # full backward gear
  - {type: follow, out: j_valve, in: j_shaft, expect: -0.0205, tol: 0.0031, min_r2: 0.95, settle_s: 1.75, window_s: 0.5}   # forward: the valve's quarter-turn about its fastest point
  - {type: follow, out: j_valve, in: j_shaft, expect: 0.0202, tol: 0.0031, min_r2: 0.95, settle_s: 17.75, window_s: 0.5}   # backward: the same quarter turn, the valve reversed (tol 15%: the crank runs up to 0.1 rad behind time by 18 s, which tilts the slope)
  - {type: penetration, max: 0.001, settle_s: 0.5}
camera: {target: [-28, 0, 3], position: [-28, -130, 4], fov: 34}
display:
  output: j_valve
  labels: {j_shaft: "Crank-shaft (driver)", j_valve: "Valve rod", j_arm: "Reversing handle (by hand)"}
  proof: {label: "Die out of the slot", sub: "the link swings, the valve stands"}

