# No. 57 (Brown 1868): "The small pulley at the top being the driver, the large, internally-toothed
# gear and the concentric gear within will be driven in opposite directions by the bands, and at the
# same time will impart motion to the intermediate pinion at the bottom, both around its own center
# and also around the common center of the two concentric gears."
#
# As drawn (cm; the drawing plane is x-z, depth y): the small driving pulley (r 5.0) at the top, 34.0
# above the common centre, the one motor-driven shaft. An open cord band runs from it to a pulley (r
# 10.0) on the back of the large internal gear (36 teeth), and a crossed cord band to a pulley (r
# 7.0) in front of the concentric spur gear (16): the two gears turn opposite ways, each loose on
# the common centre. The intermediate pinion (10) gears with both; it turns on a pin in an arm that
# is itself free about the common centre, so it turns on its own centre and is carried round the
# common one, at the speed the two gears' difference leaves it (the arm's speed is
# (ZR wR + ZS wS) / (ZR + ZS)). Both bands are elastic cord links driving by friction alone.
# Teeth as No. 55 (module 0.8). Generator: opencode-runs/batch7/gen057.py.
number: 57
slug: bands-drive-concentric-gears
name: Bands driving two concentric gears and a pinion between them
brown: "The small pulley at the top being the driver, the large, internally-toothed gear and the concentric gear within will be driven in opposite directions by the bands, and at the same time will impart motion to the intermediate pinion at the bottom, both around its own center and also around the common center of the two concentric gears."
units: cm
sim:
  timestep: 0.0002
  integrator: implicitfast
  iterations: 100
  solver: PGS   # as No. 55 (CG blows up at the first tooth contacts)
  multiccd: true
  duration_s: 8
  floor: false
