Arm Length Fractions
This notebook performs a parameter study of the projectile and counterweight arm lengths of a hinged counterweight trebuchet. It fixes the total arm length and varies the fraction projectile_arm_length/total_arm_length. For some values of this fraction, the projectile sling is not in tension for the full duration of the launch.
[1]:
import matplotlib.pyplot as plt
import numpy as np
from pytrebuchet.simulation import Simulation
from pytrebuchet.trebuchet import HingedCounterweightTrebuchet, Arm
# Define range of arm fraction values to test
arm_fractions = np.linspace(
0.5, 0.8, 100
) # fraction of total arm length that is projectile arm
total_arm_length = 1.75 + 6.792
# Define result arrays
distances = np.empty_like(arm_fractions, dtype=np.float64)
in_tension = np.empty_like(arm_fractions, dtype=bool) # Track if sling stays in tension
# Compute distance for each arm fraction
default = HingedCounterweightTrebuchet.default()
for i, arm_fraction in enumerate(arm_fractions):
# Create trebuchet with specified arm lengths
projectile_arm_length = arm_fraction * total_arm_length
counterweight_arm_length = total_arm_length - projectile_arm_length
trebuchet = HingedCounterweightTrebuchet(
arm=Arm(
length_projectile_side=projectile_arm_length,
length_weight_side=counterweight_arm_length,
mass=default.arm.mass,
),
weight=default.weight,
pivot=default.pivot,
sling_projectile=default.sling_projectile,
sling_weight=default.sling_weight,
release_angle=default.release_angle,
projectile=default.projectile,
)
# Simulate
simulation = Simulation(
trebuchet, verify_sling_tension=False
) # we will check tension manually
simulation.solve()
# Record distance and tension status
distances[i] = simulation.distance_traveled
in_tension[i] = np.all(simulation.where_sling_in_tension())
# Plot results
fig, ax = plt.subplots()
ax.plot(arm_fractions, distances, label="Distance Traveled")
ax.fill_between(
arm_fractions,
0,
np.max(distances),
where=in_tension,
color="green",
alpha=0.3,
label="Sling in Tension",
)
ax.fill_between(
arm_fractions,
0,
np.max(distances),
where=~in_tension,
color="red",
alpha=0.3,
label="Sling Slack",
)
ax.set_xlabel("Projectile Arm Length / Total Arm Length")
ax.set_ylabel("Distance Traveled (m)")
ax.legend()
plt.show()