pytrebuchet package
PyTrebuchet: a Python package for simulating trebuchet mechanics.
- class pytrebuchet.EnvironmentConfig(wind_speed: float = 0.0, air_density: float = 1.225, air_kinematic_viscosity: float = 1.47e-05, gravitational_acceleration: float = 9.81)
Bases:
objectClass for holding environment configuration parameters.
- wind_speed: float = 0.0
- air_density: float = 1.225
- air_kinematic_viscosity: float = 1.47e-05
- gravitational_acceleration: float = 9.81
- __init__(wind_speed: float = 0.0, air_density: float = 1.225, air_kinematic_viscosity: float = 1.47e-05, gravitational_acceleration: float = 9.81) None
- class pytrebuchet.HingedCounterweightTrebuchet(arm: Arm, weight: Weight, pivot: Pivot, sling_projectile: Sling, sling_weight: Sling, release_angle: float = 0.7853981633974483, projectile: Projectile | None = None)
Bases:
TrebuchetClass representing a hinged counterweight trebuchet.
- _abc_impl = <_abc._abc_data object>
- _initialize_angles() None
Calculate the initial angles of the trebuchet.
Calculate:
angle_arm such that the projectile arm end just touches the ground. If the arm is too short to reach the ground, set a default angle of 55 degrees.
angle_weight such that the weight hangs vertically downwards.
angle_projectile such that the projectile just touches the ground. If the sling is too short to reach the ground, set the sling angle such that it hangs vertically downwards.
- classmethod default() HingedCounterweightTrebuchet
Create a hinged counterweight Trebuchet instance with default parameters.
These parameters are taken from https://virtualtrebuchet.com/.
- class pytrebuchet.PhysicalConstants(AIR_DENSITY: float = 1.225, AIR_KINEMATIC_VISCOSITY: float = 1.47e-05, GRAVITATIONAL_ACCELERATION_EARTH: float = 9.81)
Bases:
objectClass for holding physical constants used in simulations.
- AIR_DENSITY: float = 1.225
- AIR_KINEMATIC_VISCOSITY: float = 1.47e-05
- GRAVITATIONAL_ACCELERATION_EARTH: float = 9.81
- __init__(AIR_DENSITY: float = 1.225, AIR_KINEMATIC_VISCOSITY: float = 1.47e-05, GRAVITATIONAL_ACCELERATION_EARTH: float = 9.81) None
- class pytrebuchet.Projectile(*, mass: float | None = 3.0, density: float | None = None, diameter: float = 0.2, drag_coefficient: float | Callable[[float | ndarray[tuple[Any, ...], dtype[floating]]], float | ndarray[tuple[Any, ...], dtype[floating]]] | None = None)
Bases:
objectRepresent a spherical projectile launched by the trebuchet.
- __init__(*, mass: float | None = 3.0, density: float | None = None, diameter: float = 0.2, drag_coefficient: float | Callable[[float | ndarray[tuple[Any, ...], dtype[floating]]], float | ndarray[tuple[Any, ...], dtype[floating]]] | None = None) None
Initialize a Projectile instance.
It assumes a spherical shape for drag calculations.
- Parameters:
mass – mass of the projectile (kg). If None, mass is calculated from density and diameter.
density – density of the projectile (kg/m^3). If mass is given, density should be None.
diameter – diameter of the projectile (m)
drag_coefficient –
drag coefficient (dimensionless)
float: constant drag coefficient
callable: function that takes Reynolds number as input and returns a drag coefficient. The function should be vectorized to handle numpy arrays.
None: use default drag coefficient function for smooth spheres calculated using the Clift-Grace-Weber correlation.
- drag_coefficient: Callable[[float | ndarray[tuple[Any, ...], dtype[floating]]], float | ndarray[tuple[Any, ...], dtype[floating]]]
- classmethod default() Projectile
Create a Projectile instance with default parameters.
- Returns:
Projectile instance with default mass, diameter, and drag coefficient
- property radius: float
Get the radius of the spherical projectile.
- Returns:
radius (m)
- property volume: float
Get the volume of the spherical projectile.
- Returns:
volume (m^3)
- property density: float
Get the density of the spherical projectile.
- Returns:
density (kg/m^3)
- property effective_area: float
Get the effective cross-sectional area of the spherical projectile.
- Returns:
effective area (m^2)
- class pytrebuchet.Simulation(trebuchet: Trebuchet, environment: EnvironmentConfig | None = None, *, verify_sling_tension: bool = True, atol: float = 1e-06, rtol: float = 1e-05)
Bases:
objectClass for simulating trebuchet projectile launches.
- Parameters:
trebuchet – Trebuchet object containing trebuchet parameters
wind_speed – Wind speed in m/s (default is 0.0)
air_density – Density of the air in kg/m^3 (default is standard air density at sea level)
air_kinematic_viscosity – Kinematic viscosity of the air in m^2/s (default is approximate value at 15 degrees Celsius at sea level)
gravitational_acceleration – Gravitational acceleration in m/s^2 (default is Earth’s gravity)
verify_sling_tension – Whether to verify sling tension after solving the simulation (default is True)
atol – Absolute tolerance for the ODE solver (default is 1e-6)
rtol – Relative tolerance for the ODE solver (default is 1e-5), spikes in the distance calculations occur for rtol >= 1e-4
- __init__(trebuchet: Trebuchet, environment: EnvironmentConfig | None = None, *, verify_sling_tension: bool = True, atol: float = 1e-06, rtol: float = 1e-05) None
Initialize the simulation with the given trebuchet and projectile.
- Parameters:
trebuchet – Trebuchet object containing trebuchet parameters
environment – EnvironmentConfig object containing environment parameters
verify_sling_tension – Whether to verify sling tension after solving the simulation (default is True)
atol – Absolute tolerance for the ODE solver (default is 1e-6)
rtol – Relative tolerance for the ODE solver (default is 1e-5), spikes in the distance calculations seem to occur for rtol >= 1e-4
- _get_sling_phase_solution(phase: SlingPhases) Bunch
Get sling phase solution with validation.
- Parameters:
phase – The sling phase to get the solution for
- Returns:
The solve_ivp solution for the specified phase
- Raises:
RuntimeError – If the solution is not available
- _get_ballistic_solution() Bunch
Get ballistic phase solution with validation.
- Returns:
The solve_ivp solution for the ballistic phase
- Raises:
RuntimeError – If the solution is not available
- solve() None
Run the simulation of the trebuchet launching the projectile.
- _solve_sling_phase(phase_index: int) None
Solve the differential equations for a specific sling phase.
- Parameters:
phase_index – The index of the sling phase to be solved
- _solve_ballistic_phase() None
Solve the differential equations for the ballistic phase.
The differential equations have the following arguments: environment: EnvironmentConfig object containing environment parameters projectile: Projectile object containing properties of the projectile
- get_phase_end_time(sim_phase: SimulationPhases, sling_phase: SlingPhases | None = None) float
Return the end time of the specified phase.
- Parameters:
sim_phase – The simulation phase to get the end time for.
sling_phase – The sling phase to get the end time for, required if sim_phase is SLING.
- Returns:
The end time of the specified phase.
- property solved: bool
Return whether the simulation has been run.
- Returns:
True if the simulation has been run, False otherwise.
- property distance_traveled: float
Return the horizontal distance traveled by the projectile.
Distance as measured from the pivot’s x-coordinate.
- Returns:
Horizontal distance traveled by the projectile.
- property release_velocity: float
Return the velocity of the projectile at sling release.
- Returns:
Velocity of the projectile at sling release.
- get_tsteps(sim_phase: SimulationPhases = SimulationPhases.ALL, sling_phase: SlingPhases | None = None) ndarray[tuple[Any, ...], dtype[floating]]
Return the time steps for the specified phase(s) of the simulation.
- Parameters:
sim_phase – Phase of the simulation to get time steps for. Options are: ALL - all phases (default) BALLISTIC - ballistic phase SLING - sling phases
sling_phase – Specific sling phase to get time steps for, required if sim_phase is SLING.
- Returns:
Numpy array of time steps for the specified phase(s).
- _get_phase_state_variables(sim_phase: SimulationPhases, sling_phase: SlingPhases | None = None) ndarray[tuple[Any, ...], dtype[floating]]
Return the state variables of the specified sling phase.
Combines the regular solution and the event solution.
- Parameters:
sim_phase – The simulation phase to get the state variables for.
sling_phase – The sling phase to get the state variables for, required if sim_phase is SLING.
- Returns:
Numpy array of shape (n, 6) where n is the number of time steps, containing the state variables
- get_trebuchet_state_variables(*, calculate_accelerations: bool = False) ndarray[tuple[Any, ...], dtype[floating]]
Return the state variables (angles and angular velocities) of the trebuchet.
- Parameters:
calculate_accelerations – Whether to include angular accelerations in the returned array (default is False)
- Returns:
Numpy array of shape (n, 6) or (n, 9) where n is the number of time steps, containing the state variables [ angle_arm, angle_weight, angle_projectile, angular_velocity_arm, angular_velocity_weight, angular_velocity_projectile, angular_acceleration_arm (if calculate_accelerations is True), angular_acceleration_weight (if calculate_accelerations is True), angular_acceleration_projectile (if calculate_accelerations is True), ]
- get_projectile_state_variables(phase: SimulationPhases = SimulationPhases.ALL, *, calculate_accelerations: bool = False) ndarray[tuple[Any, ...], dtype[floating]]
Return the state variables of the projectile throughout its flight.
This includes the (positions, velocities, optional accelerations)
- Parameters:
phase – Phase of the simulation to get projectile state variables for. Options are: ALL - all phases (default) BALLISTIC - ballistic phase SLING - sling phases
calculate_accelerations – Whether to include accelerations in the returned array (default is False)
- Returns:
Numpy array of shape (n, 4) or (n, 6) where n is the number of time steps, containing the state variables [ position_x, position_y, velocity_x, velocity_y, acceleration_x (if calculate_accelerations is True), acceleration_y (if calculate_accelerations is True), ]
- where_sling_in_tension(*, return_projection_array: bool = False) ndarray[tuple[Any, ...], dtype[floating]] | ndarray[tuple[Any, ...], dtype[bool]]
Determine where the sling is in tension throughout the sling phases.
- Parameters:
return_projection_array – If True, returns the projection values instead of booleans (default is False)
- Returns:
- if return_projection_array: Numpy array of projection values
at each time step.
- else: Numpy boolean array indicating whether the sling is in tension
at each time step.
- class pytrebuchet.SimulationPhases(*values)
Bases:
StrEnumEnumeration of the different phases of the simulation.
- ALL = 'ALL'
- SLING = 'SLING'
- BALLISTIC = 'BALLISTIC'
- static _generate_next_value_(name, start, count, last_values)
Return the lower-cased version of the member name.
- class pytrebuchet.WhipperTrebuchet(arm: Arm, weight: Weight, pivot: Pivot, projectile: Projectile, sling_projectile: Sling, sling_weight: Sling, release_angle: float, arm_angle: float = 1.0471975511965976, weight_angle: float = 0.17453292519943295)
Bases:
TrebuchetClass representing a whipper 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.
- _abc_impl = <_abc._abc_data object>
- __init__(arm: Arm, weight: Weight, pivot: Pivot, projectile: Projectile, sling_projectile: Sling, sling_weight: Sling, release_angle: float, arm_angle: float = 1.0471975511965976, weight_angle: float = 0.17453292519943295) None
Initialize a WhipperTrebuchet instance with the given parameters.
- Parameters:
arm – Arm instance
weight – Weight instance
pivot – Pivot instance
projectile – Projectile instance
sling_projectile – Sling instance for the projectile
sling_weight – Sling instance for the weight
release_angle – angle at which the projectile is released (radians)
arm_angle – initial angle of the arm as measured from the horizontal (radians).
weight_angle – initial angle of the weight sling as measured from the arm (radians).
- _initialize_angles() None
Calculate the initial angles of the trebuchet.
- Calculate:
-angle_arm based on the specified arm_angle parameter. -angle_projectile such that the projectile rests on the arm. -angle_weight based on the specified weight_angle parameter.
- classmethod default() WhipperTrebuchet
Create a whipper Trebuchet instance with default parameters.
Subpackages
Submodules
- pytrebuchet.custom_warnings module
- pytrebuchet.drag_coefficient module
- pytrebuchet.environment module
- pytrebuchet.physical_constants module
- pytrebuchet.projectile module
- pytrebuchet.simulation module
requires_solved()SimulationPhasesSlingODETerminationEventBallisticODETerminationEventSimulationSimulation.__init__()Simulation._sling_phasesSimulation._sling_phase_solutionsSimulation._ballistic_solutionSimulation._get_sling_phase_solution()Simulation._get_ballistic_solution()Simulation.solve()Simulation._solve_sling_phase()Simulation._solve_ballistic_phase()Simulation.get_phase_end_time()Simulation.solvedSimulation.distance_traveledSimulation.release_velocitySimulation.get_tsteps()Simulation._get_phase_state_variables()Simulation.get_trebuchet_state_variables()Simulation.get_projectile_state_variables()Simulation.where_sling_in_tension()
- pytrebuchet.trebuchet module
ArmWeightPivotSlingTrebuchetTrebuchet.__init__()Trebuchet.init_angle_armTrebuchet.init_angle_weightTrebuchet.init_angle_projectileTrebuchet._initialize_angles()Trebuchet.default()Trebuchet.calculate_arm_cog()Trebuchet.calculate_arm_endpoint_projectile()Trebuchet.calculate_arm_endpoint_weight()Trebuchet.calculate_weight_point()Trebuchet.calculate_projectile_point()Trebuchet._abc_implTrebuchet.calculate_projectile_velocity()Trebuchet.calculate_projectile_acceleration()
HingedCounterweightTrebuchetWhipperTrebuchet