# No. 429 (Brown 1868): "Holly's patent double-elliptical rotary engine. The two elliptical pistons geared together are operated upon by the
# steam entering between them, in such manner as to produce their rotary motion in opposite directions. These rotary engines can all be
# converted into pumps."
# Model (cm, Brown's section, no gravity; only the back half of the cut cylinder is drawn). Two equal two-lobed pistons on shafts 8 cm
# apart, each in its own bore of the figure-of-eight cylinder; their outlines are conjugate (epicycloid lobes and hypocycloid pockets on the
# pitch circle), so turning 1:1 opposite ways each lobe rolls in the other's pocket, 0.1 cm clear. They are geared together by two equal
# 20-tooth wheels behind the cylinder (real tooth contact, the only contact). The steam entering between them at the top (the one input) acts
# on each piston in turn, as a torque on that piston (0.1225 N m) while its lobe is exposed to the inlet, timed by the pistons' own position;
# each shaft works against a load (0.01 N m s). Generator: opencode-runs/batch13/gen429.py.
number: 429
slug: hollys-double-elliptical-rotary-engine
name: Holly's double-elliptical rotary engine
brown: "Holly's patent double-elliptical rotary engine. The two elliptical pistons geared together are operated upon by the steam entering between them, in such manner as to produce their rotary motion in opposite directions. These rotary engines can all be converted into pumps."
units: cm
sim:
  timestep: 0.0002
  integrator: implicitfast
  iterations: 100
  solver: PGS
  duration_s: 10
  floor: false
  gravity: 0
