Spaces:
Sleeping
Sleeping
from logging import getLogger | |
from pathlib import Path | |
import numpy as np | |
import streamlit as st | |
from shotshaper.projectile import DiscGolfDisc | |
from utilities.visualize import get_plot, get_subplots, stl_meshes, visualize_disc | |
# Define the default values | |
default_U = 24.2 | |
default_omega = 116.8 | |
default_z0 = 1.3 | |
default_pitch = 15.5 | |
default_nose = 0.0 | |
default_roll = 14.7 | |
faq = """ | |
# Motivation | |
I saw some great work by [kegiljarhus](https://github.com/kegiljarhus) [repo](https://github.com/kegiljarhus/shotshaper) | |
and wanted to make this available as an app so people could learn more about disc golf. I really want to commend | |
the amazing idea of writing a [scientific article](https://link.springer.com/article/10.1007/s12283-022-00390-5) | |
AND releasing code, and actually executing it well. This is what gets people excited about STEM. | |
I originally saw this | |
[reddit post](https://www.reddit.com/r/discgolf/comments/yyhbcj/wrote_a_scientific_article_on_disc_golf_flight/) | |
which really piqued my interest. | |
# Questions | |
- I imagine some of you will want to add your disc here, if you can convert your disc into an `.stl` then I will | |
add it to the database. If this gets common enough I will add an option to upload your own. | |
- I imagine there will be a barrier to entry to do this. | |
- If you have any ideas, just let me know in a discussion or in a pull request | |
""" | |
def main(): | |
tab1, tab2 = st.tabs(['Simulator', 'FAQ']) | |
vb_link = 'https://visitor-badge.glitch.me/badge?page_id=derek-thomas.disc-golf-simulator&left_color=gray&right_color=blue' | |
st.sidebar.markdown(f""" | |
![Total Visitors]({vb_link}) | |
""") | |
with tab1: | |
disc_names = { | |
'Innova Wraith': 'dd2', | |
'Innova Firebird': 'cd1', | |
'Innova Roadrunner': 'cd5', | |
'Innova Fairway Driver': 'fd2', | |
} | |
disc_selected = st.sidebar.selectbox("Disc Selection", disc_names.keys()) | |
disc_name = disc_names[disc_selected] | |
# Create the sliders with the default values | |
with st.container(): | |
st.sidebar.markdown("### Disc Orientation") | |
nose = st.sidebar.slider("Nose Angle (deg) | Up/Down", min_value=0.0, max_value=90.0, value=default_nose, | |
step=0.1) | |
roll = st.sidebar.slider("Roll Angle (deg) | Tilt Left/Right", min_value=-90.0, max_value=90.0, | |
value=default_roll, | |
step=0.1) | |
with st.sidebar.container(): | |
st.sidebar.markdown("### Throwing Properties") | |
U = st.sidebar.slider("Throwing Velocity (m/s)", min_value=0.0, max_value=40.0, value=default_U, step=0.1, | |
help='Fastest Throw on record is ~40m/s by Simon Lizotte') | |
omega = st.sidebar.slider("Omega", min_value=0.0, max_value=200.0, value=default_omega, step=0.1) | |
z0 = st.sidebar.slider("Release Height (m)", min_value=0.0, max_value=2.0, value=default_z0, step=0.1) | |
pitch = st.sidebar.slider("Pitch Angle (deg) | Release angle", min_value=0.0, max_value=90.0, | |
value=default_pitch, | |
step=0.1) | |
with st.spinner(text="Calculating Disc Orientation..."): | |
pos = np.array((0, 0, z0)) | |
disc_dict = DiscGolfDisc(disc_name) | |
stl_mesh = stl_meshes[disc_name] | |
fig = visualize_disc(stl_mesh, nose=nose, roll=roll) | |
st.markdown("""## Disc Orientation""") | |
st.plotly_chart(fig) | |
with st.spinner(text="Calculating Flight Path..."): | |
st.markdown("""## Flight Path""") | |
shot = disc_dict.shoot(speed=U, omega=omega, pitch=pitch, | |
position=pos, nose_angle=nose, roll_angle=roll) | |
# Plot trajectory | |
x, y, z = shot.position | |
x_new, y_new = -1 * y, x | |
# Reversed x and y to mimic a throw | |
fig = get_plot(x_new, y_new, z) | |
st.plotly_chart(fig, True) | |
st.markdown( | |
f""" | |
**Arrows in Blue** show you where your *s-turn* is. | |
**Arrows in Red** show you your *max height* and *lateral deviance*. | |
Hit Play to watch your animated throw. | |
| Metric | Value | | |
|--------------|--------| | |
| Drift Left | {round(min(x_new), 2)} | | |
| Drift Right | {round(max(x_new), 2)} | | |
| Max Height | {round(max(z), 2)} | | |
| Distance | {round(max(y_new), 2)} | | |
""" | |
) | |
arc, alphas, betas, lifts, drags, moms, rolls = disc_dict.post_process(shot, omega) | |
fig = get_subplots(arc, alphas, lifts, drags, moms, rolls, shot.velocity) | |
st.plotly_chart(fig, True) | |
with tab2: | |
st.markdown(faq) | |
if __name__ == "__main__": | |
# Setting up Logger and proj_dir | |
logger = getLogger(__name__) | |
proj_dir = Path(__file__).parent | |
st.title("Disc Golf Simulator") | |
# initialize_state() | |
main() | |