apaladugu3 commited on
Commit ·
ee0867c
1
Parent(s): 2ae9693
Added some more content and instructions
Browse files
app.py
CHANGED
|
@@ -83,6 +83,18 @@ def parse_all_data(path):
|
|
| 83 |
|
| 84 |
# Create the layout for the app
|
| 85 |
app.layout = html.Div([
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
html.Div([
|
| 87 |
# html.Div([
|
| 88 |
# html.Div("Select the desired input conditions, then click 'Simulate!':", id='text1'),
|
|
@@ -117,18 +129,6 @@ app.layout = html.Div([
|
|
| 117 |
# html.Br(),
|
| 118 |
# html.Button('Simulate!', id='button', n_clicks=0),
|
| 119 |
# ], style={'width': '50%', 'border': '1px solid gray'}),
|
| 120 |
-
|
| 121 |
-
html.Div([
|
| 122 |
-
html.B("This is an interactive demonstration of the What's Next Diagram for evaluating the ability of an operator to coordinate with envisioned automated systems, given a particular system design."),
|
| 123 |
-
html.Br(),
|
| 124 |
-
dcc.Markdown("More information can be found in the associated proceedings paper: Post, A., Nijveldt, R., Woods, D.D., IJtsma, M. (2024). Determining What's Next: Visual Analytics for Evaluating Human-Automation Coordination. Proceedings of the 2024 Human Factor and Ergonomics Annual Meeting, Phoenix, AZ. This work is partially funded by NSF Early Career Award #2238402 to Dr. Martijn IJtsma. This interactive demo also builds on earlier work under NASA grant 80NSSC23CA121.", id="explanation")
|
| 125 |
-
], style={'width': '100%', 'border': '1px solid gray'}),
|
| 126 |
-
html.Div([
|
| 127 |
-
dcc.Markdown("The example highlights a coordination problem in the operations of Unmanned Aerial Vehicle (UAV), which is the loss of a command and control (C2) link to the ground operator when the UAV *GCCRaven* is in busy airspace (i.e., there is surrounding traffic). The C2 link is used to receive data in real-time about the state/activity of GCCRaven, onboard automation, and to (re-)direct the automation to change GCCRaven's behavior. We use the What's Next Diagram to identify how the pilot of a second aircraft, *SNLBlaze* can coordinate with *GCCRaven*.", id="explanation")
|
| 128 |
-
], style={'width': '100%', 'border': '1px solid gray'}),
|
| 129 |
-
html.Div([
|
| 130 |
-
dcc.Markdown("It is envisioned that in future operatoins, each UAV is programmed with one or more contingency procedures that are to be executed in the case of a lost link. For this example, we assume the contingency procedure is to divert to and land at the nearest vertiport. However, even with contingency procedures onboard, there is potential for ambiguity in what GCCRaven will do next, depending on the logic that GCCRaven uses for determining what the nearest vertiport is, feedback it provides (Woods & Balkin, 2018), and--quite possibly--any related or additional failures onboard the UAV. The operator of *SNLBlaze* must therefore determine in real-time if what they think is the controlling contingency procedure is in fact being followed.", id="explanation2")
|
| 131 |
-
], style={'width': '100%', 'border': '1px solid gray'}),
|
| 132 |
html.Div([
|
| 133 |
# html.Div("Next, input the relative path to your results folder, then click 'Submit'. This will load the data:", id='text2'),
|
| 134 |
# dcc.Input(
|
|
@@ -140,7 +140,7 @@ app.layout = html.Div([
|
|
| 140 |
# ),
|
| 141 |
# html.Button('Submit', id='submit-button', n_clicks=0),
|
| 142 |
# Create a dropdown menu with the subfolders as options
|
| 143 |
-
html.Div("
|
| 144 |
dcc.Dropdown(
|
| 145 |
id='subfolder-dropdown',
|
| 146 |
value=None #subfolders[0] # Default value
|
|
@@ -225,16 +225,17 @@ def run_wmc(workAllocation, selected_time, ConAircraftResponse, OtherAircraftRes
|
|
| 225 |
@app.callback(
|
| 226 |
dash.dependencies.Output('subfolder-dropdown', 'options'),
|
| 227 |
dash.dependencies.Output('variable-dropdown', 'options'),
|
| 228 |
-
|
| 229 |
-
[dash.dependencies.Input('interval-component', 'n_intervals')
|
|
|
|
| 230 |
# [dash.dependencies.Input('path-input', 'value')],
|
| 231 |
)
|
| 232 |
-
def load_data(n_intervals):
|
| 233 |
selected_path = "Results"
|
| 234 |
print("selected path is",selected_path)
|
| 235 |
global data_store
|
| 236 |
|
| 237 |
-
if n_intervals > 0:
|
| 238 |
if selected_path is None or not os.path.isdir(selected_path):
|
| 239 |
return [], []
|
| 240 |
subfolder_labels, data = parse_all_data(selected_path)
|
|
@@ -244,9 +245,9 @@ def load_data(n_intervals):
|
|
| 244 |
# Store data in the global dictionary
|
| 245 |
data_store = data
|
| 246 |
labels = list(data[list(data.keys())[0]]['aircraft_data'][list(data[list(data.keys())[0]]['aircraft_data'].keys())[0]].columns.tolist()) # Extracting column names for the first aircraft-specific dataframe
|
| 247 |
-
return subfolder_labels, labels
|
| 248 |
else:
|
| 249 |
-
return [], []
|
| 250 |
|
| 251 |
# Define the callback to update the graphs based on the slider value
|
| 252 |
@app.callback(
|
|
|
|
| 83 |
|
| 84 |
# Create the layout for the app
|
| 85 |
app.layout = html.Div([
|
| 86 |
+
html.Div([
|
| 87 |
+
html.B("This is an interactive demonstration of case study results to showcase the ability of modeling and simulation to help envision distributed work systems"),
|
| 88 |
+
html.Br(),
|
| 89 |
+
dcc.Markdown("This interactive demo was performed under NASA contract number 80NSSC23CA121.", id="explanation")
|
| 90 |
+
], style={'width': '100%', 'border': '1px solid gray'}),
|
| 91 |
+
html.Div([
|
| 92 |
+
dcc.Markdown("It is envisioned that in future operatoins, each UAV is going to be controlled using a command and control (C2) link that allows communication with the remote pilot. This architecture can have potentially dangerous implications in the case of a failure of the command and control link. The UAV's are envisioned to be programmed with one or more contingency procedures that are to be executed in the case of a lost link. For example, to divert to and land at the nearest vertiport or continue along its preapproved route. This brings the question of how will the rest of the system need to react to the change in the aircraft trajectory. Is a system like this robust to an event like loss of link? ", id="explanation2")
|
| 93 |
+
], style={'width': '100%', 'border': '1px solid gray'}),
|
| 94 |
+
html.Div([
|
| 95 |
+
dcc.Markdown("If the dropdown menu is empty please wait a few seconds to allow the data to load. If the data doesnt load then click the submit button to force reload the dropdown. The files that contain data will take a few seconds to load so please be patient.", id="explanation"),
|
| 96 |
+
html.Button('Submit', id='submit-button', n_clicks=0)
|
| 97 |
+
], style={'width': '100%', 'border': '1px solid gray'}),
|
| 98 |
html.Div([
|
| 99 |
# html.Div([
|
| 100 |
# html.Div("Select the desired input conditions, then click 'Simulate!':", id='text1'),
|
|
|
|
| 129 |
# html.Br(),
|
| 130 |
# html.Button('Simulate!', id='button', n_clicks=0),
|
| 131 |
# ], style={'width': '50%', 'border': '1px solid gray'}),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 132 |
html.Div([
|
| 133 |
# html.Div("Next, input the relative path to your results folder, then click 'Submit'. This will load the data:", id='text2'),
|
| 134 |
# dcc.Input(
|
|
|
|
| 140 |
# ),
|
| 141 |
# html.Button('Submit', id='submit-button', n_clicks=0),
|
| 142 |
# Create a dropdown menu with the subfolders as options
|
| 143 |
+
html.Div("Select which condition to load in the interactive graphs:", id='text2'),
|
| 144 |
dcc.Dropdown(
|
| 145 |
id='subfolder-dropdown',
|
| 146 |
value=None #subfolders[0] # Default value
|
|
|
|
| 225 |
@app.callback(
|
| 226 |
dash.dependencies.Output('subfolder-dropdown', 'options'),
|
| 227 |
dash.dependencies.Output('variable-dropdown', 'options'),
|
| 228 |
+
dash.dependencies.Output('submit-button', 'n_clicks'), # Add this output to reset submit button clicks
|
| 229 |
+
[dash.dependencies.Input('interval-component', 'n_intervals'),
|
| 230 |
+
dash.dependencies.Input('submit-button', 'n_clicks')],
|
| 231 |
# [dash.dependencies.Input('path-input', 'value')],
|
| 232 |
)
|
| 233 |
+
def load_data(n_intervals, n_clicks):
|
| 234 |
selected_path = "Results"
|
| 235 |
print("selected path is",selected_path)
|
| 236 |
global data_store
|
| 237 |
|
| 238 |
+
if n_intervals > 0 or n_clicks > 0:
|
| 239 |
if selected_path is None or not os.path.isdir(selected_path):
|
| 240 |
return [], []
|
| 241 |
subfolder_labels, data = parse_all_data(selected_path)
|
|
|
|
| 245 |
# Store data in the global dictionary
|
| 246 |
data_store = data
|
| 247 |
labels = list(data[list(data.keys())[0]]['aircraft_data'][list(data[list(data.keys())[0]]['aircraft_data'].keys())[0]].columns.tolist()) # Extracting column names for the first aircraft-specific dataframe
|
| 248 |
+
return subfolder_labels, labels, 0
|
| 249 |
else:
|
| 250 |
+
return [], [], 0
|
| 251 |
|
| 252 |
# Define the callback to update the graphs based on the slider value
|
| 253 |
@app.callback(
|