# No. 426 (Brown 1868): "Another form of rotary engine, in which there are two stationary abutments, D, D, within the cylinder, and the two
# pistons, A, A, in order to enable them to pass the abutments, are made to slide radially in grooves in the hub, C, of the main shaft, B. The
# steam acts on both pistons at once, to produce the rotation of the hub and shaft. The induction and eduction are indicated by arrows."
# Model (cm, Brown's section, gravity on; only the back half of the cut cylinder is drawn). The hub C (5.2 cm) is fast on the shaft B at the
# cylinder's centre; the bore is 8 cm except at the two abutments D, D (left a little high, right a little low), which come in to the hub
# (5.28 cm), with easy ramps either side. The two pistons A, A slide radially in one groove through the hub, each pressed out by a spring in the
# groove (6 N/m), so each rides the bore: out across the working spaces and pressed back into the hub by an abutment's ramp to pass it. The
# only contact is the pistons' edges on the bore. The steam (the one input) acts on both pistons at once: in at one side of each abutment,
# out at the other, as Brown's arrows, so each piston has steam behind it from just past one abutment to just before the next; it is a
# push on each piston's face (up to 5 N, at the middle of the face exposed between hub and bore), let in and shut off by the hub's own
# turn, the shaft free against a load (0.0405 N m s). A steel fly-wheel on the shaft behind the cylinder (hidden by its back; not in Brown's
# figure) carries the pistons past the abutments, where the steam has no face to push on.
# Generator: opencode-runs/steam/gen426.py.
number: 426
slug: rotary-engine-sliding-pistons
name: Rotary engine with sliding pistons
brown: "Another form of rotary engine, in which there are two stationary abutments, D, D, within the cylinder, and the two pistons, A, A, in order to enable them to pass the abutments, are made to slide radially in grooves in the hub, C, of the main shaft, B. The steam acts on both pistons at once, to produce the rotation of the hub and shaft. The induction and eduction are indicated by arrows."
units: cm
sim:
  timestep: 0.0002
  integrator: implicitfast
  iterations: 100
  solver: PGS
  duration_s: 10
  floor: false
