multimodalsim-viewer 0.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- multimodalsim_viewer/__init__.py +0 -0
- multimodalsim_viewer/server/__init__.py +0 -0
- multimodalsim_viewer/server/http_routes.py +125 -0
- multimodalsim_viewer/server/log_manager.py +15 -0
- multimodalsim_viewer/server/scripts.py +72 -0
- multimodalsim_viewer/server/server.py +210 -0
- multimodalsim_viewer/server/server_utils.py +129 -0
- multimodalsim_viewer/server/simulation.py +154 -0
- multimodalsim_viewer/server/simulation_manager.py +607 -0
- multimodalsim_viewer/server/simulation_visualization_data_collector.py +756 -0
- multimodalsim_viewer/server/simulation_visualization_data_model.py +1693 -0
- multimodalsim_viewer/ui/__init__.py +0 -0
- multimodalsim_viewer/ui/cli.py +45 -0
- multimodalsim_viewer/ui/server.py +44 -0
- multimodalsim_viewer/ui/static/bitmap-fonts/custom-sans-serif.png +0 -0
- multimodalsim_viewer/ui/static/bitmap-fonts/custom-sans-serif.xml +1 -0
- multimodalsim_viewer/ui/static/chunk-MTC2LSCT.js +1 -0
- multimodalsim_viewer/ui/static/chunk-U5CGW4P4.js +7 -0
- multimodalsim_viewer/ui/static/favicon.ico +0 -0
- multimodalsim_viewer/ui/static/images/control-bar.png +0 -0
- multimodalsim_viewer/ui/static/images/sample-bus.png +0 -0
- multimodalsim_viewer/ui/static/images/sample-stop.png +0 -0
- multimodalsim_viewer/ui/static/images/sample-wait.png +0 -0
- multimodalsim_viewer/ui/static/images/simulation-control-bar.png +0 -0
- multimodalsim_viewer/ui/static/images/zoom-out-passenger.png +0 -0
- multimodalsim_viewer/ui/static/images/zoom-out-vehicle.png +0 -0
- multimodalsim_viewer/ui/static/index.html +15 -0
- multimodalsim_viewer/ui/static/main-X7OVCS3N.js +3648 -0
- multimodalsim_viewer/ui/static/media/layers-2x-TBM42ERR.png +0 -0
- multimodalsim_viewer/ui/static/media/layers-55W3Q4RM.png +0 -0
- multimodalsim_viewer/ui/static/media/marker-icon-2V3QKKVC.png +0 -0
- multimodalsim_viewer/ui/static/polyfills-FFHMD2TL.js +2 -0
- multimodalsim_viewer/ui/static/styles-KU7LTPET.css +1 -0
- multimodalsim_viewer-0.0.1.dist-info/METADATA +21 -0
- multimodalsim_viewer-0.0.1.dist-info/RECORD +38 -0
- multimodalsim_viewer-0.0.1.dist-info/WHEEL +5 -0
- multimodalsim_viewer-0.0.1.dist-info/entry_points.txt +8 -0
- multimodalsim_viewer-0.0.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,607 @@
|
|
1
|
+
import inspect
|
2
|
+
import logging
|
3
|
+
import multiprocessing
|
4
|
+
|
5
|
+
from flask_socketio import emit
|
6
|
+
from multimodalsim_viewer.server.server_utils import (
|
7
|
+
CLIENT_ROOM,
|
8
|
+
RUNNING_SIMULATION_STATUSES,
|
9
|
+
SAVE_VERSION,
|
10
|
+
SIMULATION_SAVE_FILE_SEPARATOR,
|
11
|
+
SimulationStatus,
|
12
|
+
build_simulation_id,
|
13
|
+
get_session_id,
|
14
|
+
log,
|
15
|
+
)
|
16
|
+
from multimodalsim_viewer.server.simulation import run_simulation
|
17
|
+
from multimodalsim_viewer.server.simulation_visualization_data_model import (
|
18
|
+
SimulationVisualizationDataManager,
|
19
|
+
)
|
20
|
+
|
21
|
+
|
22
|
+
class SimulationHandler:
|
23
|
+
simulation_id: str
|
24
|
+
name: str
|
25
|
+
start_time: float
|
26
|
+
data: str
|
27
|
+
process: multiprocessing.Process | None
|
28
|
+
status: SimulationStatus
|
29
|
+
socket_id: str | None
|
30
|
+
|
31
|
+
simulation_start_time: float | None
|
32
|
+
simulation_end_time: float | None
|
33
|
+
|
34
|
+
simulation_time: float | None
|
35
|
+
simulation_estimated_end_time: float | None
|
36
|
+
|
37
|
+
max_duration: float | None
|
38
|
+
|
39
|
+
polylines_version: int | None
|
40
|
+
|
41
|
+
def __init__(
|
42
|
+
self,
|
43
|
+
simulation_id: str,
|
44
|
+
name: str,
|
45
|
+
start_time: float,
|
46
|
+
data: str,
|
47
|
+
status: SimulationStatus,
|
48
|
+
max_duration: float | None,
|
49
|
+
process: multiprocessing.Process | None,
|
50
|
+
) -> None:
|
51
|
+
self.simulation_id = simulation_id
|
52
|
+
self.name = name
|
53
|
+
self.start_time = start_time
|
54
|
+
self.data = data
|
55
|
+
self.process = process
|
56
|
+
self.status = status
|
57
|
+
|
58
|
+
self.socket_id = None
|
59
|
+
|
60
|
+
self.simulation_start_time = None
|
61
|
+
self.simulation_end_time = None
|
62
|
+
self.simulation_time = None
|
63
|
+
self.simulation_estimated_end_time = None
|
64
|
+
|
65
|
+
self.max_duration = max_duration
|
66
|
+
|
67
|
+
self.polylines_version = None
|
68
|
+
|
69
|
+
|
70
|
+
class SimulationManager:
|
71
|
+
simulations: dict[str, SimulationHandler]
|
72
|
+
|
73
|
+
def __init__(self):
|
74
|
+
self.simulations = {}
|
75
|
+
|
76
|
+
def start_simulation(
|
77
|
+
self, name: str, data: str, response_event: str, max_duration: float | None
|
78
|
+
) -> SimulationHandler:
|
79
|
+
simulation_id, start_time = build_simulation_id(name)
|
80
|
+
|
81
|
+
simulation_process = multiprocessing.Process(
|
82
|
+
target=run_simulation, args=(simulation_id, data, max_duration)
|
83
|
+
)
|
84
|
+
|
85
|
+
simulation_handler = SimulationHandler(
|
86
|
+
simulation_id,
|
87
|
+
name,
|
88
|
+
start_time,
|
89
|
+
data,
|
90
|
+
SimulationStatus.STARTING,
|
91
|
+
max_duration,
|
92
|
+
simulation_process,
|
93
|
+
)
|
94
|
+
|
95
|
+
self.simulations[simulation_id] = simulation_handler
|
96
|
+
|
97
|
+
simulation_process.start()
|
98
|
+
|
99
|
+
self.emit_simulations()
|
100
|
+
|
101
|
+
log(f'Emitting response event "{response_event}"', "server")
|
102
|
+
emit(response_event, simulation_id, to=CLIENT_ROOM)
|
103
|
+
|
104
|
+
return simulation_handler
|
105
|
+
|
106
|
+
def on_simulation_start(self, simulation_id, socket_id, simulation_start_time):
|
107
|
+
if simulation_id not in self.simulations:
|
108
|
+
log(
|
109
|
+
f"{__file__} {inspect.currentframe().f_lineno}: Simulation {simulation_id} not found",
|
110
|
+
"server",
|
111
|
+
logging.ERROR,
|
112
|
+
)
|
113
|
+
return
|
114
|
+
|
115
|
+
simulation = self.simulations[simulation_id]
|
116
|
+
|
117
|
+
simulation.socket_id = socket_id
|
118
|
+
simulation.status = SimulationStatus.RUNNING
|
119
|
+
simulation.simulation_start_time = simulation_start_time
|
120
|
+
|
121
|
+
self.emit_simulations()
|
122
|
+
|
123
|
+
def stop_simulation(self, simulation_id):
|
124
|
+
if simulation_id not in self.simulations:
|
125
|
+
log(
|
126
|
+
f"{__file__} {inspect.currentframe().f_lineno}: Simulation {simulation_id} not found",
|
127
|
+
"server",
|
128
|
+
logging.ERROR,
|
129
|
+
)
|
130
|
+
return
|
131
|
+
|
132
|
+
simulation = self.simulations[simulation_id]
|
133
|
+
simulation.status = SimulationStatus.STOPPING
|
134
|
+
|
135
|
+
emit("stop-simulation", to=simulation.socket_id)
|
136
|
+
|
137
|
+
def pause_simulation(self, simulation_id):
|
138
|
+
if simulation_id not in self.simulations:
|
139
|
+
log(
|
140
|
+
f"{__file__} {inspect.currentframe().f_lineno}: Simulation {simulation_id} not found",
|
141
|
+
"server",
|
142
|
+
logging.ERROR,
|
143
|
+
)
|
144
|
+
return
|
145
|
+
|
146
|
+
simulation = self.simulations[simulation_id]
|
147
|
+
|
148
|
+
emit("pause-simulation", to=simulation.socket_id)
|
149
|
+
|
150
|
+
def on_simulation_pause(self, simulation_id):
|
151
|
+
if simulation_id not in self.simulations:
|
152
|
+
log(
|
153
|
+
f"{__file__} {inspect.currentframe().f_lineno}: Simulation {simulation_id} not found",
|
154
|
+
"server",
|
155
|
+
logging.ERROR,
|
156
|
+
)
|
157
|
+
return
|
158
|
+
|
159
|
+
simulation = self.simulations[simulation_id]
|
160
|
+
|
161
|
+
simulation.status = SimulationStatus.PAUSED
|
162
|
+
|
163
|
+
self.emit_simulations()
|
164
|
+
|
165
|
+
def resume_simulation(self, simulation_id):
|
166
|
+
if simulation_id not in self.simulations:
|
167
|
+
log(
|
168
|
+
f"{__file__} {inspect.currentframe().f_lineno}: Simulation {simulation_id} not found",
|
169
|
+
"server",
|
170
|
+
logging.ERROR,
|
171
|
+
)
|
172
|
+
return
|
173
|
+
|
174
|
+
simulation = self.simulations[simulation_id]
|
175
|
+
|
176
|
+
emit("resume-simulation", to=simulation.socket_id)
|
177
|
+
|
178
|
+
def on_simulation_resume(self, simulation_id):
|
179
|
+
if simulation_id not in self.simulations:
|
180
|
+
log(
|
181
|
+
f"{__file__} {inspect.currentframe().f_lineno}: Simulation {simulation_id} not found",
|
182
|
+
"server",
|
183
|
+
logging.ERROR,
|
184
|
+
)
|
185
|
+
return
|
186
|
+
|
187
|
+
simulation = self.simulations[simulation_id]
|
188
|
+
|
189
|
+
simulation.status = SimulationStatus.RUNNING
|
190
|
+
|
191
|
+
self.emit_simulations()
|
192
|
+
|
193
|
+
def edit_simulation_configuration(
|
194
|
+
self, simulation_id: str, max_duration: float | None
|
195
|
+
) -> None:
|
196
|
+
if simulation_id not in self.simulations:
|
197
|
+
log(
|
198
|
+
f"{__file__} {inspect.currentframe().f_lineno}: Simulation {simulation_id} not found",
|
199
|
+
"server",
|
200
|
+
logging.ERROR,
|
201
|
+
)
|
202
|
+
return
|
203
|
+
|
204
|
+
simulation = self.simulations[simulation_id]
|
205
|
+
|
206
|
+
simulation.max_duration = max_duration
|
207
|
+
|
208
|
+
emit("edit-simulation-configuration", (max_duration,), to=simulation.socket_id)
|
209
|
+
|
210
|
+
self.emit_simulations()
|
211
|
+
|
212
|
+
log(
|
213
|
+
f"Emitted simulations with new max duration {max_duration} for simulation {simulation_id}",
|
214
|
+
"server",
|
215
|
+
logging.WARN,
|
216
|
+
)
|
217
|
+
|
218
|
+
def on_simulation_disconnect(self, socket_id):
|
219
|
+
matching_simulation_ids = [
|
220
|
+
simulation_id
|
221
|
+
for simulation_id, simulation in self.simulations.items()
|
222
|
+
if simulation.socket_id == socket_id
|
223
|
+
]
|
224
|
+
|
225
|
+
if len(matching_simulation_ids) != 1:
|
226
|
+
# The simulation has already been disconnected properly
|
227
|
+
return
|
228
|
+
|
229
|
+
simulation_id = matching_simulation_ids[0]
|
230
|
+
|
231
|
+
# Get the simulation information from the save file
|
232
|
+
simulation_information = (
|
233
|
+
SimulationVisualizationDataManager.get_simulation_information(simulation_id)
|
234
|
+
)
|
235
|
+
|
236
|
+
simulation = self.simulations[simulation_id]
|
237
|
+
|
238
|
+
if simulation.status in RUNNING_SIMULATION_STATUSES:
|
239
|
+
if simulation_information.simulation_end_time is None:
|
240
|
+
# The simulation has been lost
|
241
|
+
simulation.status = SimulationStatus.LOST
|
242
|
+
else:
|
243
|
+
# The simulation has been completed
|
244
|
+
simulation.status = SimulationStatus.COMPLETED
|
245
|
+
|
246
|
+
simulation.socket_id = None
|
247
|
+
|
248
|
+
self.emit_simulations()
|
249
|
+
|
250
|
+
def on_simulation_update_time(self, simulation_id, timestamp):
|
251
|
+
if simulation_id not in self.simulations:
|
252
|
+
log(
|
253
|
+
f"{__file__} {inspect.currentframe().f_lineno}: Simulation {simulation_id} not found",
|
254
|
+
"server",
|
255
|
+
logging.ERROR,
|
256
|
+
)
|
257
|
+
return
|
258
|
+
|
259
|
+
simulation = self.simulations[simulation_id]
|
260
|
+
|
261
|
+
simulation.simulation_time = timestamp
|
262
|
+
|
263
|
+
self.emit_simulations()
|
264
|
+
|
265
|
+
def on_simulation_update_estimated_end_time(
|
266
|
+
self, simulation_id, estimated_end_time
|
267
|
+
):
|
268
|
+
if simulation_id not in self.simulations:
|
269
|
+
log(
|
270
|
+
f"{__file__} {inspect.currentframe().f_lineno}: Simulation {simulation_id} not found",
|
271
|
+
"server",
|
272
|
+
logging.ERROR,
|
273
|
+
)
|
274
|
+
return
|
275
|
+
|
276
|
+
simulation = self.simulations[simulation_id]
|
277
|
+
|
278
|
+
simulation.simulation_estimated_end_time = estimated_end_time
|
279
|
+
|
280
|
+
self.emit_simulations()
|
281
|
+
|
282
|
+
def on_simulation_update_polylines_version(self, simulation_id):
|
283
|
+
if simulation_id not in self.simulations:
|
284
|
+
log(
|
285
|
+
f"{__file__} {inspect.currentframe().f_lineno}: Simulation {simulation_id} not found",
|
286
|
+
"server",
|
287
|
+
logging.ERROR,
|
288
|
+
)
|
289
|
+
return
|
290
|
+
|
291
|
+
simulation = self.simulations[simulation_id]
|
292
|
+
|
293
|
+
simulation.polylines_version = (
|
294
|
+
SimulationVisualizationDataManager.get_polylines_version_with_lock(
|
295
|
+
simulation_id
|
296
|
+
)
|
297
|
+
)
|
298
|
+
|
299
|
+
self.emit_simulations()
|
300
|
+
|
301
|
+
def on_simulation_identification(
|
302
|
+
self,
|
303
|
+
simulation_id,
|
304
|
+
data,
|
305
|
+
simulation_start_time,
|
306
|
+
simulation_time,
|
307
|
+
simulation_estimated_end_time,
|
308
|
+
max_duration,
|
309
|
+
status,
|
310
|
+
socket_id,
|
311
|
+
):
|
312
|
+
|
313
|
+
log(
|
314
|
+
f"Identifying simulation {simulation_id}",
|
315
|
+
"simulation",
|
316
|
+
)
|
317
|
+
|
318
|
+
start_time, name = simulation_id.split(SIMULATION_SAVE_FILE_SEPARATOR)
|
319
|
+
|
320
|
+
if simulation_id in self.simulations:
|
321
|
+
simulation = self.simulations[simulation_id]
|
322
|
+
else:
|
323
|
+
start_time, name = simulation_id.split(SIMULATION_SAVE_FILE_SEPARATOR)
|
324
|
+
|
325
|
+
simulation = SimulationHandler(
|
326
|
+
simulation_id,
|
327
|
+
name,
|
328
|
+
start_time,
|
329
|
+
data,
|
330
|
+
SimulationStatus(status),
|
331
|
+
max_duration,
|
332
|
+
None,
|
333
|
+
)
|
334
|
+
|
335
|
+
self.simulations[simulation_id] = simulation
|
336
|
+
|
337
|
+
simulation.name = name
|
338
|
+
simulation.start_time = start_time
|
339
|
+
simulation.data = data
|
340
|
+
simulation.simulation_start_time = simulation_start_time
|
341
|
+
simulation.simulation_time = simulation_time
|
342
|
+
simulation.simulation_estimated_end_time = simulation_estimated_end_time
|
343
|
+
simulation.max_duration = max_duration
|
344
|
+
simulation.status = SimulationStatus(status)
|
345
|
+
simulation.socket_id = socket_id
|
346
|
+
|
347
|
+
simulation.polylines_version = (
|
348
|
+
SimulationVisualizationDataManager.get_polylines_version_with_lock(
|
349
|
+
simulation_id
|
350
|
+
)
|
351
|
+
)
|
352
|
+
|
353
|
+
self.emit_simulations()
|
354
|
+
|
355
|
+
def emit_simulations(self):
|
356
|
+
self.query_simulations()
|
357
|
+
|
358
|
+
serialized_simulations = []
|
359
|
+
|
360
|
+
for simulation_id, simulation in self.simulations.items():
|
361
|
+
serialized_simulation = {
|
362
|
+
"id": simulation_id,
|
363
|
+
"name": simulation.name,
|
364
|
+
"status": simulation.status.value,
|
365
|
+
"startTime": simulation.start_time,
|
366
|
+
"data": simulation.data,
|
367
|
+
}
|
368
|
+
|
369
|
+
if simulation.simulation_start_time is not None:
|
370
|
+
serialized_simulation["simulationStartTime"] = (
|
371
|
+
simulation.simulation_start_time
|
372
|
+
)
|
373
|
+
|
374
|
+
if simulation.simulation_end_time is not None:
|
375
|
+
serialized_simulation["simulationEndTime"] = (
|
376
|
+
simulation.simulation_end_time
|
377
|
+
)
|
378
|
+
|
379
|
+
if simulation.simulation_time is not None:
|
380
|
+
serialized_simulation["simulationTime"] = simulation.simulation_time
|
381
|
+
|
382
|
+
if simulation.simulation_estimated_end_time is not None:
|
383
|
+
serialized_simulation["simulationEstimatedEndTime"] = (
|
384
|
+
simulation.simulation_estimated_end_time
|
385
|
+
)
|
386
|
+
|
387
|
+
if simulation.max_duration is not None:
|
388
|
+
serialized_simulation["configuration"] = {
|
389
|
+
"maxDuration": simulation.max_duration
|
390
|
+
}
|
391
|
+
|
392
|
+
if simulation.polylines_version is not None:
|
393
|
+
serialized_simulation["polylinesVersion"] = simulation.polylines_version
|
394
|
+
|
395
|
+
serialized_simulations.append(serialized_simulation)
|
396
|
+
|
397
|
+
emit(
|
398
|
+
"simulations",
|
399
|
+
serialized_simulations,
|
400
|
+
to=CLIENT_ROOM,
|
401
|
+
)
|
402
|
+
|
403
|
+
log("Emitting simulations", "server")
|
404
|
+
|
405
|
+
def emit_missing_simulation_states(
|
406
|
+
self,
|
407
|
+
simulation_id: str,
|
408
|
+
visualization_time: float,
|
409
|
+
loaded_state_orders: list[int],
|
410
|
+
) -> None:
|
411
|
+
if simulation_id not in self.simulations:
|
412
|
+
log(
|
413
|
+
f"{__file__} {inspect.currentframe().f_lineno}: Simulation {simulation_id} not found",
|
414
|
+
"server",
|
415
|
+
logging.ERROR,
|
416
|
+
)
|
417
|
+
return
|
418
|
+
|
419
|
+
simulation = self.simulations[simulation_id]
|
420
|
+
|
421
|
+
try:
|
422
|
+
(
|
423
|
+
missing_states,
|
424
|
+
missing_updates,
|
425
|
+
state_orders_to_keep,
|
426
|
+
should_request_more_states,
|
427
|
+
first_continuous_state_order,
|
428
|
+
last_continuous_state_order,
|
429
|
+
necessary_state_order,
|
430
|
+
) = SimulationVisualizationDataManager.get_missing_states(
|
431
|
+
simulation_id,
|
432
|
+
visualization_time,
|
433
|
+
loaded_state_orders,
|
434
|
+
simulation.status not in RUNNING_SIMULATION_STATUSES,
|
435
|
+
)
|
436
|
+
|
437
|
+
emit(
|
438
|
+
"missing-simulation-states",
|
439
|
+
(
|
440
|
+
missing_states,
|
441
|
+
missing_updates,
|
442
|
+
state_orders_to_keep,
|
443
|
+
should_request_more_states,
|
444
|
+
first_continuous_state_order,
|
445
|
+
last_continuous_state_order,
|
446
|
+
necessary_state_order,
|
447
|
+
),
|
448
|
+
to=get_session_id(),
|
449
|
+
)
|
450
|
+
|
451
|
+
except Exception as e:
|
452
|
+
log(
|
453
|
+
f"Error while emitting missing simulation states for {simulation_id}: {e}",
|
454
|
+
"server",
|
455
|
+
logging.ERROR,
|
456
|
+
)
|
457
|
+
log(
|
458
|
+
f"Marking simulation {simulation_id} as corrupted",
|
459
|
+
"server",
|
460
|
+
logging.ERROR,
|
461
|
+
)
|
462
|
+
|
463
|
+
simulation.status = SimulationStatus.CORRUPTED
|
464
|
+
|
465
|
+
SimulationVisualizationDataManager.mark_simulation_as_corrupted(
|
466
|
+
simulation_id
|
467
|
+
)
|
468
|
+
|
469
|
+
self.emit_simulations()
|
470
|
+
|
471
|
+
def emit_simulation_polylines(self, simulation_id):
|
472
|
+
if simulation_id not in self.simulations:
|
473
|
+
log(
|
474
|
+
f"{__file__} {inspect.currentframe().f_lineno}: Simulation {simulation_id} not found",
|
475
|
+
"server",
|
476
|
+
logging.ERROR,
|
477
|
+
)
|
478
|
+
return
|
479
|
+
|
480
|
+
polylines, version = SimulationVisualizationDataManager.get_polylines(
|
481
|
+
simulation_id
|
482
|
+
)
|
483
|
+
|
484
|
+
emit(f"polylines-{simulation_id}", (polylines, version), to=CLIENT_ROOM)
|
485
|
+
|
486
|
+
def query_simulations(self):
|
487
|
+
all_simulation_ids = (
|
488
|
+
SimulationVisualizationDataManager.get_all_saved_simulation_ids()
|
489
|
+
)
|
490
|
+
|
491
|
+
for simulation_id, _ in list(self.simulations.items()):
|
492
|
+
if simulation_id not in all_simulation_ids and self.simulations[
|
493
|
+
simulation_id
|
494
|
+
].status not in [
|
495
|
+
SimulationStatus.RUNNING,
|
496
|
+
SimulationStatus.PAUSED,
|
497
|
+
SimulationStatus.STOPPING,
|
498
|
+
SimulationStatus.STARTING,
|
499
|
+
SimulationStatus.LOST,
|
500
|
+
]:
|
501
|
+
del self.simulations[simulation_id]
|
502
|
+
|
503
|
+
for simulation_id in all_simulation_ids:
|
504
|
+
# Non valid save files might throw an exception
|
505
|
+
self.query_simulation(simulation_id)
|
506
|
+
|
507
|
+
def query_simulation(self, simulation_id) -> None:
|
508
|
+
if simulation_id in self.simulations and self.simulations[
|
509
|
+
simulation_id
|
510
|
+
].status in [
|
511
|
+
SimulationStatus.RUNNING,
|
512
|
+
SimulationStatus.PAUSED,
|
513
|
+
SimulationStatus.STOPPING,
|
514
|
+
SimulationStatus.STARTING,
|
515
|
+
SimulationStatus.LOST,
|
516
|
+
]:
|
517
|
+
return
|
518
|
+
|
519
|
+
is_corrupted = SimulationVisualizationDataManager.is_simulation_corrupted(
|
520
|
+
simulation_id
|
521
|
+
)
|
522
|
+
|
523
|
+
if not is_corrupted:
|
524
|
+
# Non valid save files throw an exception
|
525
|
+
try:
|
526
|
+
# Get the simulation information from the save file
|
527
|
+
simulation_information = (
|
528
|
+
SimulationVisualizationDataManager.get_simulation_information(
|
529
|
+
simulation_id
|
530
|
+
)
|
531
|
+
)
|
532
|
+
|
533
|
+
# Get the version of the polylines
|
534
|
+
polylines_version = (
|
535
|
+
SimulationVisualizationDataManager.get_polylines_version_with_lock(
|
536
|
+
simulation_id
|
537
|
+
)
|
538
|
+
)
|
539
|
+
|
540
|
+
# Verify the version of the save file
|
541
|
+
version = simulation_information.version
|
542
|
+
|
543
|
+
status = SimulationStatus.COMPLETED
|
544
|
+
if version < SAVE_VERSION:
|
545
|
+
status = SimulationStatus.OUTDATED
|
546
|
+
elif version > SAVE_VERSION:
|
547
|
+
status = SimulationStatus.FUTURE
|
548
|
+
|
549
|
+
if status == SimulationStatus.OUTDATED:
|
550
|
+
log(
|
551
|
+
f"Simulation {simulation_id} version is outdated",
|
552
|
+
"server",
|
553
|
+
logging.DEBUG,
|
554
|
+
)
|
555
|
+
if status == SimulationStatus.FUTURE:
|
556
|
+
log(
|
557
|
+
f"Simulation {simulation_id} version is future",
|
558
|
+
"server",
|
559
|
+
logging.DEBUG,
|
560
|
+
)
|
561
|
+
|
562
|
+
simulation = SimulationHandler(
|
563
|
+
simulation_id,
|
564
|
+
simulation_information.name,
|
565
|
+
simulation_information.start_time,
|
566
|
+
simulation_information.data,
|
567
|
+
status,
|
568
|
+
None,
|
569
|
+
None,
|
570
|
+
)
|
571
|
+
|
572
|
+
simulation.simulation_start_time = (
|
573
|
+
simulation_information.simulation_start_time
|
574
|
+
)
|
575
|
+
simulation.simulation_end_time = (
|
576
|
+
simulation_information.simulation_end_time
|
577
|
+
)
|
578
|
+
|
579
|
+
simulation.polylines_version = polylines_version
|
580
|
+
|
581
|
+
if simulation_information.simulation_end_time is None:
|
582
|
+
# The simulation is not running but the end time is not set
|
583
|
+
raise Exception("Simulation is corrupted")
|
584
|
+
|
585
|
+
self.simulations[simulation_id] = simulation
|
586
|
+
|
587
|
+
except:
|
588
|
+
is_corrupted = True
|
589
|
+
|
590
|
+
if is_corrupted:
|
591
|
+
log(f"Simulation {simulation_id} is corrupted", "server", logging.DEBUG)
|
592
|
+
|
593
|
+
simulation = SimulationHandler(
|
594
|
+
simulation_id,
|
595
|
+
"unknown",
|
596
|
+
"unknown",
|
597
|
+
"unknown",
|
598
|
+
SimulationStatus.CORRUPTED,
|
599
|
+
None,
|
600
|
+
None,
|
601
|
+
)
|
602
|
+
|
603
|
+
self.simulations[simulation_id] = simulation
|
604
|
+
|
605
|
+
SimulationVisualizationDataManager.mark_simulation_as_corrupted(
|
606
|
+
simulation_id
|
607
|
+
)
|