Variables in SimulationThread now consistently distinguish real vs
simulation time in names.
This commit is contained in:
parent
82a40b5143
commit
e5060b33c5
|
@ -82,11 +82,3 @@ Project settings are in the standard Django location, `trafflights/settings.py`.
|
|||
1. **SIMULATION_START_TIME**: The internal time at which the simulation starts, in ISO text format. By default this is 07:59 for demonstration purposes.
|
||||
1. **SIMULATION_TIME_FACTOR**: The time "acceleration" factor (floating point) for the simulation. A factor of 1.0 will run in real-time, and higher factors will run faster. Default is 4.0.
|
||||
|
||||
# TODO List
|
||||
|
||||
1. Add instructions for installation/execution to README (including pre-requisites)
|
||||
1. Add configuration options for periods data file, start time, and time factor
|
||||
1. Change print statements to formal logging
|
||||
1. Remaining refinements for frontend (font, remove debug visual aids, time remaining)
|
||||
1. Move algorithm testing file to simulation directory, and change to use SimulationThread
|
||||
1. Consider variable naming to better delineate similation vs real time variables
|
||||
|
|
|
@ -45,8 +45,8 @@ class SimulationThread(threading.Thread):
|
|||
self.mutex = threading.Lock()
|
||||
|
||||
self.periods = periods
|
||||
self.start_time = start_time
|
||||
self.run_time = run_time
|
||||
self.start_simulation_time = start_time
|
||||
self.run_real_time = run_time
|
||||
self.time_factor = time_factor
|
||||
self.verbose = verbose
|
||||
|
||||
|
@ -55,9 +55,11 @@ class SimulationThread(threading.Thread):
|
|||
|
||||
self.current_period_index = 0
|
||||
self.current_state_index = 0
|
||||
self.next_changeover_time = None
|
||||
|
||||
self.simulation_start_datetime = None
|
||||
self.next_changeover_real_time = None
|
||||
|
||||
self.start_simulation_datetime = None
|
||||
self.current_simulation_datetime = None
|
||||
|
||||
# For convenience, convert all ISO format times to datetime.time objects
|
||||
for period in self.periods:
|
||||
|
@ -78,13 +80,12 @@ class SimulationThread(threading.Thread):
|
|||
"""
|
||||
Resets the simulation time to the provided time. This is for testing purposes; the current state is IGNORED and the sequence immediately resets to the beginning.
|
||||
"""
|
||||
new_datetime = datetime.datetime.fromisoformat("1900-01-01 " + new_time.isoformat())
|
||||
new_simulation_datetime = datetime.datetime.fromisoformat("1900-01-01 " + new_time.isoformat())
|
||||
self.mutex.acquire()
|
||||
print()
|
||||
# print("Forcing internal time change from {} to {}".format(self.simulation_start_datetime.time().isoformat(), new_time.isoformat()))
|
||||
self.current_period_index = self._get_period_index(self.periods, new_datetime.time())
|
||||
self.current_period_index = self._get_period_index(self.periods, new_simulation_datetime.time())
|
||||
self.current_state_index = 0
|
||||
self.next_changeover_time = time.time() + (self.periods[self.current_period_index]["states"][self.current_state_index]["duration"] / self.time_factor)
|
||||
self.next_changeover_real_time = time.time() + (self.periods[self.current_period_index]["states"][self.current_state_index]["duration"] / self.time_factor)
|
||||
self.mutex.release()
|
||||
|
||||
def get_snapshot(self):
|
||||
|
@ -98,9 +99,9 @@ class SimulationThread(threading.Thread):
|
|||
"current_period_index": self.current_period_index,
|
||||
"current_state_index": self.current_state_index,
|
||||
"current_state_data": self.periods[self.current_period_index]["states"][self.current_state_index],
|
||||
"next_changeover_time": self.next_changeover_time,
|
||||
"next_changeover_real_time": self.next_changeover_real_time,
|
||||
"simulation_time": self.current_simulation_datetime.time(),
|
||||
"time_remaining": (self.next_changeover_time - time.time()) * self.time_factor,
|
||||
"time_remaining": (self.next_changeover_real_time - time.time()) * self.time_factor,
|
||||
}
|
||||
self.mutex.release()
|
||||
return return_data
|
||||
|
@ -128,30 +129,29 @@ class SimulationThread(threading.Thread):
|
|||
- signal_stop() has been called
|
||||
- The executing program finishes (daemon=True)
|
||||
"""
|
||||
real_start_time = time.time()
|
||||
start_real_time = time.time()
|
||||
|
||||
self.simulation_start_datetime = None
|
||||
if self.start_time is None:
|
||||
self.simulation_start_datetime = datetime.datetime.now()
|
||||
if self.start_simulation_time is None:
|
||||
self.start_simulation_datetime = datetime.datetime.now()
|
||||
else:
|
||||
self.simulation_start_datetime = datetime.datetime.fromisoformat(
|
||||
"1900-01-01 " + self.start_time.isoformat())
|
||||
self.start_simulation_datetime = datetime.datetime.fromisoformat(
|
||||
"1900-01-01 " + self.start_simulation_time.isoformat())
|
||||
|
||||
self.current_period_index = self._get_period_index(self.simulation_start_datetime.time())
|
||||
self.current_period_index = self._get_period_index(self.start_simulation_datetime.time())
|
||||
self.current_state_index = 0
|
||||
|
||||
self.next_changeover_time = real_start_time + (self.periods[self.current_period_index]["states"][self.current_state_index]["duration"] / self.time_factor)
|
||||
self.next_changeover_real_time = start_real_time + (self.periods[self.current_period_index]["states"][self.current_state_index]["duration"] / self.time_factor)
|
||||
|
||||
if self.verbose:
|
||||
print("Starting with simulation time {}".format(self.simulation_start_datetime.time()))
|
||||
print("Starting with simulation time {}".format(self.start_simulation_datetime.time()))
|
||||
print("Initial state data: {}".format(self.periods[self.current_period_index]["states"][self.current_state_index]))
|
||||
if self.run_time is None:
|
||||
if self.run_real_time is None:
|
||||
print("No simulation time limit.")
|
||||
else:
|
||||
print("Simulation duration (in real second(s)): {}".format(self.run_time))
|
||||
print("Simulation duration (in real second(s)): {}".format(self.run_real_time))
|
||||
print("Time compression factor: {}".format(self.time_factor))
|
||||
|
||||
while (self.run_time is None) or (self.run_time is not None and time.time() < real_start_time + self.run_time):
|
||||
while (self.run_real_time is None) or (self.run_real_time is not None and time.time() < start_real_time + self.run_real_time):
|
||||
self.mutex.acquire()
|
||||
|
||||
if not self.running:
|
||||
|
@ -159,10 +159,10 @@ class SimulationThread(threading.Thread):
|
|||
break
|
||||
|
||||
now = time.time()
|
||||
self.current_simulation_datetime = self.simulation_start_datetime + datetime.timedelta(seconds=int((now - real_start_time) * self.time_factor))
|
||||
self.current_simulation_datetime = self.start_simulation_datetime + datetime.timedelta(seconds=int((now - start_real_time) * self.time_factor))
|
||||
timed_period_index = self._get_period_index(self.current_simulation_datetime.time())
|
||||
|
||||
if now >= self.next_changeover_time:
|
||||
if now >= self.next_changeover_real_time:
|
||||
timed_period_index = self._get_period_index(self.current_simulation_datetime.time())
|
||||
if timed_period_index != self.current_period_index and self.current_state_index == len(self.periods[self.current_period_index]["states"])-1:
|
||||
if self.verbose:
|
||||
|
@ -192,7 +192,8 @@ class SimulationThread(threading.Thread):
|
|||
|
||||
self.current_state_index = next_cycle_index
|
||||
|
||||
self.next_changeover_time = self.next_changeover_time + (self.periods[self.current_period_index]["states"][self.current_state_index]["duration"] / self.time_factor)
|
||||
# Ensure this calculation is done based on the PREVIOUS scheduled time to avoid "timing drift"
|
||||
self.next_changeover_real_time = self.next_changeover_real_time + (self.periods[self.current_period_index]["states"][self.current_state_index]["duration"] / self.time_factor)
|
||||
else:
|
||||
if self.verbose:
|
||||
print(".", end="")
|
||||
|
|
|
@ -105,7 +105,7 @@
|
|||
while (true)
|
||||
{
|
||||
await sleep(250);
|
||||
console.log("Tick");
|
||||
// console.log("Tick");
|
||||
req.open("GET", "/frontend/status", false);
|
||||
|
||||
// Note try/catch for exceptions is the only way to account for net::ERR_CONNECTION_REFUSED - this is NOT dealt with by XMLHttpRequest event hooks.
|
||||
|
|
Loading…
Reference in New Issue