bodies:
  - {id: p_top, shape: pulley, radius: 5.0, width: 11.4, rim_width: 2.4, groove: 1.8, grooves: [[0, -4.2, 0], [0, 5.0, 0]], pos: [0, -0.4, 34.0], mass: 1.0, spokes: 4, hub: 1.2, flange: 0.5}
  - {id: p_ring, shape: pulley, radius: 10.0, width: 1.6, groove: 1.1, pos: [0, 4.6, 0], mass: 0.6, spokes: 6, hub: 1.4, flange: 0.5}
  - {id: p_sun, shape: pulley, radius: 7.0, width: 2.2, groove: 1.8, pos: [0, -4.6, 0], mass: 0.4, spokes: 4, hub: 1.2, flange: 0.5}
  - id: ring
    shape: part
    pos: [0, 0, 0]
    mount: p_ring
    fixed: true   # keyed to its pulley (carried by it, no bearing of its own)
    friction: 0.1
    color: "#e8dec6"
    pieces:
      - {kind: band, center: [0, 0], r: [15.3, 16.8], a: [0, 6.2831853], y: [-0.8, 0.8]}   # the rim
      - {kind: disc, center: [0, 0], radius: 16.8, inner: 10.6, y: [0.8, 1.4]}   # the web behind, out to the pulley
      - {kind: disc, center: [0, 11.8], radius: 1.0, y: [0.78, 0.8], color: "#b9ab8e"}
      - {kind: poly, points: [[-0.8585, 13.8178], [-1.554, 13.7569], [-2.1657, 15.0686], [-0.4839, 15.2157]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-3.2449, 13.4588], [-3.9193, 13.2781], [-4.7494, 14.4636], [-3.1187, 14.9005]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-5.5326, 12.6908], [-6.1654, 12.3958], [-7.1888, 13.4191], [-5.6588, 14.1326]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-7.6523, 11.5373], [-8.2243, 11.1368], [-9.4098, 11.967], [-8.0269, 12.9353]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-9.5395, 10.0332], [-10.0332, 9.5395], [-11.3449, 10.1512], [-10.1512, 11.3449]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-11.1368, 8.2243], [-11.5373, 7.6523], [-12.9353, 8.0269], [-11.967, 9.4098]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-12.3958, 6.1654], [-12.6908, 5.5326], [-14.1326, 5.6588], [-13.4191, 7.1888]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-13.2781, 3.9193], [-13.4588, 3.2449], [-14.9005, 3.1187], [-14.4636, 4.7494]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-13.7569, 1.554], [-13.8178, 0.8585], [-15.2157, 0.4839], [-15.0686, 2.1657]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-13.8178, -0.8585], [-13.7569, -1.554], [-15.0686, -2.1657], [-15.2157, -0.4839]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-13.4588, -3.2449], [-13.2781, -3.9193], [-14.4636, -4.7494], [-14.9005, -3.1187]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-12.6908, -5.5326], [-12.3958, -6.1654], [-13.4191, -7.1888], [-14.1326, -5.6588]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-11.5373, -7.6523], [-11.1368, -8.2243], [-11.967, -9.4098], [-12.9353, -8.0269]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-10.0332, -9.5395], [-9.5395, -10.0332], [-10.1512, -11.3449], [-11.3449, -10.1512]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-8.2243, -11.1368], [-7.6523, -11.5373], [-8.0269, -12.9353], [-9.4098, -11.967]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-6.1654, -12.3958], [-5.5326, -12.6908], [-5.6588, -14.1326], [-7.1888, -13.4191]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-3.9193, -13.2781], [-3.2449, -13.4588], [-3.1187, -14.9005], [-4.7494, -14.4636]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-1.554, -13.7569], [-0.8585, -13.8178], [-0.4839, -15.2157], [-2.1657, -15.0686]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[0.8585, -13.8178], [1.554, -13.7569], [2.1657, -15.0686], [0.4839, -15.2157]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[3.2449, -13.4588], [3.9193, -13.2781], [4.7494, -14.4636], [3.1187, -14.9005]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[5.5326, -12.6908], [6.1654, -12.3958], [7.1888, -13.4191], [5.6588, -14.1326]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[7.6523, -11.5373], [8.2243, -11.1368], [9.4098, -11.967], [8.0269, -12.9353]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[9.5395, -10.0332], [10.0332, -9.5395], [11.3449, -10.1512], [10.1512, -11.3449]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[11.1368, -8.2243], [11.5373, -7.6523], [12.9353, -8.0269], [11.967, -9.4098]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[12.3958, -6.1654], [12.6908, -5.5326], [14.1326, -5.6588], [13.4191, -7.1888]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[13.2781, -3.9193], [13.4588, -3.2449], [14.9005, -3.1187], [14.4636, -4.7494]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[13.7569, -1.554], [13.8178, -0.8585], [15.2157, -0.4839], [15.0686, -2.1657]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[13.8178, 0.8585], [13.7569, 1.554], [15.0686, 2.1657], [15.2157, 0.4839]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[13.4588, 3.2449], [13.2781, 3.9193], [14.4636, 4.7494], [14.9005, 3.1187]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[12.6908, 5.5326], [12.3958, 6.1654], [13.4191, 7.1888], [14.1326, 5.6588]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[11.5373, 7.6523], [11.1368, 8.2243], [11.967, 9.4098], [12.9353, 8.0269]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[10.0332, 9.5395], [9.5395, 10.0332], [10.1512, 11.3449], [11.3449, 10.1512]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[8.2243, 11.1368], [7.6523, 11.5373], [8.0269, 12.9353], [9.4098, 11.967]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[6.1654, 12.3958], [5.5326, 12.6908], [5.6588, 14.1326], [7.1888, 13.4191]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[3.9193, 13.2781], [3.2449, 13.4588], [3.1187, 14.9005], [4.7494, 14.4636]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[1.554, 13.7569], [0.8585, 13.8178], [0.4839, 15.2157], [2.1657, 15.0686]], y: [-0.8, 0.8], collide: 1}
  - id: sun
    shape: part
    pos: [0, 0, 0]
    mount: p_sun
    fixed: true   # keyed to its pulley
    friction: 0.1
    color: "#e4d9bf"
    pieces:
      - {kind: disc, center: [0, 0], radius: 5.55, inner: 0.6, y: [-0.8, 0.8]}
      - {kind: rod, from: [0, -4.6, 0], to: [0, 0.8, 0], radius: 0.7, color: "#8f8a80"}   # its hollow shaft out to the pulley
      - {kind: disc, center: [0, 4.0], radius: 0.7, y: [-0.82, -0.8], color: "#b9ab8e"}
      - {kind: poly, points: [[-0.2646, 5.6571], [-1.9204, 5.3277], [-1.7002, 6.7582], [-1.0154, 6.8944]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-2.4094, 5.1252], [-3.813, 4.1873], [-4.157, 5.5931], [-3.5765, 5.981]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-4.1873, 3.813], [-5.1252, 2.4094], [-5.981, 3.5765], [-5.5931, 4.157]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-5.3277, 1.9204], [-5.6571, 0.2646], [-6.8944, 1.0154], [-6.7582, 1.7002]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-5.6571, -0.2646], [-5.3277, -1.9204], [-6.7582, -1.7002], [-6.8944, -1.0154]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-5.1252, -2.4094], [-4.1873, -3.813], [-5.5931, -4.157], [-5.981, -3.5765]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-3.813, -4.1873], [-2.4094, -5.1252], [-3.5765, -5.981], [-4.157, -5.5931]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[-1.9204, -5.3277], [-0.2646, -5.6571], [-1.0154, -6.8944], [-1.7002, -6.7582]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[0.2646, -5.6571], [1.9204, -5.3277], [1.7002, -6.7582], [1.0154, -6.8944]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[2.4094, -5.1252], [3.813, -4.1873], [4.157, -5.5931], [3.5765, -5.981]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[4.1873, -3.813], [5.1252, -2.4094], [5.981, -3.5765], [5.5931, -4.157]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[5.3277, -1.9204], [5.6571, -0.2646], [6.8944, -1.0154], [6.7582, -1.7002]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[5.6571, 0.2646], [5.3277, 1.9204], [6.7582, 1.7002], [6.8944, 1.0154]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[5.1252, 2.4094], [4.1873, 3.813], [5.5931, 4.157], [5.981, 3.5765]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[3.813, 4.1873], [2.4094, 5.1252], [3.5765, 5.981], [4.157, 5.5931]], y: [-0.8, 0.8], collide: 1}
      - {kind: poly, points: [[1.9204, 5.3277], [0.2646, 5.6571], [1.0154, 6.8944], [1.7002, 6.7582]], y: [-0.8, 0.8], collide: 1}
  - id: arm
    shape: part
    pos: [0, 0, 0]
    mass: 0.15
    color: "#cfc4ad"
    pieces:
      - {kind: poly, points: [[-0.9, 0], [0.9, 0], [0.7, 10.4], [-0.7, 10.4]], y: [-2.3, -1.6]}   # the arm, in front of the gears
      - {kind: disc, center: [0, 0], radius: 1.3, inner: 0.7, y: [-2.3, -1.6]}
      - {kind: disc, center: [0.0, 10.4], radius: 1.0, y: [-2.3, -1.6]}
  - id: pinion
    shape: part
    pos: [0.0, 0, 10.4]
    mount: arm
    mass: 0.08
    friction: 0.1
    color: "#d8ceba"
    pieces:
      - {kind: disc, center: [0.0, 10.4], radius: 3.15, y: [-0.8, 0.8]}
      - {kind: rod, from: [0.0, -1.6, 10.4], to: [0.0, 0.9, 10.4], radius: 0.4, color: "#8f8a80"}   # its pin in the arm
      - {kind: disc, center: [1.6, 10.4], radius: 0.5, y: [-0.82, -0.8], color: "#9c8f78"}
      - {kind: poly, points: [[-0.5027, 7.2], [0.5027, 7.2], [0.5278, 6.4], [0.324, 5.84], [-0.324, 5.84], [-0.5278, 6.4]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[1.4743, 7.5157], [2.2876, 8.1066], [2.7781, 7.4742], [2.9424, 6.9013], [2.4182, 6.5205], [1.9242, 6.8537]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[2.8881, 8.9331], [3.1987, 9.8892], [3.9673, 9.6659], [4.4369, 9.299], [4.2367, 8.6828], [3.6411, 8.662]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[3.1987, 10.9108], [2.8881, 11.8669], [3.6411, 12.138], [4.2367, 12.1172], [4.4369, 11.501], [3.9673, 11.1341]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[2.2876, 12.6934], [1.4743, 13.2843], [1.9242, 13.9463], [2.4182, 14.2795], [2.9424, 13.8987], [2.7781, 13.3258]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[0.5027, 13.6], [-0.5027, 13.6], [-0.5278, 14.4], [-0.324, 14.96], [0.324, 14.96], [0.5278, 14.4]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-1.4743, 13.2843], [-2.2876, 12.6934], [-2.7781, 13.3258], [-2.9424, 13.8987], [-2.4182, 14.2795], [-1.9242, 13.9463]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-2.8881, 11.8669], [-3.1987, 10.9108], [-3.9673, 11.1341], [-4.4369, 11.501], [-4.2367, 12.1172], [-3.6411, 12.138]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-3.1987, 9.8892], [-2.8881, 8.9331], [-3.6411, 8.662], [-4.2367, 8.6828], [-4.4369, 9.299], [-3.9673, 9.6659]], y: [-0.8, 0.8], collide: 2}
      - {kind: poly, points: [[-2.2876, 8.1066], [-1.4743, 7.5157], [-1.9242, 6.8537], [-2.4182, 6.5205], [-2.9424, 6.9013], [-2.7781, 7.4742]], y: [-0.8, 0.8], collide: 2}
  - id: frame
    shape: part
    pos: [0, 0, 0]
    fixed: true
    color: "#cfc6b4"
    pieces:
      - {kind: rod, from: [0, -5.6, 0], to: [0, 7.0, 0], radius: 0.6, color: "#8f8a80"}   # the stud the gears, arm and pulleys turn on
      - {kind: poly, points: [[-1.5, -24], [1.5, -24], [1.0, 0], [-1.0, 0]], y: [6.0, 7.0]}   # its standard behind
      - {kind: poly, points: [[-1.2, 0], [1.2, 0], [0.9, 34.0], [-0.9, 34.0]], y: [7.6, 8.6]}   # the post for the driving pulley
      - {kind: rod, from: [0, -5.0, 34.0], to: [0, 7.6, 34.0], radius: 0.5, color: "#8f8a80"}
      - {kind: poly, points: [[-20, -25], [20, -25], [20, -24], [-20, -24]], y: [-8, 9], color: "#b9b09c"}
