# No. 303, Dead-beat Pendulum Escapement (Brown 1868).
#
# "A dead-beat pendulum escapement. The inner face of the pallet, E, and outer face of D, are
# concentric with the axis on which the pallets vibrate, and hence there is no recoil."
#
# Graham's dead-beat, laid out as Brown draws it (1 unit = 1 cm): a 30-tooth escape wheel (tips r 5)
# turning clockwise (Brown's arrow), the pallet arbor C above it at 5·√2 so that the pallets embrace
# 7½ teeth and meet the tips where the tooth path is tangent to the arbor's radius, the pendulum hanging
# from C in front of the wheel to its bob F.
#
# Each pallet has two faces. Its locking face is an arc about C (D's outer face, E's inner face, as
# Brown says): while a tooth rests on it, the force is radial to C, so it neither drives nor turns
# back the pendulum, and the wheel stands dead still (no recoil). Its impulse face is the slanted tip:
# the tooth slides down it, pushing the pallet aside through the lift angle (2.5°), which gives the
# pendulum the energy its damping took. The tooth then drops off and the other pallet's locking face
# catches the next tooth after 1.5° of free run. Wheel per beat: 4.5° of impulse + 1.5° of drop = half a tooth.
# (Geometry: gen303 in the PR notes; locking radii are the distances from C to the tooth tips at the
# wheel angles where lock and drop occur: D 5.2399 → 4.8473, E 4.7601 → 5.1527.)
#
# Fully physical: the only input is a constant torque on the escape wheel (the clock's weight). The
# pendulum swings under gravity on its arbor and is kept going only by the teeth pressing on the
# pallets (convex hulls, one per tooth and per slice of each arc face). It starts from rest, hanging
# straight, with the first tooth about to reach D's impulse face: the escapement starts itself.
number: 303
slug: dead-beat-pendulum-escapement
name: Dead-beat Pendulum Escapement
brown: "A dead-beat pendulum escapement. The inner face of the pallet, E, and outer face of D, are concentric with the axis on which the pallets vibrate, and hence there is no recoil."
units: cm
sim: {timestep: 0.0002, integrator: implicitfast, iterations: 50, duration_s: 10, floor: false}
bodies:
  # The escape wheel: brass, 30 teeth leaning forward (Graham), rim, four spokes, hub.
  - id: wheel
    shape: part
    pos: [0, 0, 0]
    density: 8500
    friction: 0.1
    color: "#e6d7b0"
    pieces:
      - kind: wheel
        center: [0, 0]
        teeth: 30
        # one tooth, polar (radius, angle from its tip) — the tip leads, the back is curved off
        tooth: [[5.0, 0], [4.45, 0.075], [3.9, 0.165], [3.9, 0.0756]]
        phase: 2.42601        # 139°: tooth 0 just short of D's impulse face
        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"}   # arbor
  # The pallets (anchor) and the pendulum: one piece on the arbor C.
  - id: pendulum
    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: [-1.15, 0.35]}                       # 0 hub on the arbor
      - {kind: poly, points: [[-0.45183, 7.16247], [-4.23406, 4.21139], [-3.80346, 3.65951], [-0.02122, 6.61058]], y: [-0.3, 0.3]}  # 1
      - {kind: poly, points: [[0.02117, 6.61058], [3.73434, 3.71273], [4.16501, 4.26457], [0.45184, 7.16242]], y: [-0.3, 0.3]}  # 2
      # D (entry): locking face = outer arc r 5.2399 about C; impulse face down to r 4.8473 over 2.5° of lift
      - {kind: band, center: [0, 7.07107], r: [4.84731, 5.23989], a: [-2.57326, -2.36382], y: [-0.35, 0.35], collide: 1}  # 3
      - {kind: poly, points: [[-3.77162, 3.43357], [-3.73332, 3.39427], [-3.30196, 3.52234], [-3.48904, 3.7061]], y: [-0.35, 0.35], collide: 1}  # 4
      # E (exit): locking face = inner arc r 4.7601 about C; impulse face out to r 5.1527
      - {kind: band, center: [0, 7.07107], r: [4.76011, 5.15269], a: [-0.77788, -0.56844], y: [-0.35, 0.35], collide: 1}  # 5
      - {kind: poly, points: [[3.42591, 3.76625], [3.39111, 3.73056], [3.50957, 3.29838], [3.70845, 3.49369]], y: [-0.35, 0.35], collide: 1}  # 6
      - {kind: rod, from: [0, -1.0, 7.07107], to: [0, -1.0, -12.92893], radius: 0.15, color: "#8f8a80"}                                        # 7 pendulum rod
      - {kind: disc, center: [0, -12.92893], radius: 1.8, y: [-1.6, -0.4], density: 8500, color: "#e6d7b0"}                                     # 8 bob F (brass, 104 g)
  # The cock that carries C (frame, drawn only).
  - id: cock
    shape: part
    pos: [0, 0, 7.07107]
    fixed: true
    color: "#cfc6b4"
    pieces:
      - {kind: poly, points: [[-1.3, 8.6], [1.3, 8.6], [0.75, 6.75], [-0.75, 6.75]], y: [0.4, 1.0]}
      - {kind: disc, center: [0, 7.07107], radius: 0.18, y: [-1.3, 1.0], color: "#8f8a80"}
