# No. 298 (Brown 1868): "An old-fashioned watch escapement."
#
# Model (cm, a plan of the watch: gravity off). Brown's figure: an escape-wheel with ratchet teeth, an arbor across its top carrying two pallets, and on the
# same arbor a toothed sector that gears with a pinion on the balance's staff, so the balance swings several times as far as the pallets (the rack escapement).
# Here the pallets are a recoil anchor laid out as No. 288 (a 30-tooth escape-wheel A, tips r 5, the anchor's axis a at 5 sqrt 2 above it, the pallets
# embracing 7 1/2 teeth; A turns counter-clockwise). Above a the anchor carries a sector of 7 teeth, pitch radius 3.6, which gears with an 8-leaf pinion
# (pitch radius 0.9) on the balance's staff, 4.5 above a: the balance turns 4 times as far as the anchor, the other way. The balance has a spring
# (stiffness 0.01385 N m/rad). The teeth's flanks are straight (convex hulls), with a little backlash.
# The only input is a constant torque on A (the mainspring). The anchor and balance are kept going only by the teeth pressing on the pallets. It starts at rest,
# with a tooth about to reach K's impulse face. Generator: opencode-runs/batch12/gen298.py.
number: 298
slug: old-fashioned-watch-escapement
name: An old-fashioned watch escapement
brown: "An old-fashioned watch escapement."
units: cm
sim: {timestep: 0.0002, integrator: implicitfast, iterations: 50, duration_s: 10, floor: false, gravity: 0}
bodies:
  - id: wheel
    shape: part
    pos: [0, 0, 0]
    density: 8500
    friction: 0.1
    color: "#e6d7b0"
    pieces:
      - kind: wheel
        center: [0, 0]
        teeth: 30
        tooth: [[3.9, -0.0756], [3.9, -0.165], [4.45, -0.075], [5.0, 0]]
        phase: 0.71558
        root: 4.2
        rim: 3.6
        hub: 0.8
        spokes: 4
        spoke_width: 0.45
        y: [-0.25, 0.25]
        collide: 2
      - {kind: disc, center: [0, 0], radius: 0.25, y: [-0.7, 0.9], color: "#8f8a80"}   # A's arbor
  - id: anchor
    shape: part
    pos: [0, 0, 7.07107]
    density: 7800
    friction: 0.1
    color: "#d9cfba"
    pieces:
      - {kind: disc, center: [0, 7.07107], radius: 0.6, y: [-0.35, 0.35]}   # the anchor's hub on the axis a
      - {kind: poly, points: [[0.02122, 6.61058], [3.80346, 3.65951], [4.23406, 4.21139], [0.45183, 7.16247]], y: [-0.3, 0.3]}   # the anchor's arms
      - {kind: poly, points: [[-0.45184, 7.16242], [-4.16501, 4.26457], [-3.73434, 3.71273], [-0.02117, 6.61058]], y: [-0.3, 0.3]}
      - {kind: poly, points: [[0.32472, 7.45127], [2.23572, 9.68877], [1.74073, 10.04103], [1.19151, 10.30079], [0.60518, 10.45996], [0.0, 10.51357], [-0.60518, 10.45996], [-1.19151, 10.30079], [-1.74073, 10.04103], [-2.23572, 9.68877], [-0.32472, 7.45127]], y: [-0.2, 0.2]}   # the sector's web
      - {kind: poly, points: [[4.628, 4.11555], [4.52302, 4.01301], [4.01562, 4.35607], [4.08531, 4.46211]], y: [-0.35, 0.35], collide: 1}   # K: its outer (locking) face reaching into the wheel
      - {kind: poly, points: [[4.52302, 4.01301], [4.41586, 3.91393], [3.94317, 4.25188], [4.01562, 4.35607]], y: [-0.35, 0.35], collide: 1}
      - {kind: poly, points: [[4.41586, 3.91393], [4.30663, 3.81835], [3.86802, 4.14963], [3.94317, 4.25188]], y: [-0.35, 0.35], collide: 1}
      - {kind: poly, points: [[4.30663, 3.81835], [4.19545, 3.72631], [3.79022, 4.04937], [3.86802, 4.14963]], y: [-0.35, 0.35], collide: 1}
      - {kind: poly, points: [[4.19545, 3.72631], [4.08241, 3.63786], [3.70982, 3.95119], [3.79022, 4.04937]], y: [-0.35, 0.35], collide: 1}
      - {kind: poly, points: [[4.08241, 3.63786], [3.96763, 3.55301], [3.62688, 3.85515], [3.70982, 3.95119]], y: [-0.35, 0.35], collide: 1}
      - {kind: poly, points: [[3.96763, 3.55301], [3.85123, 3.47181], [3.54146, 3.76131], [3.62688, 3.85515]], y: [-0.35, 0.35], collide: 1}
      - {kind: poly, points: [[3.85123, 3.47181], [3.73331, 3.39427], [3.4536, 3.66974], [3.54146, 3.76131]], y: [-0.35, 0.35], collide: 1}
      - {kind: poly, points: [[3.48904, 3.7061], [3.30196, 3.52234], [3.73332, 3.39427], [3.77162, 3.43357]], y: [-0.35, 0.35], collide: 1, color: "#b85c38"}   # K's impulse face
      - {kind: poly, points: [[-3.67079, 3.45506], [-3.76419, 3.55239], [-3.45445, 3.84193], [-3.39112, 3.73056]], y: [-0.35, 0.35], collide: 1}   # H: its inner (locking) face reaching into the wheel
      - {kind: poly, points: [[-3.76419, 3.55239], [-3.85501, 3.65213], [-3.51429, 3.95431], [-3.45445, 3.84193]], y: [-0.35, 0.35], collide: 1}
      - {kind: poly, points: [[-3.85501, 3.65213], [-3.94318, 3.75422], [-3.57063, 4.0676], [-3.51429, 3.95431]], y: [-0.35, 0.35], collide: 1}
      - {kind: poly, points: [[-3.94318, 3.75422], [-4.02866, 3.85858], [-3.62347, 4.18168], [-3.57063, 4.0676]], y: [-0.35, 0.35], collide: 1}
      - {kind: poly, points: [[-4.02866, 3.85858], [-4.11137, 3.96513], [-3.67279, 4.29646], [-3.62347, 4.18168]], y: [-0.35, 0.35], collide: 1}
      - {kind: poly, points: [[-4.11137, 3.96513], [-4.19127, 4.07382], [-3.71861, 4.41183], [-3.67279, 4.29646]], y: [-0.35, 0.35], collide: 1}
      - {kind: poly, points: [[-4.19127, 4.07382], [-4.26829, 4.18456], [-3.76092, 4.52768], [-3.71861, 4.41183]], y: [-0.35, 0.35], collide: 1}
      - {kind: poly, points: [[-4.26829, 4.18456], [-4.34239, 4.29728], [-3.79974, 4.64391], [-3.76092, 4.52768]], y: [-0.35, 0.35], collide: 1}
      - {kind: poly, points: [[-3.70845, 3.49369], [-3.50957, 3.29838], [-3.39111, 3.73056], [-3.42591, 3.76625]], y: [-0.35, 0.35], collide: 1, color: "#b85c38"}   # H's impulse face
      - {kind: poly, points: [[2.0494, 9.82306], [2.15019, 9.9584], [2.1537, 9.96384], [2.16273, 9.98099], [2.17486, 10.01078], [2.18756, 10.05367], [2.19824, 10.1097], [2.20435, 10.17838], [2.20435, 10.17838], [2.02721, 10.29674], [2.02721, 10.29674], [1.96609, 10.26481], [1.91842, 10.23351], [1.88365, 10.20536], [1.86077, 10.18275], [1.84838, 10.16785], [1.8447, 10.16252], [1.75823, 10.01761]], y: [-0.3, 0.3], collide: 1}   # the toothed sector's teeth (the rack)
      - {kind: poly, points: [[1.47314, 10.17], [1.54559, 10.3224], [1.54797, 10.32842], [1.55348, 10.347], [1.55957, 10.37858], [1.56365, 10.42314], [1.56319, 10.48016], [1.55578, 10.54872], [1.55578, 10.54872], [1.35896, 10.63025], [1.35896, 10.63025], [1.30525, 10.58701], [1.2646, 10.54701], [1.23599, 10.51262], [1.21796, 10.48598], [1.20872, 10.46895], [1.20615, 10.463], [1.14961, 10.30401]], y: [-0.3, 0.3], collide: 1}
      - {kind: poly, points: [[0.84026, 10.39785], [0.88158, 10.56146], [0.88275, 10.56783], [0.88453, 10.58713], [0.88434, 10.61929], [0.87965, 10.66378], [0.86808, 10.71962], [0.84743, 10.78542], [0.84743, 10.78542], [0.63849, 10.82698], [0.63849, 10.82698], [0.59424, 10.77409], [0.56218, 10.72693], [0.54082, 10.68762], [0.52834, 10.65798], [0.5226, 10.63947], [0.52124, 10.63314], [0.4968, 10.46616]], y: [-0.3, 0.3], collide: 1}
      - {kind: poly, points: [[0.17509, 10.49785], [0.1837, 10.66638], [0.1836, 10.67285], [0.18158, 10.69213], [0.17512, 10.72364], [0.16185, 10.76636], [0.1396, 10.81887], [0.10652, 10.87937], [0.10652, 10.87937], [-0.10652, 10.87937], [-0.10652, 10.87937], [-0.1396, 10.81887], [-0.16185, 10.76636], [-0.17512, 10.72364], [-0.18158, 10.69213], [-0.1836, 10.67285], [-0.1837, 10.66638], [-0.17509, 10.49785]], y: [-0.3, 0.3], collide: 1}
      - {kind: poly, points: [[-0.4968, 10.46616], [-0.52124, 10.63314], [-0.5226, 10.63947], [-0.52834, 10.65798], [-0.54082, 10.68762], [-0.56218, 10.72693], [-0.59424, 10.77409], [-0.63849, 10.82698], [-0.63849, 10.82698], [-0.84743, 10.78542], [-0.84743, 10.78542], [-0.86808, 10.71962], [-0.87965, 10.66378], [-0.88434, 10.61929], [-0.88453, 10.58713], [-0.88275, 10.56783], [-0.88158, 10.56146], [-0.84026, 10.39785]], y: [-0.3, 0.3], collide: 1}
      - {kind: poly, points: [[-1.14961, 10.30401], [-1.20615, 10.463], [-1.20872, 10.46895], [-1.21796, 10.48598], [-1.23599, 10.51262], [-1.2646, 10.54701], [-1.30525, 10.58701], [-1.35896, 10.63025], [-1.35896, 10.63025], [-1.55578, 10.54872], [-1.55578, 10.54872], [-1.56319, 10.48016], [-1.56365, 10.42314], [-1.55957, 10.37858], [-1.55348, 10.347], [-1.54797, 10.32842], [-1.54559, 10.3224], [-1.47314, 10.17]], y: [-0.3, 0.3], collide: 1}
      - {kind: poly, points: [[-1.75823, 10.01761], [-1.8447, 10.16252], [-1.84838, 10.16785], [-1.86077, 10.18275], [-1.88365, 10.20536], [-1.91842, 10.23351], [-1.96609, 10.26481], [-2.02721, 10.29674], [-2.02721, 10.29674], [-2.20435, 10.17838], [-2.20435, 10.17838], [-2.19824, 10.1097], [-2.18756, 10.05367], [-2.17486, 10.01078], [-2.16273, 9.98099], [-2.1537, 9.96384], [-2.15019, 9.9584], [-2.0494, 9.82306]], y: [-0.3, 0.3], collide: 1}
  - id: balance
    shape: part
    pos: [0, 0, 11.57107]
    mass: 0.17
    friction: 0.1
    color: "#e6d7b0"
    pieces:
      - {kind: disc, center: [0, 11.57107], radius: 4.0, inner: 3.65, y: [0.6, 0.9]}   # the balance's rim, behind
      - {kind: poly, points: [[-0.12, 11.57107], [-0.12, 15.27107], [0.12, 15.27107], [0.12, 11.57107]], y: [0.65, 0.85]}   # its arms
      - {kind: poly, points: [[-0.12, 11.57107], [-0.12, 7.87107], [0.12, 7.87107], [0.12, 11.57107]], y: [0.65, 0.85]}
      - {kind: disc, center: [0, 11.57107], radius: 0.64125, y: [-0.3, 0.9], color: "#8f8a80"}   # the staff
      - {kind: poly, points: [[0.13497, 10.94418], [0.18942, 10.69123], [0.18949, 10.69097], [0.19061, 10.68708], [0.19369, 10.67872], [0.19939, 10.66619], [0.20833, 10.64987], [0.22111, 10.63019], [0.23825, 10.60766], [0.26024, 10.58286], [0.26873, 10.5742], [0.51488, 10.67616], [0.51475, 10.68828], [0.51276, 10.72137], [0.50896, 10.74942], [0.50408, 10.77237], [0.49886, 10.79024], [0.49403, 10.80312], [0.49029, 10.81121], [0.48834, 10.81476], [0.4882, 10.81499], [0.34784, 11.03236]], y: [-0.3, 0.3], collide: 2, color: "#8f8a80"}   # the pinion's leaves
      - {kind: poly, points: [[0.53871, 11.22323], [0.75608, 11.08287], [0.75631, 11.08273], [0.75986, 11.08078], [0.76795, 11.07704], [0.78083, 11.07221], [0.7987, 11.06699], [0.82165, 11.06211], [0.8497, 11.05831], [0.88279, 11.05632], [0.89491, 11.05619], [0.99687, 11.30234], [0.98821, 11.31083], [0.96341, 11.33282], [0.94088, 11.34996], [0.9212, 11.36274], [0.90488, 11.37168], [0.89235, 11.37738], [0.88399, 11.38046], [0.8801, 11.38158], [0.87984, 11.38165], [0.62689, 11.4361]], y: [-0.3, 0.3], collide: 2, color: "#8f8a80"}
      - {kind: poly, points: [[0.62689, 11.70604], [0.87984, 11.76049], [0.8801, 11.76056], [0.88399, 11.76168], [0.89235, 11.76476], [0.90488, 11.77046], [0.9212, 11.7794], [0.94088, 11.79218], [0.96341, 11.80932], [0.98821, 11.83131], [0.99687, 11.8398], [0.89491, 12.08595], [0.88279, 12.08582], [0.8497, 12.08383], [0.82165, 12.08003], [0.7987, 12.07515], [0.78083, 12.06993], [0.76795, 12.0651], [0.75986, 12.06136], [0.75631, 12.05941], [0.75608, 12.05927], [0.53871, 11.91891]], y: [-0.3, 0.3], collide: 2, color: "#8f8a80"}
      - {kind: poly, points: [[0.34784, 12.10978], [0.4882, 12.32715], [0.48834, 12.32738], [0.49029, 12.33093], [0.49403, 12.33902], [0.49886, 12.3519], [0.50408, 12.36977], [0.50896, 12.39272], [0.51276, 12.42077], [0.51475, 12.45386], [0.51488, 12.46598], [0.26873, 12.56794], [0.26024, 12.55928], [0.23825, 12.53448], [0.22111, 12.51195], [0.20833, 12.49227], [0.19939, 12.47595], [0.19369, 12.46342], [0.19061, 12.45506], [0.18949, 12.45117], [0.18942, 12.45091], [0.13497, 12.19796]], y: [-0.3, 0.3], collide: 2, color: "#8f8a80"}
      - {kind: poly, points: [[-0.13497, 12.19796], [-0.18942, 12.45091], [-0.18949, 12.45117], [-0.19061, 12.45506], [-0.19369, 12.46342], [-0.19939, 12.47595], [-0.20833, 12.49227], [-0.22111, 12.51195], [-0.23825, 12.53448], [-0.26024, 12.55928], [-0.26873, 12.56794], [-0.51488, 12.46598], [-0.51475, 12.45386], [-0.51276, 12.42077], [-0.50896, 12.39272], [-0.50408, 12.36977], [-0.49886, 12.3519], [-0.49403, 12.33902], [-0.49029, 12.33093], [-0.48834, 12.32738], [-0.4882, 12.32715], [-0.34784, 12.10978]], y: [-0.3, 0.3], collide: 2, color: "#8f8a80"}
      - {kind: poly, points: [[-0.53871, 11.91891], [-0.75608, 12.05927], [-0.75631, 12.05941], [-0.75986, 12.06136], [-0.76795, 12.0651], [-0.78083, 12.06993], [-0.7987, 12.07515], [-0.82165, 12.08003], [-0.8497, 12.08383], [-0.88279, 12.08582], [-0.89491, 12.08595], [-0.99687, 11.8398], [-0.98821, 11.83131], [-0.96341, 11.80932], [-0.94088, 11.79218], [-0.9212, 11.7794], [-0.90488, 11.77046], [-0.89235, 11.76476], [-0.88399, 11.76168], [-0.8801, 11.76056], [-0.87984, 11.76049], [-0.62689, 11.70604]], y: [-0.3, 0.3], collide: 2, color: "#8f8a80"}
      - {kind: poly, points: [[-0.62689, 11.4361], [-0.87984, 11.38165], [-0.8801, 11.38158], [-0.88399, 11.38046], [-0.89235, 11.37738], [-0.90488, 11.37168], [-0.9212, 11.36274], [-0.94088, 11.34996], [-0.96341, 11.33282], [-0.98821, 11.31083], [-0.99687, 11.30234], [-0.89491, 11.05619], [-0.88279, 11.05632], [-0.8497, 11.05831], [-0.82165, 11.06211], [-0.7987, 11.06699], [-0.78083, 11.07221], [-0.76795, 11.07704], [-0.75986, 11.08078], [-0.75631, 11.08273], [-0.75608, 11.08287], [-0.53871, 11.22323]], y: [-0.3, 0.3], collide: 2, color: "#8f8a80"}
      - {kind: poly, points: [[-0.34784, 11.03236], [-0.4882, 10.81499], [-0.48834, 10.81476], [-0.49029, 10.81121], [-0.49403, 10.80312], [-0.49886, 10.79024], [-0.50408, 10.77237], [-0.50896, 10.74942], [-0.51276, 10.72137], [-0.51475, 10.68828], [-0.51488, 10.67616], [-0.26873, 10.5742], [-0.26024, 10.58286], [-0.23825, 10.60766], [-0.22111, 10.63019], [-0.20833, 10.64987], [-0.19939, 10.66619], [-0.19369, 10.67872], [-0.19061, 10.68708], [-0.18949, 10.69097], [-0.18942, 10.69123], [-0.13497, 10.94418]], y: [-0.3, 0.3], collide: 2, color: "#8f8a80"}
