{ "cells": [ { "cell_type": "markdown", "id": "0", "metadata": {}, "source": [ "# Hinged Counterweight Simulation\n", "\n", "This notebook:\n", "\n", "- Instantiates a default hinged counterweight trebuchet and projectile\n", "- Solves the multi-phase motion (in sling & sliding over ground, in sling, ballistic)\n", "- Reports key timing and range metrics\n", "- Generates an animation of the launch\n", "\n", "Tip: For clearer visuals you can adjust `skip` (frame thinning) and `delay` (ms between frames) in the animation cell." ] }, { "cell_type": "code", "execution_count": null, "id": "1", "metadata": {}, "outputs": [], "source": [ "from pytrebuchet.simulation import Simulation, SimulationPhases\n", "from pytrebuchet.differential_equations.sling_phase import SlingPhases\n", "from pytrebuchet.trebuchet import HingedCounterweightTrebuchet" ] }, { "cell_type": "markdown", "id": "2", "metadata": {}, "source": [ "## 1. Setup & Solve\n", "\n", "We create a default `HingedCounterweightTrebuchet` and run the `Simulation.solve()` method to solve the differential equations of the trebuchet and projectile.\n", "\n", "Key reported metrics:\n", "\n", "- Ground separation time: when the projectile separates from the ground, marking the end of the 'sliding' sling phase.\n", "- Sling release time: when projectile exits the sling, marking the end of the 'sling' phases and the start of the 'ballistic' phase.\n", "- Ground impact time: end of ballistic phase.\n", "- Horizontal range: total distance traveled before impact." ] }, { "cell_type": "code", "execution_count": null, "id": "3", "metadata": {}, "outputs": [], "source": [ "trebuchet = HingedCounterweightTrebuchet.default()\n", "simulation = Simulation(trebuchet)\n", "\n", "simulation.solve()\n", "\n", "print(\n", " f\"Ground separation time: {\n", " simulation.get_phase_end_time(\n", " sim_phase=SimulationPhases.SLING,\n", " sling_phase=SlingPhases.SLIDING_OVER_GROUND,\n", " ):.4f} s\"\n", ")\n", "print(\n", " f\"Sling release time: {\n", " simulation.get_phase_end_time(\n", " sim_phase=SimulationPhases.SLING, sling_phase=SlingPhases.UNCONSTRAINED\n", " ):.4f} s\"\n", ")\n", "print(\n", " f\"Ground impact time: {\n", " simulation.get_phase_end_time(sim_phase=SimulationPhases.BALLISTIC):.4f} s\"\n", ")\n", "print(f\"Horizontal range: {simulation.distance_traveled:.2f} m\")" ] }, { "cell_type": "markdown", "id": "4", "metadata": {}, "source": [ "## 3. Animation\n", "\n", "Below we animate the launch sequence.\n", "\n", "Adjust parameters in `animate_launch(simulation, skip=10, delay=50)` for smoother or faster playback." ] }, { "cell_type": "code", "execution_count": null, "id": "5", "metadata": {}, "outputs": [], "source": [ "from matplotlib import rc\n", "from pytrebuchet.plotting import animate_launch\n", "from IPython.display import HTML\n", "\n", "# Configure matplotlib to render animations as interactive JavaScript\n", "rc(\"animation\", html=\"jshtml\")\n", "\n", "ani = animate_launch(simulation, skip=10, delay=50, show=False)\n", "HTML(ani.to_jshtml())" ] } ], "metadata": { "kernelspec": { "display_name": ".venv (3.13.9)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.9" } }, "nbformat": 4, "nbformat_minor": 5 }