number: 334
slug: rack-and-segment-parallel-motion
name: A rack and toothed segment parallel motion
brown: "Shows a parallel motion used in some of the old single-acting beam engines. The piston-rod is formed with a straight rack gearing with a toothed segment on the beam. The back of the rack works against a roller, A."
units: cm
sim: {timestep: 0.0002, integrator: implicitfast, iterations: 100, solver: CG, multiccd: true, duration_s: 8, floor: false}
bodies:
  # the framing: the beam's centre F, roller A's stud, and the bed
  - id: frame
    shape: part
    pos: [0, 0, 0]
    fixed: true
    density: 7800
    color: "#9a9284"
    pieces:
      - {kind: poly, points: [[-34.81, -25.7], [26.0, -25.7], [26.0, -24.5], [-34.81, -24.5]], y: [0.9, 3.6], collide: 0}
      - {kind: poly, points: [[-1.4, -24.5], [1.4, -24.5], [1.4, 0.0], [-1.4, 0.0]], y: [2.2, 3.2], collide: 0}
      - {kind: disc, center: [0, 0], radius: 2.0, y: [2.2, 3.2], collide: 0}
      - {kind: rod, from: [0, -1.4, 0], to: [0, 3.2, 0], radius: 0.8, collide: 0, color: "#6f6a60"}
      - {kind: poly, points: [[-30.01, -24.5], [-27.61, -24.5], [-27.61, 0.0], [-30.01, 0.0]], y: [1.4, 2.4], collide: 0}
      - {kind: rod, from: [-28.81, -1.2, 0], to: [-28.81, 2.4, 0], radius: 0.5, collide: 0, color: "#6f6a60"}
  # the beam, turned on F (the driven joint), with the toothed segment on its end, centred on F
  - id: beam
    shape: part
    pos: [0, 0, 0]
    mount: frame
    density: 7800
    color: "#b0a690"
    pieces:
      - {kind: poly, points: [[-20.3, -1.8], [22.0, -1.8], [22.0, 1.8], [-20.3, 1.8]], y: [-0.5, 0.5], collide: 0}
      - {kind: poly, points: [[-17.2773, 15.1518], [-18.9668, 12.9747], [-20.3835, 10.611], [-21.5071, 8.0947], [-22.3214, 5.462], [-22.8148, 2.7508], [-22.98, 0.0], [-22.8148, -2.7508], [-22.3214, -5.462], [-21.5071, -8.0947], [-20.3835, -10.611], [-18.9668, -12.9747], [-17.2773, -15.1518], [-15.6383, -13.7144], [-17.1675, -11.7438], [-18.4498, -9.6044], [-19.4668, -7.3268], [-20.2039, -4.9439], [-20.6504, -2.4898], [-20.8, 0.0], [-20.6504, 2.4898], [-20.2039, 4.9439], [-19.4668, 7.3268], [-18.4498, 9.6044], [-17.1675, 11.7438], [-15.6383, 13.7144]], y: [-0.6, 0.6], collide: 0}
      - {kind: rod, from: [0.0, 0, 0.0], to: [-16.1742, 0, 13.0781], radius: 0.7, collide: 0}
      - {kind: rod, from: [0.0, 0, 0.0], to: [-16.1742, 0, -13.0781], radius: 0.7, collide: 0}
      - {kind: disc, center: [0, 0], radius: 2.6, y: [-0.9, 0.9], collide: 0}
      - {kind: disc, center: [18, 0], radius: 4.0, y: [-1.2, 1.2], collide: 0, color: "#7d776c"}   # a weight on the beam's other end, in place of the engine's pump side
      - {kind: poly, points: [[-17.6048, 14.8386], [-18.8894, 13.1644], [-19.8615, 14.6902], [-19.3302, 15.3826]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-19.391, 12.4138], [-20.4461, 10.5862], [-21.609, 11.9721], [-21.1726, 12.7279]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-20.8455, 9.7765], [-21.653, 7.8269], [-22.9868, 9.0491], [-22.6528, 9.8554]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-21.9432, 6.972], [-22.4894, 4.9337], [-23.9713, 5.9713], [-23.7454, 6.8143]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-22.6655, 4.0482], [-22.941, 1.956], [-24.5456, 2.7914], [-24.4317, 3.6566]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-23.0, 1.0551], [-23.0, -1.0551], [-24.7, -0.4364], [-24.7, 0.4364]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-22.941, -1.956], [-22.6655, -4.0482], [-24.4317, -3.6566], [-24.5456, -2.7914]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-22.4894, -4.9337], [-21.9432, -6.972], [-23.7454, -6.8143], [-23.9713, -5.9713]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-21.653, -7.8269], [-20.8455, -9.7765], [-22.6528, -9.8554], [-22.9868, -9.0491]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-20.4461, -10.5862], [-19.391, -12.4138], [-21.1726, -12.7279], [-21.609, -11.9721]], y: [-0.6, 0.6], collide: 1}
      - {kind: poly, points: [[-18.8894, -13.1644], [-17.6048, -14.8386], [-19.3302, -15.3826], [-19.8615, -14.6902]], y: [-0.6, 0.6], collide: 1}
  # roller A, free on its stud: the back of the rack works against it
  - id: A
    shape: part
    pos: [-28.81, 0, 0]
    mount: frame
    density: 7800
    color: "#a39a88"
    pieces:
      - {kind: disc, center: [-28.81, 0], radius: 2.4, y: [-0.8, 0.8], collide: 1}
      - {kind: disc, center: [-28.81, 0], radius: 0.8, y: [-0.9, 0.9], collide: 0, color: "#6f6a60"}
  # the piston-rod with its rack: free to move across and up and down; only the segment and the roller place it
  - {id: Px, shape: part, pos: [-24.0, 0, 0], mount: frame, mass: 0.01, color: "#8f8a80", pieces: [{kind: disc, center: [-24.0, -25.1], radius: 0.1, y: [2.0, 2.1], collide: 0}]}
  - id: P
    shape: part
    pos: [-24.0, 0, 0]
    mount: Px
    density: 7800
    color: "#b8ad96"
    pieces:
      - {kind: poly, points: [[-26.4, -18.8496], [-25.0, -18.8496], [-25.0, 18.8496], [-26.4, 18.8496]], y: [-0.6, 0.6], collide: 0}
      - {kind: poly, points: [[-26.4, -18.8496], [-26.1, -18.8496], [-26.1, 18.8496], [-26.4, 18.8496]], y: [-0.6, 0.6], collide: 2}
      - {kind: rod, from: [-25.7, 0, -18.8496], to: [-25.7, 0, -19.6496], radius: 0.6, collide: 0, color: "#8f8a80"}
      - {kind: poly, points: [[-25.0, -18.3025], [-23.5, -17.7565], [-23.5, -16.801], [-25.0, -16.2551]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-25.0, -15.1609], [-23.5, -14.6149], [-23.5, -13.6594], [-25.0, -13.1135]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-25.0, -12.0193], [-23.5, -11.4733], [-23.5, -10.5178], [-25.0, -9.9719]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-25.0, -8.8777], [-23.5, -8.3317], [-23.5, -7.3762], [-25.0, -6.8303]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-25.0, -5.7361], [-23.5, -5.1901], [-23.5, -4.2346], [-25.0, -3.6887]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-25.0, -2.5945], [-23.5, -2.0485], [-23.5, -1.093], [-25.0, -0.5471]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-25.0, 0.5471], [-23.5, 1.093], [-23.5, 2.0485], [-25.0, 2.5945]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-25.0, 3.6887], [-23.5, 4.2346], [-23.5, 5.1901], [-25.0, 5.7361]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-25.0, 6.8303], [-23.5, 7.3762], [-23.5, 8.3317], [-25.0, 8.8777]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-25.0, 9.9719], [-23.5, 10.5178], [-23.5, 11.4733], [-25.0, 12.0193]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-25.0, 13.1135], [-23.5, 13.6594], [-23.5, 14.6149], [-25.0, 15.1609]], y: [-0.6, 0.6], collide: 2}
      - {kind: poly, points: [[-25.0, 16.2551], [-23.5, 16.801], [-23.5, 17.7565], [-25.0, 18.3025]], y: [-0.6, 0.6], collide: 2}
