Whipper Simulation
This notebook demonstrates a whipper-style trebuchet. A whipper trebuchet features a hinged counterweight system, but with the counterweight hanger positioned at the top of the throwing arm. When cocked, the arm points forward in the direction of the throw. At the start, the weight and projectile ‘rest’ on the trebuchet arm.
What you’ll see here:
Build a default whipper configuration (
Trebuchet.default_whipper())Solve the multi-phase motion for the whipper mechanism
Report key timing and range metrics
Animate the launch sequence
Tip: For clearer visuals, tweak skip (frame thinning) and delay (milliseconds per frame) in the animation cell.
[1]:
from pytrebuchet.simulation import Simulation, SimulationPhases
from pytrebuchet.differential_equations.sling_phase import SlingPhases
from pytrebuchet.trebuchet import WhipperTrebuchet
1. Setup & Solve
We create a whipper Trebuchet and a default Projectile, then call Simulation.solve() to integrate the equations of motion through the whipper-specific phases:
Both constrained: arm, whipper, and projectile move kinematically linked
Projectile constrained: projectile remains constrained while the whip transitions
Sling unconstrained: sling dynamics prior to release
Ballistic: free-flight trajectory after release
Printed metrics include sling release time, ground impact time, and horizontal range.
[2]:
trebuchet = WhipperTrebuchet.default()
simulation = Simulation(trebuchet)
simulation.solve()
print(
f"Sling release time: {
simulation.get_phase_end_time(
sim_phase=SimulationPhases.SLING, sling_phase=SlingPhases.UNCONSTRAINED
):.4f} s"
)
print(
f"Ground impact time: {
simulation.get_phase_end_time(sim_phase=SimulationPhases.BALLISTIC):.4f} s"
)
print(f"Horizontal range: {simulation.distance_traveled:.2f} m")
Sling release time: 2.1423 s
Ground impact time: 10.3851 s
Horizontal range: 302.04 m
2. Animation
Below we animate the whipper launch sequence.
Adjust parameters in animate_launch(simulation, skip=10, delay=50) for smoother or faster playback.
[3]:
from matplotlib import rc
from pytrebuchet.plotting import animate_launch
from IPython.display import HTML
# Configure matplotlib to render animations as interactive JavaScript
rc("animation", html="jshtml")
ani = animate_launch(simulation, skip=10, delay=50, show=False)
HTML(ani.to_jshtml())
[3]: