# No. 369 (Brown 1868): "Cycloidal surfaces, causing pendulum to move in cycloidal curve, rendering oscillations isochronous or equal-timed."
#
# Reading of the figure (cm, gravity on): the pendulum's cord, 37 cm long to the bob (40 cm to the bob's centre), hangs from the cusp between two cheeks, each a half-arch
# of the cycloid generated by a circle of 10 cm radius. As the pendulum swings, the cord wraps on one cheek, and the bob goes along the
# cycloid (the cord's involute) instead of a circular arc, so its swings take the same time whatever their size: 2 pi sqrt(4a/g) = 1.2687 s.
# The cord is 20 short links, hinged end to end. The operator's hand (a joint spring whose set point is moved: the one input) pushes the
# bob out with a pad, step by step, to 27.7 cm aside, and at 3 s draws the pad away; after that nothing acts but gravity.
# Generator: opencode-runs/batch12/gen369.py.
number: 369
slug: cycloidal-pendulum
name: Cycloidal pendulum
brown: "Cycloidal surfaces, causing pendulum to move in cycloidal curve, rendering oscillations isochronous or equal-timed."
units: cm
sim: {timestep: 0.0002, integrator: implicitfast, iterations: 80, solver: PGS, multiccd: false, duration_s: 12, floor: false}
bodies:
  - id: frame
    shape: part
    pos: [0, 0, 0]
    fixed: true
    friction: 0.3
    color: "#cfc6b4"
    pieces:
      - {kind: poly, points: [[0.1500, -0.0005], [0.1678, -0.2339], [0.1678, 2.0000], [0.1500, 2.0000]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[0.1678, -0.2339], [0.2954, -0.9569], [0.2954, 2.0000], [0.1678, 2.0000]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[0.2954, -0.9569], [0.6387, -2.1321], [0.6387, 2.0000], [0.2954, 2.0000]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[0.6387, -2.1321], [1.2928, -3.7000], [1.2928, 2.0000], [0.6387, 2.0000]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[1.2928, -3.7000], [2.3373, -5.5814], [2.3373, 2.0000], [1.2928, 2.0000]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[2.3373, -5.5814], [3.8320, -7.6813], [3.8320, 2.0000], [2.3373, 2.0000]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[3.8320, -7.6813], [5.8140, -9.8939], [5.8140, 2.0000], [3.8320, 2.0000]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[5.8140, -9.8939], [8.2962, -12.1079], [8.2962, 2.0000], [5.8140, 2.0000]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[8.2962, -12.1079], [11.2661, -14.2118], [11.2661, 2.0000], [8.2962, 2.0000]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[11.2661, -14.2118], [14.6867, -16.0998], [14.6867, 2.0000], [11.2661, 2.0000]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[14.6867, -16.0998], [18.4986, -17.6767], [18.4986, 2.0000], [14.6867, 2.0000]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[18.4986, -17.6767], [22.6225, -18.8634], [22.6225, 2.0000], [18.4986, 2.0000]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[22.6225, -18.8634], [26.9635, -19.6002], [26.9635, 2.0000], [22.6225, 2.0000]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[26.9635, -19.6002], [31.4159, -19.8500], [31.4159, 2.0000], [26.9635, 2.0000]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[-0.1500, 2.0000], [-0.1678, 2.0000], [-0.1678, -0.2339], [-0.1500, -0.0005]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[-0.1678, 2.0000], [-0.2954, 2.0000], [-0.2954, -0.9569], [-0.1678, -0.2339]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[-0.2954, 2.0000], [-0.6387, 2.0000], [-0.6387, -2.1321], [-0.2954, -0.9569]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[-0.6387, 2.0000], [-1.2928, 2.0000], [-1.2928, -3.7000], [-0.6387, -2.1321]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[-1.2928, 2.0000], [-2.3373, 2.0000], [-2.3373, -5.5814], [-1.2928, -3.7000]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[-2.3373, 2.0000], [-3.8320, 2.0000], [-3.8320, -7.6813], [-2.3373, -5.5814]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[-3.8320, 2.0000], [-5.8140, 2.0000], [-5.8140, -9.8939], [-3.8320, -7.6813]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[-5.8140, 2.0000], [-8.2962, 2.0000], [-8.2962, -12.1079], [-5.8140, -9.8939]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[-8.2962, 2.0000], [-11.2661, 2.0000], [-11.2661, -14.2118], [-8.2962, -12.1079]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[-11.2661, 2.0000], [-14.6867, 2.0000], [-14.6867, -16.0998], [-11.2661, -14.2118]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[-14.6867, 2.0000], [-18.4986, 2.0000], [-18.4986, -17.6767], [-14.6867, -16.0998]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[-18.4986, 2.0000], [-22.6225, 2.0000], [-22.6225, -18.8634], [-18.4986, -17.6767]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[-22.6225, 2.0000], [-26.9635, 2.0000], [-26.9635, -19.6002], [-22.6225, -18.8634]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: poly, points: [[-26.9635, 2.0000], [-31.4159, 2.0000], [-31.4159, -19.8500], [-26.9635, -19.6002]], y: [-1.5, 1.5], collide: 2, color: "#7d6a52"}
      - {kind: rod, from: [-31.3971, 2.4, -20.2507], to: [-31.3971, 2.6, -20.2507], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [-31.2668, 2.4, -20.9903], to: [-31.2668, 2.6, -20.9903], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [-30.9188, 2.4, -22.1817], to: [-30.9188, 2.6, -22.1817], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [-30.2583, 2.4, -23.7651], to: [-30.2583, 2.6, -23.7651], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [-29.2056, 2.4, -25.6612], to: [-29.2056, 2.6, -25.6612], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [-27.7012, 2.4, -27.7748], to: [-27.7012, 2.6, -27.7748], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [-25.7080, 2.4, -30.0000], to: [-25.7080, 2.6, -30.0000], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [-23.2132, 2.4, -32.2252], to: [-23.2132, 2.6, -32.2252], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [-20.2297, 2.4, -34.3388], to: [-20.2297, 2.6, -34.3388], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [-16.7943, 2.4, -36.2349], to: [-16.7943, 2.6, -36.2349], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [-12.9669, 2.4, -37.8183], to: [-12.9669, 2.6, -37.8183], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [-8.8268, 2.4, -39.0097], to: [-8.8268, 2.6, -39.0097], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [-4.4692, 2.4, -39.7493], to: [-4.4692, 2.6, -39.7493], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [0.0000, 2.4, -40.0000], to: [0.0000, 2.6, -40.0000], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [4.4692, 2.4, -39.7493], to: [4.4692, 2.6, -39.7493], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [8.8268, 2.4, -39.0097], to: [8.8268, 2.6, -39.0097], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [12.9669, 2.4, -37.8183], to: [12.9669, 2.6, -37.8183], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [16.7943, 2.4, -36.2349], to: [16.7943, 2.6, -36.2349], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [20.2297, 2.4, -34.3388], to: [20.2297, 2.6, -34.3388], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [23.2132, 2.4, -32.2252], to: [23.2132, 2.6, -32.2252], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [25.7080, 2.4, -30.0000], to: [25.7080, 2.6, -30.0000], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [27.7012, 2.4, -27.7748], to: [27.7012, 2.6, -27.7748], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [29.2056, 2.4, -25.6612], to: [29.2056, 2.6, -25.6612], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [30.2583, 2.4, -23.7651], to: [30.2583, 2.6, -23.7651], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [30.9188, 2.4, -22.1817], to: [30.9188, 2.6, -22.1817], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [31.2668, 2.4, -20.9903], to: [31.2668, 2.6, -20.9903], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: rod, from: [31.3971, 2.4, -20.2507], to: [31.3971, 2.6, -20.2507], radius: 0.35, collide: 0, color: "#8f8a80"}
      - {kind: poly, points: [[31.4159, -20.0000], [39.4159, -21.2000], [39.4159, -19.6000], [31.4159, -18.4000]], y: [-1.5, 1.5], collide: 0, color: "#7d6a52"}
      - {kind: poly, points: [[-31.4159, -18.4000], [-39.4159, -19.6000], [-39.4159, -21.2000], [-31.4159, -20.0000]], y: [-1.5, 1.5], collide: 0, color: "#7d6a52"}
      - {kind: poly, points: [[-36, 2.0], [36, 2.0], [36, 4.0], [-36, 4.0]], y: [-3, 3], collide: 0, color: "#b9b09c"}
  - id: l0
    shape: part
    pos: [0, 0, 0.0000]
    mass: 0.002
    friction: 0.3
    color: "#d8cfb8"
    pieces:
      - {kind: rod, from: [0, 0, 0.0000], to: [0, 0, -1.8500], radius: 0.15, capsule: true, collide: 1}
  - id: l1
    shape: part
    pos: [0, 0, -1.8500]
    mount: l0
    mass: 0.002
    friction: 0.3
    color: "#d8cfb8"
    pieces:
      - {kind: rod, from: [0, 0, -1.8500], to: [0, 0, -3.7000], radius: 0.15, capsule: true, collide: 1}
  - id: l2
    shape: part
    pos: [0, 0, -3.7000]
    mount: l1
    mass: 0.002
    friction: 0.3
    color: "#d8cfb8"
    pieces:
      - {kind: rod, from: [0, 0, -3.7000], to: [0, 0, -5.5500], radius: 0.15, capsule: true, collide: 1}
  - id: l3
    shape: part
    pos: [0, 0, -5.5500]
    mount: l2
    mass: 0.002
    friction: 0.3
    color: "#d8cfb8"
    pieces:
      - {kind: rod, from: [0, 0, -5.5500], to: [0, 0, -7.4000], radius: 0.15, capsule: true, collide: 1}
  - id: l4
    shape: part
    pos: [0, 0, -7.4000]
    mount: l3
    mass: 0.002
    friction: 0.3
    color: "#d8cfb8"
    pieces:
      - {kind: rod, from: [0, 0, -7.4000], to: [0, 0, -9.2500], radius: 0.15, capsule: true, collide: 1}
  - id: l5
    shape: part
    pos: [0, 0, -9.2500]
    mount: l4
    mass: 0.002
    friction: 0.3
    color: "#d8cfb8"
    pieces:
      - {kind: rod, from: [0, 0, -9.2500], to: [0, 0, -11.1000], radius: 0.15, capsule: true, collide: 1}
  - id: l6
    shape: part
    pos: [0, 0, -11.1000]
    mount: l5
    mass: 0.002
    friction: 0.3
    color: "#d8cfb8"
    pieces:
      - {kind: rod, from: [0, 0, -11.1000], to: [0, 0, -12.9500], radius: 0.15, capsule: true, collide: 1}
  - id: l7
    shape: part
    pos: [0, 0, -12.9500]
    mount: l6
    mass: 0.002
    friction: 0.3
    color: "#d8cfb8"
    pieces:
      - {kind: rod, from: [0, 0, -12.9500], to: [0, 0, -14.8000], radius: 0.15, capsule: true, collide: 1}
  - id: l8
    shape: part
    pos: [0, 0, -14.8000]
    mount: l7
    mass: 0.002
    friction: 0.3
    color: "#d8cfb8"
    pieces:
      - {kind: rod, from: [0, 0, -14.8000], to: [0, 0, -16.6500], radius: 0.15, capsule: true, collide: 1}
  - id: l9
    shape: part
    pos: [0, 0, -16.6500]
    mount: l8
    mass: 0.002
    friction: 0.3
    color: "#d8cfb8"
    pieces:
      - {kind: rod, from: [0, 0, -16.6500], to: [0, 0, -18.5000], radius: 0.15, capsule: true, collide: 1}
  - id: l10
    shape: part
    pos: [0, 0, -18.5000]
    mount: l9
    mass: 0.002
    friction: 0.3
    color: "#d8cfb8"
    pieces:
      - {kind: rod, from: [0, 0, -18.5000], to: [0, 0, -20.3500], radius: 0.15, capsule: true, collide: 1}
  - id: l11
    shape: part
    pos: [0, 0, -20.3500]
    mount: l10
    mass: 0.002
    friction: 0.3
    color: "#d8cfb8"
    pieces:
      - {kind: rod, from: [0, 0, -20.3500], to: [0, 0, -22.2000], radius: 0.15, capsule: true, collide: 1}
  - id: l12
    shape: part
    pos: [0, 0, -22.2000]
    mount: l11
    mass: 0.002
    friction: 0.3
    color: "#d8cfb8"
    pieces:
      - {kind: rod, from: [0, 0, -22.2000], to: [0, 0, -24.0500], radius: 0.15, capsule: true, collide: 1}
  - id: l13
    shape: part
    pos: [0, 0, -24.0500]
    mount: l12
    mass: 0.002
    friction: 0.3
    color: "#d8cfb8"
    pieces:
      - {kind: rod, from: [0, 0, -24.0500], to: [0, 0, -25.9000], radius: 0.15, capsule: true, collide: 1}
  - id: l14
    shape: part
    pos: [0, 0, -25.9000]
    mount: l13
    mass: 0.002
    friction: 0.3
    color: "#d8cfb8"
    pieces:
      - {kind: rod, from: [0, 0, -25.9000], to: [0, 0, -27.7500], radius: 0.15, capsule: true, collide: 1}
  - id: l15
    shape: part
    pos: [0, 0, -27.7500]
    mount: l14
    mass: 0.002
    friction: 0.3
    color: "#d8cfb8"
    pieces:
      - {kind: rod, from: [0, 0, -27.7500], to: [0, 0, -29.6000], radius: 0.15, capsule: true, collide: 1}
  - id: l16
    shape: part
    pos: [0, 0, -29.6000]
    mount: l15
    mass: 0.002
    friction: 0.3
    color: "#d8cfb8"
    pieces:
      - {kind: rod, from: [0, 0, -29.6000], to: [0, 0, -31.4500], radius: 0.15, capsule: true, collide: 1}
  - id: l17
    shape: part
    pos: [0, 0, -31.4500]
    mount: l16
    mass: 0.002
    friction: 0.3
    color: "#d8cfb8"
    pieces:
      - {kind: rod, from: [0, 0, -31.4500], to: [0, 0, -33.3000], radius: 0.15, capsule: true, collide: 1}
  - id: l18
    shape: part
    pos: [0, 0, -33.3000]
    mount: l17
    mass: 0.002
    friction: 0.3
    color: "#d8cfb8"
    pieces:
      - {kind: rod, from: [0, 0, -33.3000], to: [0, 0, -35.1500], radius: 0.15, capsule: true, collide: 1}
  - id: l19
    shape: part
    pos: [0, 0, -35.1500]
    mount: l18
    mass: 0.5
    friction: 0.3
    color: "#d8cfb8"
    pieces:
      - {kind: rod, from: [0, 0, -35.1500], to: [0, 0, -37.0000], radius: 0.15, capsule: true, collide: 1}
      - {kind: disc, center: [0, -40.0000], radius: 3.0, y: [-1.2, 1.2], collide: 2, color: "#c9a85c"}
  - id: hand
    shape: part
    pos: [-4.0000, 0, -40.0000]
    mass: 0.05
    friction: 0.1
    color: "#a88a5c"
    pieces:
      - {kind: poly, points: [[-5.0000, -42.5000], [-4.0000, -42.5000], [-4.0000, -28.3280], [-5.0000, -28.3280]], y: [-1.5, 1.5], collide: 1}
      - {kind: rod, from: [-4.5000, -1.5, -40.0000], to: [-4.5000, -9, -40.0000], radius: 0.4, collide: 0}
joints:
  - {id: j_0, type: hinge, body: l0, axis: [0, 1, 0], damping: 0.00001}
  - {id: j_1, type: hinge, body: l1, axis: [0, 1, 0], damping: 0.00001}
  - {id: j_2, type: hinge, body: l2, axis: [0, 1, 0], damping: 0.00001}
  - {id: j_3, type: hinge, body: l3, axis: [0, 1, 0], damping: 0.00001}
  - {id: j_4, type: hinge, body: l4, axis: [0, 1, 0], damping: 0.00001}
  - {id: j_5, type: hinge, body: l5, axis: [0, 1, 0], damping: 0.00001}
  - {id: j_6, type: hinge, body: l6, axis: [0, 1, 0], damping: 0.00001}
  - {id: j_7, type: hinge, body: l7, axis: [0, 1, 0], damping: 0.00001}
  - {id: j_8, type: hinge, body: l8, axis: [0, 1, 0], damping: 0.00001}
  - {id: j_9, type: hinge, body: l9, axis: [0, 1, 0], damping: 0.00001}
  - {id: j_10, type: hinge, body: l10, axis: [0, 1, 0], damping: 0.00001}
  - {id: j_11, type: hinge, body: l11, axis: [0, 1, 0], damping: 0.00001}
  - {id: j_12, type: hinge, body: l12, axis: [0, 1, 0], damping: 0.00001}
  - {id: j_13, type: hinge, body: l13, axis: [0, 1, 0], damping: 0.00001}
  - {id: j_14, type: hinge, body: l14, axis: [0, 1, 0], damping: 0.00001}
  - {id: j_15, type: hinge, body: l15, axis: [0, 1, 0], damping: 0.00001}
  - {id: j_16, type: hinge, body: l16, axis: [0, 1, 0], damping: 0.00001}
  - {id: j_17, type: hinge, body: l17, axis: [0, 1, 0], damping: 0.00001}
  - {id: j_18, type: hinge, body: l18, axis: [0, 1, 0], damping: 0.00001}
  - {id: j_19, type: hinge, body: l19, axis: [0, 1, 0], damping: 0.00001}
  - {id: j_hand, type: slide, body: hand, axis: [1, 0, 0], range: [-46, 36], stiffness: 200.0, springref: 0, damping: 4.0}   # the operator's hand: a spring whose set point is moved
hand:
  - {t: 0.0, springref: {j_hand: 5.9077}}
  - {t: 0.4, springref: {j_hand: 11.8154}}
  - {t: 0.8, springref: {j_hand: 17.7231}}
  - {t: 1.2, springref: {j_hand: 23.6308}}
  - {t: 1.6, springref: {j_hand: 29.5385}}
  - {t: 3.0, springref: {j_hand: -42}}
contact: {solref: [0.002, 1.0], solimp: [0.95, 0.99, 0.0005], margin: 0}
driver: {joint: j_0, kind: torque, torque: 0, max_torque: 0.001}
checks:
  - {type: period, joint: j_0, expect_s: 1.2687, tol: 0.012, settle_s: 3.5, window_s: 8.4}
  - {type: amplitude, joint: j_0, min: 0.08, max: 0.16, sustain: 0.8, settle_s: 3.5, window_s: 8.4}
  - {type: penetration, max: 0.002, settle_s: 0.5}
camera: {target: [0, 0, -31.0], position: [0, -150, -31.0], fov: 34}
display:
  output: j_0
  labels: {j_0: "Cord at the cusp", j_hand: "Operator's hand (pad)"}