bodies:
  - id: hub
    shape: part
    pos: [0, 0, 10]
    density: 7800
    color: "#8f8a80"
    pieces:
      - {kind: disc, center: [0, 10], radius: 5.2, y: [0.4, 2.0]}   # the hub C
      - {kind: disc, center: [0, 10], radius: 1.0, y: [-0.3, 6], color: "#6f6a60"}   # the shaft B
      - {kind: disc, center: [0, 10], radius: 8, y: [3.0, 6], collide: 0, color: "#6f6a60"}   # the fly-wheel, behind the cylinder (carries the pistons past the abutments)
  - id: piston_a
    shape: part
    pos: [0, 0, 17.72]
    mount: hub
    density: 7800
    friction: 0.05
    color: "#a39d90"
    pieces:
      - {kind: poly, points: [[-0.3, 13.57], [0.3, 13.57], [0.3, 17.72], [-0.3, 17.72]], y: [0.1, 2.3]}   # a piston A, cut through
      - {kind: rod, from: [0, 0.2, 17.72], to: [0, 2.2, 17.72], radius: 0.25, capsule: true, collide: 2}   # its edge, on the bore
  - id: piston_b
    shape: part
    pos: [0, 0, 2.28]
    mount: hub
    density: 7800
    friction: 0.05
    color: "#a39d90"
    pieces:
      - {kind: poly, points: [[-0.3, 2.28], [0.3, 2.28], [0.3, 6.43], [-0.3, 6.43]], y: [0.1, 2.3]}   # a piston A, cut through
      - {kind: rod, from: [0, 0.2, 2.28], to: [0, 2.2, 2.28], radius: 0.25, capsule: true, collide: 2}   # its edge, on the bore
  - id: frame
    shape: part
    pos: [0, 0, 0]
    fixed: true
    color: "#cfc6b4"
    pieces:
      - {kind: poly, points: [[5.3195, 10], [8.9, 10], [8.8946, 10.3106], [5.3538, 10.187]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.3538, 10.187], [8.8946, 10.3106], [8.8783, 10.6208], [5.3935, 10.3771]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.3935, 10.3771], [8.8783, 10.6208], [8.8512, 10.9303], [5.4378, 10.5715]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.4378, 10.5715], [8.8512, 10.9303], [8.8134, 11.2386], [5.4858, 10.771]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.4858, 10.771], [8.8134, 11.2386], [8.7648, 11.5455], [5.5366, 10.9763]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.5366, 10.9763], [8.7648, 11.5455], [8.7055, 11.8504], [5.589, 11.188]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.589, 11.188], [8.7055, 11.8504], [8.6356, 12.1531], [5.6416, 11.4066]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.6416, 11.4066], [8.6356, 12.1531], [8.5552, 12.4532], [5.693, 11.6324]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.693, 11.6324], [8.5552, 12.4532], [8.4644, 12.7503], [5.7418, 11.8656]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.7418, 11.8656], [8.4644, 12.7503], [8.3633, 13.044], [5.7864, 12.1061]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.7864, 12.1061], [8.3633, 13.044], [8.2519, 13.334], [5.8252, 12.3535]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.8252, 12.3535], [8.2519, 13.334], [8.1306, 13.62], [5.8568, 12.6076]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.8568, 12.6076], [8.1306, 13.62], [7.9993, 13.9015], [5.8795, 12.8676]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.8795, 12.8676], [7.9993, 13.9015], [7.8582, 14.1783], [5.8918, 13.1327]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.8918, 13.1327], [7.8582, 14.1783], [7.7076, 14.45], [5.8924, 13.402]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.8924, 13.402], [7.7076, 14.45], [7.5476, 14.7163], [5.8799, 13.6742]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.8799, 13.6742], [7.5476, 14.7163], [7.3784, 14.9768], [5.8532, 13.948]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.8532, 13.948], [7.3784, 14.9768], [7.2003, 15.2313], [5.8113, 14.2221]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.8113, 14.2221], [7.2003, 15.2313], [7.0133, 15.4794], [5.7532, 14.4949]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.7532, 14.4949], [7.0133, 15.4794], [6.8178, 15.7208], [5.6784, 14.7647]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.6784, 14.7647], [6.8178, 15.7208], [6.614, 15.9553], [5.5862, 15.0298]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.5862, 15.0298], [6.614, 15.9553], [6.4021, 16.1825], [5.4765, 15.2886]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.4765, 15.2886], [6.4021, 16.1825], [6.1825, 16.4021], [5.3491, 15.5392]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.3491, 15.5392], [6.1825, 16.4021], [5.9553, 16.614], [5.2042, 15.7799]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.2042, 15.7799], [5.9553, 16.614], [5.7208, 16.8178], [5.0422, 16.009]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.0422, 16.009], [5.7208, 16.8178], [5.4794, 17.0133], [4.8635, 16.225]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[4.8635, 16.225], [5.4794, 17.0133], [5.2313, 17.2003], [4.6689, 16.4262]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[4.6689, 16.4262], [5.2313, 17.2003], [4.9768, 17.3784], [4.4594, 16.6113]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[4.4594, 16.6113], [4.9768, 17.3784], [4.7163, 17.5476], [4.236, 16.779]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[4.236, 16.779], [4.7163, 17.5476], [4.45, 17.7076], [4, 16.9282]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[4, 16.9282], [4.45, 17.7076], [4.1783, 17.8582], [3.7558, 17.0636]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[3.7558, 17.0636], [4.1783, 17.8582], [3.9015, 17.9993], [3.507, 17.1904]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[3.507, 17.1904], [3.9015, 17.9993], [3.62, 18.1306], [3.2539, 17.3084]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[3.2539, 17.3084], [3.62, 18.1306], [3.334, 18.2519], [2.9969, 17.4175]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[2.9969, 17.4175], [3.334, 18.2519], [3.044, 18.3633], [2.7362, 17.5175]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[2.7362, 17.5175], [3.044, 18.3633], [2.7503, 18.4644], [2.4721, 17.6085]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[2.4721, 17.6085], [2.7503, 18.4644], [2.4532, 18.5552], [2.2051, 17.6901]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[2.2051, 17.6901], [2.4532, 18.5552], [2.1531, 18.6356], [1.9354, 17.7624]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[1.9354, 17.7624], [2.1531, 18.6356], [1.8504, 18.7055], [1.6633, 17.8252]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[1.6633, 17.8252], [1.8504, 18.7055], [1.5455, 18.7648], [1.3892, 17.8785]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[1.3892, 17.8785], [1.5455, 18.7648], [1.2386, 18.8134], [1.1134, 17.9221]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[1.1134, 17.9221], [1.2386, 18.8134], [0.9303, 18.8512], [0.8362, 17.9562]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[0.8362, 17.9562], [0.9303, 18.8512], [0.6208, 18.8783], [0.5581, 17.9805]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[0.5581, 17.9805], [0.6208, 18.8783], [0.3106, 18.8946], [0.2792, 17.9951]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[0.2792, 17.9951], [0.3106, 18.8946], [0, 18.9], [0, 18]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[0, 18], [0, 18.9], [-0.3106, 18.8946], [-0.2792, 17.9951]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-0.2792, 17.9951], [-0.3106, 18.8946], [-0.6208, 18.8783], [-0.5581, 17.9805]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-0.5581, 17.9805], [-0.6208, 18.8783], [-0.9303, 18.8512], [-0.8362, 17.9562]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-0.8362, 17.9562], [-0.9303, 18.8512], [-1.2386, 18.8134], [-1.1134, 17.9221]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-1.1134, 17.9221], [-1.2386, 18.8134], [-1.5455, 18.7648], [-1.3892, 17.8785]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-1.3892, 17.8785], [-1.5455, 18.7648], [-1.8504, 18.7055], [-1.662, 17.819]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-1.662, 17.819], [-1.8504, 18.7055], [-2.1531, 18.6356], [-1.9292, 17.7378]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-1.9292, 17.7378], [-2.1531, 18.6356], [-2.4532, 18.5552], [-2.1894, 17.6355]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-2.1894, 17.6355], [-2.4532, 18.5552], [-2.7503, 18.4644], [-2.4411, 17.513]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-2.4411, 17.513], [-2.7503, 18.4644], [-3.044, 18.3633], [-2.6829, 17.3712]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-2.6829, 17.3712], [-3.044, 18.3633], [-3.334, 18.2519], [-2.9135, 17.2113]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-2.9135, 17.2113], [-3.334, 18.2519], [-3.62, 18.1306], [-3.132, 17.0346]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-3.132, 17.0346], [-3.62, 18.1306], [-3.9015, 17.9993], [-3.3374, 16.8427]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-3.3374, 16.8427], [-3.9015, 17.9993], [-4.1783, 17.8582], [-3.529, 16.6371]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-3.529, 16.6371], [-4.1783, 17.8582], [-4.45, 17.7076], [-3.7063, 16.4195]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-3.7063, 16.4195], [-4.45, 17.7076], [-4.7163, 17.5476], [-3.8689, 16.1915]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-3.8689, 16.1915], [-4.7163, 17.5476], [-4.9768, 17.3784], [-4.0168, 15.9551]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-4.0168, 15.9551], [-4.9768, 17.3784], [-5.2313, 17.2003], [-4.1499, 15.7119]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-4.1499, 15.7119], [-5.2313, 17.2003], [-5.4794, 17.0133], [-4.2687, 15.4636]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-4.2687, 15.4636], [-5.4794, 17.0133], [-5.7208, 16.8178], [-4.3735, 15.2121]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-4.3735, 15.2121], [-5.7208, 16.8178], [-5.9553, 16.614], [-4.465, 14.9589]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-4.465, 14.9589], [-5.9553, 16.614], [-6.1825, 16.4021], [-4.5441, 14.7056]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-4.5441, 14.7056], [-6.1825, 16.4021], [-6.4021, 16.1825], [-4.6117, 14.4535]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-4.6117, 14.4535], [-6.4021, 16.1825], [-6.614, 15.9553], [-4.669, 14.204]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-4.669, 14.204], [-6.614, 15.9553], [-6.8178, 15.7208], [-4.7171, 13.9581]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-4.7171, 13.9581], [-6.8178, 15.7208], [-7.0133, 15.4794], [-4.7574, 13.7169]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-4.7574, 13.7169], [-7.0133, 15.4794], [-7.2003, 15.2313], [-4.7913, 13.4811]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-4.7913, 13.4811], [-7.2003, 15.2313], [-7.3784, 14.9768], [-4.8202, 13.2513]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-4.8202, 13.2513], [-7.3784, 14.9768], [-7.5476, 14.7163], [-4.8456, 13.0279]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-4.8456, 13.0279], [-7.5476, 14.7163], [-7.7076, 14.45], [-4.8688, 12.811]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-4.8688, 12.811], [-7.7076, 14.45], [-7.8582, 14.1783], [-4.8913, 12.6007]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-4.8913, 12.6007], [-7.8582, 14.1783], [-7.9993, 13.9015], [-4.9144, 12.3969]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-4.9144, 12.3969], [-7.9993, 13.9015], [-8.1306, 13.62], [-4.9392, 12.1991]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-4.9392, 12.1991], [-8.1306, 13.62], [-8.2519, 13.334], [-4.967, 12.0068]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-4.967, 12.0068], [-8.2519, 13.334], [-8.3633, 13.044], [-4.9987, 11.8194]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-4.9987, 11.8194], [-8.3633, 13.044], [-8.4644, 12.7503], [-5.0352, 11.636]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.0352, 11.636], [-8.4644, 12.7503], [-8.5552, 12.4532], [-5.077, 11.4558]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.077, 11.4558], [-8.5552, 12.4532], [-8.6356, 12.1531], [-5.1232, 11.2773]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.1232, 11.2773], [-8.6356, 12.1531], [-8.7055, 11.8504], [-5.1646, 11.0978]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.1646, 11.0978], [-8.7055, 11.8504], [-8.7648, 11.5455], [-5.1998, 10.9169]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.1998, 10.9169], [-8.7648, 11.5455], [-8.8134, 11.2386], [-5.2286, 10.7348]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.2286, 10.7348], [-8.8134, 11.2386], [-8.8512, 10.9303], [-5.2511, 10.5519]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.2511, 10.5519], [-8.8512, 10.9303], [-8.8783, 10.6208], [-5.2687, 10.3684]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.2687, 10.3684], [-8.8783, 10.6208], [-8.8946, 10.3106], [-5.291, 10.1848]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.291, 10.1848], [-8.8946, 10.3106], [-8.9, 10], [-5.3195, 10]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.3195, 10], [-8.9, 10], [-8.8946, 9.6894], [-5.3538, 9.813]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.3538, 9.813], [-8.8946, 9.6894], [-8.8783, 9.3792], [-5.3935, 9.6229]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.3935, 9.6229], [-8.8783, 9.3792], [-8.8512, 9.0697], [-5.4378, 9.4285]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.4378, 9.4285], [-8.8512, 9.0697], [-8.8134, 8.7614], [-5.4858, 9.229]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.4858, 9.229], [-8.8134, 8.7614], [-8.7648, 8.4545], [-5.5366, 9.0237]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.5366, 9.0237], [-8.7648, 8.4545], [-8.7055, 8.1496], [-5.589, 8.812]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.589, 8.812], [-8.7055, 8.1496], [-8.6356, 7.8469], [-5.6416, 8.5934]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.6416, 8.5934], [-8.6356, 7.8469], [-8.5552, 7.5468], [-5.693, 8.3676]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.693, 8.3676], [-8.5552, 7.5468], [-8.4644, 7.2497], [-5.7418, 8.1344]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.7418, 8.1344], [-8.4644, 7.2497], [-8.3633, 6.956], [-5.7864, 7.8939]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.7864, 7.8939], [-8.3633, 6.956], [-8.2519, 6.666], [-5.8252, 7.6465]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.8252, 7.6465], [-8.2519, 6.666], [-8.1306, 6.38], [-5.8568, 7.3924]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.8568, 7.3924], [-8.1306, 6.38], [-7.9993, 6.0985], [-5.8795, 7.1324]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.8795, 7.1324], [-7.9993, 6.0985], [-7.8582, 5.8217], [-5.8918, 6.8673]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.8918, 6.8673], [-7.8582, 5.8217], [-7.7076, 5.55], [-5.8924, 6.598]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.8924, 6.598], [-7.7076, 5.55], [-7.5476, 5.2837], [-5.8799, 6.3258]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.8799, 6.3258], [-7.5476, 5.2837], [-7.3784, 5.0232], [-5.8532, 6.052]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.8532, 6.052], [-7.3784, 5.0232], [-7.2003, 4.7687], [-5.8113, 5.7779]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.8113, 5.7779], [-7.2003, 4.7687], [-7.0133, 4.5206], [-5.7532, 5.5051]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.7532, 5.5051], [-7.0133, 4.5206], [-6.8178, 4.2792], [-5.6784, 5.2353]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.6784, 5.2353], [-6.8178, 4.2792], [-6.614, 4.0447], [-5.5862, 4.9702]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.5862, 4.9702], [-6.614, 4.0447], [-6.4021, 3.8175], [-5.4765, 4.7114]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.4765, 4.7114], [-6.4021, 3.8175], [-6.1825, 3.5979], [-5.3491, 4.4608]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.3491, 4.4608], [-6.1825, 3.5979], [-5.9553, 3.386], [-5.2042, 4.2201]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.2042, 4.2201], [-5.9553, 3.386], [-5.7208, 3.1822], [-5.0422, 3.991]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-5.0422, 3.991], [-5.7208, 3.1822], [-5.4794, 2.9867], [-4.8635, 3.775]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-4.8635, 3.775], [-5.4794, 2.9867], [-5.2313, 2.7997], [-4.6689, 3.5738]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-4.6689, 3.5738], [-5.2313, 2.7997], [-4.9768, 2.6216], [-4.4594, 3.3887]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-4.4594, 3.3887], [-4.9768, 2.6216], [-4.7163, 2.4524], [-4.236, 3.221]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-4.236, 3.221], [-4.7163, 2.4524], [-4.45, 2.2924], [-4, 3.0718]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-4, 3.0718], [-4.45, 2.2924], [-4.1783, 2.1418], [-3.7558, 2.9364]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-3.7558, 2.9364], [-4.1783, 2.1418], [-3.9015, 2.0007], [-3.507, 2.8096]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-3.507, 2.8096], [-3.9015, 2.0007], [-3.62, 1.8694], [-3.2539, 2.6916]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-3.2539, 2.6916], [-3.62, 1.8694], [-3.334, 1.7481], [-2.9969, 2.5825]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-2.9969, 2.5825], [-3.334, 1.7481], [-3.044, 1.6367], [-2.7362, 2.4825]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-2.7362, 2.4825], [-3.044, 1.6367], [-2.7503, 1.5356], [-2.4721, 2.3915]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-2.4721, 2.3915], [-2.7503, 1.5356], [-2.4532, 1.4448], [-2.2051, 2.3099]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-2.2051, 2.3099], [-2.4532, 1.4448], [-2.1531, 1.3644], [-1.9354, 2.2376]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-1.9354, 2.2376], [-2.1531, 1.3644], [-1.8504, 1.2945], [-1.6633, 2.1748]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-1.6633, 2.1748], [-1.8504, 1.2945], [-1.5455, 1.2352], [-1.3892, 2.1215]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-1.3892, 2.1215], [-1.5455, 1.2352], [-1.2386, 1.1866], [-1.1134, 2.0779]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-1.1134, 2.0779], [-1.2386, 1.1866], [-0.9303, 1.1488], [-0.8362, 2.0438]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-0.8362, 2.0438], [-0.9303, 1.1488], [-0.6208, 1.1217], [-0.5581, 2.0195]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-0.5581, 2.0195], [-0.6208, 1.1217], [-0.3106, 1.1054], [-0.2792, 2.0049]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-0.2792, 2.0049], [-0.3106, 1.1054], [-0, 1.1], [-0, 2]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[-0, 2], [-0, 1.1], [0.3106, 1.1054], [0.2792, 2.0049]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[0.2792, 2.0049], [0.3106, 1.1054], [0.6208, 1.1217], [0.5581, 2.0195]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[0.5581, 2.0195], [0.6208, 1.1217], [0.9303, 1.1488], [0.8362, 2.0438]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[0.8362, 2.0438], [0.9303, 1.1488], [1.2386, 1.1866], [1.1134, 2.0779]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[1.1134, 2.0779], [1.2386, 1.1866], [1.5455, 1.2352], [1.3892, 2.1215]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[1.3892, 2.1215], [1.5455, 1.2352], [1.8504, 1.2945], [1.662, 2.181]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[1.662, 2.181], [1.8504, 1.2945], [2.1531, 1.3644], [1.9292, 2.2622]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[1.9292, 2.2622], [2.1531, 1.3644], [2.4532, 1.4448], [2.1894, 2.3645]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[2.1894, 2.3645], [2.4532, 1.4448], [2.7503, 1.5356], [2.4411, 2.487]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[2.4411, 2.487], [2.7503, 1.5356], [3.044, 1.6367], [2.6829, 2.6288]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[2.6829, 2.6288], [3.044, 1.6367], [3.334, 1.7481], [2.9135, 2.7887]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[2.9135, 2.7887], [3.334, 1.7481], [3.62, 1.8694], [3.132, 2.9654]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[3.132, 2.9654], [3.62, 1.8694], [3.9015, 2.0007], [3.3374, 3.1573]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[3.3374, 3.1573], [3.9015, 2.0007], [4.1783, 2.1418], [3.529, 3.3629]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[3.529, 3.3629], [4.1783, 2.1418], [4.45, 2.2924], [3.7063, 3.5805]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[3.7063, 3.5805], [4.45, 2.2924], [4.7163, 2.4524], [3.8689, 3.8085]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[3.8689, 3.8085], [4.7163, 2.4524], [4.9768, 2.6216], [4.0168, 4.0449]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[4.0168, 4.0449], [4.9768, 2.6216], [5.2313, 2.7997], [4.1499, 4.2881]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[4.1499, 4.2881], [5.2313, 2.7997], [5.4794, 2.9867], [4.2687, 4.5364]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[4.2687, 4.5364], [5.4794, 2.9867], [5.7208, 3.1822], [4.3735, 4.7879]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[4.3735, 4.7879], [5.7208, 3.1822], [5.9553, 3.386], [4.465, 5.0411]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[4.465, 5.0411], [5.9553, 3.386], [6.1825, 3.5979], [4.5441, 5.2944]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[4.5441, 5.2944], [6.1825, 3.5979], [6.4021, 3.8175], [4.6117, 5.5465]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[4.6117, 5.5465], [6.4021, 3.8175], [6.614, 4.0447], [4.669, 5.796]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[4.669, 5.796], [6.614, 4.0447], [6.8178, 4.2792], [4.7171, 6.0419]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[4.7171, 6.0419], [6.8178, 4.2792], [7.0133, 4.5206], [4.7574, 6.2831]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[4.7574, 6.2831], [7.0133, 4.5206], [7.2003, 4.7687], [4.7913, 6.5189]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[4.7913, 6.5189], [7.2003, 4.7687], [7.3784, 5.0232], [4.8202, 6.7487]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[4.8202, 6.7487], [7.3784, 5.0232], [7.5476, 5.2837], [4.8456, 6.9721]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[4.8456, 6.9721], [7.5476, 5.2837], [7.7076, 5.55], [4.8688, 7.189]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[4.8688, 7.189], [7.7076, 5.55], [7.8582, 5.8217], [4.8913, 7.3993]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[4.8913, 7.3993], [7.8582, 5.8217], [7.9993, 6.0985], [4.9144, 7.6031]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[4.9144, 7.6031], [7.9993, 6.0985], [8.1306, 6.38], [4.9392, 7.8009]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[4.9392, 7.8009], [8.1306, 6.38], [8.2519, 6.666], [4.967, 7.9932]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[4.967, 7.9932], [8.2519, 6.666], [8.3633, 6.956], [4.9987, 8.1806]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[4.9987, 8.1806], [8.3633, 6.956], [8.4644, 7.2497], [5.0352, 8.364]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.0352, 8.364], [8.4644, 7.2497], [8.5552, 7.5468], [5.077, 8.5442]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.077, 8.5442], [8.5552, 7.5468], [8.6356, 7.8469], [5.1232, 8.7227]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.1232, 8.7227], [8.6356, 7.8469], [8.7055, 8.1496], [5.1646, 8.9022]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.1646, 8.9022], [8.7055, 8.1496], [8.7648, 8.4545], [5.1998, 9.0831]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.1998, 9.0831], [8.7648, 8.4545], [8.8134, 8.7614], [5.2286, 9.2652]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.2286, 9.2652], [8.8134, 8.7614], [8.8512, 9.0697], [5.2511, 9.4481]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.2511, 9.4481], [8.8512, 9.0697], [8.8783, 9.3792], [5.2687, 9.6316]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.2687, 9.6316], [8.8783, 9.3792], [8.8946, 9.6894], [5.291, 9.8152]], y: [0, 2.4], collide: 1}
      - {kind: poly, points: [[5.291, 9.8152], [8.8946, 9.6894], [8.9, 10], [5.3195, 10]], y: [0, 2.4], collide: 1}
      - {kind: disc, center: [0, 10], radius: 10.4, y: [2.4, 2.9], color: "#bdb4a2"}   # the cylinder's back
      - {kind: poly, points: [[-11.6, 10.6], [-7.8, 10.6], [-7.8, 12.4], [-11.6, 12.4]], y: [2.4, 2.9], color: "#bdb4a2"}   # the steam-ways at D, D
      - {kind: poly, points: [[7.8, 7.6], [11.6, 7.6], [11.6, 9.4], [7.8, 9.4]], y: [2.4, 2.9], color: "#bdb4a2"}
      - {kind: poly, points: [[-9.5, -0.8], [9.5, -0.8], [9.5, 0.2], [-9.5, 0.2]], y: [-1.5, 3.5], color: "#bdb4a2"}   # the bed
      - {kind: poly, points: [[-6, 0.2], [6, 0.2], [3.5, 1.5], [-3.5, 1.5]], y: [0, 2.9], color: "#bdb4a2"}
