File size: 5,785 Bytes
3c74b8c |
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 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
import time
import streamlit as st
from params import *
from stable_baselines3 import SAC
import pandas as pd
import pydeck as pdk
from TwoDimEnv import TwoDimEnv
import gymnasium as gym
def run_episode(env, model, lat_tg, lon_tg, rho_init=RHO_INIT, theta_init=THETA_INIT, zed=Z_INIT):
'''
runs the episode given an observation init ... and an env and a model
:param env: TwoDimEnv
:param model:
:param lat_tg: lattitude de la target (0,0)
:param lon_tg: longitude de la target (0,0)
:param rho_init:
:param theta_init:
:param zed:
:return:
'''
obs = env.reset(training=False, rho_init=rho_init, theta_init=theta_init, z_init=zed)
step = 0
lat, lon = rhotheta_to_latlon(MOVE_TO_METERS * rho_init, theta_init, lat_tg, lon_tg)
path = [[lon, lat, MOVE_TO_METERS * zed]]
traj = [lat, lon, MOVE_TO_METERS * zed]
while step < zed:
step += 1
action, _ = model.predict(obs, deterministic=True)
obs, _, _, _ = env.step(action)
rho = obs[0] * env.space_limits
theta = obs[1] * 2 * PI
lat, lon = rhotheta_to_latlon(MOVE_TO_METERS*rho, theta, lat_tg, lon_tg)
traj = np.vstack((traj, [lat, lon, MOVE_TO_METERS*(zed - step)]))
path.append([lon, lat, MOVE_TO_METERS*(zed - step)])
df_col = pd.DataFrame(traj, columns=['lat', 'lon', 'zed'])
df_path = pd.DataFrame([{
'color': [0, 0, 200, 120],
'path': path
}])
return df_path, df_col
def rhotheta_to_latlon(rho, theta, lat_tg, lon_tg):
'''
transforms polar coordinates into lat, lon
:param rho:
:param theta:
:param lat_tg: latitude de la target (0,0)
:param lon_tg: longitude de la target (0,0)
:return:
'''
z = rho * np.exp(1j * theta)
lat = np.imag(z)*360/(40075*1000) + lat_tg
lon = np.real(z)*360/(40075*1000*np.cos(PI/180*lat)) + lon_tg
return lat, lon
def get_layers(df, df_past, df_target, df_path, df_col):
'''
renders the layers to be displayed with df in different formats as entries
:param df:
:param df_past:
:param df_target:
:param df_path:
:param df_col:
:return:
'''
return [
pdk.Layer(
'ScatterplotLayer',
data=df,
get_position='[lon, lat]',
get_color='[200, 30, 0, 160, 40]',
get_radius=10,
),
pdk.Layer(
'ScatterplotLayer',
data=df_target,
get_position='[lon, lat]',
get_color='[200, 30, 0]',
get_radius=65,
),
pdk.Layer(
'ScatterplotLayer',
data=df_target,
get_position='[lon, lat]',
get_color='[255, 255, 255]',
get_radius=45,
),
pdk.Layer(
'ScatterplotLayer',
data=df_target,
get_position='[lon, lat]',
get_color='[0, 0, 200]',
get_radius=25,
),
pdk.Layer(
'ScatterplotLayer',
data=df_past,
get_position='[lon, lat]',
get_color='[200, 30, 0, 40]',
get_radius=10,
),
pdk.Layer(
type="PathLayer",
data=df_path,
pickable=True,
get_color="color",
width_scale=20,
width_min_pixels=1,
get_path="path",
get_width=1,
),
pdk.Layer(
type="ColumnLayer",
data=df_col,
get_position=['lon', 'lat'],
get_elevation="zed",
elevation_scale=1,
radius=10,
get_fill_color=[160, 20, 0, 10],
pickable=True,
auto_highlight=True
),
]
def show():
'''
shows the i-PADS in Streamlit
:return:
'''
env = TwoDimEnv()
model = SAC.load("longModel")
st.title('Intelligent PADS by hexamind')
st.write('This is a quick demo of an autonomous Parachute (Precision Air Delivery System) controlled by Reinforcement learning. ')
st.text('<- Set the starting point')
st.sidebar.write("Where do you want the parachute to start from?")
rho = st.sidebar.slider('What distance? (in m)', 0, 3000, 1500) / MOVE_TO_METERS
theta = 2*PI/360 * st.sidebar.slider('What angle?', 0, 360, 90)
zed = int(st.sidebar.slider('What elevation? (in m)', 0, 1200, 600) / MOVE_TO_METERS)
location = st.sidebar.radio("Location", ['San Francisco', 'Paris', 'Puilaurens'])
lat_tg = LOC[location]['lat']
lon_tg = LOC[location]['lon']
df_path, df_col = run_episode(env, model, lat_tg, lon_tg, rho_init=rho, theta_init=theta, zed=zed)
st.sidebar.write(
'If you like to play, you will probably find some starting points where the parachute is out of control :) '
'No worries, we have plenty more efficient models at www.hexamind.com ')
df_target = pd.DataFrame({'lat': [lat_tg], 'lon': [lon_tg]})
deck_map = st.empty()
pitch = st.slider('pitch', 0, 100, 50)
initial_view_state = pdk.ViewState(
latitude=lat_tg,
longitude=lon_tg,
zoom=12,
pitch=pitch
)
deck_map.pydeck_chart(pdk.Deck(
map_style='mapbox://styles/mapbox/light-v9',
initial_view_state=initial_view_state
))
df_pathi = df_path.copy()
for i in range(zed):
df_pathi['path'][0] = df_path['path'][0][0:i+1]
layers = get_layers(df_col[i:i+1], df_col[0:i], df_target, df_pathi, df_col[0:i+1])
deck_map.pydeck_chart(pdk.Deck(
map_style='mapbox://styles/mapbox/light-v9',
initial_view_state=initial_view_state,
layers=layers
))
time.sleep(TIMESLEEP)
show()
# to uncomment for debug
#show_print()
|