disc-golf-simulator / disc_golf_simulator.py
derek-thomas's picture
derek-thomas HF staff
Renaming
90924b0
raw history blame
No virus
4.63 kB
from logging import getLogger
from pathlib import Path
proj_dir = Path(__file__).parents[1]
import sys
sys.path.append(str(proj_dir))
import numpy as np
import streamlit as st
from shotshaper.projectile import DiscGolfDisc
from visualize import get_plot, get_stl, get_subplots, 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
def main():
tab1, tab2 = st.tabs(['Simulator', 'FAQ'])
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
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)
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)
pos = np.array((0, 0, default_z0))
disc_dict = DiscGolfDisc(disc_name)
stl_mesh = get_stl(proj_dir / 'shotshaper' / 'discs' / (disc_name + '.stl'))
fig = visualize_disc(stl_mesh, nose=nose, roll=roll)
st.markdown("""## Disc orientation""")
st.plotly_chart(fig)
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("""
# 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
""")
if __name__ == "__main__":
# Setting up Logger and proj_dir
logger = getLogger(__name__)
proj_dir = Path(__file__).parents[1]
st.title("Disc Golf Simulator")
# initialize_state()
main()