File size: 6,226 Bytes
3dc2c17
c67ece1
 
aa651cf
7238c11
 
3dc2c17
aa651cf
7238c11
aa651cf
 
 
 
 
 
 
 
 
7238c11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
aa651cf
 
 
8683ed3
 
 
 
aa651cf
 
 
 
 
 
 
 
 
 
 
b4f0e09
 
3dc2c17
 
b4f0e09
3dc2c17
 
 
 
b4f0e09
 
 
 
 
3dc2c17
 
 
 
 
 
 
b4f0e09
3dc2c17
b4f0e09
 
aa651cf
8ad27c3
8683ed3
 
aa651cf
3dc2c17
8683ed3
aa651cf
3dc2c17
 
 
 
8683ed3
8ad27c3
3dc2c17
 
 
8683ed3
 
aa651cf
8683ed3
 
 
aa651cf
8683ed3
 
 
 
 
 
aa651cf
8683ed3
aa651cf
3dc2c17
aa651cf
8683ed3
 
 
 
 
 
aa651cf
8683ed3
 
aa651cf
8683ed3
 
3dc2c17
 
c67ece1
aa651cf
7238c11
aa651cf
 
 
 
 
c67ece1
aa651cf
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
from copy import deepcopy
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=-45.0, max_value=90.0, value=default_nose,
                                     help='0 is the disc pointing to the horizon\n90 is the disc pointing to the sky.',
                                     step=0.1)
            roll = st.sidebar.slider("Roll Angle (deg) | Anhyzer/Hyzer", min_value=-90.0, max_value=90.0,
                                     help='-90 the disc is very anhyzer, '
                                          '0 is the disc flat on the table, '
                                          '90 the disc is very hyzer',
                                     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='20m/s is a begginer\'s throw. '
                                       'The fastest throw on record is ~40m/s by Simon Lizotte')
            omega = st.sidebar.slider("Omega (revolutions/s)", min_value=0.0, max_value=200.0, value=default_omega,
                                      step=0.1,
                                      help='How much spin do you have?')
            z0 = st.sidebar.slider("Release Height (m)", min_value=0.0, max_value=2.0, value=default_z0, step=0.1,
                                   help='How high is your arm when throwing?')
            pitch = st.sidebar.slider("Pitch Angle (deg) | Release angle", min_value=0.0, max_value=90.0,
                                      help='0 = flat, 90 = aiming straight up',
                                      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 = deepcopy(stl_meshes[disc_name])
            fig = visualize_disc(stl_mesh, nose=nose, roll=roll)

            st.markdown("""
            ## Disc Orientation
            This is what your disc should look like after you release. The `Nose Angle` and `Roll Angle` 
            sidebar sliders control this.""")
            st.plotly_chart(fig)
        with st.spinner(text="Calculating Flight Path..."):
            st.markdown("""
            ## Flight Path
            Based on the sliders to the left, this will determine what your throw will look like.""")
            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)
            with st.expander("Optional Charts for science-y people"):
                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()