joints:
  - {id: j_B, type: hinge, body: hub, axis: [0, -1, 0], damping: 0.0405}   # the shaft and hub; + : anticlockwise as drawn (Brown's arrows)
  - {id: j_a, type: slide, body: piston_a, axis: [0, 0, 1], range: [-3.12, 0.4], stiffness: 6, springref: 12, damping: 0.02}   # the upper piston, in and out of its groove
  - {id: j_b, type: slide, body: piston_b, axis: [0, 0, -1], range: [-3.12, 0.4], stiffness: 6, springref: 12, damping: 0.02}
contact: {solref: [0.002, 1.0], solimp: [0.95, 0.99, 0.0005], margin: 0}
driver:
  joint: j_B
  kind: feet
  max_torque: 1.0
  feet:
    force: 5
    timed: {joint: j_B, gain: 2, offset: -1.5708}   # x = 2 x the upper piston's angle (deg from the right, anticlockwise)
    ports:   # the steam on the upper and the lower piston, square to it, anticlockwise (the hub's way)
      - {body: piston_a, at: [0, 1.2, 16.6], dir: [-1, 0, 0], frame: body, open: [350, 690], profile: [0.496, -0.4736, 0.1724]}
      - {body: piston_b, at: [0, 1.2, 3.4], dir: [1, 0, 0], frame: body, open: [350, 690], profile: [0.496, -0.4736, 0.1724]}
checks:
  - {type: monotonic, joint: j_B, direction: 1, max_back: 0.05, settle_s: 0.0, window_s: 9.5}
  - {type: turning, joint: j_B, direction: 1, min_mean: 3.5, min_fraction: 0.9, settle_s: 3.0, window_s: 6.5}
  - {type: amplitude, joint: j_a, min: 0.0129, max: 0.014, sustain: 0.95, settle_s: 3.0, window_s: 6.5}   # each piston is pressed into the hub to pass an abutment and goes out again to the bore (1.360 cm either way)
  - {type: amplitude, joint: j_b, min: 0.0129, max: 0.014, sustain: 0.95, settle_s: 3.0, window_s: 6.5}
  - {type: penetration, max: 0.002}
camera: {target: [0, 0, 9.6], position: [0, -95, 9.6], fov: 22}
display:
  output: j_B
  labels: {j_B: "Shaft B and hub C", j_a: "Upper piston A", j_b: "Lower piston A"}
  proof: {label: "Pistons out of contact", sub: "the hub turns but the pistons lie out on their stops, through the abutments"}