bodies:
  - id: piston_l
    shape: part
    pos: [-4, 0, 9]
    density: 7800
    friction: 0.1
    color: "#a39d90"
    pieces:
      - {kind: poly, points: [[-4, 9], [-0.1, 9], [-0.0576, 9.0054], [0.0639, 9.0428], [0.2484, 9.1407], [0.4711, 9.321], [0.7008, 9.5967], [0.904, 9.9701], [1.0475, 10.4323], [1.1028, 10.9641], [1.0488, 11.5378], [0.874, 12.1204], [0.5781, 12.6764], [0.1719, 13.1719], [-0.3236, 13.5781], [-0.8796, 13.874], [-1.4622, 14.0488], [-2.0359, 14.1028], [-2.5677, 14.0475], [-3.0299, 13.904], [-3.4033, 13.7008], [-3.679, 13.4711], [-3.8593, 13.2484], [-3.9572, 13.0639], [-3.9946, 12.9424], [-4, 12.9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-4, 12.9], [-4.0011, 12.8744], [-4.0087, 12.7982]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-4.0087, 12.7982], [-4.0289, 12.6738], [-4.0674, 12.5049]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-4.0674, 12.5049], [-4.1289, 12.2964], [-4.2171, 12.0546]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-4.2171, 12.0546], [-4.3342, 11.7864], [-4.4811, 11.4999]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-4.4811, 11.4999], [-4.6573, 11.2035], [-4.8612, 10.9062]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-4.8612, 10.9062], [-5.0907, 10.617], [-5.3435, 10.3435]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-5.3435, 10.3435], [-5.617, 10.0907], [-5.9062, 9.8612]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-5.9062, 9.8612], [-6.2035, 9.6573], [-6.4999, 9.4811]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-6.4999, 9.4811], [-6.7864, 9.3342], [-7.0546, 9.2171]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-7.0546, 9.2171], [-7.2964, 9.1289], [-7.5049, 9.0674]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-7.5049, 9.0674], [-7.6738, 9.0289], [-7.7982, 9.0087]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-7.7982, 9.0087], [-7.8744, 9.0011], [-7.9, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-7.9, 9], [-7.9424, 8.9946], [-8.0639, 8.9572], [-8.2484, 8.8593], [-8.4711, 8.679], [-8.7008, 8.4033], [-8.904, 8.0299], [-9.0475, 7.5677], [-9.1028, 7.0359], [-9.0488, 6.4622], [-8.874, 5.8796], [-8.5781, 5.3236], [-8.1719, 4.8281], [-7.6764, 4.4219], [-7.1204, 4.126], [-6.5378, 3.9512], [-5.9641, 3.8972], [-5.4323, 3.9525], [-4.9701, 4.096], [-4.5967, 4.2992], [-4.321, 4.5289], [-4.1407, 4.7516], [-4.0428, 4.9361], [-4.0054, 5.0576], [-4, 5.1]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-4, 5.1], [-3.9989, 5.1256], [-3.9913, 5.2018]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-3.9913, 5.2018], [-3.9711, 5.3262], [-3.9326, 5.4951]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-3.9326, 5.4951], [-3.8711, 5.7036], [-3.7829, 5.9454]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-3.7829, 5.9454], [-3.6658, 6.2136], [-3.5189, 6.5001]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-3.5189, 6.5001], [-3.3427, 6.7965], [-3.1388, 7.0938]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-3.1388, 7.0938], [-2.9093, 7.383], [-2.6565, 7.6565]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-2.6565, 7.6565], [-2.383, 7.9093], [-2.0938, 8.1388]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-2.0938, 8.1388], [-1.7965, 8.3427], [-1.5001, 8.5189]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-1.5001, 8.5189], [-1.2136, 8.6658], [-0.9454, 8.7829]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-0.9454, 8.7829], [-0.7036, 8.8711], [-0.4951, 8.9326]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-0.4951, 8.9326], [-0.3262, 8.9711], [-0.2018, 8.9913]], y: [0.4, 2.0]}
      - {kind: poly, points: [[-4, 9], [-0.2018, 8.9913], [-0.1256, 8.9989], [-0.1, 9]], y: [0.4, 2.0]}
      - {kind: disc, center: [-4, 9], radius: 0.9, y: [-0.2, 3.9], color: "#6f6a60"}   # its shaft
      - {kind: wheel, center: [-4, 9], teeth: 20, tooth: [[3.4333, -0.1399], [4.4, -0.0292], [4.4, 0.0292], [3.4333, 0.1399]], phase: 0.7854, root: 3.5, rim: 3.1667, hub: 0.9, spokes: 4, y: [3.0, 3.8], collide: 1}   # the left piston's gear
  - id: piston_r
    shape: part
    pos: [4, 0, 9]
    density: 7800
    friction: 0.1
    color: "#a39d90"
    pieces:
      - {kind: poly, points: [[0.1, 9], [0.0576, 8.9946], [-0.0639, 8.9572], [-0.2484, 8.8593], [-0.4711, 8.679], [-0.7008, 8.4033], [-0.904, 8.0299], [-1.0475, 7.5677], [-1.1028, 7.0359], [-1.0488, 6.4622], [-0.874, 5.8796], [-0.5781, 5.3236], [-0.1719, 4.8281], [0.3236, 4.4219], [0.8796, 4.126], [1.4622, 3.9512], [2.0359, 3.8972], [2.5677, 3.9525], [3.0299, 4.096], [3.4033, 4.2992], [3.679, 4.5289], [3.8593, 4.7516], [3.9572, 4.9361], [3.9946, 5.0576], [4, 5.1], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[0.2018, 9.0087], [0.1256, 9.0011], [0.1, 9], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[0.4951, 9.0674], [0.3262, 9.0289], [0.2018, 9.0087], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[0.9454, 9.2171], [0.7036, 9.1289], [0.4951, 9.0674], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[1.5001, 9.4811], [1.2136, 9.3342], [0.9454, 9.2171], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[2.0938, 9.8612], [1.7965, 9.6573], [1.5001, 9.4811], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[2.6565, 10.3435], [2.383, 10.0907], [2.0938, 9.8612], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[3.1388, 10.9062], [2.9093, 10.617], [2.6565, 10.3435], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[3.5189, 11.4999], [3.3427, 11.2035], [3.1388, 10.9062], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[3.7829, 12.0546], [3.6658, 11.7864], [3.5189, 11.4999], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[3.9326, 12.5049], [3.8711, 12.2964], [3.7829, 12.0546], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[3.9913, 12.7982], [3.9711, 12.6738], [3.9326, 12.5049], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[4, 12.9], [3.9989, 12.8744], [3.9913, 12.7982], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[7.9, 9], [7.9424, 9.0054], [8.0639, 9.0428], [8.2484, 9.1407], [8.4711, 9.321], [8.7008, 9.5967], [8.904, 9.9701], [9.0475, 10.4323], [9.1028, 10.9641], [9.0488, 11.5378], [8.874, 12.1204], [8.5781, 12.6764], [8.1719, 13.1719], [7.6764, 13.5781], [7.1204, 13.874], [6.5378, 14.0488], [5.9641, 14.1028], [5.4323, 14.0475], [4.9701, 13.904], [4.5967, 13.7008], [4.321, 13.4711], [4.1407, 13.2484], [4.0428, 13.0639], [4.0054, 12.9424], [4, 12.9], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[7.7982, 8.9913], [7.8744, 8.9989], [7.9, 9], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[7.5049, 8.9326], [7.6738, 8.9711], [7.7982, 8.9913], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[7.0546, 8.7829], [7.2964, 8.8711], [7.5049, 8.9326], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[6.4999, 8.5189], [6.7864, 8.6658], [7.0546, 8.7829], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[5.9062, 8.1388], [6.2035, 8.3427], [6.4999, 8.5189], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[5.3435, 7.6565], [5.617, 7.9093], [5.9062, 8.1388], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[4.8612, 7.0938], [5.0907, 7.383], [5.3435, 7.6565], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[4.4811, 6.5001], [4.6573, 6.7965], [4.8612, 7.0938], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[4.2171, 5.9454], [4.3342, 6.2136], [4.4811, 6.5001], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[4.0674, 5.4951], [4.1289, 5.7036], [4.2171, 5.9454], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[4.0087, 5.2018], [4.0289, 5.3262], [4.0674, 5.4951], [4, 9]], y: [0.4, 2.0]}
      - {kind: poly, points: [[4, 5.1], [4.0011, 5.1256], [4.0087, 5.2018], [4, 9]], y: [0.4, 2.0]}
      - {kind: disc, center: [4, 9], radius: 0.9, y: [-0.2, 3.9], color: "#6f6a60"}   # its shaft
      - {kind: wheel, center: [4, 9], teeth: 20, tooth: [[3.4333, -0.1399], [4.4, -0.0292], [4.4, 0.0292], [3.4333, 0.1399]], phase: 2.5229, root: 3.5, rim: 3.1667, hub: 0.9, spokes: 4, y: [3.0, 3.8], collide: 2}   # the right piston's gear, in mesh
  - id: frame
    shape: part
    pos: [0, 0, 0]
    fixed: true
    color: "#cfc6b4"
    pieces:
      - {kind: poly, points: [[-0.9, 14.2303], [-0.6706, 14.6174], [-1.2794, 14.9363], [-1.4669, 14.5272]], y: [0, 2.4]}
      - {kind: poly, points: [[-1.4669, 14.5272], [-1.2794, 14.9363], [-1.9183, 15.1893], [-2.0618, 14.7628]], y: [0, 2.4]}
      - {kind: poly, points: [[-2.0618, 14.7628], [-1.9183, 15.1893], [-2.5803, 15.3738], [-2.6782, 14.9346]], y: [0, 2.4]}
      - {kind: poly, points: [[-2.6782, 14.9346], [-2.5803, 15.3738], [-3.2581, 15.4877], [-3.3092, 15.0406]], y: [0, 2.4]}
      - {kind: poly, points: [[-3.3092, 15.0406], [-3.2581, 15.4877], [-3.944, 15.5298], [-3.9479, 15.0798]], y: [0, 2.4]}
      - {kind: poly, points: [[-3.9479, 15.0798], [-3.944, 15.5298], [-4.6306, 15.4995], [-4.5871, 15.0516]], y: [0, 2.4]}
      - {kind: poly, points: [[-4.5871, 15.0516], [-4.6306, 15.4995], [-5.3102, 15.3972], [-5.2199, 14.9564]], y: [0, 2.4]}
      - {kind: poly, points: [[-5.2199, 14.9564], [-5.3102, 15.3972], [-5.9752, 15.2241], [-5.8391, 14.7952]], y: [0, 2.4]}
      - {kind: poly, points: [[-5.8391, 14.7952], [-5.9752, 15.2241], [-6.6184, 14.982], [-6.438, 14.5698]], y: [0, 2.4]}
      - {kind: poly, points: [[-6.438, 14.5698], [-6.6184, 14.982], [-7.2326, 14.6737], [-7.0099, 14.2827]], y: [0, 2.4]}
      - {kind: poly, points: [[-7.0099, 14.2827], [-7.2326, 14.6737], [-7.811, 14.3026], [-7.5484, 13.9371]], y: [0, 2.4]}
      - {kind: poly, points: [[-7.5484, 13.9371], [-7.811, 14.3026], [-8.3472, 13.8727], [-8.0476, 13.5369]], y: [0, 2.4]}
      - {kind: poly, points: [[-8.0476, 13.5369], [-8.3472, 13.8727], [-8.8352, 13.3888], [-8.502, 13.0864]], y: [0, 2.4]}
      - {kind: poly, points: [[-8.502, 13.0864], [-8.8352, 13.3888], [-9.2697, 12.8563], [-8.9065, 12.5906]], y: [0, 2.4]}
      - {kind: poly, points: [[-8.9065, 12.5906], [-9.2697, 12.8563], [-9.6458, 12.2812], [-9.2567, 12.055]], y: [0, 2.4]}
      - {kind: poly, points: [[-9.2567, 12.055], [-9.6458, 12.2812], [-9.9594, 11.6696], [-9.5487, 11.4857]], y: [0, 2.4]}
      - {kind: poly, points: [[-9.5487, 11.4857], [-9.9594, 11.6696], [-10.2069, 11.0285], [-9.7792, 10.8887]], y: [0, 2.4]}
      - {kind: poly, points: [[-9.7792, 10.8887], [-10.2069, 11.0285], [-10.3857, 10.365], [-9.9457, 10.2709]], y: [0, 2.4]}
      - {kind: poly, points: [[-9.9457, 10.2709], [-10.3857, 10.365], [-10.4938, 9.6863], [-10.0463, 9.639]], y: [0, 2.4]}
      - {kind: poly, points: [[-10.0463, 9.639], [-10.4938, 9.6863], [-10.53, 9], [-10.08, 9]], y: [0, 2.4]}
      - {kind: poly, points: [[-10.08, 9], [-10.53, 9], [-10.4938, 8.3137], [-10.0463, 8.361]], y: [0, 2.4]}
      - {kind: poly, points: [[-10.0463, 8.361], [-10.4938, 8.3137], [-10.3857, 7.635], [-9.9457, 7.7291]], y: [0, 2.4]}
      - {kind: poly, points: [[-9.9457, 7.7291], [-10.3857, 7.635], [-10.2069, 6.9715], [-9.7792, 7.1113]], y: [0, 2.4]}
      - {kind: poly, points: [[-9.7792, 7.1113], [-10.2069, 6.9715], [-9.9594, 6.3304], [-9.5487, 6.5143]], y: [0, 2.4]}
      - {kind: poly, points: [[-9.5487, 6.5143], [-9.9594, 6.3304], [-9.6458, 5.7188], [-9.2567, 5.945]], y: [0, 2.4]}
      - {kind: poly, points: [[-9.2567, 5.945], [-9.6458, 5.7188], [-9.2697, 5.1437], [-8.9065, 5.4094]], y: [0, 2.4]}
      - {kind: poly, points: [[-8.9065, 5.4094], [-9.2697, 5.1437], [-8.8352, 4.6112], [-8.502, 4.9136]], y: [0, 2.4]}
      - {kind: poly, points: [[-8.502, 4.9136], [-8.8352, 4.6112], [-8.3472, 4.1273], [-8.0476, 4.4631]], y: [0, 2.4]}
      - {kind: poly, points: [[-8.0476, 4.4631], [-8.3472, 4.1273], [-7.811, 3.6974], [-7.5484, 4.0629]], y: [0, 2.4]}
      - {kind: poly, points: [[-7.5484, 4.0629], [-7.811, 3.6974], [-7.2326, 3.3263], [-7.0099, 3.7173]], y: [0, 2.4]}
      - {kind: poly, points: [[-7.0099, 3.7173], [-7.2326, 3.3263], [-6.6184, 3.018], [-6.438, 3.4302]], y: [0, 2.4]}
      - {kind: poly, points: [[-6.438, 3.4302], [-6.6184, 3.018], [-5.9752, 2.7759], [-5.8391, 3.2048]], y: [0, 2.4]}
      - {kind: poly, points: [[-5.8391, 3.2048], [-5.9752, 2.7759], [-5.3102, 2.6028], [-5.2199, 3.0436]], y: [0, 2.4]}
      - {kind: poly, points: [[-5.2199, 3.0436], [-5.3102, 2.6028], [-4.6306, 2.5005], [-4.5871, 2.9484]], y: [0, 2.4]}
      - {kind: poly, points: [[-4.5871, 2.9484], [-4.6306, 2.5005], [-3.944, 2.4702], [-3.9479, 2.9202]], y: [0, 2.4]}
      - {kind: poly, points: [[-3.9479, 2.9202], [-3.944, 2.4702], [-3.2581, 2.5123], [-3.3092, 2.9594]], y: [0, 2.4]}
      - {kind: poly, points: [[-3.3092, 2.9594], [-3.2581, 2.5123], [-2.5803, 2.6262], [-2.6782, 3.0654]], y: [0, 2.4]}
      - {kind: poly, points: [[-2.6782, 3.0654], [-2.5803, 2.6262], [-1.9183, 2.8107], [-2.0618, 3.2372]], y: [0, 2.4]}
      - {kind: poly, points: [[-2.0618, 3.2372], [-1.9183, 2.8107], [-1.2794, 3.0637], [-1.4669, 3.4728]], y: [0, 2.4]}
      - {kind: poly, points: [[-1.4669, 3.4728], [-1.2794, 3.0637], [-0.6706, 3.3826], [-0.9, 3.7697]], y: [0, 2.4]}
      - {kind: poly, points: [[0.9, 3.7697], [0.6706, 3.3826], [1.2794, 3.0637], [1.4669, 3.4728]], y: [0, 2.4]}
      - {kind: poly, points: [[1.4669, 3.4728], [1.2794, 3.0637], [1.9183, 2.8107], [2.0618, 3.2372]], y: [0, 2.4]}
      - {kind: poly, points: [[2.0618, 3.2372], [1.9183, 2.8107], [2.5803, 2.6262], [2.6782, 3.0654]], y: [0, 2.4]}
      - {kind: poly, points: [[2.6782, 3.0654], [2.5803, 2.6262], [3.2581, 2.5123], [3.3092, 2.9594]], y: [0, 2.4]}
      - {kind: poly, points: [[3.3092, 2.9594], [3.2581, 2.5123], [3.944, 2.4702], [3.9479, 2.9202]], y: [0, 2.4]}
      - {kind: poly, points: [[3.9479, 2.9202], [3.944, 2.4702], [4.6306, 2.5005], [4.5871, 2.9484]], y: [0, 2.4]}
      - {kind: poly, points: [[4.5871, 2.9484], [4.6306, 2.5005], [5.3102, 2.6028], [5.2199, 3.0436]], y: [0, 2.4]}
      - {kind: poly, points: [[5.2199, 3.0436], [5.3102, 2.6028], [5.9752, 2.7759], [5.8391, 3.2048]], y: [0, 2.4]}
      - {kind: poly, points: [[5.8391, 3.2048], [5.9752, 2.7759], [6.6184, 3.018], [6.438, 3.4302]], y: [0, 2.4]}
      - {kind: poly, points: [[6.438, 3.4302], [6.6184, 3.018], [7.2326, 3.3263], [7.0099, 3.7173]], y: [0, 2.4]}
      - {kind: poly, points: [[7.0099, 3.7173], [7.2326, 3.3263], [7.811, 3.6974], [7.5484, 4.0629]], y: [0, 2.4]}
      - {kind: poly, points: [[7.5484, 4.0629], [7.811, 3.6974], [8.3472, 4.1273], [8.0476, 4.4631]], y: [0, 2.4]}
      - {kind: poly, points: [[8.0476, 4.4631], [8.3472, 4.1273], [8.8352, 4.6112], [8.502, 4.9136]], y: [0, 2.4]}
      - {kind: poly, points: [[8.502, 4.9136], [8.8352, 4.6112], [9.2697, 5.1437], [8.9065, 5.4094]], y: [0, 2.4]}
      - {kind: poly, points: [[8.9065, 5.4094], [9.2697, 5.1437], [9.6458, 5.7188], [9.2567, 5.945]], y: [0, 2.4]}
      - {kind: poly, points: [[9.2567, 5.945], [9.6458, 5.7188], [9.9594, 6.3304], [9.5487, 6.5143]], y: [0, 2.4]}
      - {kind: poly, points: [[9.5487, 6.5143], [9.9594, 6.3304], [10.2069, 6.9715], [9.7792, 7.1113]], y: [0, 2.4]}
      - {kind: poly, points: [[9.7792, 7.1113], [10.2069, 6.9715], [10.3857, 7.635], [9.9457, 7.7291]], y: [0, 2.4]}
      - {kind: poly, points: [[9.9457, 7.7291], [10.3857, 7.635], [10.4938, 8.3137], [10.0463, 8.361]], y: [0, 2.4]}
      - {kind: poly, points: [[10.0463, 8.361], [10.4938, 8.3137], [10.53, 9], [10.08, 9]], y: [0, 2.4]}
      - {kind: poly, points: [[10.08, 9], [10.53, 9], [10.4938, 9.6863], [10.0463, 9.639]], y: [0, 2.4]}
      - {kind: poly, points: [[10.0463, 9.639], [10.4938, 9.6863], [10.3857, 10.365], [9.9457, 10.2709]], y: [0, 2.4]}
      - {kind: poly, points: [[9.9457, 10.2709], [10.3857, 10.365], [10.2069, 11.0285], [9.7792, 10.8887]], y: [0, 2.4]}
      - {kind: poly, points: [[9.7792, 10.8887], [10.2069, 11.0285], [9.9594, 11.6696], [9.5487, 11.4857]], y: [0, 2.4]}
      - {kind: poly, points: [[9.5487, 11.4857], [9.9594, 11.6696], [9.6458, 12.2812], [9.2567, 12.055]], y: [0, 2.4]}
      - {kind: poly, points: [[9.2567, 12.055], [9.6458, 12.2812], [9.2697, 12.8563], [8.9065, 12.5906]], y: [0, 2.4]}
      - {kind: poly, points: [[8.9065, 12.5906], [9.2697, 12.8563], [8.8352, 13.3888], [8.502, 13.0864]], y: [0, 2.4]}
      - {kind: poly, points: [[8.502, 13.0864], [8.8352, 13.3888], [8.3472, 13.8727], [8.0476, 13.5369]], y: [0, 2.4]}
      - {kind: poly, points: [[8.0476, 13.5369], [8.3472, 13.8727], [7.811, 14.3026], [7.5484, 13.9371]], y: [0, 2.4]}
      - {kind: poly, points: [[7.5484, 13.9371], [7.811, 14.3026], [7.2326, 14.6737], [7.0099, 14.2827]], y: [0, 2.4]}
      - {kind: poly, points: [[7.0099, 14.2827], [7.2326, 14.6737], [6.6184, 14.982], [6.438, 14.5698]], y: [0, 2.4]}
      - {kind: poly, points: [[6.438, 14.5698], [6.6184, 14.982], [5.9752, 15.2241], [5.8391, 14.7952]], y: [0, 2.4]}
      - {kind: poly, points: [[5.8391, 14.7952], [5.9752, 15.2241], [5.3102, 15.3972], [5.2199, 14.9564]], y: [0, 2.4]}
      - {kind: poly, points: [[5.2199, 14.9564], [5.3102, 15.3972], [4.6306, 15.4995], [4.5871, 15.0516]], y: [0, 2.4]}
      - {kind: poly, points: [[4.5871, 15.0516], [4.6306, 15.4995], [3.944, 15.5298], [3.9479, 15.0798]], y: [0, 2.4]}
      - {kind: poly, points: [[3.9479, 15.0798], [3.944, 15.5298], [3.2581, 15.4877], [3.3092, 15.0406]], y: [0, 2.4]}
      - {kind: poly, points: [[3.3092, 15.0406], [3.2581, 15.4877], [2.5803, 15.3738], [2.6782, 14.9346]], y: [0, 2.4]}
      - {kind: poly, points: [[2.6782, 14.9346], [2.5803, 15.3738], [1.9183, 15.1893], [2.0618, 14.7628]], y: [0, 2.4]}
      - {kind: poly, points: [[2.0618, 14.7628], [1.9183, 15.1893], [1.2794, 14.9363], [1.4669, 14.5272]], y: [0, 2.4]}
      - {kind: poly, points: [[1.4669, 14.5272], [1.2794, 14.9363], [0.6706, 14.6174], [0.9, 14.2303]], y: [0, 2.4]}
      - {kind: poly, points: [[0, 15.4387], [0.2375, 15.8209], [-0.5104, 16.2321], [-0.706, 15.8268]], y: [0, 2.4]}
      - {kind: poly, points: [[-0.706, 15.8268], [-0.5104, 16.2321], [-1.2977, 16.5616], [-1.4491, 16.1379]], y: [0, 2.4]}
      - {kind: poly, points: [[-1.4491, 16.1379], [-1.2977, 16.5616], [-2.1155, 16.8057], [-2.2211, 16.3683]], y: [0, 2.4]}
      - {kind: poly, points: [[-2.2211, 16.3683], [-2.1155, 16.8057], [-2.9546, 16.9617], [-3.0132, 16.5155]], y: [0, 2.4]}
      - {kind: poly, points: [[-3.0132, 16.5155], [-2.9546, 16.9617], [-3.8055, 17.0276], [-3.8164, 16.5778]], y: [0, 2.4]}
      - {kind: poly, points: [[-3.8164, 16.5778], [-3.8055, 17.0276], [-4.6586, 17.0029], [-4.6217, 16.5545]], y: [0, 2.4]}
      - {kind: poly, points: [[-4.6217, 16.5545], [-4.6586, 17.0029], [-5.5043, 16.8878], [-5.42, 16.4458]], y: [0, 2.4]}
      - {kind: poly, points: [[-5.42, 16.4458], [-5.5043, 16.8878], [-6.333, 16.6836], [-6.2022, 16.253]], y: [0, 2.4]}
      - {kind: poly, points: [[-6.2022, 16.253], [-6.333, 16.6836], [-7.1353, 16.3926], [-6.9596, 15.9783]], y: [0, 2.4]}
      - {kind: poly, points: [[-6.9596, 15.9783], [-7.1353, 16.3926], [-7.9022, 16.0181], [-7.6835, 15.6248]], y: [0, 2.4]}
      - {kind: poly, points: [[-7.6835, 15.6248], [-7.9022, 16.0181], [-8.625, 15.5643], [-8.3658, 15.1965]], y: [0, 2.4]}
      - {kind: poly, points: [[-8.3658, 15.1965], [-8.625, 15.5643], [-9.2956, 15.0364], [-8.9988, 14.6981]], y: [0, 2.4]}
      - {kind: poly, points: [[-8.9988, 14.6981], [-9.2956, 15.0364], [-9.9063, 14.4402], [-9.5753, 14.1354]], y: [0, 2.4]}
      - {kind: poly, points: [[-9.5753, 14.1354], [-9.9063, 14.4402], [-10.4504, 13.7826], [-10.0889, 13.5146]], y: [0, 2.4]}
      - {kind: poly, points: [[-10.0889, 13.5146], [-10.4504, 13.7826], [-10.9215, 13.071], [-10.5337, 12.8429]], y: [0, 2.4]}
      - {kind: poly, points: [[-10.5337, 12.8429], [-10.9215, 13.071], [-11.3145, 12.3134], [-10.9046, 12.1277]], y: [0, 2.4]}
      - {kind: poly, points: [[-10.9046, 12.1277], [-11.3145, 12.3134], [-11.6249, 11.5184], [-11.1976, 11.3772]], y: [0, 2.4]}
      - {kind: poly, points: [[-11.1976, 11.3772], [-11.6249, 11.5184], [-11.8491, 10.6949], [-11.4092, 10.5999]], y: [0, 2.4]}
      - {kind: poly, points: [[-11.4092, 10.5999], [-11.8491, 10.6949], [-11.9846, 9.8523], [-11.5372, 9.8045]], y: [0, 2.4]}
      - {kind: poly, points: [[-11.5372, 9.8045], [-11.9846, 9.8523], [-12.03, 9], [-11.58, 9]], y: [0, 2.4]}
      - {kind: poly, points: [[-11.58, 9], [-12.03, 9], [-11.9846, 8.1477], [-11.5372, 8.1955]], y: [0, 2.4]}
      - {kind: poly, points: [[-11.5372, 8.1955], [-11.9846, 8.1477], [-11.8491, 7.3051], [-11.4092, 7.4001]], y: [0, 2.4]}
      - {kind: poly, points: [[-11.4092, 7.4001], [-11.8491, 7.3051], [-11.6249, 6.4816], [-11.1976, 6.6228]], y: [0, 2.4]}
      - {kind: poly, points: [[-11.1976, 6.6228], [-11.6249, 6.4816], [-11.3145, 5.6866], [-10.9046, 5.8723]], y: [0, 2.4]}
      - {kind: poly, points: [[-10.9046, 5.8723], [-11.3145, 5.6866], [-10.9215, 4.929], [-10.5337, 5.1571]], y: [0, 2.4]}
      - {kind: poly, points: [[-10.5337, 5.1571], [-10.9215, 4.929], [-10.4504, 4.2174], [-10.0889, 4.4854]], y: [0, 2.4]}
      - {kind: poly, points: [[-10.0889, 4.4854], [-10.4504, 4.2174], [-9.9063, 3.5598], [-9.5753, 3.8646]], y: [0, 2.4]}
      - {kind: poly, points: [[-9.5753, 3.8646], [-9.9063, 3.5598], [-9.2956, 2.9636], [-8.9988, 3.3019]], y: [0, 2.4]}
      - {kind: poly, points: [[-8.9988, 3.3019], [-9.2956, 2.9636], [-8.625, 2.4357], [-8.3658, 2.8035]], y: [0, 2.4]}
      - {kind: poly, points: [[-8.3658, 2.8035], [-8.625, 2.4357], [-7.9022, 1.9819], [-7.6835, 2.3752]], y: [0, 2.4]}
      - {kind: poly, points: [[-7.6835, 2.3752], [-7.9022, 1.9819], [-7.1353, 1.6074], [-6.9596, 2.0217]], y: [0, 2.4]}
      - {kind: poly, points: [[-6.9596, 2.0217], [-7.1353, 1.6074], [-6.333, 1.3164], [-6.2022, 1.747]], y: [0, 2.4]}
      - {kind: poly, points: [[-6.2022, 1.747], [-6.333, 1.3164], [-5.5043, 1.1122], [-5.42, 1.5542]], y: [0, 2.4]}
      - {kind: poly, points: [[-5.42, 1.5542], [-5.5043, 1.1122], [-4.6586, 0.9971], [-4.6217, 1.4455]], y: [0, 2.4]}
      - {kind: poly, points: [[-4.6217, 1.4455], [-4.6586, 0.9971], [-3.8055, 0.9724], [-3.8164, 1.4222]], y: [0, 2.4]}
      - {kind: poly, points: [[-3.8164, 1.4222], [-3.8055, 0.9724], [-2.9546, 1.0383], [-3.0132, 1.4845]], y: [0, 2.4]}
      - {kind: poly, points: [[-3.0132, 1.4845], [-2.9546, 1.0383], [-2.1155, 1.1943], [-2.2211, 1.6317]], y: [0, 2.4]}
      - {kind: poly, points: [[-2.2211, 1.6317], [-2.1155, 1.1943], [-1.2977, 1.4384], [-1.4491, 1.8621]], y: [0, 2.4]}
      - {kind: poly, points: [[-1.4491, 1.8621], [-1.2977, 1.4384], [-0.5104, 1.7679], [-0.706, 2.1732]], y: [0, 2.4]}
      - {kind: poly, points: [[-0.706, 2.1732], [-0.5104, 1.7679], [0.2375, 2.1791], [0, 2.5613]], y: [0, 2.4]}
      - {kind: poly, points: [[-0, 2.5613], [-0.2375, 2.1791], [0.5104, 1.7679], [0.706, 2.1732]], y: [0, 2.4]}
      - {kind: poly, points: [[0.706, 2.1732], [0.5104, 1.7679], [1.2977, 1.4384], [1.4491, 1.8621]], y: [0, 2.4]}
      - {kind: poly, points: [[1.4491, 1.8621], [1.2977, 1.4384], [2.1155, 1.1943], [2.2211, 1.6317]], y: [0, 2.4]}
      - {kind: poly, points: [[2.2211, 1.6317], [2.1155, 1.1943], [2.9546, 1.0383], [3.0132, 1.4845]], y: [0, 2.4]}
      - {kind: poly, points: [[3.0132, 1.4845], [2.9546, 1.0383], [3.8055, 0.9724], [3.8164, 1.4222]], y: [0, 2.4]}
      - {kind: poly, points: [[3.8164, 1.4222], [3.8055, 0.9724], [4.6586, 0.9971], [4.6217, 1.4455]], y: [0, 2.4]}
      - {kind: poly, points: [[4.6217, 1.4455], [4.6586, 0.9971], [5.5043, 1.1122], [5.42, 1.5542]], y: [0, 2.4]}
      - {kind: poly, points: [[5.42, 1.5542], [5.5043, 1.1122], [6.333, 1.3164], [6.2022, 1.747]], y: [0, 2.4]}
      - {kind: poly, points: [[6.2022, 1.747], [6.333, 1.3164], [7.1353, 1.6074], [6.9596, 2.0217]], y: [0, 2.4]}
      - {kind: poly, points: [[6.9596, 2.0217], [7.1353, 1.6074], [7.9022, 1.9819], [7.6835, 2.3752]], y: [0, 2.4]}
      - {kind: poly, points: [[7.6835, 2.3752], [7.9022, 1.9819], [8.625, 2.4357], [8.3658, 2.8035]], y: [0, 2.4]}
      - {kind: poly, points: [[8.3658, 2.8035], [8.625, 2.4357], [9.2956, 2.9636], [8.9988, 3.3019]], y: [0, 2.4]}
      - {kind: poly, points: [[8.9988, 3.3019], [9.2956, 2.9636], [9.9063, 3.5598], [9.5753, 3.8646]], y: [0, 2.4]}
      - {kind: poly, points: [[9.5753, 3.8646], [9.9063, 3.5598], [10.4504, 4.2174], [10.0889, 4.4854]], y: [0, 2.4]}
      - {kind: poly, points: [[10.0889, 4.4854], [10.4504, 4.2174], [10.9215, 4.929], [10.5337, 5.1571]], y: [0, 2.4]}
      - {kind: poly, points: [[10.5337, 5.1571], [10.9215, 4.929], [11.3145, 5.6866], [10.9046, 5.8723]], y: [0, 2.4]}
      - {kind: poly, points: [[10.9046, 5.8723], [11.3145, 5.6866], [11.6249, 6.4816], [11.1976, 6.6228]], y: [0, 2.4]}
      - {kind: poly, points: [[11.1976, 6.6228], [11.6249, 6.4816], [11.8491, 7.3051], [11.4092, 7.4001]], y: [0, 2.4]}
      - {kind: poly, points: [[11.4092, 7.4001], [11.8491, 7.3051], [11.9846, 8.1477], [11.5372, 8.1955]], y: [0, 2.4]}
      - {kind: poly, points: [[11.5372, 8.1955], [11.9846, 8.1477], [12.03, 9], [11.58, 9]], y: [0, 2.4]}
      - {kind: poly, points: [[11.58, 9], [12.03, 9], [11.9846, 9.8523], [11.5372, 9.8045]], y: [0, 2.4]}
      - {kind: poly, points: [[11.5372, 9.8045], [11.9846, 9.8523], [11.8491, 10.6949], [11.4092, 10.5999]], y: [0, 2.4]}
      - {kind: poly, points: [[11.4092, 10.5999], [11.8491, 10.6949], [11.6249, 11.5184], [11.1976, 11.3772]], y: [0, 2.4]}
      - {kind: poly, points: [[11.1976, 11.3772], [11.6249, 11.5184], [11.3145, 12.3134], [10.9046, 12.1277]], y: [0, 2.4]}
      - {kind: poly, points: [[10.9046, 12.1277], [11.3145, 12.3134], [10.9215, 13.071], [10.5337, 12.8429]], y: [0, 2.4]}
      - {kind: poly, points: [[10.5337, 12.8429], [10.9215, 13.071], [10.4504, 13.7826], [10.0889, 13.5146]], y: [0, 2.4]}
      - {kind: poly, points: [[10.0889, 13.5146], [10.4504, 13.7826], [9.9063, 14.4402], [9.5753, 14.1354]], y: [0, 2.4]}
      - {kind: poly, points: [[9.5753, 14.1354], [9.9063, 14.4402], [9.2956, 15.0364], [8.9988, 14.6981]], y: [0, 2.4]}
      - {kind: poly, points: [[8.9988, 14.6981], [9.2956, 15.0364], [8.625, 15.5643], [8.3658, 15.1965]], y: [0, 2.4]}
      - {kind: poly, points: [[8.3658, 15.1965], [8.625, 15.5643], [7.9022, 16.0181], [7.6835, 15.6248]], y: [0, 2.4]}
      - {kind: poly, points: [[7.6835, 15.6248], [7.9022, 16.0181], [7.1353, 16.3926], [6.9596, 15.9783]], y: [0, 2.4]}
      - {kind: poly, points: [[6.9596, 15.9783], [7.1353, 16.3926], [6.333, 16.6836], [6.2022, 16.253]], y: [0, 2.4]}
      - {kind: poly, points: [[6.2022, 16.253], [6.333, 16.6836], [5.5043, 16.8878], [5.42, 16.4458]], y: [0, 2.4]}
      - {kind: poly, points: [[5.42, 16.4458], [5.5043, 16.8878], [4.6586, 17.0029], [4.6217, 16.5545]], y: [0, 2.4]}
      - {kind: poly, points: [[4.6217, 16.5545], [4.6586, 17.0029], [3.8055, 17.0276], [3.8164, 16.5778]], y: [0, 2.4]}
      - {kind: poly, points: [[3.8164, 16.5778], [3.8055, 17.0276], [2.9546, 16.9617], [3.0132, 16.5155]], y: [0, 2.4]}
      - {kind: poly, points: [[3.0132, 16.5155], [2.9546, 16.9617], [2.1155, 16.8057], [2.2211, 16.3683]], y: [0, 2.4]}
      - {kind: poly, points: [[2.2211, 16.3683], [2.1155, 16.8057], [1.2977, 16.5616], [1.4491, 16.1379]], y: [0, 2.4]}
      - {kind: poly, points: [[1.4491, 16.1379], [1.2977, 16.5616], [0.5104, 16.2321], [0.706, 15.8268]], y: [0, 2.4]}
      - {kind: poly, points: [[0.706, 15.8268], [0.5104, 16.2321], [-0.2375, 15.8209], [-0, 15.4387]], y: [0, 2.4]}
      - {kind: poly, points: [[-1.35, 14.2303], [-0.9, 14.2303], [-0.9, 19.78], [-1.35, 19.78]], y: [0, 2.4]}
      - {kind: poly, points: [[0.9, 14.2303], [1.35, 14.2303], [1.35, 19.78], [0.9, 19.78]], y: [0, 2.4]}
      - {kind: poly, points: [[-1.35, -1.78], [-0.9, -1.78], [-0.9, 3.7697], [-1.35, 3.7697]], y: [0, 2.4]}
      - {kind: poly, points: [[0.9, -1.78], [1.35, -1.78], [1.35, 3.7697], [0.9, 3.7697]], y: [0, 2.4]}
      - {kind: disc, center: [-4, 9], radius: 8.03, y: [4.2, 4.6], color: "#bdb4a2"}   # the cylinder-head behind the gears
      - {kind: disc, center: [4, 9], radius: 8.03, y: [4.2, 4.6], color: "#bdb4a2"}
      - {kind: poly, points: [[-0.9, 4.4211], [0.9, 4.4211], [0.9, 13.5789], [-0.9, 13.5789]], y: [4.2, 4.6], color: "#bdb4a2"}
      - {kind: poly, points: [[-0.9, 13.5789], [0.9, 13.5789], [0.9, 19.78], [-0.9, 19.78]], y: [2.4, 2.6], color: "#bdb4a2"}   # the inlet
      - {kind: poly, points: [[-0.9, -1.78], [0.9, -1.78], [0.9, 4.4211], [-0.9, 4.4211]], y: [2.4, 2.6], color: "#bdb4a2"}   # the outlet