joints:
  - {id: j_top, type: hinge, body: p_top, axis: [0, 1, 0], damping: 0.002}
  - {id: j_ring, type: hinge, body: p_ring, axis: [0, 1, 0], damping: 0.02}
  - {id: j_sun, type: hinge, body: p_sun, axis: [0, 1, 0], damping: 0.02}
  - {id: j_arm, type: hinge, body: arm, axis: [0, 1, 0], damping: 0.01}
  - {id: j_pinion, type: hinge, body: pinion, axis: [0, 1, 0], damping: 0.002}
belts:
  - {id: open, around: [p_top, p_ring], station: 4.6, section: round, links: 120, segments: 8, thickness: 0.8, width: 0.8, density: 950, stiffness: 30000, damping: 2, pretension: 30, friction: 0.6}
  - {id: crossed, around: [p_top, p_sun], station: -4.6, section: round, crossed: true, links: 110, segments: 8, thickness: 0.8, width: 0.8, density: 950, stiffness: 30000, damping: 2, pretension: 30, friction: 0.6}
contact: {solref: [0.004, 1.0], solimp: [0.9, 0.95, 0.001], margin: 0}
driver: {joint: j_top, kind: velocity, rpm: 30, kv: 2, max_torque: 6}
checks:
  - {type: ratio, out: j_ring, in: j_top, expect: 0.5, tol: 0.03, settle_s: 2, window_s: 5}
  - {type: ratio, out: j_sun, in: j_top, expect: -0.7, tol: 0.05, settle_s: 2, window_s: 5}
  - {type: ratio, out: j_arm, in: j_top, expect: 0.13, tol: 0.03, settle_s: 2, window_s: 5}
  - {type: belt_on, belt: open, max_radial_dev: 1.0, max_lateral: 1.0, duration_s: 2}
  - {type: belt_on, belt: crossed, max_radial_dev: 1.0, max_lateral: 1.0, duration_s: 2}
camera: {target: [0, 0, 10], position: [40, -120, 30], fov: 34}
display:
  tiers:
    - {id: full, label: Full, ms: 6.786}
    - {id: friction, label: Friction model, timestep: 0.001, integrator: implicitfast, model: capstan, ms: 0.1594}
  output: j_arm
  labels: {j_top: "Driving pulley (top)", j_ring: "Internal gear (36, open band)", j_sun: "Inner gear (16, crossed band)", j_arm: "Pinion's arm (round the common centre)", j_pinion: "Pinion on its own centre"}
  proof: {label: "Pinion's teeth out of contact", sub: "the bands still turn both gears, but nothing carries the pinion round"}