joints:
  - {id: j_wheel, type: hinge, body: wheel, axis: [0, 1, 0], damping: 0.00002}
  - {id: j_pend, type: hinge, body: pendulum, axis: [0, 1, 0], damping: 0.0015}   # air and pivot losses
contact: {solref: [0.002, 1], solimp: [0.95, 0.99, 0.0005], margin: 0}
# The clock's weight: a constant torque on the escape wheel, clockwise (+y). Nothing else is driven.
driver: {joint: j_wheel, kind: torque, torque: 0.008, max_torque: 0.05}
checks:
  # the pendulum keeps time: its period against the compound pendulum's 2π√(I/(m g d)) from the model
  - {type: period, joint: j_pend, tol: 0.03, settle_s: 4, window_s: 4}
  # half a tooth (2π/30 / 2) per beat: one tooth per two beats
  - {type: advance, joint: j_wheel, beat: j_pend, expect: 0.10472, tol: 0.03, settle_s: 4, window_s: 4}
  # dead beat: the wheel never turns back while locked (recoil) beyond contact compliance
  - {type: monotonic, joint: j_wheel, direction: 1, max_back: 0.004, settle_s: 2, window_s: 6}
  # the impulse keeps the swing going against the damping
  - {type: amplitude, joint: j_pend, min: 0.05, max: 0.2, sustain: 0.9, settle_s: 4, window_s: 4}
  - {type: penetration, max: 0.0005, settle_s: 1}
camera: {target: [0, 0, -3.6], position: [11, -54, 1.5], fov: 30}
display:
  output: j_pend
  swing: j_pend
  labels: {j_wheel: Escape wheel (weight), j_pend: Pendulum and pallets}
  brake: Extra air drag on the pendulum
  proof: {label: Pallets out of contact, sub: "the teeth no longer touch the pallets: nothing makes good the pendulum's losses, so its swing dies away, and the weight spins the wheel freely"}
  sliders:
    - {id: len, label: Pendulum length, sub: "arbor C to the bob's centre F: the period goes as √L", min: 10, max: 30, step: 0.5, value: 20, unit: cm,
       edits: [{body: pendulum, piece: 7, field: to.2, k: -1, offset: 7.07107}, {body: pendulum, piece: 8, field: center.1, k: -1, offset: 7.07107}]}
    - {id: bob, label: Bob weight, sub: "a heavier bob swings at the same rate but stores more energy, so each impulse changes it less", min: 30, max: 300, step: 5, value: 104, unit: g,
       edits: [{body: pendulum, piece: 8, field: density, k: 81.87}]}