joints:
  - {id: j_wheel, type: hinge, body: wheel, axis: [0, 1, 0], damping: 0.00002}   # the escape-wheel A; - : counter-clockwise (its way)
  - {id: j_anchor, type: hinge, body: anchor, axis: [0, 1, 0], damping: 0.0002}   # the anchor and sector on a
  - {id: j_bal, type: hinge, body: balance, axis: [0, 1, 0], stiffness: 0.01385, springref: 0, damping: 8e-05}   # the balance and its spring
contact: {solref: [0.002, 1], solimp: [0.95, 0.99, 0.0005], margin: 0}
# The mainspring: a constant torque on the escape-wheel, counter-clockwise. Nothing else is driven.
driver: {joint: j_wheel, kind: torque, torque: -0.008, max_torque: 0.05}
checks:
  # half a tooth (2 pi/30 / 2) per beat of the balance: one tooth per two beats, counter-clockwise
  - {type: advance, joint: j_wheel, beat: j_bal, expect: -0.10472, tol: 0.03, settle_s: 4, window_s: 4.0}
  # the sector and pinion: the balance turns 4 times as far as the anchor, the other way
  # the balance's period: its spring against its own inertia and the anchor's through the gearing, 2 pi sqrt((I_b + I_a / n^2) / k)
  - {type: period, joint: j_bal, expect_s: 0.62884, tol: 0.06, settle_s: 4, window_s: 4}
  - {type: ratio, out: j_bal, in: j_anchor, expect: -4.0, tol: 0.1, settle_s: 4, window_s: 4}
  - {type: monotonic, joint: j_wheel, direction: -1, max_back: 0.03, settle_s: 2, window_s: 6}
  - {type: amplitude, joint: j_bal, min: 0.2, max: 0.8, sustain: 0.9, settle_s: 4, window_s: 4}
  - {type: penetration, max: 0.0005, settle_s: 1}
camera: {target: [0, 0, 1.0], position: [0, -84.0, 1.0], fov: 30}
display:
  output: j_bal
  swing: j_bal
  labels: {j_wheel: "Escape-wheel A (mainspring)", j_anchor: "Anchor and sector", j_bal: "Balance"}
  proof: {label: "Pallets out of contact", sub: "nothing makes good the balance's losses, so it stands still, and the mainspring spins the wheel freely"}