joints:
  - {id: j_L, type: hinge, body: piston_l, axis: [0, -1, 0], damping: 0.01}   # the left piston; + : anticlockwise as drawn (Brown's arrow)
  - {id: j_R, type: hinge, body: piston_r, axis: [0, 1, 0], damping: 0.01}   # the right piston; + : clockwise as drawn
contact: {solref: [0.001, 1.0], solimp: [0.95, 0.99, 0.0005], margin: 0}
driver: {joint: j_L, kind: feet, feet: {joints: [j_L, j_R], sign: [1, 1], force: 0.1225, timed: {joint: j_L, shape: sign, gain: 2, offset: 2.3562}}, max_torque: 0.245}
checks:
  - {type: monotonic, joint: j_L, direction: 1, max_back: 0.05, settle_s: 0.0, window_s: 9.5}
  - {type: monotonic, joint: j_R, direction: 1, max_back: 0.05, settle_s: 0.0, window_s: 9.5}   # the two turn opposite ways
  - {type: turning, joint: j_L, direction: 1, min_mean: 3.5, min_fraction: 0.9, settle_s: 3.0, window_s: 6.5}
  - {type: ratio, out: j_R, in: j_L, expect: 1.0, tol: 0.02, settle_s: 3.0, window_s: 6.5}
  - {type: penetration, max: 0.002}
camera: {target: [0, 0, 9], position: [0, -95, 9], fov: 19}
display:
  output: j_R
  labels: {j_L: "Left piston (steam)", j_R: "Right piston (steam)"}
  proof: {label: "Gears out of mesh", sub: "each piston gets steam only half the time and the left one stands"}