joints:
  - {id: j_F, type: hinge, body: beam, axis: [0, -1, 0], damping: 0.001}
  - {id: j_A, type: hinge, body: A, axis: [0, -1, 0], damping: 0.001}
  - {id: j_x, type: slide, body: Px, axis: [1, 0, 0], damping: 0.2, range: [-1, 1]}
  - {id: j_z, type: slide, body: P, axis: [0, 0, 1], damping: 0.2, range: [-8, 8]}
contact: {solref: [0.002, 1], solimp: [0.95, 0.99, 0.0005], margin: 0}
driver: {joint: j_F, kind: velocity, rpm: 0, swing: {amplitude: 0.2, hz: 0.25}, kv: 2000, max_torque: 100}
checks:
  # the beam, rocked on F, turns the segment, whose teeth carry the rack, and the piston-rod, straight up
  # and down: the segment's pitch radius, 24 cm, to the radian ...
  - {type: follow, out: j_z, in: j_F, expect: -0.24, tol: 0.005, min_r2: 0.999, settle_s: 0.5, window_s: 7.0}
  - {type: amplitude, joint: j_z, min: 0.046, max: 0.051, settle_s: 0.5, window_s: 7.0}
  # ... the back of the rack bearing on roller A, which rolls with it (1 / 2.4 cm to the metre) ...
  - {type: follow, out: j_A, in: j_z, expect: 41.7, tol: 1.5, min_r2: 0.995, settle_s: 0.5, window_s: 7.0}
  # ... and holds it in gear: it stays within a fraction of a millimetre of its line
  - {type: position, joint: j_x, min: -0.1, max: 0.1, settle_s: 0.5, window_s: 7.0}
  - {type: penetration, max: 0.0003, settle_s: 0.2}
camera: {target: [-6, 0, -6], position: [-6, -135, -1], fov: 30}
display:
  output: j_z
  labels: {j_F: "Beam and segment, on F (driver)", j_A: Roller A, j_x: Rack across, j_z: Piston-rod and rack}

